Working 'Enable Transport' adhoc setting

This commit is contained in:
HanzZ 2012-08-17 13:54:21 +02:00
parent 8bb71e5148
commit a28e64cfe4
5 changed files with 153 additions and 23 deletions

View file

@ -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<Swift::Command> SettingsAdHocCommand::getForm() {
if (!m_storageBackend) {
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> 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<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
form->addField(Swift::FixedFormField::create("You are not registered."));
return response;
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
boost::shared_ptr<Swift::Form> form(new Swift::Form());
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
// FIXME: Support for more types than boolean
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(field)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(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<Swift::Command> SettingsAdHocCommand::getForm() {
}
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> 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<Swift::BooleanFormField>(received)) {
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(received));
std::string value = f->getValue() ? "1" : "0";
m_storageBackend->updateUserSetting(user.id, f->getName(), value);
}
}
}
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
return response;

View file

@ -89,6 +89,7 @@ class TestingStorageBackend : public StorageBackend {
bool connected;
std::map<std::string, UserInfo> users;
std::map<std::string, bool> online_users;
std::map<int, std::map<std::string, std::string> > 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<Swift::Element> element);
protected:

View file

@ -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<Swift::DiscoItems>()->getItems()[0].getNode());
}
void executeNotRegistered() {
boost::shared_ptr<Swift::Command> payload(new Swift::Command("settings"));
boost::shared_ptr<Swift::IQ> 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<Swift::IQ *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Result, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>());
CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload<Swift::Command>()->getNode());
CPPUNIT_ASSERT_EQUAL(Swift::Command::Completed, getStanza(received[0])->getPayload<Swift::Command>()->getStatus());
}
void execute() {
addUser();
boost::shared_ptr<Swift::Command> payload(new Swift::Command("settings"));
boost::shared_ptr<Swift::IQ> 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<Swift::Command>()->getNode());
CPPUNIT_ASSERT_EQUAL(Swift::Command::Executing, getStanza(received[0])->getPayload<Swift::Command>()->getStatus());
// form element
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm()->getField("enable_transport"));
// set enabled_transport = 0
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("enable_transport");
boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->setValue(false);
std::string sessionId = getStanza(received[0])->getPayload<Swift::Command>()->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<Swift::Command>(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<Swift::Command>());
CPPUNIT_ASSERT_EQUAL(std::string("settings"), getStanza(received[0])->getPayload<Swift::Command>()->getNode());
CPPUNIT_ASSERT_EQUAL(Swift::Command::Completed, getStanza(received[0])->getPayload<Swift::Command>()->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<Swift::Command> payload(new Swift::Command("settings"));
boost::shared_ptr<Swift::IQ> 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<Swift::Command> payload(new Swift::Command("settings"));
boost::shared_ptr<Swift::IQ> iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload);
iq->setFrom("user@localhost");

View file

@ -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<Swift::DiscoInfo>());
}
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();

View file

@ -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<std::string> 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<std::string> 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);