TeaSpeakLibrary/src/PermissionManager.h

725 lines
29 KiB
C++

#pragma once
#include <deque>
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <iostream>
#include "Definitions.h"
#include "Variable.h"
#define permNotGranted (-2)
#define PERM_ID_GRANT ((ts::permission::PermissionType) (1 << 15))
namespace ts {
class BasicChannel;
namespace permission {
typedef int32_t PermissionValue;
enum PermissionSqlType {
SQL_PERM_GROUP,
SQL_PERM_CHANNEL,
SQL_PERM_USER,
SQL_PERM_PLAYLIST
};
enum PermissionType : uint16_t {
undefined = (uint16_t) -1,
unknown = (uint16_t) 0,
type_begin = 1,
/* global */
/* global::information */
b_serverinstance_help_view = type_begin,
b_serverinstance_version_view,
b_serverinstance_info_view,
b_serverinstance_virtualserver_list,
b_serverinstance_binding_list,
b_serverinstance_permission_list,
b_serverinstance_permission_find,
//b_serverinstance_allow_teaspeak_plugin,
/* global::vs_management */
b_virtualserver_create,
b_virtualserver_delete,
b_virtualserver_start_any,
b_virtualserver_stop_any,
b_virtualserver_change_machine_id,
b_virtualserver_change_template,
/* global::administration */
b_serverquery_login,
b_serverinstance_textmessage_send,
b_serverinstance_log_view,
b_serverinstance_log_add,
b_serverinstance_stop,
/* global::settings */
b_serverinstance_modify_settings,
b_serverinstance_modify_querygroup,
b_serverinstance_modify_templates,
/* virtual_server */
/* virtual_server::information */
b_virtualserver_select,
b_virtualserver_select_godmode,
b_virtualserver_info_view,
b_virtualserver_connectioninfo_view,
b_virtualserver_channel_list,
b_virtualserver_channel_search,
b_virtualserver_client_list,
b_virtualserver_client_search,
b_virtualserver_client_dblist,
b_virtualserver_client_dbsearch,
b_virtualserver_client_dbinfo,
b_virtualserver_permission_find,
b_virtualserver_custom_search,
/* virtual_server::administration */
b_virtualserver_start,
b_virtualserver_stop,
b_virtualserver_token_list,
b_virtualserver_token_add,
b_virtualserver_token_use,
b_virtualserver_token_delete,
b_virtualserver_log_view,
b_virtualserver_log_add,
b_virtualserver_join_ignore_password,
b_virtualserver_notify_register,
b_virtualserver_notify_unregister,
b_virtualserver_snapshot_create,
b_virtualserver_snapshot_deploy,
b_virtualserver_permission_reset,
/* virtual_server::settings */
b_virtualserver_modify_name,
b_virtualserver_modify_welcomemessage,
b_virtualserver_modify_maxclients,
b_virtualserver_modify_reserved_slots,
b_virtualserver_modify_password,
b_virtualserver_modify_default_servergroup,
b_virtualserver_modify_default_musicgroup,
b_virtualserver_modify_default_channelgroup,
b_virtualserver_modify_default_channeladmingroup,
b_virtualserver_modify_channel_forced_silence,
b_virtualserver_modify_complain,
b_virtualserver_modify_antiflood,
b_virtualserver_modify_ft_settings,
b_virtualserver_modify_ft_quotas,
b_virtualserver_modify_hostmessage,
b_virtualserver_modify_hostbanner,
b_virtualserver_modify_hostbutton,
b_virtualserver_modify_port,
#ifndef LAGENCY
b_virtualserver_modify_host,
b_virtualserver_modify_default_messages,
#endif
b_virtualserver_modify_autostart,
b_virtualserver_modify_needed_identity_security_level,
b_virtualserver_modify_priority_speaker_dimm_modificator,
b_virtualserver_modify_log_settings,
b_virtualserver_modify_min_client_version,
b_virtualserver_modify_icon_id,
b_virtualserver_modify_weblist,
b_virtualserver_modify_codec_encryption_mode,
b_virtualserver_modify_temporary_passwords,
b_virtualserver_modify_temporary_passwords_own,
b_virtualserver_modify_channel_temp_delete_delay_default,
b_virtualserver_modify_music_bot_limit,
/* channel */
i_channel_min_depth,
i_channel_max_depth,
b_channel_group_inheritance_end,
i_channel_permission_modify_power,
i_channel_needed_permission_modify_power,
/* channel::info */
b_channel_info_view,
b_virtualserver_channel_permission_list,
/* channel::create */
b_channel_create_child,
b_channel_create_permanent,
b_channel_create_semi_permanent,
b_channel_create_temporary,
b_channel_create_private,
b_channel_create_with_topic,
b_channel_create_with_description,
b_channel_create_with_password,
b_channel_create_modify_with_codec_speex8,
b_channel_create_modify_with_codec_speex16,
b_channel_create_modify_with_codec_speex32,
b_channel_create_modify_with_codec_celtmono48,
b_channel_create_modify_with_codec_opusvoice,
b_channel_create_modify_with_codec_opusmusic,
i_channel_create_modify_with_codec_maxquality,
i_channel_create_modify_with_codec_latency_factor_min,
b_channel_create_with_maxclients,
b_channel_create_with_maxfamilyclients,
b_channel_create_with_sortorder,
b_channel_create_with_default,
b_channel_create_with_needed_talk_power,
b_channel_create_modify_with_force_password,
i_channel_create_modify_with_temp_delete_delay,
/* channel::modify */
b_channel_modify_parent,
b_channel_modify_make_default,
b_channel_modify_make_permanent,
b_channel_modify_make_semi_permanent,
b_channel_modify_make_temporary,
b_channel_modify_name,
b_channel_modify_topic,
b_channel_modify_description,
b_channel_modify_password,
b_channel_modify_codec,
b_channel_modify_codec_quality,
b_channel_modify_codec_latency_factor,
b_channel_modify_maxclients,
b_channel_modify_maxfamilyclients,
b_channel_modify_sortorder,
b_channel_modify_needed_talk_power,
i_channel_modify_power,
i_channel_needed_modify_power,
b_channel_modify_make_codec_encrypted,
b_channel_modify_temp_delete_delay,
/* channel::delete */
b_channel_delete_permanent,
b_channel_delete_semi_permanent,
b_channel_delete_temporary,
b_channel_delete_flag_force,
i_channel_delete_power,
i_channel_needed_delete_power,
/* channel::access */
b_channel_join_permanent,
b_channel_join_semi_permanent,
b_channel_join_temporary,
b_channel_join_ignore_password,
b_channel_join_ignore_maxclients,
i_channel_join_power,
i_channel_needed_join_power,
b_channel_ignore_join_power,
i_channel_view_power,
i_channel_needed_view_power,
b_channel_ignore_view_power,
i_channel_subscribe_power,
i_channel_needed_subscribe_power,
b_channel_ignore_subscribe_power,
i_channel_description_view_power,
i_channel_needed_description_view_power,
b_channel_ignore_description_view_power,
/* group */
i_icon_id,
i_max_icon_filesize,
i_max_playlist_size,
i_max_playlists,
b_icon_manage,
b_group_is_permanent,
i_group_auto_update_type,
i_group_auto_update_max_value,
i_group_sort_id,
i_group_show_name_in_tree,
/* group::info */
b_virtualserver_servergroup_list, //Unused
b_virtualserver_servergroup_permission_list,
b_virtualserver_servergroup_client_list,
b_virtualserver_channelgroup_list, //Unused
b_virtualserver_channelgroup_permission_list,
b_virtualserver_channelgroup_client_list,
/* group::create */
b_virtualserver_servergroup_create,
b_virtualserver_channelgroup_create,
/* group::modify */
#ifdef LAGENCY
i_group_modify_power,
i_group_needed_modify_power,
i_group_member_add_power,
i_group_needed_member_add_power,
i_group_member_remove_power,
i_group_needed_member_remove_power,
#else
//permission patch start
i_server_group_modify_power,
i_server_group_needed_modify_power,
i_server_group_member_add_power,
i_server_group_self_add_power,
i_server_group_needed_member_add_power,
i_server_group_member_remove_power,
i_server_group_self_remove_power,
i_server_group_needed_member_remove_power,
i_channel_group_modify_power,
i_channel_group_needed_modify_power,
i_channel_group_member_add_power,
i_channel_group_self_add_power,
i_channel_group_needed_member_add_power,
i_channel_group_member_remove_power,
i_channel_group_self_remove_power,
i_channel_group_needed_member_remove_power,
i_displayed_group_member_add_power,
i_displayed_group_needed_member_add_power,
i_displayed_group_member_remove_power,
i_displayed_group_needed_member_remove_power,
i_displayed_group_modify_power,
i_displayed_group_needed_modify_power,
//permission patch end
#endif
i_permission_modify_power,
b_permission_modify_power_ignore,
/* group::delete */
b_virtualserver_servergroup_delete,
b_virtualserver_channelgroup_delete,
/* client */
i_client_permission_modify_power,
i_client_needed_permission_modify_power,
i_client_max_clones_uid,
i_client_max_clones_ip,
i_client_max_clones_hwid,
i_client_max_idletime,
i_client_max_avatar_filesize,
i_client_max_channel_subscriptions,
i_client_max_channels,
i_client_max_temporary_channels,
i_client_max_semi_channels,
i_client_max_permanent_channels,
b_client_use_priority_speaker,
b_client_is_priority_speaker,
b_client_skip_channelgroup_permissions,
b_client_force_push_to_talk,
b_client_ignore_bans,
b_client_ignore_vpn,
b_client_ignore_antiflood,
b_client_enforce_valid_hwid,
b_client_allow_invalid_packet,
b_client_allow_invalid_badges,
b_client_issue_client_query_command,
b_client_use_reserved_slot,
b_client_use_channel_commander,
b_client_request_talker,
b_client_avatar_delete_other,
b_client_is_sticky,
b_client_ignore_sticky,
b_client_music_create_permanent,
b_client_music_create_semi_permanent,
b_client_music_create_temporary,
b_client_music_modify_permanent,
b_client_music_modify_semi_permanent,
b_client_music_modify_temporary,
i_client_music_create_modify_max_volume,
i_client_music_limit,
i_client_music_needed_delete_power,
i_client_music_delete_power,
i_client_music_play_power,
i_client_music_needed_play_power,
i_client_music_modify_power,
i_client_music_needed_modify_power,
i_client_music_rename_power,
i_client_music_needed_rename_power,
b_virtualserver_playlist_permission_list,
b_playlist_create,
i_playlist_view_power,
i_playlist_needed_view_power,
i_playlist_modify_power,
i_playlist_needed_modify_power,
i_playlist_permission_modify_power,
i_playlist_needed_permission_modify_power,
i_playlist_delete_power,
i_playlist_needed_delete_power,
i_playlist_song_add_power,
i_playlist_song_needed_add_power,
i_playlist_song_remove_power,
i_playlist_song_needed_remove_power,
i_playlist_song_move_power,
i_playlist_song_needed_move_power,
/* client::info */
b_client_info_view,
b_client_permissionoverview_view,
b_client_permissionoverview_own,
b_client_remoteaddress_view,
i_client_serverquery_view_power,
i_client_needed_serverquery_view_power,
b_client_custom_info_view,
b_client_music_channel_list,
b_client_music_server_list,
i_client_music_info,
i_client_music_needed_info,
b_virtualserver_channelclient_permission_list,
b_virtualserver_client_permission_list,
/* client::admin */
i_client_kick_from_server_power,
i_client_needed_kick_from_server_power,
i_client_kick_from_channel_power,
i_client_needed_kick_from_channel_power,
i_client_ban_power,
i_client_needed_ban_power,
i_client_move_power,
i_client_needed_move_power,
i_client_complain_power,
i_client_needed_complain_power,
b_client_complain_list,
b_client_complain_delete_own,
b_client_complain_delete,
b_client_ban_list,
b_client_ban_list_global,
b_client_ban_trigger_list,
b_client_ban_create,
b_client_ban_create_global,
b_client_ban_name,
b_client_ban_ip,
b_client_ban_hwid,
b_client_ban_edit,
b_client_ban_edit_global,
b_client_ban_delete_own,
b_client_ban_delete,
b_client_ban_delete_own_global,
b_client_ban_delete_global,
i_client_ban_max_bantime,
/* client::basics */
i_client_private_textmessage_power,
i_client_needed_private_textmessage_power,
b_client_even_textmessage_send,
b_client_server_textmessage_send,
b_client_channel_textmessage_send,
b_client_offline_textmessage_send,
i_client_talk_power,
i_client_needed_talk_power,
i_client_poke_power,
i_client_needed_poke_power,
b_client_set_flag_talker,
i_client_whisper_power,
i_client_needed_whisper_power,
/* client::modify */
b_client_modify_description,
b_client_modify_own_description,
b_client_use_bbcode_any,
b_client_use_bbcode_url,
b_client_use_bbcode_image,
b_client_modify_dbproperties,
b_client_delete_dbproperties,
b_client_create_modify_serverquery_login,
b_client_query_create,
b_client_query_list,
b_client_query_list_own,
b_client_query_rename,
b_client_query_rename_own,
b_client_query_change_password,
b_client_query_change_own_password,
b_client_query_change_password_global,
b_client_query_delete,
b_client_query_delete_own,
/* file_transfer */
b_ft_ignore_password,
b_ft_transfer_list,
i_ft_file_upload_power,
i_ft_needed_file_upload_power,
i_ft_file_download_power,
i_ft_needed_file_download_power,
i_ft_file_delete_power,
i_ft_needed_file_delete_power,
i_ft_file_rename_power,
i_ft_needed_file_rename_power,
i_ft_file_browse_power,
i_ft_needed_file_browse_power,
i_ft_directory_create_power,
i_ft_needed_directory_create_power,
i_ft_quota_mb_download_per_client,
i_ft_quota_mb_upload_per_client
};
inline PermissionType& operator&=(PermissionType& a, int b) { return a = (PermissionType) ((int) a & b); }
enum PermissionGroup : uint16_t {
group_begin,
global = group_begin,
global_info = b_serverinstance_permission_find,
global_vsmanage = b_virtualserver_change_template,
global_admin = b_serverinstance_stop,
global_settings = b_serverinstance_modify_templates,
vs = global_settings, /* we dont have any permissions in here */
vs_info = b_virtualserver_custom_search,
vs_admin = b_virtualserver_permission_reset,
#ifdef LEGENCY
vs_settings = b_virtualserver_modify_channel_temp_delete_delay_default,
#else
vs_settings = b_virtualserver_modify_music_bot_limit,
#endif
channel = i_channel_needed_permission_modify_power,
channel_info = b_virtualserver_channel_permission_list,
channel_create = i_channel_create_modify_with_temp_delete_delay,
channel_modify = b_channel_modify_temp_delete_delay,
channel_delete = i_channel_needed_delete_power,
channel_access = b_channel_ignore_description_view_power,
group = i_group_show_name_in_tree,
group_info = b_virtualserver_channelgroup_client_list,
group_create = b_virtualserver_channelgroup_create,
group_modify = b_permission_modify_power_ignore,
group_delete = b_virtualserver_channelgroup_delete,
#ifdef LAGENCY
client = b_client_ignore_sticky,
#else
client = i_playlist_song_needed_move_power,
#endif
#ifdef LAGENCY
client_info = b_client_custom_info_view,
#else
client_info = b_virtualserver_client_permission_list,
#endif
client_admin = i_client_ban_max_bantime,
client_basic = i_client_needed_whisper_power,
client_modify = b_client_query_delete_own,
ft = i_ft_quota_mb_upload_per_client,
group_end
};
enum PermissionTestType {
PERMTEST_HIGHEST,
PERMTEST_ORDERED,
};
struct PermissionTypeEntry {
static std::shared_ptr<PermissionTypeEntry> unknown;
PermissionTypeEntry& operator=(const PermissionTypeEntry& other) = delete;
/*
PermissionTypeEntry& operator=(const PermissionTypeEntry& other) {
this->type = other.type;
this->group = other.group;
this->name = other.name;
this->description = other.description;
this->clientSupported = other.clientSupported;
this->grant_name = std::string() + (name[0] == 'i' ? "i" : "i") + "_needed_modify_power_" + name.substr(2);
return *this;
}
bool operator==(const PermissionTypeEntry& other) {
return other.type == this->type;
}
*/
PermissionType type;
PermissionGroup group;
std::string name;
std::string grant_name;
inline std::string grantName(bool useBool = false) const { return this->grant_name; }
std::string description;
bool clientSupported = true;
// PermissionTypeEntry(PermissionTypeEntry&& ref) : type(ref.type), group(ref.group), name(ref.name), description(ref.description), clientSupported(ref.clientSupported) {}
//PermissionTypeEntry(const PermissionTypeEntry& ref) : type(ref.type), group(ref.group), name(ref.name), description(ref.description), clientSupported(ref.clientSupported) {}
PermissionTypeEntry(PermissionTypeEntry&& ref) = delete;
PermissionTypeEntry(const PermissionTypeEntry& ref) = delete;
//PermissionTypeEntry(const PermissionTypeEntry& ref) : type(ref.type), group(ref.group), name(ref.name), description(ref.description), clientSupported(ref.clientSupported) {}
PermissionTypeEntry(PermissionType type, PermissionGroup group, std::string name, std::string description, bool clientSupported = true) : type(type),
group(group),
name(std::move(name)),
description(std::move(description)),
clientSupported(clientSupported) {
this->grant_name = std::string() + (this->name[0] == 'i' ? "i" : "i") + "_needed_modify_power_" + this->name.substr(2);
}
};
namespace teamspeak {
enum GroupType {
GENERAL,
SERVER,
CHANNEL,
CLIENT
};
typedef std::map<GroupType, std::multimap<std::string, std::deque<std::string>>> MapType;
extern MapType unmapping;
extern MapType mapping;
extern std::deque<std::string> map_key(std::string key, GroupType type); //TeamSpeak -> TeaSpeak
extern std::deque<std::string> unmap_key(std::string key, GroupType type); //TeaSpeak -> TeamSpeak
}
namespace update {
enum GroupUpdateType {
NONE = 0,
CHANNEL_GUEST = 10,
CHANNEL_VOICE = 25,
CHANNEL_OPERATOR = 35,
CHANNEL_ADMIN = 40,
SERVER_GUEST = 15,
SERVER_NORMAL = 30,
SERVER_ADMIN = 45,
QUERY_GUEST = 20,
QUERY_ADMIN = 50
};
struct UpdatePermission {
UpdatePermission(std::string name, permission::PermissionValue value, permission::PermissionValue granted, bool negated, bool skipped) : name(std::move(name)), value(value), granted(granted), negated(negated), skipped(skipped) {}
UpdatePermission() = default;
std::string name;
permission::PermissionValue value = permNotGranted;
permission::PermissionValue granted = permNotGranted;
bool negated = false;
bool skipped = false;
};
struct UpdateEntry {
GroupUpdateType type;
UpdatePermission permission;
};
extern std::deque<UpdateEntry> migrate; //TeamSpeak -> TeaSpeak
}
extern std::deque<std::shared_ptr<PermissionTypeEntry>> availablePermissions;
extern std::deque<PermissionType> neededPermissions;
extern std::deque<PermissionGroup> availableGroups;
std::shared_ptr<PermissionTypeEntry> resolvePermissionData(PermissionType);
std::shared_ptr<PermissionTypeEntry> resolvePermissionData(const std::string&);
#define PERM_FLAG_PRIVATE 0b1
#define PERM_FLAG_PUBLIC 0b10
class PermissionManager;
struct Permission {
public:
Permission(const std::shared_ptr<PermissionTypeEntry>& type, PermissionValue value, PermissionValue grant, uint16_t flagMask, std::shared_ptr<BasicChannel> ch) : type(type), channel(std::move(ch)) {
this->type = type;
this->value = value;
this->granted = grant;
this->flagMask = flagMask;
}
Permission(Permission &) = delete;
Permission(const Permission &) = delete;
Permission() = delete;
~Permission(){ }
std::shared_ptr<BasicChannel> channel = nullptr;
ChannelId channelId();
bool hasValue(){ return value != permNotGranted; }
bool hasGrant(){ return granted != permNotGranted; }
std::shared_ptr<PermissionTypeEntry> type;
PermissionValue value;
PermissionValue granted;
uint16_t flagMask;
bool flag_negate = false;
bool flag_skip = false;
bool dbReference = false;
};
class PermissionManager {
public:
PermissionManager();
~PermissionManager();
std::shared_ptr<Permission> registerPermission(PermissionType, PermissionValue, const std::shared_ptr<BasicChannel>& channel, uint16_t = PERM_FLAG_PUBLIC);
std::shared_ptr<Permission> registerPermission(const std::shared_ptr<PermissionTypeEntry>&, PermissionValue, const std::shared_ptr<BasicChannel>& channel, uint16_t = PERM_FLAG_PUBLIC);
//void registerAllPermissions(uint16_t flagMask);
bool setPermissionGranted(PermissionType, PermissionValue, const std::shared_ptr<BasicChannel>& channel);
bool setPermission(PermissionType, PermissionValue, const std::shared_ptr<BasicChannel>& channel);
bool setPermission(PermissionType, PermissionValue, const std::shared_ptr<BasicChannel>& channel, bool negated, bool skiped);
void deletePermission(PermissionType, const std::shared_ptr<BasicChannel>& channel);
bool hasPermission(PermissionType, const std::shared_ptr<BasicChannel>& channel, bool testGlobal);
/**
* @param channel Should be null for general testing
* @return <channel>, <global>
*/
std::deque<std::shared_ptr<Permission>> getPermission(PermissionType, const std::shared_ptr<BasicChannel>& channel, bool testGlobal = true);
PermissionValue getPermissionGrand(permission::PermissionTestType test, PermissionType type, const std::shared_ptr<BasicChannel>& channel, PermissionValue def = permNotGranted){
PermissionValue result = def;
auto perms = this->getPermission(type, channel);
if(test == PermissionTestType::PERMTEST_HIGHEST) {
PermissionValue higest = permNotGranted;
for(const auto &e : perms)
if((e->granted > higest || e->granted == -1) && higest != -1) higest = e->granted;
if(higest != permNotGranted)
result = higest;
} else if(test == PermissionTestType::PERMTEST_ORDERED)
while(!perms.empty() && result == permNotGranted) {
result = perms.front()->granted;
perms.pop_front();
};
return result;
}
inline PermissionValue getPermissionValue(PermissionType type, const std::shared_ptr<BasicChannel>& channel = nullptr, PermissionValue default_value = permNotGranted) {
return this->getPermissionValue(permission::PERMTEST_ORDERED, type, channel, default_value);
}
PermissionValue getPermissionValue(permission::PermissionTestType test, PermissionType type, const std::shared_ptr<BasicChannel>& channel = nullptr, PermissionValue def = permNotGranted) {
PermissionValue result = permNotGranted;
auto perms = this->getPermission(type, channel);
if(test == permission::PERMTEST_HIGHEST) {
PermissionValue higest = permNotGranted;
for(const auto &e : perms)
if((e->value > higest || e->value == -1) && higest != -1) higest = e->value;
if(higest != permNotGranted)
result = higest;
} else if(test == PermissionTestType::PERMTEST_ORDERED)
while(!perms.empty() && result == permNotGranted) {
result = perms.front()->value;
perms.pop_front();
};
return result == permNotGranted ? def : result;
}
std::vector<std::shared_ptr<Permission>> listPermissions(uint16_t = ~0);
std::vector<std::shared_ptr<Permission>> allPermissions();
std::deque<std::shared_ptr<Permission>> all_channel_specific_permissions();
std::deque<std::shared_ptr<Permission>> all_channel_unspecific_permissions();
void fireUpdate(PermissionType);
void registerUpdateHandler(const std::function<void(std::shared_ptr<Permission>)> &fn){ updateHandler.push_back(fn); }
void clearPermissions(){
permissions.clear();
}
private:
std::deque<std::shared_ptr<Permission>> permissions;
std::deque<std::function<void(std::shared_ptr<Permission>)>> updateHandler;
};
}
}
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionType, VARTYPE_INT, std::to_string((int16_t) in), static_cast<ts::permission::PermissionType>(in.as<int16_t>()));
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionGroup, VARTYPE_INT, std::to_string((uint16_t) in), static_cast<ts::permission::PermissionGroup>(in.as<uint16_t>()));
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionSqlType, VARTYPE_INT, std::to_string((int8_t) in), static_cast<ts::permission::PermissionSqlType>(in.as<int8_t>()));