diff --git a/git-teaspeak b/git-teaspeak index 0063a5a..6dd8f87 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 0063a5acb2f6f5af91ca1d06dd27f432ec78e8a9 +Subproject commit 6dd8f87281e6fd60df0c5babfc1303df74ce1c0a diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 68c7e79..32bc648 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -85,6 +85,7 @@ set(SERVER_SOURCE_FILES src/DatabaseHelper.cpp src/manager/LetterManager.cpp + src/manager/PermissionNameManager.cpp tomcryptTest.cpp @@ -186,6 +187,46 @@ target_link_libraries(PermHelper jemalloc ) +add_executable(PermMapHelper helpers/PermMapGen.cpp) +target_link_libraries(PermMapHelper + ${LIBRARY_PATH_ED255} + + TeaSpeak #Static + TeaLicenseHelper #Static + TeaMusic #Static + ${LIBRARY_PATH_THREAD_POOL} #Static + ${LIBRARY_PATH_TERMINAL} #Static + ${LIBRARY_PATH_VARIBALES} + ${LIBRARY_PATH_YAML} + pthread + stdc++fs + ${LIBEVENT_PATH}/libevent.a + ${LIBEVENT_PATH}/libevent_pthreads.a + ${LIBRARY_PATH_OPUS} + ${LIBRARY_PATH_JSON} + ${LIBRARY_PATH_PROTOBUF} + + #${LIBWEBRTC_LIBRARIES} #ATTENTIAN! WebRTC does not work with crypto! (Already contains a crypto version) + ${LIBRARY_TOM_CRYPT} + ${LIBRARY_TOM_MATH} + + #We're forsed to use boringssl caused by the fact that boringssl is already within webrtc! + + #Require a so + sqlite3 + + ${LIBRARY_PATH_BREAKPAD} + ${LIBRARY_PATH_JDBC} + ${LIBRARY_PATH_PROTOBUF} + + ${LIBRARY_PATH_DATA_PIPES} + ${LIBRARY_PATH_BORINGSSL_SSL} + ${LIBRARY_PATH_BORINGSSL_CRYPTO} + dl + jemalloc + ) + + SET(CPACK_PACKAGE_VERSION_MAJOR "1") SET(CPACK_PACKAGE_VERSION_MINOR "4") SET(CPACK_PACKAGE_VERSION_PATCH "0") diff --git a/server/helpers/PermMapGen.cpp b/server/helpers/PermMapGen.cpp new file mode 100644 index 0000000..a0cebd5 --- /dev/null +++ b/server/helpers/PermMapGen.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#include /* required from permission manager */ +#include "log/LogUtils.h" +#include "Definitions.h" +#include "PermissionManager.h" + +using namespace std; +using namespace ts; + +/* Took from the permission mapper within the TeaSpeakServer */ +enum PermissionMapGroup { + MIN, + TS3 = MIN, + TEAWEB, + TEACLIENT, + QUERY, + MAX +}; + +std::map group_names = { + {PermissionMapGroup::TS3, "TeamSpeak 3"}, + {PermissionMapGroup::TEAWEB, "TeaSpeak-Web"}, + {PermissionMapGroup::TEACLIENT, "TeaSpeak-Client"}, + {PermissionMapGroup::QUERY, "Query"} +}; + +//TODO: Does it work with a space at the end? +#define I "\x5f\xcc\xb2" /* an underscore with an non-spacing underscore */ +std::map replacements = { + {"_music", I "music"}, + {"_hwid", I "hwid" }, + {"_playlist", I "playlist"} +}; + +std::string replace_all(std::string str, const std::string& from, const std::string& to) { + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } + return str; +} + + +int main(int argc, char** argv) { + ofstream of("permission_mapping.txt"); + + of << "# This is a auto generated template file!" << endl; + of << "# DO NOT EDIT IF YOU'RE NOT SURE WHAT YOU'RE DOING!" << endl; + of << "# Syntax:" << endl; + of << "# group: -> group id values: 0 := TS3 | 1 := TeaWeb | 2 := TeaClient | 3 := Query " << endl; + of << "# mapping::" << endl; + of << "# Note: Be aware of spaces and line endings. The TeaSpeakServer does not trim the values!" << endl; + of << "#" << endl; + + + for(PermissionMapGroup type = PermissionMapGroup::MIN; type < PermissionMapGroup::MAX; (*(int*) &type)++) { + of << "# Begin mapping for group " << (int) type << " (" << group_names[type] << ")" << endl; + of << "group:" << (int) type << endl; + + if(type == PermissionMapGroup::TS3) { + for(const auto& permission : permission::availablePermissions) { + if(!permission->clientSupported) + continue; + + auto value = permission->name; + for(auto& replacement : replacements) + value = replace_all(value, replacement.first, replacement.second); + of << "mapping:" << permission->name << ":" << value << endl; + } + } else { + of << "# No mapping required here. You're of course free to add stuff here." << endl; + } + of << "# End mapping of group" << endl; + } + + of.close(); +} \ No newline at end of file diff --git a/server/src/Configuration.cpp b/server/src/Configuration.cpp index facfaaf..8edc479 100644 --- a/server/src/Configuration.cpp +++ b/server/src/Configuration.cpp @@ -39,6 +39,7 @@ std::string config::database::sqlite::sync_mode; std::shared_ptr config::license; std::shared_ptr config::license_original; bool config::experimental_31 = false; +std::string config::permission_mapping_file; bool ts::config::binding::enforce_default_voice_host = false; std::string ts::config::binding::DefaultVoiceHost; @@ -896,6 +897,12 @@ std::deque> config::create_bindings() { BIND_STRING(config::music::command_prefix, "."); ADD_DESCRIPTION("The default channel chat command prefix"); } + { + CREATE_BINDING("permission_mapping", 0); + BIND_STRING(config::permission_mapping_file, "resources/permission_mapping.txt"); + ADD_DESCRIPTION("Mapping for the permission names"); + ADD_SENSITIVE(); + } } { BIND_GROUP(log) diff --git a/server/src/Configuration.h b/server/src/Configuration.h index 69b89db..092515f 100644 --- a/server/src/Configuration.h +++ b/server/src/Configuration.h @@ -46,6 +46,7 @@ namespace ts { extern std::shared_ptr license_original; extern bool experimental_31; + extern std::string permission_mapping_file; namespace binding { extern bool enforce_default_voice_host; diff --git a/server/src/InstanceHandler.cpp b/server/src/InstanceHandler.cpp index ccec6e4..7f4cd9d 100644 --- a/server/src/InstanceHandler.cpp +++ b/server/src/InstanceHandler.cpp @@ -12,6 +12,7 @@ #include "src/server/QueryServer.h" #include "src/server/file/FileServer.h" #include "SignalHandler.h" +#include "src/manager/PermissionNameMapper.h" #include #include "ShutdownHelper.h" #include @@ -252,9 +253,15 @@ bool InstanceHandler::startInstance() { if (this->active) return false; active = true; + string errorMessage; + this->web_list->enabled = ts::config::server::enable_teamspeak_weblist; - string errorMessage; + this->permission_mapper = make_shared(); + if(!this->permission_mapper->initialize(config::permission_mapping_file, errorMessage)) { + logCritical(LOG_INSTANCE, "Failed to initialize permission name mapping from file {}: {}", config::permission_mapping_file, errorMessage); + return false; + } this->sslMgr = new ssl::SSLManager(); if(!this->sslMgr->initialize()) { logCritical("Failed to initialize ssl manager."); diff --git a/server/src/InstanceHandler.h b/server/src/InstanceHandler.h index 04b5ff9..36b0593 100644 --- a/server/src/InstanceHandler.h +++ b/server/src/InstanceHandler.h @@ -15,6 +15,10 @@ namespace ts { class WebListManager; } + namespace permission { + class PermissionNameMapper; + } + namespace server { class InstanceHandler { public: @@ -62,6 +66,8 @@ namespace ts { std::shared_ptr getDefaultServerProperties() { return this->default_server_properties; } std::shared_ptr getWebIoLoop() { return this->web_event_loop; } std::shared_ptr getWebList() { return this->web_list; } + + std::shared_ptr getPermissionMapper() { return this->permission_mapper; } std::shared_ptr getConversationIo() { return this->conversation_io; } private: std::mutex activeLock; @@ -103,6 +109,7 @@ namespace ts { std::shared_ptr statistics = nullptr; std::shared_ptr tick_manager = nullptr; + std::shared_ptr permission_mapper = nullptr; std::shared_ptr teamspeak_license = nullptr; threads::Mutex lock_tick; diff --git a/server/src/TSServer.cpp b/server/src/TSServer.cpp index aee5a88..2a703ba 100644 --- a/server/src/TSServer.cpp +++ b/server/src/TSServer.cpp @@ -84,6 +84,7 @@ bool TSServer::initialize(bool test_properties) { properties()[property::VIRTUALSERVER_KEYPAIR] = ""; } } + int err; if(!_serverKey){ debugMessage(this->serverId, "Generating new server keypair"); diff --git a/server/src/client/ConnectedClientCommandHandler.cpp b/server/src/client/ConnectedClientCommandHandler.cpp index dd24f6a..f5de7b0 100644 --- a/server/src/client/ConnectedClientCommandHandler.cpp +++ b/server/src/client/ConnectedClientCommandHandler.cpp @@ -18,6 +18,7 @@ #include "query/QueryClient.h" #include "../weblist/WebListManager.h" #include "../manager/ConversationManager.h" +#include "../manager/PermissionNameMapper.h" #include #include #include @@ -43,6 +44,7 @@ extern ts::server::InstanceHandler *serverInstance; #define QUERY_PASSWORD_LENGTH 12 +//TODO: Map permsid! #define PARSE_PERMISSION(cmd) \ permission::PermissionType permType = permission::PermissionType::unknown; \ bool grant = false; \ @@ -859,10 +861,10 @@ CommandResult ConnectedClient::handleCommandChannelUnsubscribeAll(Command &cmd) CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); - static std::string permission_list_string; + static std::string permission_list_string[ClientType::MAX]; static std::mutex permission_list_string_lock; - static auto build_permission_list = [](const std::string& command) { + static auto build_permission_list = [](const std::string& command, const ClientType& type) { Command list_builder(command); int index = 0; for (auto group : permission::availableGroups) @@ -872,29 +874,33 @@ CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) { std::sort(avPerms.begin(), avPerms.end(), [](const std::shared_ptr &a, const std::shared_ptr &b) { return a->type < b->type; }); + + auto mapper = serverInstance->getPermissionMapper(); for (const auto& permission : avPerms) { if (!permission->clientSupported) continue; auto &blk = list_builder[index++]; blk["permname"] = permission->name; + blk["permname"] = mapper->permission_name(type, permission->type); blk["permdesc"] = permission->description; blk["permid"] = permission->type; } return list_builder; }; - if((this->getType() == CLIENT_TEASPEAK || this->getType() == CLIENT_TEAMSPEAK || this->getType() == CLIENT_QUERY) && false) { + auto type = this->getType(); + if(type == CLIENT_TEASPEAK || type == CLIENT_TEAMSPEAK || type == CLIENT_QUERY) { Command response(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : ""); { lock_guard lock(permission_list_string_lock); - if(permission_list_string.empty()) - permission_list_string = build_permission_list("").build(); - response[0][""] = permission_list_string; + if(permission_list_string[type].empty()) + permission_list_string[type] = build_permission_list("", type).build(); + response[0][""] = permission_list_string[type]; } this->sendCommand(response); } else { - this->sendCommand(build_permission_list(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "")); + this->sendCommand(build_permission_list(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "", type)); } return CommandResult::Success; } @@ -2314,12 +2320,14 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) { int index = 0; result["cid"] = channel->channelId(); + auto permission_mapper = serverInstance->getPermissionMapper(); + auto type = this->getType(); auto permission_manager = channel->permissions(); for (const auto &permission_data : permission_manager->permissions()) { auto& permission = std::get<1>(permission_data); if(permission.flags.value_set) { if(sids) { - result[index]["permsid"] = permission::resolvePermissionData(std::get<0>(permission_data))->name; + result[index]["permsid"] = permission_mapper->permission_name(type, std::get<0>(permission_data)); } else { result[index]["permid"] = std::get<0>(permission_data); } @@ -2331,7 +2339,7 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) { } if(permission.flags.grant_set) { if(sids) { - result[index]["permsid"] = permission::resolvePermissionData(std::get<0>(permission_data))->grant_name; + result[index]["permsid"] = permission_mapper->permission_name_grant(type, std::get<0>(permission_data)); } else { result[index]["permid"] = (uint16_t) (std::get<0>(permission_data) | PERM_ID_GRANT); } @@ -5083,11 +5091,14 @@ CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd) res[index]["cldbid"] = cmd["cldbid"].as(); auto sids = cmd.hasParm("permsid"); + auto permission_mapper = serverInstance->getPermissionMapper(); + auto type = this->getType(); + for (const auto &permission_data : permissions) { auto& permission = std::get<1>(permission_data); if(permission.flags.value_set) { if (sids) - res[index]["permsid"] = permission::resolvePermissionData(get<0>(permission_data))->name; + res[index]["permsid"] = permission_mapper->permission_name(type, get<0>(permission_data)); else res[index]["permid"] = get<0>(permission_data); res[index]["permvalue"] = permission.values.value; @@ -5100,7 +5111,7 @@ CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd) if(permission.flags.grant_set) { if (sids) - res[index]["permsid"] = permission::resolvePermissionData(get<0>(permission_data))->grant_name; + res[index]["permsid"] = permission_mapper->permission_name_grant(type, get<0>(permission_data)); else res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT); res[index]["permvalue"] = permission.values.grant; @@ -5562,12 +5573,14 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { Command res(""); deque requrested; + auto permission_mapper = serverInstance->getPermissionMapper(); + auto type = this->getType(); for (int index = 0; index < cmd.bulkCount(); index++) { permission::PermissionType permType = permission::unknown; if (cmd[index].has("permid")) permType = cmd[index]["permid"].as(); else if (cmd[index].has("permsid")) - permType = permission::resolvePermissionData(cmd[index]["permsid"].as())->type; + permType = permission::resolvePermissionData(cmd[index]["permsid"].as())->type; //TODO: Map the other way around! if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) return {findError("parameter_invalid"), "could not resolve permission"}; requrested.push_back(permType); @@ -5575,7 +5588,7 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { int index = 0; for(const auto& entry : this->permissionValues(permission::PERMTEST_ORDERED, requrested, this->currentChannel)) { - res[index]["permsid"] = permission::resolvePermissionData(entry.first)->name; + res[index]["permsid"] = permission_mapper->permission_name(type, entry.first);; res[index]["permid"] = entry.first; res[index++]["permvalue"] = entry.second; } @@ -5585,7 +5598,7 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { } CommandResult ConnectedClient::handleCommandPermIdGetByName(Command &cmd) { - auto found = permission::resolvePermissionData(cmd["permsid"].as()); + auto found = permission::resolvePermissionData(cmd["permsid"].as()); //TODO: Map the other way around Command res(""); res["permid"] = found->type; this->sendCommand(res); @@ -5622,7 +5635,7 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { if(permission->type == permission::PermissionType::unknown) return {findError("parameter_invalid"), "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"}; } else if (cmd[index].has("permsid")) { - permission = permission::resolvePermissionData(cmd[index]["permsid"].as()); + permission = permission::resolvePermissionData(cmd[index]["permsid"].as()); //TODO: Map the other way around granted = permission->grant_name == cmd[index]["permsid"].as(); if(permission->type == permission::PermissionType::unknown) diff --git a/server/src/client/ConnectedClientNotifyHandler.cpp b/server/src/client/ConnectedClientNotifyHandler.cpp index 827a0af..37bbe18 100644 --- a/server/src/client/ConnectedClientNotifyHandler.cpp +++ b/server/src/client/ConnectedClientNotifyHandler.cpp @@ -7,6 +7,7 @@ #include "../server/VoiceServer.h" #include "../InstanceHandler.h" #include "../server/QueryServer.h" +#include "../manager/PermissionNameMapper.h" #include "music/MusicClient.h" #include #include @@ -73,16 +74,17 @@ bool ConnectedClient::notifyGroupPermList(const std::shared_ptr& group, b int index = 0; auto permissions = group->permissions()->permissions(); + auto permission_mapper = serverInstance->getPermissionMapper(); + auto client_type = this->getType(); for (const auto &permission_data : permissions) { auto& permission = get<1>(permission_data); if(!permission.flags.value_set) continue; - auto type = permission::resolvePermissionData(get<0>(permission_data)); if(as_sid) { - cmd[index]["permsid"] = type->name; + cmd[index]["permsid"] = permission_mapper->permission_name(client_type, get<0>(permission_data)); } else { - cmd[index]["permid"] = (uint16_t) type->type; + cmd[index]["permid"] = (uint16_t) get<0>(permission_data); } cmd[index]["permvalue"] = permission.values.value; cmd[index]["permnegated"] = permission.flags.negate; @@ -94,11 +96,10 @@ bool ConnectedClient::notifyGroupPermList(const std::shared_ptr& group, b if(!permission.flags.grant_set) continue; - auto type = permission::resolvePermissionData(get<0>(permission_data)); if(as_sid) { - cmd[index]["permsid"] = type->grant_name; + cmd[index]["permsid"] = permission_mapper->permission_name_grant(client_type, get<0>(permission_data)); } else { - cmd[index]["permid"] = (uint16_t) (type->type | PERM_ID_GRANT); + cmd[index]["permid"] = (uint16_t) (get<0>(permission_data) | PERM_ID_GRANT); } cmd[index]["permvalue"] = permission.values.grant; cmd[index]["permnegated"] = permission.flags.negate; @@ -123,11 +124,13 @@ bool ConnectedClient::notifyClientPermList(ClientDbId cldbid, const std::shared_ int index = 0; res[index]["cldbid"] = cldbid; + auto permission_mapper = serverInstance->getPermissionMapper(); + auto client_type = this->getType(); for (const auto &permission_data : permissions) { auto& permission = std::get<1>(permission_data); if(permission.flags.value_set) { if (perm_sids) - res[index]["permsid"] = permission::resolvePermissionData(get<0>(permission_data))->name; + res[index]["permsid"] = permission_mapper->permission_name(client_type, get<0>(permission_data)); else res[index]["permid"] = get<0>(permission_data); res[index]["permvalue"] = permission.values.value; @@ -140,7 +143,7 @@ bool ConnectedClient::notifyClientPermList(ClientDbId cldbid, const std::shared_ if(permission.flags.grant_set) { if (perm_sids) - res[index]["permsid"] = permission::resolvePermissionData(get<0>(permission_data))->grant_name; + res[index]["permsid"] = permission_mapper->permission_name_grant(client_type, get<0>(permission_data)); else res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT); res[index]["permvalue"] = permission.values.grant; diff --git a/server/src/client/voice/VoiceClientPacketHandler.cpp b/server/src/client/voice/VoiceClientPacketHandler.cpp index 1af3154..e75be64 100644 --- a/server/src/client/voice/VoiceClientPacketHandler.cpp +++ b/server/src/client/voice/VoiceClientPacketHandler.cpp @@ -70,7 +70,6 @@ void VoiceClient::handlePacketPing(const std::unique_ptr this->connection->sendPacket(pkt); } - void VoiceClient::handlePacketVoice(const std::unique_ptr& packet) { if (packet->type() == PacketTypeInfo::Voice) { SpeakingClient::handlePacketVoice(packet->data(), packet->has_flag(PacketFlag::Compressed), packet->has_flag(PacketFlag::Fragmented)); diff --git a/server/src/manager/PermissionNameManager.cpp b/server/src/manager/PermissionNameManager.cpp new file mode 100644 index 0000000..b87c2dd --- /dev/null +++ b/server/src/manager/PermissionNameManager.cpp @@ -0,0 +1,122 @@ +#include +#include +#include +#include "PermissionNameMapper.h" + +using namespace ts::permission; +using namespace std; +namespace fs = std::experimental::filesystem; + +PermissionNameMapper::PermissionNameMapper() {} +PermissionNameMapper::~PermissionNameMapper() {} + + +std::string PermissionNameMapper::permission_name(const Type::value& type, const ts::permission::PermissionType &permission) const { + const static std::string unknown = "unknown"; + + if(type < 0 || type > Type::MAX) + return unknown; + + if(permission < 0 || permission >= PermissionType::permission_id_max) + return unknown; + + return this->mapping[type][permission].mapped_name; +} + +std::string PermissionNameMapper::permission_name_grant(const Type::value& type, const ts::permission::PermissionType &permission) const { + const static std::string unknown = "unknown"; + + if(type < 0 || type > Type::MAX) + return unknown; + + if(permission < 0 || permission >= PermissionType::permission_id_max) + return unknown; + + return this->mapping[type][permission].grant_name; +} + +bool PermissionNameMapper::initialize(const std::string &file, std::string &error) { + auto file_path = fs::u8path(file); + if(!fs::exists(file)) { + error = "file does not exists"; + return false; + } + + ifstream istream(file_path); + if(!istream.good()) { + error = "failed to open file"; + return false; + } + + array, PermissionType::permission_id_max> mapping; + + string line; + auto current_type = Type::MAX; + size_t line_index = 0; + + std::string key, value; + while(istream) { + line.clear(); + getline(istream, line); + line_index++; + if(line.empty() || line[0] == '#') + continue; + + auto seperator = line.find(':'); + if(seperator == -1) { + logWarning(LOG_INSTANCE, "Invalid permission mapping line {}: {}", line_index, line); + continue; + } + + key = line.substr(0, seperator); + value = line.substr(seperator + 1); + + if(key == "group") { + try { + auto index = stol(value); + if(index < 0 || index >= Type::MAX) { + logWarning(LOG_INSTANCE, "Invalid permission group at {}. Value is not in bounds: {}", line_index, line); + continue; + } + + current_type = (Type::value) index; + continue; + } catch(std::exception& ex) { + logWarning(LOG_INSTANCE, "Invalid permission group at {}. Value is not a number: {}", line_index, line); + continue; + } + } else if(key == "mapping") { + if(current_type == Type::MAX) { + logWarning(LOG_INSTANCE, "Invalid permission mapping entry at line {} (No group set): {}", line_index, line); + continue; + } + seperator = value.find(':'); + if(seperator == -1) { + logWarning(LOG_INSTANCE, "Invalid permission mapping entry at line {} (Missing colon): {}", line_index, line); + continue; + } + key = value.substr(0, seperator); + value = value.substr(seperator + 1); + + mapping[current_type][key] = value; + } else { + logWarning(LOG_INSTANCE, "Invalid permission mapping line at {}. Key is unknown: {}", line_index, line); + continue; + } + } + + /* lets build the index */ + for(Type::value type = Type::MIN; type < Type::MAX; (*(int*) &type)++) { + auto& array = this->mapping[type]; + auto& map = mapping[type]; + + for(PermissionType permission = PermissionType::permission_id_min; permission < PermissionType::permission_id_max; (*(uint16_t *)&permission)++) { + auto data = permission::resolvePermissionData(permission); + + array[permission].mapped_name = map.count(data->name) > 0 ? map[data->name] : data->name; + array[permission].grant_name = "i_needed_modify_power_" + array[permission].mapped_name.substr(2); + } + } + + return true; +} \ No newline at end of file diff --git a/server/src/manager/PermissionNameMapper.h b/server/src/manager/PermissionNameMapper.h new file mode 100644 index 0000000..d8a5dd2 --- /dev/null +++ b/server/src/manager/PermissionNameMapper.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include "PermissionManager.h" +#include "Definitions.h" + +namespace ts { + namespace permission { + class PermissionNameMapper { + public: + struct Type { + enum value { + MIN, + TS3 = MIN, + TEAWEB, + TEACLIENT, + QUERY, + MAX + }; + + inline static value from_client_type(const server::ClientType& client) { + if(client == server::ClientType::CLIENT_TEAMSPEAK) + return value::TS3; + + if(client == server::ClientType::CLIENT_TEASPEAK) + return value::TEACLIENT; + + if(client == server::ClientType::CLIENT_WEB) + return value::TEAWEB; + + return value::QUERY; + } + }; + + PermissionNameMapper(); + virtual ~PermissionNameMapper(); + + bool initialize(const std::string& file, std::string& error); + + std::string permission_name(const Type::value& /* type */, const permission::PermissionType& /* permission */) const; + inline std::string permission_name(const server::ClientType& type, const permission::PermissionType& permission) const { + return this->permission_name(Type::from_client_type(type), permission); + } + + std::string permission_name_grant(const Type::value& /* type */, const permission::PermissionType& /* permission */) const; + inline std::string permission_name_grant(const server::ClientType& type, const permission::PermissionType& permission) const { + return this->permission_name_grant(Type::from_client_type(type), permission); + } + private: + struct PermissionMap { + std::string mapped_name; + std::string grant_name; + }; + std::array< + std::array, + Type::value::MAX + > mapping; + }; + } +} \ No newline at end of file diff --git a/shared b/shared index 5c4df78..2052317 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 5c4df786ed9a2d3610c416f2d9c6e7a1fb07d5f0 +Subproject commit 2052317e6c6feba915bdb64d4c8187ff8479e585