Fix #92 - Handle the XMPP user's VCard change and forward it to the backend.

This commit is contained in:
Jan Kaluza 2016-02-04 06:55:14 +01:00
parent 8ba77c9ede
commit 321215840b
6 changed files with 96 additions and 1 deletions

View file

@ -76,6 +76,7 @@ class User {
UserManager *getUserManager() { return m_userManager; }
virtual void disconnectUser(const std::string &error, Swift::SpectrumErrorPayload::Error e) = 0;
virtual void requestVCard() {}
void setData(void *data) { m_data = data; }
void *getData() { return m_data; }
@ -138,6 +139,10 @@ class User {
m_reconnectLimit = limit;
}
void setStorageBackend(StorageBackend *storageBackend) {
m_storageBackend = storageBackend;
}
void leaveRoom(const std::string &room);
boost::signal<void ()> onReadyToConnect;
@ -172,6 +177,7 @@ class User {
std::map<std::string, std::string> m_settings;
bool m_cacheMessages;
int m_reconnectLimit;
StorageBackend *m_storageBackend;
};
}

View file

@ -1842,6 +1842,11 @@ void NetworkPluginServer::handleBlockToggled(Buddy *b) {
void NetworkPluginServer::handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> v) {
if (!v) {
LOG4CXX_INFO(logger, user->getJID().toString() << ": Received empty VCard");
return;
}
pbnetwork::VCard vcard;
vcard.set_username(user->getJID().toBare());
vcard.set_buddyname("");

View file

@ -34,6 +34,7 @@
#include "Swiften/Elements/MUCPayload.h"
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "Swiften/Elements/CapsInfo.h"
#include "Swiften/Elements/VCardUpdate.h"
#include <boost/foreach.hpp>
#include <stdio.h>
#include <stdlib.h>
@ -67,6 +68,7 @@ User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, User
m_rosterManager = component->getFrontend()->createRosterManager(this, m_component);
m_conversationManager = new ConversationManager(this, m_component);
LOG4CXX_INFO(logger, m_jid.toString() << ": Created");
updateLastActivity();
}
@ -170,6 +172,21 @@ void User::leaveRoom(const std::string &room) {
void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString());
if (m_storageBackend) {
boost::shared_ptr<Swift::VCardUpdate> vcardUpdate = presence->getPayload<Swift::VCardUpdate>();
if (vcardUpdate) {
std::string value = "";
int type = (int) TYPE_STRING;
m_storageBackend->getUserSetting(m_userInfo.id, "photohash", type, value);
if (value != vcardUpdate->getPhotoHash()) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Requesting VCard")
m_storageBackend->updateUserSetting(m_userInfo.id, "photohash", vcardUpdate->getPhotoHash());
requestVCard();
}
}
}
if (!m_connected) {
// we are not connected to legacy network, so we should do it when disco#info arrive :)
if (m_readyForConnect == false) {

View file

@ -26,6 +26,7 @@
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Elements/StreamError.h"
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "Swiften/Queries/IQRouter.h"
#include <boost/foreach.hpp>
#include <stdio.h>
#include <stdlib.h>
@ -54,6 +55,15 @@ XMPPUser::~XMPPUser(){
dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend*>(m_component->getFrontend())->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr<Swift::Element>());
#endif
}
if (m_vcardRequests.size() != 0) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Removing " << m_vcardRequests.size() << " unresponded IQs");
BOOST_FOREACH(Swift::GetVCardRequest::ref request, m_vcardRequests) {
request->onResponse.disconnect_all_slots();
static_cast<XMPPFrontend *>(m_component->getFrontend())->getIQRouter()->removeHandler(request);
}
m_vcardRequests.clear();
}
}
void XMPPUser::disconnectUser(const std::string &error, Swift::SpectrumErrorPayload::Error e) {
@ -73,5 +83,20 @@ void XMPPUser::disconnectUser(const std::string &error, Swift::SpectrumErrorPayl
}
}
void XMPPUser::handleVCardReceived(boost::shared_ptr<Swift::VCard> vcard, Swift::ErrorPayload::ref error, Swift::GetVCardRequest::ref request) {
m_vcardRequests.remove(request);
request->onResponse.disconnect_all_slots();
m_component->getFrontend()->onVCardUpdated(this, vcard);
}
void XMPPUser::requestVCard() {
LOG4CXX_INFO(logger, m_jid.toString() << ": Requesting VCard");
Swift::GetVCardRequest::ref request = Swift::GetVCardRequest::create(m_jid, static_cast<XMPPFrontend *>(m_component->getFrontend())->getIQRouter());
request->onResponse.connect(boost::bind(&XMPPUser::handleVCardReceived, this, _1, _2, request));
request->send();
m_vcardRequests.push_back(request);
}
}

