From 41f5b30f56942907b2a74d4979749ae649f5804a Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Mon, 22 Mar 2021 18:43:00 +0100 Subject: [PATCH] Fixed some bugs related to the new server setup --- git-teaspeak | 2 +- server/src/InstanceHandlerSetup.cpp | 6 ++--- server/src/PermissionCalculator.cpp | 9 ++++++- server/src/PermissionCalculator.h | 1 + server/src/VirtualServer.cpp | 28 +++++++++++++++++--- server/src/VirtualServer.h | 2 ++ server/src/client/ConnectedClient.cpp | 4 +++ server/src/client/command_handler/server.cpp | 16 ++++++----- server/src/groups/GroupAssignmentManager.cpp | 5 ++++ server/src/groups/GroupManager.cpp | 7 ++--- 10 files changed, 63 insertions(+), 17 deletions(-) diff --git a/git-teaspeak b/git-teaspeak index 8c2608f..4dfe9fb 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 8c2608f90739a42cd727c8c8eab3d60bbb6dca53 +Subproject commit 4dfe9fbf023777cbc6dbb278cd1e161fe464edb4 diff --git a/server/src/InstanceHandlerSetup.cpp b/server/src/InstanceHandlerSetup.cpp index 4d53915..70e6da6 100644 --- a/server/src/InstanceHandlerSetup.cpp +++ b/server/src/InstanceHandlerSetup.cpp @@ -118,7 +118,7 @@ bool InstanceHandler::setupDefaultGroups() { groups.push_back(group); } - debugMessage(LOG_INSTANCE, "Read " + to_string(groups.size()) + " default groups"); + debugMessage(LOG_INSTANCE, "Read {} default groups", groups.size()); for(const auto& info : groups) { debugMessage(LOG_INSTANCE, "Creating default group {} with type {}", info->name, to_string(info->target)); //Query groups @@ -131,8 +131,8 @@ bool InstanceHandler::setupDefaultGroups() { create_result = serverInstance->group_manager()->channel_groups()->create_group(groups::GroupType::GROUP_TYPE_TEMPLATE, info->name, c_group); created_group = c_group; } else { - std::shared_ptr s_group{}; - create_result = serverInstance->group_manager()->channel_groups()->create_group(info->target == 0 ? groups::GroupType::GROUP_TYPE_QUERY : groups::GroupType::GROUP_TYPE_TEMPLATE, info->name, s_group); + std::shared_ptr s_group{}; + create_result = serverInstance->group_manager()->server_groups()->create_group(info->target == 0 ? groups::GroupType::GROUP_TYPE_QUERY : groups::GroupType::GROUP_TYPE_TEMPLATE, info->name, s_group); created_group = s_group; } diff --git a/server/src/PermissionCalculator.cpp b/server/src/PermissionCalculator.cpp index f87ba01..3708340 100644 --- a/server/src/PermissionCalculator.cpp +++ b/server/src/PermissionCalculator.cpp @@ -62,8 +62,8 @@ ClientPermissionCalculator::ClientPermissionCalculator( if(server) { this->virtual_server_id = server->getServerId(); this->group_manager_ = server->group_manager(); + this->default_server_group = [server]{ return server->default_server_group(); }; this->default_channel_group = [server]{ return server->default_channel_group(); }; - std::shared_ptr channel{}; try { std::shared_lock channel_lock{server->get_channel_tree_lock()}; @@ -94,6 +94,7 @@ void ClientPermissionCalculator::initialize_client(DataClient* client) { auto server = client->getServer(); if(server) { this->group_manager_ = server->group_manager(); + this->default_server_group = [server]{ return server->default_server_group(); }; this->default_channel_group = [server]{ return server->default_channel_group(); }; } else { this->group_manager_ = serverInstance->group_manager(); @@ -340,6 +341,12 @@ const std::vector>& ClientPermissionCalcula this->assigned_server_groups_->push_back(group); } } + if(this->assigned_server_groups_->empty() && this->default_server_group) { + auto default_group = this->default_server_group(); + if(default_group) { + this->assigned_server_groups_->push_back(default_group); + } + } return *this->assigned_server_groups_; } diff --git a/server/src/PermissionCalculator.h b/server/src/PermissionCalculator.h index a0d3dbb..ff8faab 100644 --- a/server/src/PermissionCalculator.h +++ b/server/src/PermissionCalculator.h @@ -65,6 +65,7 @@ namespace ts::server { std::shared_ptr group_manager_{}; std::shared_ptr channel_permissions{}; std::function()> default_channel_group{[]{ return nullptr; }}; + std::function()> default_server_group{[]{ return nullptr; }}; /* fields which will be set when calculating permissions */ std::shared_ptr client_permissions{}; diff --git a/server/src/VirtualServer.cpp b/server/src/VirtualServer.cpp index 14c34f2..58df99d 100644 --- a/server/src/VirtualServer.cpp +++ b/server/src/VirtualServer.cpp @@ -1028,15 +1028,15 @@ bool VirtualServer::resetPermissions(std::string& new_permission_token) { this->ensureValidDefaultGroups(); + this->task_notify_channel_group_list.enqueue(); + this->task_notify_server_group_list.enqueue(); + for(const auto& client : this->getClients()) { client->task_update_displayed_groups.enqueue(); client->task_update_needed_permissions.enqueue(); client->task_update_channel_client_properties.enqueue(); } - this->task_notify_channel_group_list.enqueue(); - this->task_notify_server_group_list.enqueue(); - return true; } @@ -1169,11 +1169,33 @@ void VirtualServer::update_channel_from_permissions(const std::shared_ptr VirtualServer::default_server_group() { + auto group_id = this->properties()[property::VIRTUALSERVER_DEFAULT_SERVER_GROUP].as_or(0); + auto group = this->group_manager()->server_groups()->find_group(groups::GroupCalculateMode::GLOBAL, group_id); + if(!group) { + auto groups = this->group_manager()->server_groups()->available_groups(groups::GroupCalculateMode::GLOBAL); + if(groups.empty()) { + logCritical(this->serverId, "Having no available server groups."); + return nullptr; + } + + /* TODO: Log warning? */ + group = groups.back(); + } + + return group; +} + std::shared_ptr VirtualServer::default_channel_group() { auto group_id = this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_or(0); auto group = this->group_manager()->channel_groups()->find_group(groups::GroupCalculateMode::GLOBAL, group_id); if(!group) { auto groups = this->group_manager()->channel_groups()->available_groups(groups::GroupCalculateMode::GLOBAL); + if(groups.empty()) { + logCritical(this->serverId, "Having no available channel groups."); + return nullptr; + } + /* TODO: Log warning? */ group = groups.back(); } diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index d48c882..c38a8aa 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -72,6 +72,7 @@ namespace ts { } namespace groups { + class ServerGroup; class ChannelGroup; class GroupManager; } @@ -182,6 +183,7 @@ namespace ts { } [[nodiscard]] inline auto group_manager() { return this->groups_manager_; } + [[nodiscard]] std::shared_ptr default_server_group(); [[nodiscard]] std::shared_ptr default_channel_group(); bool notifyServerEdited(std::shared_ptr, std::deque keys); diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index 4fc7c9d..dca53ae 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -1047,6 +1047,10 @@ void ConnectedClient::update_displayed_client_groups(bool& server_groups_changed if(!server_group_assignments.empty()) { server_group_assignments = server_group_assignments.substr(1); + } else if(auto default_group{ref_server->default_server_group()}; default_group) { + server_group_assignments = std::to_string(default_group->group_id()); + } else { + server_group_assignments = "0"; } std::unique_lock view_lock{this->channel_lock}; diff --git a/server/src/client/command_handler/server.cpp b/server/src/client/command_handler/server.cpp index ece708b..8284bcc 100644 --- a/server/src/client/command_handler/server.cpp +++ b/server/src/client/command_handler/server.cpp @@ -91,28 +91,28 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) { SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_server_group", permission::b_virtualserver_modify_default_servergroup, GroupId) if(target_server) { auto target_group = group_manager->server_groups()->find_group(groups::GroupCalculateMode::GLOBAL, cmd["virtualserver_default_server_group"].as()); - if (target_group) { + if (!target_group) { return command_result{error::group_invalid_id}; } } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_channel_group", permission::b_virtualserver_modify_default_channelgroup, GroupId) if(target_server) { auto target_group = group_manager->channel_groups()->find_group(groups::GroupCalculateMode::GLOBAL, cmd["virtualserver_default_channel_group"].as()); - if (target_group) { + if (!target_group) { return command_result{error::group_invalid_id}; } } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_channel_admin_group", permission::b_virtualserver_modify_default_channeladmingroup, GroupId) if(target_server) { auto target_group = group_manager->channel_groups()->find_group(groups::GroupCalculateMode::GLOBAL, cmd["virtualserver_default_channel_admin_group"].as()); - if (target_group) { + if (!target_group) { return command_result{error::group_invalid_id}; } } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_music_group", permission::b_virtualserver_modify_default_musicgroup, GroupId) if(target_server) { auto target_group = group_manager->server_groups()->find_group(groups::GroupCalculateMode::GLOBAL, cmd["virtualserver_default_server_group"].as()); - if (target_group) { + if (!target_group) { return command_result{error::group_invalid_id}; } } @@ -366,10 +366,14 @@ command_result ConnectedClient::handleCommandServerGroupClientList(Command &cmd) } if(index == 0) { - return ts::command_result{error::database_empty_result}; + if(this->getType() != ClientType::CLIENT_TEAMSPEAK) { + /* TS3 clients don't want a error here. They're fine with just not receiving a notify */ + return ts::command_result{error::database_empty_result}; + } + } else { + this->sendCommand(notify); } - this->sendCommand(notify); return command_result{error::ok}; } diff --git a/server/src/groups/GroupAssignmentManager.cpp b/server/src/groups/GroupAssignmentManager.cpp index 96bf285..e04620d 100644 --- a/server/src/groups/GroupAssignmentManager.cpp +++ b/server/src/groups/GroupAssignmentManager.cpp @@ -734,6 +734,11 @@ void GroupAssignmentManager::handle_channel_group_deleted(GroupId group_id) { void GroupAssignmentManager::reset_all() { auto sql = sql::command{this->sql_manager(), "DELETE FROM `assignedGroups` WHERE `serverId` = :sid", variable{":sid", this->server_id()}}; sql.executeLater().waitAndGetLater(LOG_SQL_CMD, {-1, "failed to delete all assignments"}); + + { + std::lock_guard cache_lock{*this->client_cache_lock}; + this->client_cache.clear(); + } } std::shared_ptr GroupAssignmentManager::create_tmp_assignment_lock(ClientDbId cldbid) { diff --git a/server/src/groups/GroupManager.cpp b/server/src/groups/GroupManager.cpp index 9744b11..2062fbf 100644 --- a/server/src/groups/GroupManager.cpp +++ b/server/src/groups/GroupManager.cpp @@ -122,12 +122,12 @@ void AbstractGroupManager::reset_groups(std::map &mapping) { /* Delete all old groups */ { - LOG_SQL_CMD(sql::command(this->sql_manager(), "DELETE FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` IN (SELECT `groupId` FROM `groups` WHERE `serverId` = :serverId AND AND `target` = :target)", + LOG_SQL_CMD(sql::command(this->sql_manager(), "DELETE FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` IN (SELECT `groupId` FROM `groups` WHERE `serverId` = :serverId AND `target` = :target)", variable{":serverId", this->server_id()}, variable{":type", ts::permission::SQL_PERM_GROUP}, variable{":target", (uint8_t) this->database_target_}).execute()); - LOG_SQL_CMD(sql::command(this->sql_manager(), "DELETE FROM `assignedGroups` WHERE `serverId` = :serverId AND `groupId` IN (SELECT `groupId` FROM `groups` WHERE `serverId` = :serverId AND AND `target` = :target)", + LOG_SQL_CMD(sql::command(this->sql_manager(), "DELETE FROM `assignedGroups` WHERE `serverId` = :serverId AND `groupId` IN (SELECT `groupId` FROM `groups` WHERE `serverId` = :AND AND `target` = :target)", variable{":serverId", this->server_id()}, variable{":target", (uint8_t) this->database_target_}).execute()); @@ -137,7 +137,8 @@ void AbstractGroupManager::reset_groups(std::map &mapping) { ).execute()); } - if(auto error = this->load_data(true); error != GroupLoadResult::SUCCESS) { + /* we expect to not have any groups */ + if(auto error = this->load_data(true); error != GroupLoadResult::NO_GROUPS) { logCritical(this->server_id(), "Failed to load groups after group unload ({}). There might be no groups loaded now!", (int) error); }