From a80c90f0255ebf7cec43829b4e8c2fc7b39ce88e Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Wed, 19 Aug 2020 14:50:42 +0200 Subject: [PATCH] Some minor fixes --- server/src/Group.cpp | 3 ++ server/src/VirtualServer.h | 4 +++ server/src/manager/SqlDataManager.cpp | 10 +++--- server/src/manager/TokeManager.cpp | 51 +++++++++++++++++++-------- server/src/manager/TokeManager.h | 12 ++++--- 5 files changed, 57 insertions(+), 23 deletions(-) diff --git a/server/src/Group.cpp b/server/src/Group.cpp index 1285cad..fd48f8d 100644 --- a/server/src/Group.cpp +++ b/server/src/Group.cpp @@ -452,6 +452,9 @@ bool GroupManager::deleteGroup(std::shared_ptr group) { flag_sql |= !res; serverInstance->databaseHelper()->deleteGroupArtifacts(this->getServerId(), group->groupId()); + if(auto server{this->server.lock()}; server) + server->getTokenManager()->handleGroupDelete(group->groupId()); + if(flag_sql) logError(this->getServerId(), "Could not delete group {} ({}) from database. May leader to invalid data", group->name(), group->groupId()); diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index a35413d..5e30229 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -185,6 +185,10 @@ namespace ts { inline ServerChannelTree* getChannelTree(){ return this->channelTree; } inline GroupManager* getGroupManager() { return this->groups; } + [[nodiscard]] inline auto getTokenManager() -> token::TokenManager* { + return this->tokenManager; + } + bool notifyServerEdited(std::shared_ptr, std::deque keys); bool notifyClientPropertyUpdates(std::shared_ptr, const std::deque& keys, bool selfNotify = true); /* execute only with at least channel tree read lock! */ inline bool notifyClientPropertyUpdates(const std::shared_ptr& client, const std::deque& keys, bool selfNotify = true) { diff --git a/server/src/manager/SqlDataManager.cpp b/server/src/manager/SqlDataManager.cpp index db48565..3d7bb98 100644 --- a/server/src/manager/SqlDataManager.cpp +++ b/server/src/manager/SqlDataManager.cpp @@ -541,11 +541,11 @@ bool SqlDataManager::update_database(std::string &error) { } case 14: { constexpr static std::array kUpdateCommands{ - "CREATE TABLE general_dg_tmp(id INTEGER NOT NULL PRIMARY KEY [AUTO_INCREMENT], key VARCHAR(256), value TEXT);", - "INSERT INTO general_dg_tmp(key, value) SELECT key, value FROM general;", - "DROP TABLE general;", - "ALTER TABLE general_dg_tmp rename TO general;", - "CREATE UNIQUE INDEX general_id_uindex ON general (id);" + "CREATE TABLE general_dg_tmp(`id` INTEGER NOT NULL PRIMARY KEY [AUTO_INCREMENT], `key` VARCHAR(256), `value` TEXT);", + "INSERT INTO general_dg_tmp(`key`, `value`) SELECT `key`, `value` FROM `general`;", + "DROP TABLE `general`;", + "ALTER TABLE `general_dg_tmp` RENAME TO `general`;", + "CREATE UNIQUE INDEX `general_id_uindex` ON `general` (`id`);" }; if(!execute_commands(this->sql(), error, kUpdateCommands)) diff --git a/server/src/manager/TokeManager.cpp b/server/src/manager/TokeManager.cpp index c922f4e..a4d5272 100644 --- a/server/src/manager/TokeManager.cpp +++ b/server/src/manager/TokeManager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "TokeManager.h" @@ -21,11 +22,10 @@ TokenManager::TokenManager(server::VirtualServer* handle) : handle(handle) { } -TokenManager::~TokenManager() {} +TokenManager::~TokenManager() = default; bool TokenManager::loadTokens() { - auto fn = LOG_SQL_CMD; - fn(sql::command(handle->getSql(), "SELECT * FROM `tokens` WHERE `serverId` = :sid", variable{":sid", handle->getServerId()}).query(&TokenManager::loadTokenFromDb, this)); + LOG_SQL_CMD(sql::command(handle->getSql(), "SELECT * FROM `tokens` WHERE `serverId` = :sid", variable{":sid", handle->getServerId()}).query(&TokenManager::loadTokenFromDb, this)); return true; } @@ -59,15 +59,22 @@ int TokenManager::loadTokenFromDb(int length, char **values, char **columns) { assert(group != 0); assert(created.time_since_epoch().count() != 0); - this->tokens.push_back(make_shared(token, type, group, chId, system_clock::now(), description)); + auto token_entry = std::make_shared(token, type, group, chId, system_clock::now(), description); + { + std::lock_guard tlock{this->token_lock}; + this->tokens.push_back(token_entry); + } return 0; } -std::shared_ptr TokenManager::createToken(TokenType type, GroupId group, std::string description, ChannelId chid, std::string token) { +std::shared_ptr TokenManager::createToken(TokenType type, GroupId group, const std::string& description, ChannelId chid, std::string token) { token = token.empty() ? rnd_string(20) : token; shared_ptr entry = make_shared(token, type, group, chid, system_clock::now(), description); - this->tokens.push_back(entry); + { + std::lock_guard tlock{this->token_lock}; + this->tokens.push_back(entry); + } auto res = sql::command(handle->getSql(), "INSERT INTO `tokens` (`serverId`, `type`, `token`, `targetGroup`, `targetChannel`, `description`, `created`) VALUES (:sid, :type, :token, :targetGroup, :targetChannel, :desc, :created);", variable{":sid", this->handle->getServerId()}, @@ -84,9 +91,16 @@ std::shared_ptr TokenManager::createToken(TokenType type, GroupId gr return entry; } bool TokenManager::deleteToke(const std::string& str) { - auto token = this->findToken(str); - if(!token) return false; - this->tokens.erase(std::find(this->tokens.begin(), this->tokens.end(), token)); + std::shared_ptr token; + { + std::lock_guard tlock{this->token_lock}; + auto it = std::find_if(this->tokens.begin(), this->tokens.end(), [&](const auto& token) { return token->token == str; }); + if(it == this->tokens.end()) + return false; + + token = std::move(*it); + this->tokens.erase(it); + } auto res = sql::command(handle->getSql(), "DELETE FROM `tokens` WHERE `token` = :token", variable{":token", token->token}).execute(); auto pf = LOG_SQL_CMD; @@ -95,11 +109,20 @@ bool TokenManager::deleteToke(const std::string& str) { return true; } -std::shared_ptr TokenManager::findToken(std::string str) { - for(auto& elm : this->tokens) - if(elm->token == str) return elm; +void TokenManager::handleGroupDelete(GroupId group_id) { + std::lock_guard tlock{this->token_lock}; + this->tokens.erase(std::remove_if(this->tokens.begin(), this->tokens.end(), [&](const std::shared_ptr& token) { + return token->groupId == group_id; + }), this->tokens.end()); +} + +std::shared_ptr TokenManager::findToken(const std::string& str) { + std::lock_guard tlock{this->token_lock}; + for(const auto& elm : this->tokens) + if(elm->token == str) + return elm; return nullptr; } -TokenEntry::TokenEntry(const string &token, TokenType type, GroupId groupId, ChannelId channelId, const time_point &created, const string &description) : token(token), type(type), groupId(groupId), channelId(channelId), - created(created), description(description) {} +TokenEntry::TokenEntry(string token, TokenType type, GroupId groupId, ChannelId channelId, const time_point &created, string description) : token(std::move(token)), type(type), groupId(groupId), channelId(channelId), + created(created), description(std::move(description)) {} diff --git a/server/src/manager/TokeManager.h b/server/src/manager/TokeManager.h index 891ed46..f984b88 100644 --- a/server/src/manager/TokeManager.h +++ b/server/src/manager/TokeManager.h @@ -17,7 +17,7 @@ namespace ts { TOKEN_CHANNEL }; struct TokenEntry { - TokenEntry(const std::string &token, TokenType type, GroupId groupId, ChannelId channelId, const std::chrono::time_point &created, const std::string &description); + TokenEntry(std::string token, TokenType type, GroupId groupId, ChannelId channelId, const std::chrono::time_point &created, std::string description); std::string token; TokenType type; //token_type @@ -29,17 +29,21 @@ namespace ts { class TokenManager { public: - TokenManager(server::VirtualServer*); + explicit TokenManager(server::VirtualServer*); ~TokenManager(); bool loadTokens(); std::vector> avariableTokes(){ return tokens; } - std::shared_ptr findToken(std::string); - std::shared_ptr createToken(TokenType, GroupId, std::string, ChannelId = 0, std::string token = ""); + std::shared_ptr findToken(const std::string&); + std::shared_ptr createToken(TokenType, GroupId, const std::string&, ChannelId = 0, std::string token = ""); bool deleteToke(const std::string&); + + void handleGroupDelete(GroupId); private: int loadTokenFromDb(int length, char** values, char** columns); server::VirtualServer* handle; + + std::mutex token_lock{}; std::vector> tokens; }; }