View file

@ -29,6 +29,7 @@
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "Swiften/Network/Timer.h"
#include "Swiften/Network/Connection.h"
#include "Swiften/VCards/GetVCardRequest.h"
namespace Transport {
@ -54,15 +55,17 @@ class XMPPUser : public User {
void disconnectUser(const std::string &error, Swift::SpectrumErrorPayload::Error e);
void requestVCard();
private:
void onConnectingTimeout();
void handleVCardReceived(boost::shared_ptr<Swift::VCard> vcard, Swift::ErrorPayload::ref error, Swift::GetVCardRequest::ref request);
Swift::JID m_jid;
Component *m_component;
UserManager *m_userManager;
UserInfo m_userInfo;
std::list <Swift::GetVCardRequest::ref> m_vcardRequests;
};
}

View file

@ -30,12 +30,14 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_TEST(handleDisconnectedReconnect);
CPPUNIT_TEST(joinRoomHandleDisconnectedRejoin);
CPPUNIT_TEST(joinRoomAfterFlagNotAuthorized);
CPPUNIT_TEST(requestVCard);
CPPUNIT_TEST_SUITE_END();
public:
std::string room;
std::string roomNickname;
std::string roomPassword;
std::string photo;
bool readyToConnect;
bool disconnected;
Swift::Presence::ref changedPresence;
@ -47,11 +49,14 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
room = "";
roomNickname = "";
roomPassword = "";
photo = "";
setMeUp();
userManager->onUserCreated.connect(boost::bind(&UserTest::handleUserCreated, this, _1));
connectUser();
received.clear();
frontend->onVCardUpdated.connect(boost::bind(&UserTest::handleVCardUpdated, this, _1, _2));
}
void tearDown (void) {
@ -63,6 +68,10 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
tearMeDown();
}
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> v) {
photo = Swift::byteArrayToString(v->getPhoto());
}
void handleUserCreated(User *user) {
user->onReadyToConnect.connect(boost::bind(&UserTest::handleUserReadyToConnect, this, user));
user->onPresenceChanged.connect(boost::bind(&UserTest::handleUserPresenceChanged, this, user, _1));
@ -472,6 +481,36 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
handlePresenceJoinRoom();
}
void requestVCard() {
User *user = userManager->getUser("user@localhost");
user->setStorageBackend(storage);
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("localhost");
response->setFrom("user@localhost/resource");
response->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::VCardUpdate("hash")));
injectPresence(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
Swift::VCard::ref payload1 = getStanza(received[1])->getPayload<Swift::VCard>();
CPPUNIT_ASSERT(payload1);
boost::shared_ptr<Swift::VCard> vcard(new Swift::VCard());
vcard->setPhoto(Swift::createByteArray("photo"));
injectIQ(Swift::IQ::createResult(getStanza(received[1])->getFrom(), getStanza(received[1])->getTo(), getStanza(received[1])->getID(), vcard));
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
CPPUNIT_ASSERT_EQUAL(std::string("photo"), photo);
received.clear();
injectPresence(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION (UserTest);