Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SpectrumIM/spectrum2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Takmazov <vitalyster@gmail.com>2022-02-22 20:56:43 +0300
committervitalyster <vitalyster@gmail.com>2022-02-23 14:02:31 +0300
commitee892031f8ec801f02e3ddf3005295e663d49f53 (patch)
tree19ca7c9a4a60c95fefc4008afa81d2d8b7984e3e
parentb5a2a6c2f12ed6723fa716d7473b9da3096f1b88 (diff)
libpurple: do not delete accounts.xml
* Do not delete accounts.xml, this will allow to simplify plugin a lot: no need in storage backend, no need to save/restore settings on backend side * Read old saved settings on the frontend side and push to backend on login to be backward compatible
-rw-r--r--backends/frotz/main.cpp2
-rw-r--r--backends/libcommuni/ircnetworkplugin.cpp2
-rw-r--r--backends/libcommuni/ircnetworkplugin.h2
-rw-r--r--backends/libpurple/CMakeLists.txt10
-rw-r--r--backends/libpurple/main.cpp165
-rw-r--r--backends/smstools3/main.cpp2
-rw-r--r--backends/swiften/main.cpp2
-rw-r--r--backends/template/plugin.cpp2
-rw-r--r--backends/template/plugin.h2
-rw-r--r--backends/twitter/TwitterPlugin.cpp2
-rw-r--r--backends/twitter/TwitterPlugin.h2
-rw-r--r--include/transport/MySQLBackend.h3
-rw-r--r--include/transport/NetworkPlugin.h3
-rw-r--r--include/transport/PQXXBackend.h2
-rw-r--r--include/transport/SQLite3Backend.h3
-rw-r--r--include/transport/StorageBackend.h3
-rw-r--r--include/transport/User.h5
-rw-r--r--include/transport/protocol.proto4
-rw-r--r--libtransport/MySQLBackend.cpp16
-rw-r--r--libtransport/NetworkPluginServer.cpp5
-rw-r--r--libtransport/PQXXBackend.cpp19
-rw-r--r--libtransport/SQLite3Backend.cpp17
-rw-r--r--libtransport/UserManager.cpp3
-rw-r--r--plugin/cpp/networkplugin.cpp2
-rw-r--r--tests/libtransport/basictest.h6
-rw-r--r--tests/libtransport/settingsadhoccommand.cpp1
26 files changed, 108 insertions, 177 deletions
diff --git a/backends/frotz/main.cpp b/backends/frotz/main.cpp
index a7546c5a..05e50b21 100644
--- a/backends/frotz/main.cpp
+++ b/backends/frotz/main.cpp
@@ -169,7 +169,7 @@ class FrotzNetworkPlugin : public NetworkPlugin {
handleDataRead(d);
}
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
np->handleConnected(user);
std::vector<std::string> groups;
groups.push_back("ZCode");
diff --git a/backends/libcommuni/ircnetworkplugin.cpp b/backends/libcommuni/ircnetworkplugin.cpp
index 18bb3e00..9241d0a2 100644
--- a/backends/libcommuni/ircnetworkplugin.cpp
+++ b/backends/libcommuni/ircnetworkplugin.cpp
@@ -126,7 +126,7 @@ MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std
return session;
}
-void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
if (!m_servers.empty()) {
// legacy name is user's nickname
if (m_sessions[user] != NULL) {
diff --git a/backends/libcommuni/ircnetworkplugin.h b/backends/libcommuni/ircnetworkplugin.h
index ddb9e53f..aafa05a6 100644
--- a/backends/libcommuni/ircnetworkplugin.h
+++ b/backends/libcommuni/ircnetworkplugin.h
@@ -35,7 +35,7 @@ class IRCNetworkPlugin : public QObject, public NetworkPlugin {
public:
IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port);
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings);
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
diff --git a/backends/libpurple/CMakeLists.txt b/backends/libpurple/CMakeLists.txt
index c62f4978..88722113 100644
--- a/backends/libpurple/CMakeLists.txt
+++ b/backends/libpurple/CMakeLists.txt
@@ -2,14 +2,6 @@ file(GLOB SRC *.cpp)
add_executable(spectrum2_libpurple_backend ${SRC})
-if(MSVC)
- target_link_libraries(spectrum2_libpurple_backend transport ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
-else()
- if(NOT WIN32)
- target_link_libraries(spectrum2_libpurple_backend transport ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
- else()
- target_link_libraries(spectrum2_libpurple_backend transport ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
- endif()
-endif()
+target_link_libraries(spectrum2_libpurple_backend transport-plugin ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES})
install(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)
diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp
index 70aafd1a..4b376417 100644
--- a/backends/libpurple/main.cpp
+++ b/backends/libpurple/main.cpp
@@ -16,7 +16,6 @@
#include "transport/NetworkPlugin.h"
#include "transport/Logging.h"
#include "transport/Config.h"
-#include "transport/StorageBackend.h"
#include "geventloop.h"
// #include "valgrind/memcheck.h"
@@ -78,7 +77,6 @@ class SpectrumNetworkPlugin;
std::shared_ptr<Config> config;
SpectrumNetworkPlugin *np;
-StorageBackend *storagebackend;
static std::string host;
static int port = 10000;
@@ -216,38 +214,6 @@ static std::string getAlias(PurpleBuddy *m_buddy) {
return alias;
}
-static boost::mutex dblock;
-static std::string OAUTH_TOKEN = "hangouts_oauth_token";
-static std::string STEAM_ACCESS_TOKEN = "steammobile_access_token";
-static std::string DISCORD_ACCESS_TOKEN = "discord_access_token";
-static std::string WHATSMEOW_ACCESS_TOKEN = "credentials";
-
-static bool getUserToken(const std::string user, const std::string token_name, std::string &token_value)
-{
- boost::mutex::scoped_lock lock(dblock);
- UserInfo info;
- if (storagebackend->getUser(user, info) == false) {
- LOG4CXX_ERROR(logger, "Didn't find entry for " << user << " in the database!");
- return false;
- }
- token_value = "";
- int type = TYPE_STRING;
- storagebackend->getUserSetting((long)info.id, token_name, type, token_value);
- return true;
-}
-
-static bool storeUserToken(const std::string user, const std::string token_name, const std::string token_value)
-{
- boost::mutex::scoped_lock lock(dblock);
- UserInfo info;
- if (storagebackend->getUser(user, info) == false) {
- LOG4CXX_ERROR(logger, "Didn't find entry for " << user << " in the database!");
- return false;
- }
- storagebackend->updateUserSetting((long)info.id, token_name, token_value);
- return true;
-}
-
class SpectrumNetworkPlugin : public NetworkPlugin {
public:
SpectrumNetworkPlugin() : NetworkPlugin() {
@@ -389,7 +355,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
}
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
PurpleAccount *account = NULL;
std::string name;
@@ -447,32 +413,11 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
purple_account_set_bool_wrapped(account, "custom_smileys", FALSE);
purple_account_set_bool_wrapped(account, "direct_connect", FALSE);
purple_account_set_bool_wrapped(account, "compat-verification", TRUE);
- if (protocol == "prpl-hangouts") {
- std::string token;
- if (getUserToken(user, OAUTH_TOKEN, token)) {
- purple_account_set_password_wrapped(account, token.c_str());
- }
- }
- else if (protocol == "prpl-steam-mobile") {
- std::string token;
- getUserToken(user, STEAM_ACCESS_TOKEN, token);
- if (!token.empty()) {
- purple_account_set_string_wrapped(account, "access_token", token.c_str());
- }
- }
- else if (protocol == "prpl-eionrobb-discord") {
- std::string token;
- getUserToken(user, DISCORD_ACCESS_TOKEN, token);
- if (!token.empty()) {
- purple_account_set_string_wrapped(account, "token", token.c_str());
- }
- }
- else if (protocol == "prpl-hehoe-whatsmeow") {
- std::string token;
- getUserToken(user, WHATSMEOW_ACCESS_TOKEN, token);
- if (!token.empty()) {
- purple_account_set_string_wrapped(account, "credentials", token.c_str());
- }
+
+
+ // Stored user settings
+ for (const auto& item: settings) {
+ purple_account_set_string_wrapped(account, item.first.c_str(), item.second.c_str());
}
setDefaultAccountOptions(account);
@@ -517,8 +462,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
purple_account_set_enabled_wrapped(account, "spectrum", FALSE);
m_accounts.erase(account);
-
- purple_accounts_delete_wrapped(account);
#ifndef WIN32
#if !defined(__FreeBSD__) && !defined(__APPLE__) && defined (__GLIBC__)
malloc_trim(0);
@@ -1150,69 +1093,6 @@ static PurpleBlistUiOps blistUiOps =
static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime);
-static void conv_write(PurpleConversation *conv, const char *who, const char *alias, const char *msg, PurpleMessageFlags flags, time_t mtime) {
- LOG4CXX_INFO(logger, "conv_write()");
-
- if (flags & PURPLE_MESSAGE_SYSTEM && CONFIG_STRING(config, "service.protocol") == "prpl-telegram") {
- PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
-
- // char *striped = purple_markup_strip_html_wrapped(message);
- // std::string msg = striped;
- // g_free(striped);
-
-
- // Escape HTML characters.
- char *newline = purple_strdup_withhtml_wrapped(msg);
- char *strip, *xhtml;
- purple_markup_html_to_xhtml_wrapped(newline, &xhtml, &strip);
- // xhtml_linkified = spectrum_markup_linkify(xhtml);
- std::string message_(strip);
-
- std::string xhtml_(xhtml);
- g_free(newline);
- g_free(xhtml);
- // g_free(xhtml_linkified);
- g_free(strip);
-
- // AIM and XMPP adds <body>...</body> here...
- if (xhtml_.find("<body>") == 0) {
- xhtml_ = xhtml_.substr(6);
- if (xhtml_.find("</body>") != std::string::npos) {
- xhtml_ = xhtml_.substr(0, xhtml_.find("</body>"));
- }
- }
-
- if (xhtml_ == message_) {
- xhtml_ = "";
- }
-
- std::string timestamp;
- if (mtime && (unsigned long) time(NULL)-10 > (unsigned long) mtime/* && (unsigned long) time(NULL) - 31536000 < (unsigned long) mtime*/) {
- char buf[80];
- strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", gmtime(&mtime));
- timestamp = buf;
- }
-
- if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
- std::string w = purple_normalize_wrapped(account, who);
- size_t pos = w.find("/");
- if (pos != std::string::npos)
- w.erase((int) pos, w.length() - (int) pos);
- LOG4CXX_TRACE(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "' name='" << w << "'");
- np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_, timestamp);
- }
- else {
- std::string conversationName = purple_conversation_get_name_wrapped(conv);
- LOG4CXX_TRACE(logger, "Received message body='" << message_ << "' name='" << conversationName << "' " << who);
- np->handleMessage(np->m_accounts[account], np->NameToLegacyName(account, conversationName), message_, who, xhtml_, timestamp);
- }
- }
- else {
- //Handle all non-special cases by just passing them to conv_write_im
- conv_write_im(conv, who, msg, flags, mtime);
- }
-}
-
static char *calculate_data_hash(guchar *data, size_t len,
const gchar *hash_algo)
{
@@ -1487,6 +1367,11 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
}
}
+static void conv_write(PurpleConversation *conv, const char *who, const char *alias, const char *msg, PurpleMessageFlags flags, time_t mtime) {
+ //Handle all non-special cases by just passing them to conv_write_im
+ conv_write_im(conv, who, msg, flags, mtime);
+}
+
static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) {
PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
@@ -2181,18 +2066,6 @@ static void signed_on(PurpleConnection *gc, gpointer unused) {
// For prpl-gg
execute_purple_plugin_action(gc, "Download buddylist from Server");
- if (CONFIG_STRING(config, "service.protocol") == "prpl-hangouts") {
- storeUserToken(np->m_accounts[account], OAUTH_TOKEN, purple_account_get_password_wrapped(account));
- }
- else if (CONFIG_STRING(config, "service.protocol") == "prpl-steam-mobile") {
- storeUserToken(np->m_accounts[account], STEAM_ACCESS_TOKEN, purple_account_get_string_wrapped(account, "access_token", NULL));
- }
- else if (CONFIG_STRING(config, "service.protocol") == "prpl-eionrobb-discord") {
- storeUserToken(np->m_accounts[account], DISCORD_ACCESS_TOKEN, purple_account_get_string_wrapped(account, "token", NULL));
- }
- else if (CONFIG_STRING(config, "service.protocol") == "prpl-hehoe-whatsmeow") {
- storeUserToken(np->m_accounts[account], WHATSMEOW_ACCESS_TOKEN, purple_account_get_string_wrapped(account, "credentials", NULL));
- }
}
static void printDebug(PurpleDebugLevel level, const char *category, const char *arg_s) {
@@ -2276,8 +2149,6 @@ static bool initPurple() {
LOG4CXX_INFO(logger, "Setting libpurple user directory to: " << userDir);
purple_util_set_user_dir_wrapped(userDir.c_str());
- remove("./accounts.xml");
- remove("./blist.xml");
purple_debug_set_ui_ops_wrapped(&debugUiOps);
// purple_debug_set_verbose_wrapped(true);
@@ -2430,20 +2301,6 @@ int main(int argc, char **argv) {
config = std::shared_ptr<Config>(cfg);
Logging::initBackendLogging(config.get());
- if (CONFIG_STRING(config, "service.protocol") == "prpl-hangouts" || CONFIG_STRING(config, "service.protocol") == "prpl-steam-mobile"
- || CONFIG_STRING(config, "service.protocol") == "prpl-eionrobb-discord" || CONFIG_STRING(config, "service.protocol") == "prpl-hehoe-whatsmeow")
- {
- storagebackend = StorageBackend::createBackend(config.get(), error);
- if (storagebackend == NULL) {
- LOG4CXX_ERROR(logger, "Error creating StorageBackend! " << error);
- LOG4CXX_ERROR(logger, "Selected libpurple protocol need storage backend configured to work! " << error);
- return NetworkPlugin::StorageBackendNeeded;
- }
- else if (!storagebackend->connect()) {
- LOG4CXX_ERROR(logger, "Can't connect to database!");
- return -1;
- }
- }
initPurple();
diff --git a/backends/smstools3/main.cpp b/backends/smstools3/main.cpp
index 66438c6b..52ac2823 100644
--- a/backends/smstools3/main.cpp
+++ b/backends/smstools3/main.cpp
@@ -174,7 +174,7 @@ class SMSNetworkPlugin : public NetworkPlugin {
handleDataRead(d);
}
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
UserInfo info;
if (!storageBackend->getUser(user, info)) {
handleDisconnected(user, 0, "Not registered user.");
diff --git a/backends/swiften/main.cpp b/backends/swiften/main.cpp
index 4d89170c..9d6dc4b8 100644
--- a/backends/swiften/main.cpp
+++ b/backends/swiften/main.cpp
@@ -294,7 +294,7 @@ class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient {
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
}
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
Swift::JID jid(legacyName);
if (legacyName.find("/") == std::string::npos) {
diff --git a/backends/template/plugin.cpp b/backends/template/plugin.cpp
index 45ca5256..57b82848 100644
--- a/backends/template/plugin.cpp
+++ b/backends/template/plugin.cpp
@@ -36,7 +36,7 @@ void Plugin::_handleDataRead(std::shared_ptr<Swift::SafeByteArray> data) {
handleDataRead(d);
}
-void Plugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
+void Plugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings) {
handleConnected(user);
LOG4CXX_INFO(logger, user << ": Added buddy - Echo.");
handleBuddyChanged(user, "echo", "Echo", std::vector<std::string>(), pbnetwork::STATUS_ONLINE);
diff --git a/backends/template/plugin.h b/backends/template/plugin.h
index 0b4d86a5..be2d876d 100644
--- a/backends/template/plugin.h
+++ b/backends/template/plugin.h
@@ -12,7 +12,7 @@ class Plugin : public Transport::NetworkPlugin {
// NetworkPlugin uses this method to send the data to networkplugin server
void sendData(const std::string &string);
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings);
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp
index ab9bc5bf..9e510263 100644
--- a/backends/twitter/TwitterPlugin.cpp
+++ b/backends/twitter/TwitterPlugin.cpp
@@ -121,7 +121,7 @@ void TwitterPlugin::_handleDataRead(std::shared_ptr<Swift::SafeByteArray> data)
}
// User trying to login into his twitter account
-void TwitterPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password)
+void TwitterPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings)
{
if(userdb.count(user) && (userdb[user].connectionState == NEW ||
userdb[user].connectionState == CONNECTED ||
diff --git a/backends/twitter/TwitterPlugin.h b/backends/twitter/TwitterPlugin.h
index aec182f1..967df7fc 100644
--- a/backends/twitter/TwitterPlugin.h
+++ b/backends/twitter/TwitterPlugin.h
@@ -63,7 +63,7 @@ class TwitterPlugin : public NetworkPlugin {
void _handleDataRead(std::shared_ptr<Swift::SafeByteArray> data);
// User trying to login into his twitter account
- void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
+ void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings);
// User logging out
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
diff --git a/include/transport/MySQLBackend.h b/include/transport/MySQLBackend.h
index 7256e6f6..72196b26 100644
--- a/include/transport/MySQLBackend.h
+++ b/include/transport/MySQLBackend.h
@@ -96,6 +96,8 @@ class MySQLBackend : public StorageBackend
void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value);
void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value);
+ void getAllSettings(long userId, std::map<std::string, std::string> &userSettings);
+
void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
void updateUserSetting(long userId, const std::string &variable, const std::string &value);
@@ -144,6 +146,7 @@ class MySQLBackend : public StorageBackend
// MYSQL_STMT *m_setUser;
Statement *m_setUser;
Statement *m_getUser;
+ Statement *m_getUserSettings;
Statement *m_getUserSetting;
Statement *m_setUserSetting;
Statement *m_updateUserSetting;
diff --git a/include/transport/NetworkPlugin.h b/include/transport/NetworkPlugin.h
index 8be3ad13..eecf9497 100644
--- a/include/transport/NetworkPlugin.h
+++ b/include/transport/NetworkPlugin.h
@@ -197,6 +197,7 @@ class NetworkPlugin {
/// \param user XMPP JID of user for which this event occurs.
/// \param legacyName Legacy network name of this user used for login.
/// \param password Legacy network password of this user.
+ /// \param settings User settings
/**
\msc
NetworkPlugin,YourNetworkPlugin,LegacyNetwork;
@@ -210,7 +211,7 @@ class NetworkPlugin {
YourNetworkPlugin->NetworkPlugin [label="handleDisconnected()", URL="\ref NetworkPlugin::handleDisconnected()"];
\endmsc
*/
- virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0;
+ virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map<std::string, std::string> &settings = {}) = 0;
/// Called when XMPP user wants to disconnect legacy network.
/// You should disconnect him from legacy network.
diff --git a/include/transport/PQXXBackend.h b/include/transport/PQXXBackend.h
index 8ce96eee..587f3027 100644
--- a/include/transport/PQXXBackend.h
+++ b/include/transport/PQXXBackend.h
@@ -95,6 +95,8 @@ class PQXXBackend : public StorageBackend
void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {}
void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {}
+ void getAllSettings(long userId, std::map<std::string, std::string> &userSettings);
+
void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
void updateUserSetting(long userId, const std::string &variable, const std::string &value);
diff --git a/include/transport/SQLite3Backend.h b/include/transport/SQLite3Backend.h
index 7a88a45a..fa2f6d08 100644
--- a/include/transport/SQLite3Backend.h
+++ b/include/transport/SQLite3Backend.h
@@ -95,6 +95,8 @@ class SQLite3Backend : public StorageBackend
void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value);
void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value);
+ void getAllSettings(long userId, std::map<std::string, std::string> &userSettings);
+
void getUserSetting(long userId, const std::string &variable, int &type, std::string &value);
void updateUserSetting(long userId, const std::string &variable, const std::string &value);
@@ -111,6 +113,7 @@ class SQLite3Backend : public StorageBackend
// statements
sqlite3_stmt *m_setUser;
sqlite3_stmt *m_getUser;
+ sqlite3_stmt *m_getUserSettings;
sqlite3_stmt *m_getUserSetting;
sqlite3_stmt *m_setUserSetting;
sqlite3_stmt *m_updateUserSetting;
diff --git a/include/transport/StorageBackend.h b/include/transport/StorageBackend.h
index e497588e..8bbab168 100644
--- a/include/transport/StorageBackend.h
+++ b/include/transport/StorageBackend.h
@@ -37,6 +37,7 @@ struct UserInfo {
std::string password; ///< password for legacy network
std::string language; ///< user's preferred language
std::string encoding; ///< user's preferred encoding
+ std::map<std::string, std::string> settings;
bool vip; ///< true if user is VIP
};
@@ -134,6 +135,8 @@ class StorageBackend
virtual void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) = 0;
virtual void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) = 0;
+ virtual void getAllSettings(long userId, std::map<std::string, std::string> &userSettings) = 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;
diff --git a/include/transport/User.h b/include/transport/User.h
index f688a36d..dc21f82c 100644
--- a/include/transport/User.h
+++ b/include/transport/User.h
@@ -126,11 +126,11 @@ class User {
}
void addUserSetting(const std::string &key, const std::string &value) {
- m_settings[key] = value;
+ m_userInfo.settings[key] = value;
}
const std::string &getUserSetting(const std::string &key) {
- return m_settings[key];
+ return m_userInfo.settings[key];
}
void setCacheMessages(bool cacheMessages);
@@ -177,7 +177,6 @@ class User {
int m_resources;
int m_reconnectCounter;
std::list<Swift::Presence::ref> m_joinedRooms;
- std::map<std::string, std::string> m_settings;
bool m_cacheMessages;
int m_reconnectLimit;
StorageBackend *m_storageBackend;
diff --git a/include/transport/protocol.proto b/include/transport/protocol.proto
index 749c7e7a..adf97b90 100644
--- a/include/transport/protocol.proto
+++ b/include/transport/protocol.proto
@@ -48,6 +48,10 @@ message Login {
required string legacyName = 2;
required string password = 3;
repeated string extraFields = 4;
+ message UserSettings {
+ map<string, string> value = 1;
+ }
+ optional UserSettings settings = 5;
}
message Logout {
diff --git a/libtransport/MySQLBackend.cpp b/libtransport/MySQLBackend.cpp
index 97d781d6..cf39c75a 100644
--- a/libtransport/MySQLBackend.cpp
+++ b/libtransport/MySQLBackend.cpp
@@ -248,6 +248,7 @@ void MySQLBackend::disconnect() {
delete m_updateBuddy;
delete m_getBuddies;
delete m_getBuddiesSettings;
+ delete m_getUserSettings;
delete m_getUserSetting;
delete m_setUserSetting;
delete m_updateUserSetting;
@@ -297,6 +298,8 @@ bool MySQLBackend::connect() {
m_updateBuddySetting = new Statement(&m_conn, "iisiss", "INSERT INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE value=?");
m_getBuddySetting = new Statement(&m_conn, "iss|is", "SELECT type, value FROM " + m_prefix + "buddies_settings WHERE user_id=? AND buddy_id=? AND var=?");
+ m_getUserSettings = new Statement(&m_conn, "i|sis", "SELECT var, type, value FROM " + m_prefix + "users_settings WHERE user_id=?");
+
m_getUserSetting = new Statement(&m_conn, "is|is", "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?");
m_setUserSetting = new Statement(&m_conn, "isis", "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)");
m_updateUserSetting = new Statement(&m_conn, "sis", "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?");
@@ -383,6 +386,19 @@ void MySQLBackend::setUser(const UserInfo &user) {
EXEC(m_setUser, setUser(user));
}
+void MySQLBackend::getAllSettings(long userId, std::map<std::string, std::string> &userSettings) {
+ *m_getUserSettings << userId;
+ EXEC(m_getUserSettings, getAllSettings(userId, userSettings));
+ while (m_getUserSettings->fetch() == 0) {
+ std::string var;
+ int type;
+ std::string val;
+ SettingVariableInfo value;
+ *m_getUserSettings >> var >> type >> val;
+ userSettings[var] = val;
+ }
+}
+
bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) {
*m_getUser << barejid;
EXEC(m_getUser, getUser(barejid, user));
diff --git a/libtransport/NetworkPluginServer.cpp b/libtransport/NetworkPluginServer.cpp
index 59be6df2..e11cca7c 100644
--- a/libtransport/NetworkPluginServer.cpp
+++ b/libtransport/NetworkPluginServer.cpp
@@ -1369,6 +1369,11 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) {
login.set_user(user->getJID().toBare());
login.set_legacyname(userInfo.uin);
login.set_password(userInfo.password);
+ pbnetwork::Login_UserSettings *settings = login.mutable_settings();
+ auto value = settings->mutable_value();
+ for (const auto& item : userInfo.settings) {
+ (*value)[item.first] = item.second;
+ }
std::string message;
login.SerializeToString(&message);
diff --git a/libtransport/PQXXBackend.cpp b/libtransport/PQXXBackend.cpp
index df148fac..eafcda5a 100644
--- a/libtransport/PQXXBackend.cpp
+++ b/libtransport/PQXXBackend.cpp
@@ -399,6 +399,25 @@ bool PQXXBackend::removeUser(long id) {
return false;
}
+void PQXXBackend::getAllSettings(long userId, std::map<std::string, std::string> &userSettings) {
+ try
+ {
+ pqxx::nontransaction settings_txn(*m_conn);
+ pqxx::result settings_r = settings_txn.exec("SELECT var, type, value FROM " + m_prefix + "users_settings WHERE user_id=" + pqxx::to_string(userId));
+ for (pqxx::result::const_iterator it = settings_r.begin(); it != settings_r.end(); it++)
+ {
+ std::string var = (*it)[0].as<std::string>();
+ //int type = (*it)[1].as<long>();
+ std::string val = (*it)[2].as<std::string>();
+ userSettings[var] = val;
+ }
+ }
+ catch (std::exception &e)
+ {
+ LOG4CXX_ERROR(pxxLogger, e.what());
+ }
+}
+
void PQXXBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
try {
pqxx::nontransaction txn(*m_conn);
diff --git a/libtransport/SQLite3Backend.cpp b/libtransport/SQLite3Backend.cpp
index 678310af..07aa161d 100644
--- a/libtransport/SQLite3Backend.cpp
+++ b/libtransport/SQLite3Backend.cpp
@@ -94,6 +94,7 @@ SQLite3Backend::~SQLite3Backend(){
FINALIZE_STMT(m_updateBuddy);
FINALIZE_STMT(m_getBuddies);
FINALIZE_STMT(m_getBuddiesSettings);
+ FINALIZE_STMT(m_getUserSettings);
FINALIZE_STMT(m_getUserSetting);
FINALIZE_STMT(m_setUserSetting);
FINALIZE_STMT(m_updateUserSetting);
@@ -137,6 +138,8 @@ bool SQLite3Backend::connect() {
PREP_STMT(m_updateBuddySetting, "INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)");
PREP_STMT(m_getBuddySetting, "SELECT type, value FROM " + m_prefix + "buddies_settings WHERE user_id=? AND buddy_id=? AND var=?");
+ PREP_STMT(m_getUserSettings, "SELECT var, type, value FROM " + m_prefix + "users_settings WHERE user_id=?");
+
PREP_STMT(m_getUserSetting, "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?");
PREP_STMT(m_setUserSetting, "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)");
PREP_STMT(m_updateUserSetting, "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?");
@@ -513,6 +516,20 @@ bool SQLite3Backend::removeUser(long id) {
return true;
}
+void SQLite3Backend::getAllSettings(long userId, std::map<std::string, std::string> &userSettings) {
+ BEGIN(m_getUserSettings);
+ BIND_INT(m_getUserSettings, userId);
+ int ret2;
+ while ((ret2 = sqlite3_step(m_getUserSettings)) == SQLITE_ROW)
+ {
+ RESET_GET_COUNTER(m_getUserSettings);
+ std::string var = GET_STR(m_getUserSettings);
+ int type = GET_INT(m_getUserSettings);
+ std::string val = GET_STR(m_getUserSettings);
+ userSettings[var] = val;
+ }
+}
+
void SQLite3Backend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
BEGIN(m_getUserSetting);
BIND_INT(m_getUserSetting, id);
diff --git a/libtransport/UserManager.cpp b/libtransport/UserManager.cpp
index 83eabfb4..6abd9fe6 100644
--- a/libtransport/UserManager.cpp
+++ b/libtransport/UserManager.cpp
@@ -85,6 +85,9 @@ User *UserManager::getUser(const std::string &barejid){
if (m_users.find(barejid) != m_users.end()) {
User *user = m_users[barejid];
m_cachedUser = user;
+ if (m_storageBackend) {
+ m_storageBackend->getAllSettings(user->getUserInfo().id, user->getUserInfo().settings);
+ }
return user;
}
return NULL;
diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp
index 74e1ff60..e1c2f66b 100644
--- a/plugin/cpp/networkplugin.cpp
+++ b/plugin/cpp/networkplugin.cpp
@@ -350,7 +350,7 @@ void NetworkPlugin::handleLoginPayload(const std::string &data) {
// TODO: ERROR
return;
}
- handleLoginRequest(payload.user(), payload.legacyname(), payload.password());
+ handleLoginRequest(payload.user(), payload.legacyname(), payload.password(), { payload.settings().value().begin(), payload.settings().value().end() });
}
void NetworkPlugin::handleLogoutPayload(const std::string &data) {
diff --git a/tests/libtransport/basictest.h b/tests/libtransport/basictest.h
index 3b3fe08c..d855fe00 100644
--- a/tests/libtransport/basictest.h
+++ b/tests/libtransport/basictest.h
@@ -197,6 +197,12 @@ 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 getAllSettings(long userId, std::map<std::string, std::string> &userSettings) {
+ for (const auto& it : settings[userId]) {
+ userSettings[it.first] = it.second;
+ }
+ }
+
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;
diff --git a/tests/libtransport/settingsadhoccommand.cpp b/tests/libtransport/settingsadhoccommand.cpp
index 7733b557..d57e3029 100644
--- a/tests/libtransport/settingsadhoccommand.cpp
+++ b/tests/libtransport/settingsadhoccommand.cpp
@@ -359,6 +359,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
connectUser();
User *user = userManager->getUser("user@localhost");
CPPUNIT_ASSERT_EQUAL(std::string("1"), user->getUserSetting("send_headlines"));
+ CPPUNIT_ASSERT_EQUAL(3, (int) user->getUserInfo().settings.size());
std::shared_ptr<Swift::Command> payload(new Swift::Command("settings"));
std::shared_ptr<Swift::IQ> iq = Swift::IQ::createRequest(Swift::IQ::Set, Swift::JID("localhost"), "id", payload);
iq->setFrom("user@localhost");