diff --git a/include/transport/storagebackend.h b/include/transport/storagebackend.h index 1b4051a6..221cbdd8 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 e5032b3d..afea46d8 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 00000000..e550964e --- /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 00000000..c19d7553 --- /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 b20ee231..0a143ea5 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 9815e02a..bca4cae8 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 5501eeab..9fbd9a5c 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)); }