Added the permission mapping file
This commit is contained in:
parent
bd43c53db2
commit
87fd26301d
@ -1 +1 @@
|
|||||||
Subproject commit 535d63f039b3e0b0559e7e09a5c80b04111fe93f
|
Subproject commit 6afc5f0a4fbd9b8a4b8867f14ce2c5b2bf47bfbd
|
@ -85,6 +85,7 @@ set(SERVER_SOURCE_FILES
|
|||||||
src/DatabaseHelper.cpp
|
src/DatabaseHelper.cpp
|
||||||
|
|
||||||
src/manager/LetterManager.cpp
|
src/manager/LetterManager.cpp
|
||||||
|
src/manager/PermissionNameManager.cpp
|
||||||
|
|
||||||
tomcryptTest.cpp
|
tomcryptTest.cpp
|
||||||
|
|
||||||
@ -184,9 +185,49 @@ target_link_libraries(PermHelper
|
|||||||
jemalloc
|
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_MAJOR "1")
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR "3")
|
SET(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH "23")
|
SET(CPACK_PACKAGE_VERSION_PATCH "24")
|
||||||
if(BUILD_TYPE_NAME EQUAL OFF)
|
if(BUILD_TYPE_NAME EQUAL OFF)
|
||||||
SET(CPACK_PACKAGE_VERSION_DATA "beta")
|
SET(CPACK_PACKAGE_VERSION_DATA "beta")
|
||||||
elseif(BUILD_TYPE_NAME STREQUAL "")
|
elseif(BUILD_TYPE_NAME STREQUAL "")
|
||||||
|
82
server/helpers/PermMapGen.cpp
Normal file
82
server/helpers/PermMapGen.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include <fstream>
|
||||||
|
#include <query/Command.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <functional> /* 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<PermissionMapGroup, string> 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<string, string> 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> -> group id values: 0 := TS3 | 1 := TeaWeb | 2 := TeaClient | 3 := Query " << endl;
|
||||||
|
of << "# mapping:<original name>:<mapped value>" << 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();
|
||||||
|
}
|
@ -39,6 +39,7 @@ std::string config::database::sqlite::sync_mode;
|
|||||||
std::shared_ptr<license::License> config::license;
|
std::shared_ptr<license::License> config::license;
|
||||||
std::shared_ptr<license::License> config::license_original;
|
std::shared_ptr<license::License> config::license_original;
|
||||||
bool config::experimental_31 = false;
|
bool config::experimental_31 = false;
|
||||||
|
std::string config::permission_mapping_file;
|
||||||
|
|
||||||
bool ts::config::binding::enforce_default_voice_host = false;
|
bool ts::config::binding::enforce_default_voice_host = false;
|
||||||
std::string ts::config::binding::DefaultVoiceHost;
|
std::string ts::config::binding::DefaultVoiceHost;
|
||||||
@ -887,6 +888,12 @@ std::deque<std::shared_ptr<EntryBinding>> config::create_bindings() {
|
|||||||
BIND_STRING(config::music::command_prefix, ".");
|
BIND_STRING(config::music::command_prefix, ".");
|
||||||
ADD_DESCRIPTION("The default channel chat 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)
|
BIND_GROUP(log)
|
||||||
|
@ -46,6 +46,7 @@ namespace ts {
|
|||||||
extern std::shared_ptr<license::License> license_original;
|
extern std::shared_ptr<license::License> license_original;
|
||||||
|
|
||||||
extern bool experimental_31;
|
extern bool experimental_31;
|
||||||
|
extern std::string permission_mapping_file;
|
||||||
|
|
||||||
namespace binding {
|
namespace binding {
|
||||||
extern bool enforce_default_voice_host;
|
extern bool enforce_default_voice_host;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "src/server/QueryServer.h"
|
#include "src/server/QueryServer.h"
|
||||||
#include "src/server/file/FileServer.h"
|
#include "src/server/file/FileServer.h"
|
||||||
#include "SignalHandler.h"
|
#include "SignalHandler.h"
|
||||||
|
#include "src/manager/PermissionNameMapper.h"
|
||||||
#include <ThreadPool/Timer.h>
|
#include <ThreadPool/Timer.h>
|
||||||
#include "ShutdownHelper.h"
|
#include "ShutdownHelper.h"
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
@ -228,8 +229,15 @@ inline sockaddr_in* resolveAddress(const string& host, uint16_t port) {
|
|||||||
bool InstanceHandler::startInstance() {
|
bool InstanceHandler::startInstance() {
|
||||||
if (this->active) return false;
|
if (this->active) return false;
|
||||||
active = true;
|
active = true;
|
||||||
|
string errorMessage;
|
||||||
|
|
||||||
this->web_list->enabled = ts::config::server::enable_teamspeak_weblist;
|
this->web_list->enabled = ts::config::server::enable_teamspeak_weblist;
|
||||||
|
|
||||||
|
this->permission_mapper = make_shared<permission::PermissionNameMapper>();
|
||||||
|
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();
|
this->sslMgr = new ssl::SSLManager();
|
||||||
if(!this->sslMgr->initialize()) {
|
if(!this->sslMgr->initialize()) {
|
||||||
logCritical("Failed to initialize ssl manager.");
|
logCritical("Failed to initialize ssl manager.");
|
||||||
@ -264,7 +272,6 @@ bool InstanceHandler::startInstance() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string errorMessage;
|
|
||||||
queryServer = new ts::server::QueryServer(this->getSql());
|
queryServer = new ts::server::QueryServer(this->getSql());
|
||||||
{
|
{
|
||||||
auto server_query = queryServer->find_query_account_by_name("serveradmin");
|
auto server_query = queryServer->find_query_account_by_name("serveradmin");
|
||||||
|
@ -15,6 +15,10 @@ namespace ts {
|
|||||||
class WebListManager;
|
class WebListManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace permission {
|
||||||
|
class PermissionNameMapper;
|
||||||
|
}
|
||||||
|
|
||||||
namespace server {
|
namespace server {
|
||||||
class InstanceHandler {
|
class InstanceHandler {
|
||||||
public:
|
public:
|
||||||
@ -62,6 +66,8 @@ namespace ts {
|
|||||||
std::shared_ptr<ts::Properties> getDefaultServerProperties() { return this->default_server_properties; }
|
std::shared_ptr<ts::Properties> getDefaultServerProperties() { return this->default_server_properties; }
|
||||||
std::shared_ptr<webio::LoopManager> getWebIoLoop() { return this->web_event_loop; }
|
std::shared_ptr<webio::LoopManager> getWebIoLoop() { return this->web_event_loop; }
|
||||||
std::shared_ptr<weblist::WebListManager> getWebList() { return this->web_list; }
|
std::shared_ptr<weblist::WebListManager> getWebList() { return this->web_list; }
|
||||||
|
|
||||||
|
std::shared_ptr<permission::PermissionNameMapper> getPermissionMapper() { return this->permission_mapper; }
|
||||||
private:
|
private:
|
||||||
std::mutex activeLock;
|
std::mutex activeLock;
|
||||||
std::condition_variable activeCon;
|
std::condition_variable activeCon;
|
||||||
@ -101,6 +107,7 @@ namespace ts {
|
|||||||
std::shared_ptr<stats::ConnectionStatistics> statistics = nullptr;
|
std::shared_ptr<stats::ConnectionStatistics> statistics = nullptr;
|
||||||
std::shared_ptr<threads::Scheduler> tick_manager = nullptr;
|
std::shared_ptr<threads::Scheduler> tick_manager = nullptr;
|
||||||
|
|
||||||
|
std::shared_ptr<permission::PermissionNameMapper> permission_mapper = nullptr;
|
||||||
std::shared_ptr<TeamSpeakLicense> teamspeak_license = nullptr;
|
std::shared_ptr<TeamSpeakLicense> teamspeak_license = nullptr;
|
||||||
|
|
||||||
threads::Mutex lock_tick;
|
threads::Mutex lock_tick;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "music/MusicClient.h"
|
#include "music/MusicClient.h"
|
||||||
#include "query/QueryClient.h"
|
#include "query/QueryClient.h"
|
||||||
#include "../weblist/WebListManager.h"
|
#include "../weblist/WebListManager.h"
|
||||||
|
#include "../manager/PermissionNameMapper.h"
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <StringVariable.h>
|
#include <StringVariable.h>
|
||||||
@ -42,6 +43,7 @@ extern ts::server::InstanceHandler *serverInstance;
|
|||||||
|
|
||||||
#define QUERY_PASSWORD_LENGTH 12
|
#define QUERY_PASSWORD_LENGTH 12
|
||||||
|
|
||||||
|
//TODO: Map permsid!
|
||||||
#define PARSE_PERMISSION(cmd) \
|
#define PARSE_PERMISSION(cmd) \
|
||||||
permission::PermissionType permType = permission::PermissionType::unknown; \
|
permission::PermissionType permType = permission::PermissionType::unknown; \
|
||||||
bool grant = false; \
|
bool grant = false; \
|
||||||
@ -830,10 +832,10 @@ CommandResult ConnectedClient::handleCommandChannelUnsubscribeAll(Command &cmd)
|
|||||||
CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) {
|
CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) {
|
||||||
CMD_CHK_AND_INC_FLOOD_POINTS(5);
|
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 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);
|
Command list_builder(command);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto group : permission::availableGroups)
|
for (auto group : permission::availableGroups)
|
||||||
@ -843,28 +845,31 @@ CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) {
|
|||||||
std::sort(avPerms.begin(), avPerms.end(), [](const std::shared_ptr<permission::PermissionTypeEntry> &a, const std::shared_ptr<permission::PermissionTypeEntry> &b) {
|
std::sort(avPerms.begin(), avPerms.end(), [](const std::shared_ptr<permission::PermissionTypeEntry> &a, const std::shared_ptr<permission::PermissionTypeEntry> &b) {
|
||||||
return a->type < b->type;
|
return a->type < b->type;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto mapper = serverInstance->getPermissionMapper();
|
||||||
for (const auto& permission : avPerms) {
|
for (const auto& permission : avPerms) {
|
||||||
if (!permission->clientSupported) continue;
|
if (!permission->clientSupported) continue;
|
||||||
|
|
||||||
auto &blk = list_builder[index++];
|
auto &blk = list_builder[index++];
|
||||||
blk["permname"] = permission->name;
|
blk["permname"] = mapper->permission_name(type, permission->type);
|
||||||
blk["permdesc"] = permission->description;
|
blk["permdesc"] = permission->description;
|
||||||
blk["permid"] = permission->type;
|
blk["permid"] = permission->type;
|
||||||
}
|
}
|
||||||
return list_builder;
|
return list_builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(this->getType() == CLIENT_TEASPEAK || this->getType() == CLIENT_TEAMSPEAK || this->getType() == CLIENT_QUERY) {
|
auto type = this->getType();
|
||||||
|
if(type == CLIENT_TEASPEAK || type == CLIENT_TEAMSPEAK || type == CLIENT_QUERY) {
|
||||||
Command response(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "");
|
Command response(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "");
|
||||||
{
|
{
|
||||||
lock_guard lock(permission_list_string_lock);
|
lock_guard lock(permission_list_string_lock);
|
||||||
if(permission_list_string.empty())
|
if(permission_list_string[type].empty())
|
||||||
permission_list_string = build_permission_list("").build();
|
permission_list_string[type] = build_permission_list("", type).build();
|
||||||
response[0][""] = permission_list_string;
|
response[0][""] = permission_list_string[type];
|
||||||
}
|
}
|
||||||
this->sendCommand(response);
|
this->sendCommand(response);
|
||||||
} else {
|
} 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;
|
return CommandResult::Success;
|
||||||
}
|
}
|
||||||
@ -2255,12 +2260,14 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
result["cid"] = channel->channelId();
|
result["cid"] = channel->channelId();
|
||||||
|
|
||||||
|
auto permission_mapper = serverInstance->getPermissionMapper();
|
||||||
|
auto type = this->getType();
|
||||||
auto permission_manager = channel->permissions();
|
auto permission_manager = channel->permissions();
|
||||||
for (const auto &permission_data : permission_manager->permissions()) {
|
for (const auto &permission_data : permission_manager->permissions()) {
|
||||||
auto& permission = std::get<1>(permission_data);
|
auto& permission = std::get<1>(permission_data);
|
||||||
if(permission.flags.value_set) {
|
if(permission.flags.value_set) {
|
||||||
if(sids) {
|
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 {
|
} else {
|
||||||
result[index]["permid"] = std::get<0>(permission_data);
|
result[index]["permid"] = std::get<0>(permission_data);
|
||||||
}
|
}
|
||||||
@ -2272,7 +2279,7 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) {
|
|||||||
}
|
}
|
||||||
if(permission.flags.grant_set) {
|
if(permission.flags.grant_set) {
|
||||||
if(sids) {
|
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 {
|
} else {
|
||||||
result[index]["permid"] = (uint16_t) (std::get<0>(permission_data) | PERM_ID_GRANT);
|
result[index]["permid"] = (uint16_t) (std::get<0>(permission_data) | PERM_ID_GRANT);
|
||||||
}
|
}
|
||||||
@ -4904,11 +4911,14 @@ CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd)
|
|||||||
res[index]["cldbid"] = cmd["cldbid"].as<ClientDbId>();
|
res[index]["cldbid"] = cmd["cldbid"].as<ClientDbId>();
|
||||||
|
|
||||||
auto sids = cmd.hasParm("permsid");
|
auto sids = cmd.hasParm("permsid");
|
||||||
|
auto permission_mapper = serverInstance->getPermissionMapper();
|
||||||
|
auto type = this->getType();
|
||||||
|
|
||||||
for (const auto &permission_data : permissions) {
|
for (const auto &permission_data : permissions) {
|
||||||
auto& permission = std::get<1>(permission_data);
|
auto& permission = std::get<1>(permission_data);
|
||||||
if(permission.flags.value_set) {
|
if(permission.flags.value_set) {
|
||||||
if (sids)
|
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
|
else
|
||||||
res[index]["permid"] = get<0>(permission_data);
|
res[index]["permid"] = get<0>(permission_data);
|
||||||
res[index]["permvalue"] = permission.values.value;
|
res[index]["permvalue"] = permission.values.value;
|
||||||
@ -4921,7 +4931,7 @@ CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd)
|
|||||||
|
|
||||||
if(permission.flags.grant_set) {
|
if(permission.flags.grant_set) {
|
||||||
if (sids)
|
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
|
else
|
||||||
res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT);
|
res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT);
|
||||||
res[index]["permvalue"] = permission.values.grant;
|
res[index]["permvalue"] = permission.values.grant;
|
||||||
@ -5349,12 +5359,14 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) {
|
|||||||
Command res("");
|
Command res("");
|
||||||
|
|
||||||
deque<permission::PermissionType> requrested;
|
deque<permission::PermissionType> requrested;
|
||||||
|
auto permission_mapper = serverInstance->getPermissionMapper();
|
||||||
|
auto type = this->getType();
|
||||||
for (int index = 0; index < cmd.bulkCount(); index++) {
|
for (int index = 0; index < cmd.bulkCount(); index++) {
|
||||||
permission::PermissionType permType = permission::unknown;
|
permission::PermissionType permType = permission::unknown;
|
||||||
if (cmd[index].has("permid"))
|
if (cmd[index].has("permid"))
|
||||||
permType = cmd[index]["permid"].as<permission::PermissionType>();
|
permType = cmd[index]["permid"].as<permission::PermissionType>();
|
||||||
else if (cmd[index].has("permsid"))
|
else if (cmd[index].has("permsid"))
|
||||||
permType = permission::resolvePermissionData(cmd[index]["permsid"].as<string>())->type;
|
permType = permission::resolvePermissionData(cmd[index]["permsid"].as<string>())->type; //TODO: Map the other way around!
|
||||||
if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) return {findError("parameter_invalid"), "could not resolve permission"};
|
if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) return {findError("parameter_invalid"), "could not resolve permission"};
|
||||||
|
|
||||||
requrested.push_back(permType);
|
requrested.push_back(permType);
|
||||||
@ -5362,7 +5374,7 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) {
|
|||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for(const auto& entry : this->permissionValues(permission::PERMTEST_ORDERED, requrested, this->currentChannel)) {
|
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]["permid"] = entry.first;
|
||||||
res[index++]["permvalue"] = entry.second;
|
res[index++]["permvalue"] = entry.second;
|
||||||
}
|
}
|
||||||
@ -5372,7 +5384,7 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CommandResult ConnectedClient::handleCommandPermIdGetByName(Command &cmd) {
|
CommandResult ConnectedClient::handleCommandPermIdGetByName(Command &cmd) {
|
||||||
auto found = permission::resolvePermissionData(cmd["permsid"].as<string>());
|
auto found = permission::resolvePermissionData(cmd["permsid"].as<string>()); //TODO: Map the other way around
|
||||||
Command res("");
|
Command res("");
|
||||||
res["permid"] = found->type;
|
res["permid"] = found->type;
|
||||||
this->sendCommand(res);
|
this->sendCommand(res);
|
||||||
@ -5409,7 +5421,7 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) {
|
|||||||
if(permission->type == permission::PermissionType::unknown)
|
if(permission->type == permission::PermissionType::unknown)
|
||||||
return {findError("parameter_invalid"), "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"};
|
return {findError("parameter_invalid"), "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"};
|
||||||
} else if (cmd[index].has("permsid")) {
|
} else if (cmd[index].has("permsid")) {
|
||||||
permission = permission::resolvePermissionData(cmd[index]["permsid"].as<string>());
|
permission = permission::resolvePermissionData(cmd[index]["permsid"].as<string>()); //TODO: Map the other way around
|
||||||
granted = permission->grant_name == cmd[index]["permsid"].as<string>();
|
granted = permission->grant_name == cmd[index]["permsid"].as<string>();
|
||||||
|
|
||||||
if(permission->type == permission::PermissionType::unknown)
|
if(permission->type == permission::PermissionType::unknown)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "../server/VoiceServer.h"
|
#include "../server/VoiceServer.h"
|
||||||
#include "../InstanceHandler.h"
|
#include "../InstanceHandler.h"
|
||||||
#include "../server/QueryServer.h"
|
#include "../server/QueryServer.h"
|
||||||
|
#include "../manager/PermissionNameMapper.h"
|
||||||
#include "music/MusicClient.h"
|
#include "music/MusicClient.h"
|
||||||
#include <log/LogUtils.h>
|
#include <log/LogUtils.h>
|
||||||
#include <misc/sassert.h>
|
#include <misc/sassert.h>
|
||||||
@ -72,16 +73,17 @@ bool ConnectedClient::notifyGroupPermList(const std::shared_ptr<Group>& group, b
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
auto permissions = group->permissions()->permissions();
|
auto permissions = group->permissions()->permissions();
|
||||||
|
auto permission_mapper = serverInstance->getPermissionMapper();
|
||||||
|
auto client_type = this->getType();
|
||||||
for (const auto &permission_data : permissions) {
|
for (const auto &permission_data : permissions) {
|
||||||
auto& permission = get<1>(permission_data);
|
auto& permission = get<1>(permission_data);
|
||||||
if(!permission.flags.value_set)
|
if(!permission.flags.value_set)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto type = permission::resolvePermissionData(get<0>(permission_data));
|
|
||||||
if(as_sid) {
|
if(as_sid) {
|
||||||
cmd[index]["permsid"] = type->name;
|
cmd[index]["permsid"] = permission_mapper->permission_name(client_type, get<0>(permission_data));
|
||||||
} else {
|
} 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]["permvalue"] = permission.values.value;
|
||||||
cmd[index]["permnegated"] = permission.flags.negate;
|
cmd[index]["permnegated"] = permission.flags.negate;
|
||||||
@ -93,11 +95,10 @@ bool ConnectedClient::notifyGroupPermList(const std::shared_ptr<Group>& group, b
|
|||||||
if(!permission.flags.grant_set)
|
if(!permission.flags.grant_set)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto type = permission::resolvePermissionData(get<0>(permission_data));
|
|
||||||
if(as_sid) {
|
if(as_sid) {
|
||||||
cmd[index]["permsid"] = type->grant_name;
|
cmd[index]["permsid"] = permission_mapper->permission_name_grant(client_type, get<0>(permission_data));
|
||||||
} else {
|
} 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]["permvalue"] = permission.values.grant;
|
||||||
cmd[index]["permnegated"] = permission.flags.negate;
|
cmd[index]["permnegated"] = permission.flags.negate;
|
||||||
@ -122,11 +123,13 @@ bool ConnectedClient::notifyClientPermList(ClientDbId cldbid, const std::shared_
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
res[index]["cldbid"] = cldbid;
|
res[index]["cldbid"] = cldbid;
|
||||||
|
|
||||||
|
auto permission_mapper = serverInstance->getPermissionMapper();
|
||||||
|
auto client_type = this->getType();
|
||||||
for (const auto &permission_data : permissions) {
|
for (const auto &permission_data : permissions) {
|
||||||
auto& permission = std::get<1>(permission_data);
|
auto& permission = std::get<1>(permission_data);
|
||||||
if(permission.flags.value_set) {
|
if(permission.flags.value_set) {
|
||||||
if (perm_sids)
|
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
|
else
|
||||||
res[index]["permid"] = get<0>(permission_data);
|
res[index]["permid"] = get<0>(permission_data);
|
||||||
res[index]["permvalue"] = permission.values.value;
|
res[index]["permvalue"] = permission.values.value;
|
||||||
@ -139,7 +142,7 @@ bool ConnectedClient::notifyClientPermList(ClientDbId cldbid, const std::shared_
|
|||||||
|
|
||||||
if(permission.flags.grant_set) {
|
if(permission.flags.grant_set) {
|
||||||
if (perm_sids)
|
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
|
else
|
||||||
res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT);
|
res[index]["permid"] = (get<0>(permission_data) | PERM_ID_GRANT);
|
||||||
res[index]["permvalue"] = permission.values.grant;
|
res[index]["permvalue"] = permission.values.grant;
|
||||||
|
122
server/src/manager/PermissionNameManager.cpp
Normal file
122
server/src/manager/PermissionNameManager.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include <experimental/filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <log/LogUtils.h>
|
||||||
|
#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<map<string, string>, 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;
|
||||||
|
}
|
60
server/src/manager/PermissionNameMapper.h
Normal file
60
server/src/manager/PermissionNameMapper.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#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<PermissionMap, permission::PermissionType::permission_id_max>,
|
||||||
|
Type::value::MAX
|
||||||
|
> mapping;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
2
shared
2
shared
@ -1 +1 @@
|
|||||||
Subproject commit c8cae593a016b842031b5f73e103554a4f87cb66
|
Subproject commit a086dcc214fe4ea7a983fecebb93b8e2fe3258ff
|
Loading…
Reference in New Issue
Block a user