diff --git a/spectrum/src/frontends/slack/SlackUserManager.cpp b/spectrum/src/frontends/slack/SlackUserManager.cpp index fc221a7773b0bad005b36b3760114cb3879c51e9..fbe2802f198068eee2b42e8322a1f657e8410f36 100644 --- a/spectrum/src/frontends/slack/SlackUserManager.cpp +++ b/spectrum/src/frontends/slack/SlackUserManager.cpp @@ -29,6 +29,8 @@ #include "transport/StorageBackend.h" #include "transport/Logging.h" #include "transport/Config.h" +#include "transport/AdminInterface.h" +#include "transport/AdminInterfaceCommand.h" #include #include @@ -40,18 +42,176 @@ namespace Transport { DEFINE_LOGGER(logger, "SlackUserManager"); +class ListRoomsCommand : public AdminInterfaceCommand { + public: + + ListRoomsCommand(StorageBackend *storageBackend) : AdminInterfaceCommand("list_rooms", + AdminInterfaceCommand::Frontend, + AdminInterfaceCommand::UserContext, + AdminInterfaceCommand::UserMode, + AdminInterfaceCommand::Execute) { + m_storageBackend = storageBackend; + setDescription("List connected rooms"); + } + + virtual std::string handleExecuteRequest(UserInfo &uinfo, User *user, std::vector &args) { + std::string ret = AdminInterfaceCommand::handleExecuteRequest(uinfo, user, args); + if (!ret.empty()) { + return ret; + } + + if (uinfo.id == -1) { + return "Error: Unknown user"; + } + + std::string rooms = ""; + int type = (int) TYPE_STRING; + m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); + return rooms; + } + + private: + StorageBackend *m_storageBackend; +}; + +class JoinRoomCommand : public AdminInterfaceCommand { + public: + + JoinRoomCommand(StorageBackend *storageBackend, Config *cfg) : AdminInterfaceCommand("join_room", + AdminInterfaceCommand::Frontend, + AdminInterfaceCommand::UserContext, + AdminInterfaceCommand::UserMode, + AdminInterfaceCommand::Execute) { + m_storageBackend = storageBackend; + setDescription("Join the room"); + + std::string legacyRoomLabel = CONFIG_STRING_DEFAULTED(cfg, "service.join_room_room_label", "3rd-party room name"); + if (legacyRoomLabel[0] == '%') { + legacyRoomLabel[0] = '#'; + } + + std::string legacyRoomExample = CONFIG_STRING_DEFAULTED(cfg, "service.join_room_room_example", "3rd-party room name"); + if (legacyRoomExample[0] == '%') { + legacyRoomExample[0] = '#'; + } + + addArg("nickname", + CONFIG_STRING_DEFAULTED(cfg, "service.join_room_nickname_label", "Nickname in 3rd-party room"), + CONFIG_STRING_DEFAULTED(cfg, "service.join_room_nickname_example", "BotNickname")); + addArg("legacy_room", legacyRoomLabel, legacyRoomExample); + addArg("legacy_server", + CONFIG_STRING_DEFAULTED(cfg, "service.join_room_server_label", "3rd-party server"), + CONFIG_STRING_DEFAULTED(cfg, "service.join_room_server_example", "3rd.party.server.org")); + addArg("slack_channel", "Slack Chanel", "mychannel"); + } + + virtual std::string handleExecuteRequest(UserInfo &uinfo, User *u, std::vector &args) { + std::string ret = AdminInterfaceCommand::handleExecuteRequest(uinfo, u, args); + if (!ret.empty()) { + return ret; + } + + if (uinfo.id == -1) { + return "Error: Unknown user"; + } + + std::string rooms = ""; + int type = (int) TYPE_STRING; + m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); + // 'unknown' is here to stay compatible in args.size() with older version. + rooms += "connected room " + args[0] + " " + args[1] + " " + args[2] + " " + args[3] + "\n"; + m_storageBackend->updateUserSetting(uinfo.id, "rooms", rooms); + + SlackUser *user = static_cast(u); + if (user) { + user->getSession()->handleJoinMessage("", args, true); + } + return "Joined the room"; + } + + private: + StorageBackend *m_storageBackend; +}; + +class LeaveRoomCommand : public AdminInterfaceCommand { + public: + + LeaveRoomCommand(StorageBackend *storageBackend) : AdminInterfaceCommand("leave_room", + AdminInterfaceCommand::Frontend, + AdminInterfaceCommand::UserContext, + AdminInterfaceCommand::UserMode, + AdminInterfaceCommand::Execute) { + m_storageBackend = storageBackend; + setDescription("Leave the room"); + + addArg("slack_channel", "Slack Chanel", "mychannel"); + } + + virtual std::string handleExecuteRequest(UserInfo &uinfo, User *u, std::vector &args) { + std::string ret = AdminInterfaceCommand::handleExecuteRequest(uinfo, u, args); + if (!ret.empty()) { + return ret; + } + + if (uinfo.id == -1) { + return "Error: Unknown user"; + } + + std::string rooms = ""; + int type = (int) TYPE_STRING; + m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); + + std::vector commands; + boost::split(commands, rooms, boost::is_any_of("\n")); + rooms = ""; + + BOOST_FOREACH(const std::string &command, commands) { + if (command.size() > 5) { + std::vector args2; + boost::split(args2, command, boost::is_any_of(" ")); + if (args2.size() == 6) { + if (args[0] != args2[5]) { + rooms += command + "\n"; + } + } + } + } + + m_storageBackend->updateUserSetting(uinfo.id, "rooms", rooms); + + SlackUser *user = static_cast(u); + if (user) { + user->getSession()->leaveRoom(args[0]); + } + return "Left the room"; + } + + private: + StorageBackend *m_storageBackend; +}; + SlackUserManager::SlackUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) : UserManager(component, userRegistry, storageBackend) { m_component = component; m_storageBackend = storageBackend; m_userRegistration = new SlackUserRegistration(component, this, storageBackend); onUserCreated.connect(boost::bind(&SlackUserManager::handleUserCreated, this, _1)); + m_component->onAdminInterfaceSet.connect(boost::bind(&SlackUserManager::handleAdminInterfaceSet, this)); } SlackUserManager::~SlackUserManager() { delete m_userRegistration; } +void SlackUserManager::handleAdminInterfaceSet() { + AdminInterface *adminInterface = m_component->getAdminInterface(); + if (adminInterface) { + adminInterface->addCommand(new ListRoomsCommand(m_storageBackend)); + adminInterface->addCommand(new JoinRoomCommand(m_storageBackend, m_component->getConfig())); + adminInterface->addCommand(new LeaveRoomCommand(m_storageBackend)); + } +} + void SlackUserManager::reconnectUser(const std::string &user) { UserInfo uinfo; if (!m_storageBackend->getUser(user, uinfo)) { @@ -109,121 +269,5 @@ void SlackUserManager::handleUserCreated(User *user) { static_cast(user)->getSession()->handleConnected(); } -bool SlackUserManager::handleAdminMessage(Swift::Message::ref message) { -#if HAVE_SWIFTEN_3 - std::string body = message->getBody().get_value_or(""); -#else - std::string body = message->getBody(); -#endif - - if (body.find("list_rooms") == 0) { - std::vector args; - boost::split(args, body, boost::is_any_of(" ")); - if (args.size() == 2) { - UserInfo uinfo; - if (!m_storageBackend->getUser(args[1], uinfo)) { - message->setBody("Error: Unknown user"); - return true; - } - - std::string rooms = ""; - int type = (int) TYPE_STRING; - m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); - - message->setBody(rooms); - return true; - } - } - else if (body.find("join_room_fields") == 0) { - std::string ret; - - Config *cfg = m_component->getConfig(); - ret += CONFIG_STRING_DEFAULTED(cfg, "service.join_room_nickname_label", "Nickname in 3rd-party room") + "\n"; - std::string room_name = CONFIG_STRING_DEFAULTED(cfg, "service.join_room_room_label", "3rd-party room name"); - if (room_name[0] == '%') { - room_name[0] = '#'; - } - ret += room_name + "\n"; - ret += CONFIG_STRING_DEFAULTED(cfg, "service.join_room_server_label", "3rd-party server") + "\n"; - ret += "Slack Channel\n"; - ret += CONFIG_STRING_DEFAULTED(cfg, "service.join_room_nickname_example", "BotNickname") + "\n"; - room_name = CONFIG_STRING_DEFAULTED(cfg, "service.join_room_room_example", "3rd-party room name"); - if (room_name[0] == '%') { - room_name[0] = '#'; - } - ret += room_name + "\n"; - ret += CONFIG_STRING_DEFAULTED(cfg, "service.join_room_server_example", "3rd.party.server.org") + "\n"; - ret += "mychannel"; - - message->setBody(ret); - return true; - } - else if (body.find("join_room ") == 0) { - std::vector args; - boost::split(args, body, boost::is_any_of(" ")); - if (args.size() == 6) { - UserInfo uinfo; - if (!m_storageBackend->getUser(args[1], uinfo)) { - message->setBody("Error: Unknown user"); - return true; - } - - std::string rooms = ""; - int type = (int) TYPE_STRING; - m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); - rooms += body + "\n"; - m_storageBackend->updateUserSetting(uinfo.id, "rooms", rooms); - - SlackUser *user = static_cast(getUser(args[1])); - if (user) { - user->getSession()->handleJoinMessage("", args, true); - } - message->setBody("Joined the room"); - return true; - } - } - else if (body.find("leave_room ") == 0) { - std::vector args; - boost::split(args, body, boost::is_any_of(" ")); - if (args.size() == 3) { - UserInfo uinfo; - if (!m_storageBackend->getUser(args[1], uinfo)) { - message->setBody("Error: Unknown user"); - return true; - } - - std::string rooms = ""; - int type = (int) TYPE_STRING; - m_storageBackend->getUserSetting(uinfo.id, "rooms", type, rooms); - - std::vector commands; - boost::split(commands, rooms, boost::is_any_of("\n")); - rooms = ""; - - BOOST_FOREACH(const std::string &command, commands) { - if (command.size() > 5) { - std::vector args2; - boost::split(args2, command, boost::is_any_of(" ")); - if (args2.size() == 6) { - if (args[2] != args2[5]) { - rooms += command + "\n"; - } - } - } - } - - m_storageBackend->updateUserSetting(uinfo.id, "rooms", rooms); - - SlackUser *user = static_cast(getUser(args[1])); - if (user) { - user->getSession()->leaveRoom(args[2]); - } - message->setBody("Left the room"); - return true; - } - } - return false; -} - }