support for jabber:iq:private in server mode

This commit is contained in:
HanzZ 2011-05-20 00:11:00 +02:00
parent 76eb3b54a7
commit 778a11d5dc
7 changed files with 93 additions and 7 deletions

View file

@ -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;

View file

@ -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);

41
src/storageparser.cpp Normal file
View file

@ -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);
}
}
}

23
src/storageparser.h Normal file
View file

@ -0,0 +1,23 @@
#pragma once
#include <boost/optional.hpp>
#include "Swiften/Elements/PrivateStorage.h"
#include "Swiften/Parser/GenericPayloadParser.h"
namespace Transport {
class StorageParser : public Swift::GenericPayloadParser<Swift::PrivateStorage> {
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<Swift::PayloadParser> currentPayloadParser;
};
}

View file

@ -23,6 +23,7 @@
#include <iostream>
#include <boost/bind.hpp>
#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<PrivateStorage>(router) {
StorageResponder::StorageResponder(Swift::IQRouter *router, StorageBackend *storageBackend, UserManager *userManager) : Swift::Responder<PrivateStorage>(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<Swift::PrivateStorage> payload) {
User *user = m_userManager->getUser(from.toBare().toString());
if (!user) {
sendResponse(from, id, boost::shared_ptr<PrivateStorage>(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<PrivateStorage>(new PrivateStorage()));
std::cout << value << "\n";
sendResponse(from, id, boost::shared_ptr<PrivateStorage>(new PrivateStorage(boost::shared_ptr<RawXMLPayload>(new RawXMLPayload(value)))));
return true;
}
bool StorageResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::PrivateStorage> 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<Storage>(payload->getPayload()));
m_storageBackend->updateUserSetting(user->getUserInfo().id, "storage", value);
sendResponse(from, id, boost::shared_ptr<PrivateStorage>());
return true;
}

View file

@ -22,7 +22,7 @@
#include <vector>
#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<Swift::PrivateStorage> {
class StorageResponder : public Swift::Responder<Swift::PrivateStorage> {
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<Swift::PrivateStorage> payload);
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::PrivateStorage> payload);
StorageBackend *m_storageBackend;
UserManager *m_userManager;
};

View file

@ -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<StorageParser>("private", "jabber:iq:private"));
m_server->onDataRead.connect(bind(&Component::handleDataRead, this, _1));
m_server->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1));
}