From 778a11d5dc68d2074338ec51e213b4a19949ba01 2011-05-20 00:11:00 From: HanzZ Date: 2011-05-20 00:11:00 Subject: [PATCH] support for jabber:iq:private in server mode --- diff --git a/include/transport/storagebackend.h b/include/transport/storagebackend.h index 1b4051a6efac1c9f51ae9a0ea0af99e5789d1da4..221cbdd8dda9741cb806b7d3b554f6a290734ab2 100644 --- a/include/transport/storagebackend.h +++ b/include/transport/storagebackend.h @@ -109,6 +109,7 @@ class StorageBackend virtual void removeBuddy(long id) = 0; virtual void getUserSetting(long userId, const std::string &variable, int &type, std::string &value) = 0; + virtual void updateUserSetting(long userId, const std::string &variable, const std::string &value) = 0; virtual void beginTransaction() = 0; virtual void commitTransaction() = 0; diff --git a/src/sqlite3backend.cpp b/src/sqlite3backend.cpp index e5032b3d60d56fed00d4f2446f809953ff620c84..afea46d8be1d2994bfcc4b64af0bea17929b0192 100644 --- a/src/sqlite3backend.cpp +++ b/src/sqlite3backend.cpp @@ -43,7 +43,7 @@ #define BEGIN(STATEMENT) sqlite3_reset(m_addBuddy);\ int STATEMENT##_id = 1;\ - int STATEMENT##_id_get = -1;\ + int STATEMENT##_id_get = 0;\ (void)STATEMENT##_id_get; #define BIND_INT(STATEMENT, VARIABLE) sqlite3_bind_int(STATEMENT, STATEMENT##_id++, VARIABLE) @@ -365,7 +365,7 @@ void SQLite3Backend::getUserSetting(long id, const std::string &variable, int &t BEGIN(m_getUserSetting); BIND_INT(m_getUserSetting, id); BIND_STR(m_getUserSetting, variable); - if(sqlite3_step(m_setUser) != SQLITE_ROW) { + if(sqlite3_step(m_getUserSetting) != SQLITE_ROW) { BEGIN(m_setUserSetting); BIND_INT(m_setUserSetting, id); BIND_STR(m_setUserSetting, variable); diff --git a/src/storageparser.cpp b/src/storageparser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e550964e1aa2f70769a0bd527717e87e700b8517 --- /dev/null +++ b/src/storageparser.cpp @@ -0,0 +1,41 @@ +#include "storageparser.h" +#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParser.h" + +using namespace Swift; + +namespace Transport { + +StorageParser::StorageParser() : level(0) { +} + +void StorageParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) { + if (level == 1) { + currentPayloadParser.reset(new RawXMLPayloadParser()); + } + + if (level >= 1 && currentPayloadParser.get()) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + ++level; +} + +void StorageParser::handleEndElement(const std::string& element, const std::string& ns) { + --level; + if (currentPayloadParser.get()) { + if (level >= 1) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 1) { + getPayloadInternal()->setPayload(currentPayloadParser->getPayload()); + } + } +} + +void StorageParser::handleCharacterData(const std::string& data) { + if (level > 1 && currentPayloadParser.get()) { + currentPayloadParser->handleCharacterData(data); + } +} + +} diff --git a/src/storageparser.h b/src/storageparser.h new file mode 100644 index 0000000000000000000000000000000000000000..c19d7553f0f409359c13bc403003217e9920135d --- /dev/null +++ b/src/storageparser.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "Swiften/Elements/PrivateStorage.h" +#include "Swiften/Parser/GenericPayloadParser.h" + +namespace Transport { + + class StorageParser : public Swift::GenericPayloadParser { + public: + StorageParser(); + + private: + virtual void handleStartElement(const std::string& element, const std::string&, const Swift::AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + int level; + std::auto_ptr currentPayloadParser; + }; +} diff --git a/src/storageresponder.cpp b/src/storageresponder.cpp index b20ee2311940be6ad32d13f25d5664335a6d80b2..0a143ea5571a5b02baaa6d61c4844c8f52cb1aca 100644 --- a/src/storageresponder.cpp +++ b/src/storageresponder.cpp @@ -23,6 +23,7 @@ #include #include #include "Swiften/Queries/IQRouter.h" +#include "Swiften/Elements/RawXMLPayload.h" #include "Swiften/Swiften.h" #include "transport/usermanager.h" #include "transport/user.h" @@ -32,7 +33,7 @@ using namespace boost; namespace Transport { -StorageResponder::StorageResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager) : Swift::GetResponder(router) { +StorageResponder::StorageResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager) : Swift::Responder(router) { m_storageBackend = storageBackend; m_userManager = userManager; } @@ -43,14 +44,30 @@ StorageResponder::~StorageResponder() { bool StorageResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload) { User *user = m_userManager->getUser(from.toBare().toString()); if (!user) { - sendResponse(from, id, boost::shared_ptr(new PrivateStorage())); + sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); return true; } int type = 0; std::string value = ""; m_storageBackend->getUserSetting(user->getUserInfo().id, "storage", type, value); - sendResponse(from, id, boost::shared_ptr(new PrivateStorage())); + std::cout << value << "\n"; + + sendResponse(from, id, boost::shared_ptr(new PrivateStorage(boost::shared_ptr(new RawXMLPayload(value))))); + return true; +} + +bool StorageResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload) { + User *user = m_userManager->getUser(from.toBare().toString()); + if (!user) { + sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); + return true; + } + + StorageSerializer serializer; + std::string value = serializer.serializePayload(boost::dynamic_pointer_cast(payload->getPayload())); + m_storageBackend->updateUserSetting(user->getUserInfo().id, "storage", value); + sendResponse(from, id, boost::shared_ptr()); return true; } diff --git a/src/storageresponder.h b/src/storageresponder.h index 9815e02aaaf2517a4cf3c4d4417ca7b591e5bbff..bca4cae832663b78032d15c7ca98e129112f5c09 100644 --- a/src/storageresponder.h +++ b/src/storageresponder.h @@ -22,7 +22,7 @@ #include #include "Swiften/Swiften.h" -#include "Swiften/Queries/GetResponder.h" +#include "Swiften/Queries/Responder.h" #include "Swiften/Elements/RosterPayload.h" namespace Transport { @@ -30,13 +30,14 @@ namespace Transport { class StorageBackend; class UserManager; -class StorageResponder : public Swift::GetResponder { +class StorageResponder : public Swift::Responder { public: StorageResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager); ~StorageResponder(); private: virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload); + virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr payload); StorageBackend *m_storageBackend; UserManager *m_userManager; }; diff --git a/src/transport.cpp b/src/transport.cpp index 5501eeab9a6eddfefe92b3e4778a74a52eb68b59..9fbd9a5c169c3f7e765d2c72ca73b96b6900ef49 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -25,6 +25,7 @@ #include "discoinforesponder.h" #include "discoitemsresponder.h" #include "rosterresponder.h" +#include "storageparser.h" using namespace Swift; using namespace boost; @@ -65,6 +66,8 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory) { m_stanzaChannel = m_server->getStanzaChannel(); m_iqRouter = m_server->getIQRouter(); + m_server->addPayloadParserFactory(new GenericPayloadParserFactory("private", "jabber:iq:private")); + m_server->onDataRead.connect(bind(&Component::handleDataRead, this, _1)); m_server->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1)); }