From 7f9c693b3d90ebd5bbb7a99d99ba0dc6213dcb47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Mon, 13 Jul 2009 22:40:40 +0200 Subject: Implement a clean full login procedure. diff --git a/Limber/main.cpp b/Limber/main.cpp index c3db296..be7387e 100644 --- a/Limber/main.cpp +++ b/Limber/main.cpp @@ -8,11 +8,15 @@ #include #include +#include "Swiften/Elements/IQ.h" +#include "Swiften/Elements/RosterPayload.h" +#include "Swiften/Elements/VCard.h" #include "Swiften/Server/SimpleUserRegistry.h" #include "Swiften/Base/ByteArray.h" #include "Swiften/Base/IDGenerator.h" #include "Swiften/EventLoop/MainEventLoop.h" #include "Swiften/EventLoop/SimpleEventLoop.h" +#include "Swiften/Elements/Stanza.h" #include "Swiften/Network/ConnectionServer.h" #include "Swiften/Network/BoostIOServiceThread.h" #include "Swiften/Server/ServerFromClientSession.h" @@ -136,6 +140,7 @@ class Server { void handleNewConnection(boost::shared_ptr c) { ServerFromClientSession* session = new ServerFromClientSession(idGenerator_.generateID(), c, &payloadParserFactories_, &payloadSerializers_, userRegistry_); serverFromClientSessions_.push_back(session); + session->onStanzaReceived.connect(boost::bind(&Server::handleStanzaReceived, this, _1, session)); session->onSessionFinished.connect(boost::bind(&Server::handleSessionFinished, this, session)); } @@ -144,6 +149,33 @@ class Server { delete session; } + void handleStanzaReceived(boost::shared_ptr stanza, ServerFromClientSession* session) { + stanza->setFrom(session->getJID()); + if (!stanza->getTo().isValid()) { + stanza->setTo(JID(session->getDomain())); + } + if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) { + if (boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza)) { + if (iq->getPayload()) { + session->sendStanza(IQ::createResult(iq->getFrom(), iq->getID(), boost::shared_ptr(new RosterPayload()))); + } + if (iq->getPayload()) { + if (iq->getType() == IQ::Get) { + boost::shared_ptr vcard(new VCard()); + vcard->setNickname(iq->getFrom().getNode()); + session->sendStanza(IQ::createResult(iq->getFrom(), iq->getID(), vcard)); + } + else { + session->sendStanza(IQ::createError(iq->getFrom(), iq->getID(), Error::Forbidden, Error::Cancel)); + } + } + else { + session->sendStanza(IQ::createError(iq->getFrom(), iq->getID(), Error::FeatureNotImplemented, Error::Cancel)); + } + } + } + } + private: IDGenerator idGenerator_; UserRegistry* userRegistry_; diff --git a/Swiften/Elements/VCard.h b/Swiften/Elements/VCard.h index 53be318..f389ba7 100644 --- a/Swiften/Elements/VCard.h +++ b/Swiften/Elements/VCard.h @@ -9,6 +9,9 @@ namespace Swift { public: VCard() {} + void setNickname(const String& nick) { nick_ = nick; } + const String& getNickname() const { return nick_; } + void setPhoto(const ByteArray& photo) { photo_ = photo; } const ByteArray& getPhoto() { return photo_; } @@ -18,5 +21,6 @@ namespace Swift { private: ByteArray photo_; String photoType_; + String nick_; }; } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp index 2d16636..bfae4f0 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp @@ -10,6 +10,7 @@ class VCardParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(VCardParserTest); CPPUNIT_TEST(testParse_Photo); + CPPUNIT_TEST(testParse_Nickname); CPPUNIT_TEST_SUITE_END(); public: @@ -34,6 +35,19 @@ class VCardParserTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), payload->getPhotoType()); CPPUNIT_ASSERT_EQUAL(ByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), payload->getPhoto()); } + + void testParse_Nickname() { + VCardParser testling; + PayloadParserTester parser(&testling); + + CPPUNIT_ASSERT(parser.parse( + "" + "mynick" + "")); + + VCard* payload = dynamic_cast(testling.getPayload().get()); + CPPUNIT_ASSERT_EQUAL(String("mynick"), payload->getNickname()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(VCardParserTest); diff --git a/Swiften/Parser/PayloadParsers/VCardParser.cpp b/Swiften/Parser/PayloadParsers/VCardParser.cpp index a6fe2be..b7845a7 100644 --- a/Swiften/Parser/PayloadParsers/VCardParser.cpp +++ b/Swiften/Parser/PayloadParsers/VCardParser.cpp @@ -20,6 +20,9 @@ void VCardParser::handleEndElement(const String&, const String&) { else if (elementHierarchy == "/vCard/PHOTO/BINVAL") { getPayloadInternal()->setPhoto(Base64::decode(currentText_)); } + else if (elementHierarchy == "/vCard/NICKNAME") { + getPayloadInternal()->setNickname(currentText_); + } elementStack_.pop_back(); } diff --git a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp index 4e1a762..26e1623 100644 --- a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp @@ -3,14 +3,20 @@ #include #include "Swiften/Serializer/XML/XMLElement.h" +#include "Swiften/Serializer/XML/XMLTextNode.h" namespace Swift { VCardSerializer::VCardSerializer() : GenericPayloadSerializer() { } -String VCardSerializer::serializePayload(boost::shared_ptr) const { +String VCardSerializer::serializePayload(boost::shared_ptr vcard) const { XMLElement queryElement("vCard", "vcard-temp"); + if (!vcard->getNickname().isEmpty()) { + boost::shared_ptr nickElement(new XMLElement("NICKNAME")); + nickElement->addNode(boost::shared_ptr(new XMLTextNode(vcard->getNickname()))); + queryElement.addNode(nickElement); + } // TODO return queryElement.serialize(); } diff --git a/Swiften/Server/ServerFromClientSession.cpp b/Swiften/Server/ServerFromClientSession.cpp index 4fc517f..e6ba28a 100644 --- a/Swiften/Server/ServerFromClientSession.cpp +++ b/Swiften/Server/ServerFromClientSession.cpp @@ -54,7 +54,12 @@ ServerFromClientSession::~ServerFromClientSession() { void ServerFromClientSession::handleElement(boost::shared_ptr element) { if (initialized_) { - onElementReceived(element); + if (boost::shared_ptr stanza = boost::dynamic_pointer_cast(element)) { + onStanzaReceived(stanza); + } + else { + std::cerr << "Received unexpected element" << std::endl; + } } else { if (AuthRequest* authRequest = dynamic_cast(element.get())) { @@ -64,8 +69,9 @@ void ServerFromClientSession::handleElement(boost::shared_ptr element) } else { PLAINMessage plainMessage(authRequest->getMessage()); - if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), domain_), plainMessage.getPassword())) { + if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), domain_.getDomain()), plainMessage.getPassword())) { xmppLayer_->writeElement(boost::shared_ptr(new AuthSuccess())); + user_ = plainMessage.getAuthenticationID(); authenticated_ = true; xmppLayer_->resetParser(); } @@ -77,7 +83,7 @@ void ServerFromClientSession::handleElement(boost::shared_ptr element) } else if (IQ* iq = dynamic_cast(element.get())) { if (boost::shared_ptr resourceBind = iq->getPayload()) { - jid_ = JID(user_, domain_, resourceBind->getResource()); + jid_ = JID(user_, domain_.getDomain(), resourceBind->getResource()); boost::shared_ptr resultResourceBind(new ResourceBind()); resultResourceBind->setJID(jid_); xmppLayer_->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind)); @@ -91,8 +97,8 @@ void ServerFromClientSession::handleElement(boost::shared_ptr element) } void ServerFromClientSession::handleStreamStart(const String& domain) { - domain_ = domain; - xmppLayer_->writeHeader(domain_, id_); + domain_ = JID("", domain); + xmppLayer_->writeHeader(domain, id_); boost::shared_ptr features(new StreamFeatures()); if (!authenticated_) { @@ -105,4 +111,9 @@ void ServerFromClientSession::handleStreamStart(const String& domain) { xmppLayer_->writeElement(features); } +void ServerFromClientSession::sendStanza(boost::shared_ptr stanza) { + xmppLayer_->writeElement(stanza); +} + + } diff --git a/Swiften/Server/ServerFromClientSession.h b/Swiften/Server/ServerFromClientSession.h index 9b340bc..6c74093 100644 --- a/Swiften/Server/ServerFromClientSession.h +++ b/Swiften/Server/ServerFromClientSession.h @@ -8,6 +8,7 @@ namespace Swift { class Element; + class Stanza; class PayloadParserFactoryCollection; class PayloadSerializerCollection; class StreamStack; @@ -27,7 +28,17 @@ namespace Swift { UserRegistry* userRegistry); ~ServerFromClientSession(); - boost::signal)> onElementReceived; + void sendStanza(boost::shared_ptr); + + const JID& getJID() const { + return jid_; + } + + const JID& getDomain() const { + return domain_; + } + + boost::signal)> onStanzaReceived; boost::signal onSessionFinished; boost::signal onDataWritten; boost::signal onDataRead; @@ -47,7 +58,7 @@ namespace Swift { IncomingConnectionLayer* connectionLayer_; StreamStack* streamStack_; XMPPLayer* xmppLayer_; - String domain_; + JID domain_; String user_; JID jid_; }; -- cgit v0.10.2-6-g49f6