From a28e64cfe42687d20c1663bcd7c819ea3542f4bb Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 17 Aug 2012 13:54:21 +0200 Subject: [PATCH] Working 'Enable Transport' adhoc setting --- src/settingsadhoccommand.cpp | 50 ++++++++++++++++++++++++++++-- src/tests/basictest.h | 23 ++++++++++++-- src/tests/settingsadhoccommand.cpp | 43 ++++++++++++++++++++++++- src/tests/usermanager.cpp | 13 ++++++++ src/usermanager.cpp | 47 +++++++++++++++++----------- 5 files changed, 153 insertions(+), 23 deletions(-) diff --git a/src/settingsadhoccommand.cpp b/src/settingsadhoccommand.cpp index 73077910..69939296 100644 --- a/src/settingsadhoccommand.cpp +++ b/src/settingsadhoccommand.cpp @@ -34,16 +34,46 @@ DEFINE_LOGGER(logger, "SettingsAdHocCommand"); SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, userManager, storageBackend, initiator, to) { m_state = Init; + Swift::BooleanFormField::ref field; + + field = Swift::BooleanFormField::create(true); + field->setName("enable_transport"); + field->setLabel("Enable transport"); + addFormField(field); } SettingsAdHocCommand::~SettingsAdHocCommand() { } boost::shared_ptr SettingsAdHocCommand::getForm() { + if (!m_storageBackend) { + boost::shared_ptr response(new Swift::Command("settings", m_id, Swift::Command::Completed)); + boost::shared_ptr form(new Swift::Form()); + form->addField(Swift::FixedFormField::create("This server does not support transport settings. There is no storage backend configured")); + return response; + } + + UserInfo user; + if (m_storageBackend->getUser(m_initiator.toBare().toString(), user) == false) { + boost::shared_ptr response(new Swift::Command("settings", m_id, Swift::Command::Completed)); + boost::shared_ptr form(new Swift::Form()); + form->addField(Swift::FixedFormField::create("You are not registered.")); + return response; + } + boost::shared_ptr response(new Swift::Command("settings", m_id, Swift::Command::Executing)); boost::shared_ptr form(new Swift::Form()); BOOST_FOREACH(Swift::FormField::ref field, m_fields) { + // FIXME: Support for more types than boolean + if (boost::dynamic_pointer_cast(field)) { + Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast(field)); + std::string value = f->getValue() ? "1" : "0"; + int type = (int) TYPE_BOOLEAN; + m_storageBackend->getUserSetting(user.id, f->getName(), type, value); + f->setValue(value == "1"); + } + form->addField(field); } @@ -52,8 +82,24 @@ boost::shared_ptr SettingsAdHocCommand::getForm() { } boost::shared_ptr SettingsAdHocCommand::handleResponse(boost::shared_ptr payload) { - - + UserInfo user; + bool registered = m_storageBackend->getUser(m_initiator.toBare().toString(), user); + + if (registered && payload->getForm()) { + BOOST_FOREACH(Swift::FormField::ref field, m_fields) { + Swift::FormField::ref received = payload->getForm()->getField(field->getName()); + if (!received) { + continue; + } + + // FIXME: Support for more types than boolean + if (boost::dynamic_pointer_cast(received)) { + Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast(received)); + std::string value = f->getValue() ? "1" : "0"; + m_storageBackend->updateUserSetting(user.id, f->getName(), value); + } + } + } boost::shared_ptr response(new Swift::Command("settings", m_id, Swift::Command::Completed)); return response; diff --git a/src/tests/basictest.h b/src/tests/basictest.h index 64202f8d..7fec78c6 100644 --- a/src/tests/basictest.h +++ b/src/tests/basictest.h @@ -89,6 +89,7 @@ class TestingStorageBackend : public StorageBackend { bool connected; std::map users; std::map online_users; + std::map > settings; long buddyid; TestingStorageBackend() { @@ -171,8 +172,17 @@ class TestingStorageBackend : public StorageBackend { virtual void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {} virtual void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {} - virtual void getUserSetting(long userId, const std::string &variable, int &type, std::string &value) {} - virtual void updateUserSetting(long userId, const std::string &variable, const std::string &value) {} + virtual void getUserSetting(long userId, const std::string &variable, int &type, std::string &value) { + if (settings[userId].find(variable) == settings[userId].end()) { + settings[userId][variable] = value; + return; + } + value = settings[userId][variable]; + } + + virtual void updateUserSetting(long userId, const std::string &variable, const std::string &value) { + settings[userId][variable] = value; + } virtual void beginTransaction() {} virtual void commitTransaction() {} @@ -198,6 +208,15 @@ class BasicTest : public Swift::XMPPParserClient { void dumpReceived(); + void addUser() { + UserInfo user; + user.id = 1; + user.jid = "user@localhost"; + user.uin = "legacyname"; + user.password = "password"; + storage->setUser(user); + } + Swift::Stanza *getStanza(boost::shared_ptr element); protected: diff --git a/src/tests/settingsadhoccommand.cpp b/src/tests/settingsadhoccommand.cpp index 1f01afe1..e3e14d9c 100644 --- a/src/tests/settingsadhoccommand.cpp +++ b/src/tests/settingsadhoccommand.cpp @@ -28,6 +28,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT CPPUNIT_TEST(getItems); CPPUNIT_TEST(execute); CPPUNIT_TEST(executeBadSessionID); + CPPUNIT_TEST(executeNotRegistered); CPPUNIT_TEST(cancel); CPPUNIT_TEST_SUITE_END(); @@ -38,7 +39,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT void setUp (void) { setMeUp(); - adhoc = new AdHocManager(component, itemsResponder, userManager); + adhoc = new AdHocManager(component, itemsResponder, userManager, storage); adhoc->start(); settings = new SettingsAdHocCommandFactory(); adhoc->addAdHocCommand(settings); @@ -69,7 +70,25 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload()->getItems()[0].getNode()); } + void executeNotRegistered() { + boost::shared_ptr payload(new Swift::Command("settings")); + boost::shared_ptr iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload); + iq->setFrom("user@localhost"); + injectIQ(iq); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::IQ::Result, dynamic_cast(getStanza(received[0]))->getType()); + + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload()->getNode()); + CPPUNIT_ASSERT_EQUAL(Swift::Command::Completed, getStanza(received[0])->getPayload()->getStatus()); + } + void execute() { + addUser(); boost::shared_ptr payload(new Swift::Command("settings")); boost::shared_ptr iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload); iq->setFrom("user@localhost"); @@ -85,10 +104,23 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload()->getNode()); CPPUNIT_ASSERT_EQUAL(Swift::Command::Executing, getStanza(received[0])->getPayload()->getStatus()); + // form element CPPUNIT_ASSERT(getStanza(received[0])->getPayload()->getForm()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()->getForm()->getField("enable_transport")); + + // set enabled_transport = 0 + Swift::FormField::ref f = getStanza(received[0])->getPayload()->getForm()->getField("enable_transport"); + boost::dynamic_pointer_cast(f)->setValue(false); std::string sessionId = getStanza(received[0])->getPayload()->getSessionID(); + { + std::string value = "0"; + int type; + storage->getUserSetting(1, "enable_transport", type, value); + CPPUNIT_ASSERT_EQUAL(std::string("1"), value); + } + // finish the command payload = boost::shared_ptr(new Swift::Command("settings")); payload->setSessionID(sessionId); @@ -107,9 +139,17 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload()->getNode()); CPPUNIT_ASSERT_EQUAL(Swift::Command::Completed, getStanza(received[0])->getPayload()->getStatus()); + + { + std::string value = "1"; + int type; + storage->getUserSetting(1, "enable_transport", type, value); + CPPUNIT_ASSERT_EQUAL(std::string("0"), value); + } } void executeBadSessionID() { + addUser(); boost::shared_ptr payload(new Swift::Command("settings")); boost::shared_ptr iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload); iq->setFrom("user@localhost"); @@ -145,6 +185,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT } void cancel() { + addUser(); boost::shared_ptr payload(new Swift::Command("settings")); boost::shared_ptr iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload); iq->setFrom("user@localhost"); diff --git a/src/tests/usermanager.cpp b/src/tests/usermanager.cpp index b67c8e88..d2102cf5 100644 --- a/src/tests/usermanager.cpp +++ b/src/tests/usermanager.cpp @@ -23,6 +23,7 @@ using namespace Transport; class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(UserManagerTest); CPPUNIT_TEST(connectUser); + CPPUNIT_TEST(connectUserTransportDisabled); CPPUNIT_TEST(handleProbePresence); CPPUNIT_TEST(disconnectUser); CPPUNIT_TEST_SUITE_END(); @@ -57,6 +58,18 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); } + void connectUserTransportDisabled() { + addUser(); + storage->updateUserSetting(1, "enable_transport", "0"); + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); + loop->processEvents(); + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(!user); + } + void disconnectUser() { connectUser(); received.clear(); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index ff4bb6dd..50d969eb 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -151,25 +151,24 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { if (!user) { // Admin user is not legacy network user, so do not create User class instance for him if (m_component->inServerMode()) { - std::vector const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid"); - if (std::find(x.begin(), x.end(), presence->getFrom().toBare().toString()) != x.end()) { - - // Send admin contact to the user. - Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload()); - Swift::RosterItemPayload item; - item.setJID(m_component->getJID()); - item.setName("Admin"); - item.setSubscription(Swift::RosterItemPayload::Both); - payload->addItem(item); + std::vector const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid"); + if (std::find(x.begin(), x.end(), presence->getFrom().toBare().toString()) != x.end()) { + // Send admin contact to the user. + Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload()); + Swift::RosterItemPayload item; + item.setJID(m_component->getJID()); + item.setName("Admin"); + item.setSubscription(Swift::RosterItemPayload::Both); + payload->addItem(item); - Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, presence->getFrom(), m_component->getIQRouter()); - request->send(); + Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, presence->getFrom(), m_component->getIQRouter()); + request->send(); - Swift::Presence::ref response = Swift::Presence::create(); - response->setTo(presence->getFrom()); - response->setFrom(m_component->getJID()); - m_component->getStanzaChannel()->sendPresence(response); - return; + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(presence->getFrom()); + response->setFrom(m_component->getJID()); + m_component->getStanzaChannel()->sendPresence(response); + return; } } @@ -245,13 +244,25 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { } } - // Unregistered users are not able to login if (!registered) { LOG4CXX_WARN(logger, "Unregistered user " << userkey << " tried to login"); return; } + bool transport_enabled = true; + if (m_storageBackend) { + std::string value = "1"; + int type = (int) TYPE_BOOLEAN; + m_storageBackend->getUserSetting(res.id, "enable_transport", type, value); + transport_enabled = value == "1"; + } + // User can disabled the transport using adhoc commands + if (!transport_enabled) { + LOG4CXX_INFO(logger, "User " << userkey << " has disabled transport, not logging"); + return; + } + // Create new user class and set storagebackend user = new User(presence->getFrom(), res, m_component, this); user->getRosterManager()->setStorageBackend(m_storageBackend);