2020-01-26 08:21:34 -05:00
//
// Created by wolverindev on 26.01.20.
//
# include <memory>
# include <bitset>
# include <algorithm>
# include <openssl/sha.h>
# include "../../build.h"
# include "../ConnectedClient.h"
# include "../InternalClient.h"
# include "../../server/VoiceServer.h"
# include "../voice/VoiceClient.h"
# include "../../InstanceHandler.h"
# include "../../server/QueryServer.h"
# include "../music/MusicClient.h"
# include "../query/QueryClient.h"
# include "../../weblist/WebListManager.h"
# include "../../manager/ConversationManager.h"
# include "../../manager/PermissionNameMapper.h"
2020-06-28 08:01:14 -04:00
# include "../../manager/ActionLogger.h"
2020-01-26 08:21:34 -05:00
# include "helpers.h"
2020-05-07 15:28:15 -04:00
# include "./bulk_parsers.h"
2020-01-26 08:21:34 -05:00
# include <log/LogUtils.h>
# include <misc/base64.h>
# include <misc/digest.h>
# include <misc/rnd.h>
# include <misc/scope_guard.h>
# include <bbcode/bbcodes.h>
using namespace std : : chrono ;
using namespace std ;
using namespace ts ;
using namespace ts : : server ;
using namespace ts : : token ;
# define QUERY_PASSWORD_LENGTH 12
command_result ConnectedClient : : handleCommandServerGetVariables ( Command & cmd ) {
CMD_REQ_SERVER ;
this - > notifyServerUpdated ( _this . lock ( ) ) ;
return command_result { error : : ok } ;
}
# define SERVEREDIT_CHK_PROP_CACHED(name, perm, type)\
else if ( key = = name ) { \
ACTION_REQUIRES_GLOBAL_PERMISSION ( perm , 1 ) ; \
if ( toApplay . count ( key ) = = 0 ) toApplay [ key ] = cmd [ key ] . as < std : : string > ( ) ; \
if ( ! cmd [ 0 ] [ key ] . castable < type > ( ) ) return command_result { error : : parameter_invalid } ;
# define SERVEREDIT_CHK_PROP2(name, perm, type_a, type_b)\
else if ( key = = name ) { \
ACTION_REQUIRES_GLOBAL_PERMISSION ( perm , 1 ) ; \
if ( toApplay . count ( key ) = = 0 ) toApplay [ key ] = cmd [ key ] . as < std : : string > ( ) ; \
if ( ! cmd [ 0 ] [ key ] . castable < type_a > ( ) & & ! ! cmd [ 0 ] [ key ] . castable < type_b > ( ) ) return command_result { error : : parameter_invalid } ;
command_result ConnectedClient : : handleCommandServerEdit ( Command & cmd ) {
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
if ( cmd [ 0 ] . has ( " sid " ) & & this - > getServerId ( ) ! = cmd [ " sid " ] . as < ServerId > ( ) )
return command_result { error : : server_invalid_id } ;
auto target_server = this - > server ;
if ( cmd [ 0 ] . has ( " sid " ) ) {
target_server = serverInstance - > getVoiceServerManager ( ) - > findServerById ( cmd [ " sid " ] ) ;
if ( ! target_server & & cmd [ " sid " ] . as < ServerId > ( ) ! = 0 ) return command_result { error : : server_invalid_id } ;
}
2020-06-28 08:01:14 -04:00
ServerId serverId = target_server ? target_server - > serverId : 0 ;
2020-01-26 08:21:34 -05:00
auto cache = make_shared < CalculateCache > ( ) ;
map < string , string > toApplay ;
for ( auto & key : cmd [ 0 ] . keys ( ) ) {
if ( key = = " sid " ) continue ;
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_name " , permission : : b_virtualserver_modify_name , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_name_phonetic " , permission : : b_virtualserver_modify_name , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_maxclients " , permission : : b_virtualserver_modify_maxclients , size_t )
if ( cmd [ " virtualserver_maxclients " ] . as < size_t > ( ) > 1024 )
return command_result { error : : accounting_slot_limit_reached , " Do you really need more that 1024 slots? " } ;
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_reserved_slots " , permission : : b_virtualserver_modify_reserved_slots , size_t ) }
2020-01-26 10:33:48 -05:00
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_max_channels " , permission : : b_virtualserver_modify_maxchannels , size_t )
if ( cmd [ " virtualserver_max_channels " ] . as < size_t > ( ) > 8192 )
return command_result { error : : channel_protocol_limit_reached } ;
}
2020-01-26 08:21:34 -05:00
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_icon_id " , permission : : b_virtualserver_modify_icon_id , int64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_channel_temp_delete_delay_default " , permission : : b_virtualserver_modify_channel_temp_delete_delay_default , ChannelId ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_codec_encryption_mode " , permission : : b_virtualserver_modify_codec_encryption_mode , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_server_group " , permission : : b_virtualserver_modify_default_servergroup , GroupId )
if ( target_server ) {
auto group = target_server - > groups - > findGroup ( cmd [ " virtualserver_default_server_group " ] . as < GroupId > ( ) ) ;
if ( ! group | | group - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : parameter_invalid } ;
}
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_channel_group " , permission : : b_virtualserver_modify_default_channelgroup , GroupId )
if ( target_server ) {
auto group = target_server - > groups - > findGroup ( cmd [ " virtualserver_default_channel_group " ] . as < GroupId > ( ) ) ;
if ( ! group | | group - > target ( ) ! = GROUPTARGET_CHANNEL ) return command_result { error : : parameter_invalid } ;
}
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_channel_admin_group " , permission : : b_virtualserver_modify_default_channeladmingroup , GroupId )
if ( target_server ) {
auto group = target_server - > groups - > findGroup ( cmd [ " virtualserver_default_channel_admin_group " ] . as < GroupId > ( ) ) ;
if ( ! group | | group - > target ( ) ! = GROUPTARGET_CHANNEL ) return command_result { error : : parameter_invalid } ;
}
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_music_group " , permission : : b_virtualserver_modify_default_musicgroup , GroupId )
if ( target_server ) {
auto group = target_server - > groups - > findGroup ( cmd [ " virtualserver_default_music_group " ] . as < GroupId > ( ) ) ;
if ( ! group | | group - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : parameter_invalid } ;
}
}
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_priority_speaker_dimm_modificator " , permission : : b_virtualserver_modify_priority_speaker_dimm_modificator , float ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_port " , permission : : b_virtualserver_modify_port , uint16_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_host " , permission : : b_virtualserver_modify_host , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_web_host " , permission : : b_virtualserver_modify_port , uint16_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_web_port " , permission : : b_virtualserver_modify_host , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbanner_url " , permission : : b_virtualserver_modify_hostbanner , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbanner_gfx_url " , permission : : b_virtualserver_modify_hostbanner , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbanner_gfx_interval " , permission : : b_virtualserver_modify_hostbanner , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbanner_mode " , permission : : b_virtualserver_modify_hostbanner , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbutton_tooltip " , permission : : b_virtualserver_modify_hostbutton , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbutton_url " , permission : : b_virtualserver_modify_hostbutton , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostbutton_gfx_url " , permission : : b_virtualserver_modify_hostbutton , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostmessage " , permission : : b_virtualserver_modify_hostmessage , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_hostmessage_mode " , permission : : b_virtualserver_modify_hostmessage , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_welcomemessage " , permission : : b_virtualserver_modify_welcomemessage , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_weblist_enabled " , permission : : b_virtualserver_modify_weblist , bool )
if ( target_server & & target_server - > running ( ) ) {
if ( cmd [ " virtualserver_weblist_enabled " ] . as < bool > ( ) )
serverInstance - > getWebList ( ) - > enable_report ( target_server ) ;
else
serverInstance - > getWebList ( ) - > disable_report ( target_server ) ;
debugMessage ( target_server - > getServerId ( ) , " Changed weblist state to -> {} " ,
cmd [ " virtualserver_weblist_enabled " ] . as < bool > ( ) ? " activated " : " disabled " ) ;
}
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_needed_identity_security_level " , permission : : b_virtualserver_modify_needed_identity_security_level , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_antiflood_points_tick_reduce " , permission : : b_virtualserver_modify_antiflood , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_antiflood_points_needed_command_block " , permission : : b_virtualserver_modify_antiflood , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_antiflood_points_needed_ip_block " , permission : : b_virtualserver_modify_antiflood , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_complain_autoban_count " , permission : : b_virtualserver_modify_complain , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_complain_autoban_time " , permission : : b_virtualserver_modify_complain , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_complain_remove_time " , permission : : b_virtualserver_modify_complain , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_autostart " , permission : : b_virtualserver_modify_autostart , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_min_clients_in_channel_before_forced_silence " , permission : : b_virtualserver_modify_channel_forced_silence , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_client " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_query " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_channel " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_permissions " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_server " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_log_filetransfer " , permission : : b_virtualserver_modify_log_settings , bool ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_min_client_version " , permission : : b_virtualserver_modify_min_client_version , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_min_android_version " , permission : : b_virtualserver_modify_min_client_version , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_min_ios_version " , permission : : b_virtualserver_modify_min_client_version , uint64_t ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_music_bot_limit " , permission : : b_virtualserver_modify_music_bot_limit , int ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_flag_password " , permission : : b_virtualserver_modify_password , bool )
if ( cmd [ " virtualserver_flag_password " ] . as < bool > ( ) & & ! cmd [ 0 ] . has ( " virtualserver_password " ) )
return command_result { error : : parameter_invalid } ;
} SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_password " , permission : : b_virtualserver_modify_password , string )
if ( cmd [ " virtualserver_password " ] . string ( ) . empty ( ) ) {
toApplay [ " virtualserver_flag_password " ] = " 0 " ;
} else {
toApplay [ " virtualserver_flag_password " ] = " 1 " ;
if ( this - > getType ( ) = = CLIENT_QUERY )
toApplay [ " virtualserver_password " ] = base64 : : encode ( digest : : sha1 ( cmd [ " virtualserver_password " ] . string ( ) ) ) ;
}
}
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_client_description " , permission : : b_virtualserver_modify_default_messages , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_channel_description " , permission : : b_virtualserver_modify_default_messages , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_default_channel_topic " , permission : : b_virtualserver_modify_default_messages , string ) }
SERVEREDIT_CHK_PROP_CACHED ( " virtualserver_country_code " , permission : : b_virtualserver_modify_country_code , string ) }
SERVEREDIT_CHK_PROP2 ( " virtualserver_max_download_total_bandwidth " , permission : : b_virtualserver_modify_ft_settings , uint64_t , int64_t )
if ( cmd [ " virtualserver_max_download_total_bandwidth " ] . string ( ) . find ( ' - ' ) = = string : : npos )
toApplay [ " virtualserver_max_download_total_bandwidth " ] = to_string ( ( int64_t ) cmd [ " virtualserver_max_download_total_bandwidth " ] . as < uint64_t > ( ) ) ;
else
toApplay [ " virtualserver_max_download_total_bandwidth " ] = to_string ( cmd [ " virtualserver_max_download_total_bandwidth " ] . as < int64_t > ( ) ) ;
}
SERVEREDIT_CHK_PROP2 ( " virtualserver_max_upload_total_bandwidth " , permission : : b_virtualserver_modify_ft_settings , uint64_t , int64_t )
if ( cmd [ " virtualserver_max_upload_total_bandwidth " ] . string ( ) . find ( ' - ' ) = = string : : npos )
toApplay [ " virtualserver_max_upload_total_bandwidth " ] = to_string ( ( int64_t ) cmd [ " virtualserver_max_upload_total_bandwidth " ] . as < uint64_t > ( ) ) ;
else
toApplay [ " virtualserver_max_upload_total_bandwidth " ] = to_string ( cmd [ " virtualserver_max_upload_total_bandwidth " ] . as < int64_t > ( ) ) ;
}
SERVEREDIT_CHK_PROP2 ( " virtualserver_download_quota " , permission : : b_virtualserver_modify_ft_quotas , uint64_t , int64_t )
if ( cmd [ " virtualserver_download_quota " ] . string ( ) . find ( ' - ' ) = = string : : npos )
toApplay [ " virtualserver_download_quota " ] = to_string ( ( int64_t ) cmd [ " virtualserver_download_quota " ] . as < uint64_t > ( ) ) ;
else
toApplay [ " virtualserver_download_quota " ] = to_string ( cmd [ " virtualserver_download_quota " ] . as < int64_t > ( ) ) ;
}
SERVEREDIT_CHK_PROP2 ( " virtualserver_upload_quota " , permission : : b_virtualserver_modify_ft_quotas , uint64_t , int64_t )
if ( cmd [ " virtualserver_upload_quota " ] . string ( ) . find ( ' - ' ) = = string : : npos )
toApplay [ " virtualserver_upload_quota " ] = to_string ( ( int64_t ) cmd [ " virtualserver_upload_quota " ] . as < uint64_t > ( ) ) ;
else
toApplay [ " virtualserver_upload_quota " ] = to_string ( cmd [ " virtualserver_upload_quota " ] . as < int64_t > ( ) ) ;
}
else {
logError ( target_server ? target_server - > getServerId ( ) : 0 , " Client " + this - > getDisplayName ( ) + " tried to change a not existing server properties. ( " + key + " ) " ) ;
//return command_result{error::not_implemented};
}
}
std : : deque < std : : string > keys ;
bool group_update = false ;
for ( const auto & elm : toApplay ) {
2020-04-08 07:01:41 -04:00
const auto & info = property : : find < property : : VirtualServerProperties > ( elm . first ) ;
if ( info = = property : : VIRTUALSERVER_UNDEFINED ) {
2020-01-26 08:21:34 -05:00
logCritical ( target_server ? target_server - > getServerId ( ) : 0 , " Missing server property " + elm . first ) ;
continue ;
}
2020-04-08 07:01:41 -04:00
if ( ! info . validate_input ( elm . second ) ) {
logError ( target_server ? target_server - > getServerId ( ) : 0 , " Client " + this - > getDisplayName ( ) + " tried to change a property to an invalid value. (Value: ' " + elm . second + " ', Property: ' " + std : : string { info . name } + " ') " ) ;
2020-01-26 08:21:34 -05:00
continue ;
}
2020-06-28 08:01:14 -04:00
auto property = target_server ? target_server - > properties ( ) [ info ] : ( * serverInstance - > getDefaultServerProperties ( ) ) [ info ] ;
if ( property . value ( ) = = elm . second )
continue ;
auto old_value = property . value ( ) ;
property = elm . second ;
serverInstance - > action_logger ( ) - > server_edit_logger . log_server_edit ( serverId , this - > ref ( ) , info , old_value , elm . second ) ;
2020-01-26 08:21:34 -05:00
keys . push_back ( elm . first ) ;
2020-04-08 07:01:41 -04:00
group_update | = info = = property : : VIRTUALSERVER_DEFAULT_SERVER_GROUP | | info = = property : : VIRTUALSERVER_DEFAULT_CHANNEL_GROUP | | info = = property : : VIRTUALSERVER_DEFAULT_MUSIC_GROUP ;
2020-01-26 08:21:34 -05:00
}
if ( target_server ) {
if ( group_update )
target_server - > forEachClient ( [ & ] ( const shared_ptr < ConnectedClient > & client ) {
if ( target_server - > notifyClientPropertyUpdates ( client , target_server - > groups - > update_server_group_property ( client , true , client - > getChannel ( ) ) ) ) {
if ( client - > update_cached_permissions ( ) ) /* update cached calculated permissions */
client - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
}
} ) ;
if ( ! keys . empty ( ) )
target_server - > notifyServerEdited ( _this . lock ( ) , keys ) ;
}
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerRequestConnectionInfo ( Command & ) {
CMD_REQ_SERVER ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_connectioninfo_view , 1 ) ;
2020-04-08 07:01:41 -04:00
ts : : command_builder result { " notifyserverconnectioninfo " } ;
auto first_bulk = result . bulk ( 0 ) ;
2020-01-26 08:21:34 -05:00
2020-04-08 07:01:41 -04:00
auto total_stats = this - > server - > getServerStatistics ( ) - > total_stats ( ) ;
auto minute_report = this - > server - > getServerStatistics ( ) - > minute_stats ( ) ;
auto second_report = this - > server - > getServerStatistics ( ) - > second_stats ( ) ;
auto network_report = this - > server - > generate_network_report ( ) ;
2020-01-26 08:21:34 -05:00
2020-04-08 07:01:41 -04:00
first_bulk . put_unchecked ( property : : CONNECTION_FILETRANSFER_BANDWIDTH_SENT , minute_report . file_bytes_sent ) ;
first_bulk . put_unchecked ( property : : CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED , minute_report . file_bytes_received ) ;
2020-01-26 08:21:34 -05:00
2020-06-12 19:08:49 -04:00
first_bulk . put_unchecked ( property : : CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL , this - > server - > properties ( ) [ property : : VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED ] . as < string > ( ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL , this - > server - > properties ( ) [ property : : VIRTUALSERVER_TOTAL_BYTES_UPLOADED ] . as < string > ( ) ) ;
2020-01-26 08:21:34 -05:00
2020-04-08 07:01:41 -04:00
first_bulk . put_unchecked ( " connection_filetransfer_bytes_sent_month " , this - > server - > properties ( ) [ property : : VIRTUALSERVER_MONTH_BYTES_DOWNLOADED ] . as < string > ( ) ) ;
first_bulk . put_unchecked ( " connection_filetransfer_bytes_received_month " , this - > server - > properties ( ) [ property : : VIRTUALSERVER_MONTH_BYTES_UPLOADED ] . as < string > ( ) ) ;
2020-01-26 08:21:34 -05:00
2020-05-13 06:19:19 -04:00
first_bulk . put_unchecked ( property : : CONNECTION_PACKETS_SENT_TOTAL , std : : accumulate ( total_stats . connection_packets_sent . begin ( ) , total_stats . connection_packets_sent . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BYTES_SENT_TOTAL , std : : accumulate ( total_stats . connection_bytes_sent . begin ( ) , total_stats . connection_bytes_sent . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_PACKETS_RECEIVED_TOTAL , std : : accumulate ( total_stats . connection_packets_received . begin ( ) , total_stats . connection_packets_received . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BYTES_RECEIVED_TOTAL , std : : accumulate ( total_stats . connection_bytes_received . begin ( ) , total_stats . connection_bytes_received . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL , std : : accumulate ( second_report . connection_bytes_sent . begin ( ) , second_report . connection_bytes_sent . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL , std : : accumulate ( minute_report . connection_bytes_sent . begin ( ) , minute_report . connection_bytes_sent . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL , std : : accumulate ( second_report . connection_bytes_received . begin ( ) , second_report . connection_bytes_received . end ( ) , ( size_t ) 0U ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL , std : : accumulate ( minute_report . connection_bytes_received . begin ( ) , minute_report . connection_bytes_received . end ( ) , ( size_t ) 0U ) ) ;
2020-01-26 08:21:34 -05:00
2020-04-08 07:01:41 -04:00
first_bulk . put_unchecked ( property : : CONNECTION_CONNECTED_TIME , this - > server - > properties ( ) [ property : : VIRTUALSERVER_UPTIME ] . as < string > ( ) ) ;
first_bulk . put_unchecked ( property : : CONNECTION_PACKETLOSS_TOTAL , network_report . average_loss ) ;
first_bulk . put_unchecked ( property : : CONNECTION_PING , network_report . average_ping ) ;
this - > sendCommand ( result ) ;
2020-01-26 08:21:34 -05:00
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupList ( Command & ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_list , 1 ) ;
2020-11-07 07:17:51 -05:00
this - > notifyServerGroupList ( this - > getType ( ) ! = ClientType : : CLIENT_QUERY ) ;
2020-01-26 08:21:34 -05:00
this - > command_times . servergrouplist = system_clock : : now ( ) ;
return command_result { error : : ok } ;
}
//servergroupadd name=TestGroup type=1
command_result ConnectedClient : : handleCommandServerGroupAdd ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_create , 1 ) ;
2020-09-16 08:27:27 -04:00
if ( cmd [ " name " ] . string ( ) . empty ( ) ) {
return command_result { error : : parameter_invalid , " name " } ;
}
2020-01-26 08:21:34 -05:00
2020-06-28 08:01:14 -04:00
log : : GroupType log_group_type ;
2020-09-16 08:27:27 -04:00
if ( ! cmd [ 0 ] . has ( " type " ) ) {
cmd [ " type " ] = GroupType : : GROUP_TYPE_NORMAL ;
}
2020-01-26 08:21:34 -05:00
if ( cmd [ " type " ] . as < GroupType > ( ) = = GroupType : : GROUP_TYPE_QUERY ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_querygroup , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : QUERY ;
2020-01-26 08:21:34 -05:00
} else if ( cmd [ " type " ] . as < GroupType > ( ) = = GroupType : : GROUP_TYPE_TEMPLATE ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_templates , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : TEMPLATE ;
} else {
2020-09-16 08:15:06 -04:00
if ( ! this - > server ) {
2020-06-28 08:01:14 -04:00
return command_result { error : : parameter_invalid , " you cant create normal groups on the template server! " } ;
2020-09-16 08:15:06 -04:00
}
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : NORMAL ;
}
2020-01-26 08:21:34 -05:00
auto group_manager = this - > server ? this - > server - > getGroupManager ( ) : serverInstance - > getGroupManager ( ) . get ( ) ;
2020-09-16 08:27:27 -04:00
for ( const auto & gr : group_manager - > availableServerGroups ( true ) ) {
if ( gr - > name ( ) = = cmd [ " name " ] . string ( ) & & gr - > target ( ) = = GroupTarget : : GROUPTARGET_SERVER ) {
return command_result { error : : parameter_invalid , " Group already exists " } ;
}
}
2020-01-26 08:21:34 -05:00
auto group = group_manager - > createGroup ( GroupTarget : : GROUPTARGET_SERVER , cmd [ " type " ] . as < GroupType > ( ) , cmd [ " name " ] . string ( ) ) ;
2020-09-16 08:27:27 -04:00
if ( ! group ) {
2020-06-28 08:01:14 -04:00
return command_result { error : : vs_critical } ;
2020-09-16 08:27:27 -04:00
}
2020-06-28 08:01:14 -04:00
group - > permissions ( ) - > set_permission ( permission : : b_group_is_permanent , { 1 , 0 } , permission : : v2 : : set_value , permission : : v2 : : do_nothing ) ;
2020-09-16 08:27:27 -04:00
{
ts : : command_builder notify { this - > notify_response_command ( " notifyservergroupadded " ) } ;
notify . put_unchecked ( 0 , " sgid " , group - > groupId ( ) ) ;
this - > sendCommand ( notify ) ;
}
2020-06-28 08:01:14 -04:00
if ( this - > server ) {
2020-09-16 08:27:27 -04:00
if ( this - > getType ( ) = = ClientType : : CLIENT_QUERY ) {
this - > server - > forEachClient ( [ & ] ( const shared_ptr < ConnectedClient > & cl ) {
if ( cl = = this ) {
return ;
}
cl - > notifyServerGroupList ( ) ;
} ) ;
} else {
this - > server - > forEachClient ( [ & ] ( const shared_ptr < ConnectedClient > & cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
}
2020-06-28 08:01:14 -04:00
}
serverInstance - > action_logger ( ) - > group_logger . log_group_create ( this - > getServerId ( ) , this - > ref ( ) , log : : GroupTarget : : SERVER , log_group_type , group - > groupId ( ) , group - > name ( ) , 0 , " " ) ;
2020-01-26 08:21:34 -05:00
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupCopy ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
auto ref_server = this - > server ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_create , 1 ) ;
auto group_manager = this - > server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ;
auto source_group_id = cmd [ " ssgid " ] . as < GroupId > ( ) ;
auto source_group = group_manager - > findGroup ( source_group_id ) ;
if ( ! source_group | | source_group - > target ( ) ! = GROUPTARGET_SERVER )
return command_result { error : : group_invalid_id } ;
const auto group_type_modificable = [ & ] ( GroupType type ) {
switch ( type ) {
case GroupType : : GROUP_TYPE_TEMPLATE :
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_templates , 0 ) ) )
return permission : : b_serverinstance_modify_templates ;
break ;
case GroupType : : GROUP_TYPE_QUERY :
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_querygroup , 0 ) ) )
return permission : : b_serverinstance_modify_querygroup ;
break ;
2020-06-16 06:57:20 -04:00
case GroupType : : GROUP_TYPE_NORMAL :
2020-01-26 08:21:34 -05:00
default :
break ;
}
return permission : : undefined ;
} ;
{
auto result = group_type_modificable ( source_group - > type ( ) ) ;
if ( result ! = permission : : undefined )
return command_result { result } ;
}
auto global_update = false ;
if ( cmd [ 0 ] . has ( " tsgid " ) & & cmd [ " tsgid " ] . as < GroupId > ( ) ! = 0 ) {
//Copy an existing group
auto target_group = group_manager - > findGroup ( cmd [ " tsgid " ] ) ;
if ( ! target_group | | target_group - > target ( ) ! = GROUPTARGET_SERVER )
return command_result { error : : group_invalid_id } ;
{
auto result = group_type_modificable ( target_group - > type ( ) ) ;
if ( result ! = permission : : undefined )
return command_result { result } ;
}
if ( ! target_group - > permission_granted ( permission : : i_server_group_needed_modify_power , this - > calculate_permission ( permission : : i_server_group_modify_power , 0 ) , true ) )
return command_result { permission : : i_server_group_modify_power } ;
if ( ! group_manager - > copyGroupPermissions ( source_group , target_group ) )
return command_result { error : : vs_critical , " failed to copy group permissions " } ;
2020-06-28 08:01:14 -04:00
log : : GroupType log_group_type ;
switch ( target_group - > type ( ) ) {
case GroupType : : GROUP_TYPE_QUERY :
log_group_type = log : : GroupType : : QUERY ;
break ;
case GroupType : : GROUP_TYPE_TEMPLATE :
log_group_type = log : : GroupType : : TEMPLATE ;
break ;
case GroupType : : GROUP_TYPE_NORMAL :
log_group_type = log : : GroupType : : NORMAL ;
break ;
default :
return command_result { error : : parameter_invalid , " type " } ;
}
serverInstance - > action_logger ( ) - > group_logger . log_group_permission_copy ( target_group - > type ( ) ! = GroupType : : GROUP_TYPE_NORMAL ? 0 : this - > getServerId ( ) ,
this - > ref ( ) , log : : GroupTarget : : SERVER , log_group_type , target_group - > groupId ( ) , target_group - > name ( ) , source_group - > groupId ( ) , source_group - > name ( ) ) ;
2020-01-26 08:21:34 -05:00
global_update = ! this - > server | | ! group_manager - > isLocalGroup ( target_group ) ;
} else {
//Copy a new group
auto target_type = cmd [ " type " ] . as < GroupType > ( ) ;
{
auto result = group_type_modificable ( target_type ) ;
if ( result ! = permission : : undefined )
return command_result { result } ;
}
2020-06-28 08:01:14 -04:00
log : : GroupType log_group_type ;
switch ( target_type ) {
case GroupType : : GROUP_TYPE_QUERY :
log_group_type = log : : GroupType : : QUERY ;
break ;
case GroupType : : GROUP_TYPE_TEMPLATE :
log_group_type = log : : GroupType : : TEMPLATE ;
break ;
case GroupType : : GROUP_TYPE_NORMAL :
log_group_type = log : : GroupType : : NORMAL ;
break ;
default :
return command_result { error : : parameter_invalid , " type " } ;
}
2020-01-26 08:21:34 -05:00
if ( ! ref_server & & target_type = = GroupType : : GROUP_TYPE_NORMAL )
return command_result { error : : parameter_invalid , " You cant create normal groups on the template server! " } ;
if ( ! group_manager - > findGroup ( GroupTarget : : GROUPTARGET_SERVER , cmd [ " name " ] . string ( ) ) . empty ( ) )
return command_result { error : : group_name_inuse , " You cant create normal groups on the template server! " } ;
auto target_group_id = group_manager - > copyGroup ( source_group , target_type , cmd [ " name " ] , target_type ! = GroupType : : GROUP_TYPE_NORMAL ? 0 : this - > getServerId ( ) ) ;
if ( target_group_id = = 0 )
return command_result { error : : vs_critical , " failed to copy group " } ;
2020-06-28 08:01:14 -04:00
serverInstance - > action_logger ( ) - > group_logger . log_group_create ( target_type ! = GroupType : : GROUP_TYPE_NORMAL ? 0 : this - > getServerId ( ) ,
this - > ref ( ) , log : : GroupTarget : : SERVER , log_group_type , target_group_id , cmd [ " name " ] . string ( ) , source_group - > groupId ( ) , source_group - > name ( ) ) ;
2020-01-26 08:21:34 -05:00
if ( this - > getType ( ) = = ClientType : : CLIENT_QUERY ) {
Command notify ( " " ) ;
notify [ " sgid " ] = target_group_id ;
this - > sendCommand ( notify ) ;
}
global_update = ! this - > server | | ! group_manager - > isLocalGroup ( group_manager - > findGroup ( target_group_id ) ) ;
}
2020-01-26 12:04:38 -05:00
for ( const auto & server : ( global_update ? serverInstance - > getVoiceServerManager ( ) - > serverInstances ( ) : deque < shared_ptr < VirtualServer > > { this - > server } ) )
2020-01-26 08:21:34 -05:00
if ( server )
server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupRename ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
auto group_manager = this - > server ? this - > server - > getGroupManager ( ) : serverInstance - > getGroupManager ( ) . get ( ) ;
auto serverGroup = group_manager - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup | | serverGroup - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : group_invalid_id } ;
ACTION_REQUIRES_GROUP_PERMISSION ( serverGroup , permission : : i_server_group_needed_modify_power , permission : : i_server_group_modify_power , true ) ;
auto type = serverGroup - > type ( ) ;
2020-06-28 08:01:14 -04:00
log : : GroupType log_group_type ;
2020-01-26 08:21:34 -05:00
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_querygroup , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : QUERY ;
2020-01-26 08:21:34 -05:00
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_templates , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : TEMPLATE ;
} else {
log_group_type = log : : GroupType : : NORMAL ;
2020-01-26 08:21:34 -05:00
}
2020-06-28 08:01:14 -04:00
auto old_name = serverGroup - > name ( ) ;
2020-01-26 08:21:34 -05:00
group_manager - > renameGroup ( serverGroup , cmd [ " name " ] . string ( ) ) ;
2020-06-28 08:01:14 -04:00
serverInstance - > action_logger ( ) - > group_logger . log_group_rename ( this - > getServerId ( ) , this - > ref ( ) , log : : GroupTarget : : SERVER , log_group_type , serverGroup - > groupId ( ) , serverGroup - > name ( ) , old_name ) ;
2020-01-26 08:21:34 -05:00
if ( this - > server )
this - > server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
return command_result { error : : ok } ;
}
//servergroupdel sgid=2 force=0
command_result ConnectedClient : : handleCommandServerGroupDel ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_delete , 1 ) ;
auto group_manager = this - > server ? this - > server - > getGroupManager ( ) : serverInstance - > getGroupManager ( ) . get ( ) ;
auto serverGroup = group_manager - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup | | serverGroup - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : group_invalid_id } ;
2020-06-16 06:57:20 -04:00
ACTION_REQUIRES_GROUP_PERMISSION ( serverGroup , permission : : i_server_group_needed_modify_power , permission : : i_server_group_modify_power , true ) ;
2020-01-26 08:21:34 -05:00
if ( this - > server & & this - > server - > properties ( ) [ property : : VIRTUALSERVER_DEFAULT_SERVER_GROUP ] = = serverGroup - > groupId ( ) )
return command_result { error : : parameter_invalid , " Could not delete default server group! " } ;
2020-06-28 08:01:14 -04:00
2020-01-26 08:21:34 -05:00
if ( serverInstance - > properties ( ) [ property : : SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP ] = = serverGroup - > groupId ( ) )
return command_result { error : : parameter_invalid , " Could not delete instance default server admin group! " } ;
2020-06-28 08:01:14 -04:00
2020-01-26 08:21:34 -05:00
if ( serverInstance - > properties ( ) [ property : : SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP ] = = serverGroup - > groupId ( ) )
return command_result { error : : parameter_invalid , " Could not delete instance default server group! " } ;
2020-06-28 08:01:14 -04:00
2020-01-26 08:21:34 -05:00
if ( serverInstance - > properties ( ) [ property : : SERVERINSTANCE_GUEST_SERVERQUERY_GROUP ] = = serverGroup - > groupId ( ) )
return command_result { error : : parameter_invalid , " Could not delete instance default guest server query group! " } ;
auto type = serverGroup - > type ( ) ;
2020-06-28 08:01:14 -04:00
log : : GroupType log_group_type ;
2020-01-26 08:21:34 -05:00
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_querygroup , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : QUERY ;
2020-01-26 08:21:34 -05:00
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_templates , 1 ) ;
2020-06-28 08:01:14 -04:00
log_group_type = log : : GroupType : : TEMPLATE ;
} else {
log_group_type = log : : GroupType : : NORMAL ;
2020-01-26 08:21:34 -05:00
}
if ( ! cmd [ " force " ] . as < bool > ( ) )
if ( ! group_manager - > listGroupMembers ( serverGroup , false ) . empty ( ) )
return command_result { error : : database_empty_result , " group not empty! " } ;
if ( group_manager - > deleteGroup ( serverGroup ) ) {
2020-06-28 08:01:14 -04:00
serverInstance - > action_logger ( ) - > group_logger . log_group_delete ( this - > getServerId ( ) , this - > ref ( ) , log : : GroupTarget : : SERVER , log_group_type , serverGroup - > groupId ( ) , serverGroup - > name ( ) ) ;
2020-01-26 08:21:34 -05:00
if ( this - > server )
this - > server - > forEachClient ( [ & ] ( shared_ptr < ConnectedClient > cl ) {
if ( this - > server - > notifyClientPropertyUpdates ( cl , this - > server - > groups - > update_server_group_property ( cl , true , cl - > getChannel ( ) ) ) ) {
if ( cl - > update_cached_permissions ( ) ) /* update cached calculated permissions */
cl - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
}
cl - > notifyServerGroupList ( ) ;
} ) ;
}
return command_result { error : : ok } ;
}
//servergroupclientlist sgid=2
//notifyservergroupclientlist sgid=6 cldbid=2 client_nickname=WolverinDEV client_unique_identifier=xxjnc14LmvTk+Lyrm8OOeo4tOqw=
command_result ConnectedClient : : handleCommandServerGroupClientList ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_client_list , 1 ) ;
auto server = cmd [ 0 ] . has ( " sid " ) & & cmd [ " sid " ] = = 0 ? nullptr : this - > server ;
auto groupManager = server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ;
auto serverGroup = groupManager - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup | | serverGroup - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : group_invalid_id } ;
Command notify ( this - > getExternalType ( ) = = ClientType : : CLIENT_TEAMSPEAK ? " notifyservergroupclientlist " : " " ) ;
notify [ " sgid " ] = cmd [ " sgid " ] . as < GroupId > ( ) ;
int index = 0 ;
for ( const auto & clientEntry : groupManager - > listGroupMembers ( serverGroup ) ) {
2020-08-01 10:02:03 -04:00
notify [ index ] [ " cldbid " ] = clientEntry . cldbId ;
notify [ index ] [ " client_nickname " ] = clientEntry . displayName ;
notify [ index ] [ " client_unique_identifier " ] = clientEntry . uid ;
2020-01-26 08:21:34 -05:00
index + + ;
}
2020-08-03 07:51:47 -04:00
if ( index = = 0 & & this - > getType ( ) ! = ClientType : : CLIENT_TEAMSPEAK ) {
2020-08-01 10:02:03 -04:00
return ts : : command_result { error : : database_empty_result } ;
2020-08-03 07:51:47 -04:00
}
2020-08-01 10:02:03 -04:00
2020-01-26 08:21:34 -05:00
this - > sendCommand ( notify ) ;
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupAddClient ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 25 ) ;
auto target_server = cmd [ 0 ] . has ( " sid " ) & & cmd [ " sid " ] = = 0 ? nullptr : this - > server ;
auto group_manager = target_server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ;
auto target_cldbid = cmd [ " cldbid " ] . as < ClientDbId > ( ) ;
if ( ! serverInstance - > databaseHelper ( ) - > validClientDatabaseId ( target_server , cmd [ " cldbid " ] ) ) return command_result { error : : client_invalid_id , " invalid cldbid " } ;
auto needed_client_permission = this - > server - > calculate_permission ( permission : : i_client_needed_permission_modify_power , target_cldbid , ClientType : : CLIENT_TEAMSPEAK , 0 ) ;
if ( needed_client_permission . has_value ) {
if ( ! permission : : v2 : : permission_granted ( needed_client_permission , this - > calculate_permission ( permission : : i_client_permission_modify_power , 0 ) ) )
return command_result { permission : : i_client_needed_permission_modify_power } ;
}
vector < std : : shared_ptr < Group > > target_groups ;
vector < std : : shared_ptr < Group > > applied_groups ;
target_groups . reserve ( cmd . bulkCount ( ) ) ;
auto continue_on_error = cmd . hasParm ( " continueonerror " ) ;
{
auto permission_add_power = this - > calculate_permission ( permission : : i_server_group_member_add_power , - 1 ) ;
2020-04-18 18:23:18 -04:00
auto permission_self_add_power = this - > calculate_permission ( permission : : i_server_group_self_add_power , - 1 ) ;
2020-01-26 08:21:34 -05:00
for ( auto index = 0 ; index < cmd . bulkCount ( ) ; index + + ) {
auto group_id = cmd [ index ] [ " sgid " ] ;
if ( ! group_id . castable < GroupId > ( ) & & continue_on_error )
continue ;
auto gid = group_id . as < GroupId > ( ) ;
auto group = group_manager - > findGroup ( gid ) ;
if ( ! group ) {
if ( continue_on_error )
continue ;
return command_result { error : : group_invalid_id } ;
}
if ( ! target_server & & group - > target ( ) ! = GroupTarget : : GROUPTARGET_SERVER & & group - > type ( ) ! = GroupType : : GROUP_TYPE_QUERY )
return command_result { error : : parameter_invalid } ;
if ( find ( target_groups . begin ( ) , target_groups . end ( ) , group ) ! = target_groups . end ( ) ) {
if ( continue_on_error )
continue ;
return command_result { error : : client_is_already_member_of_group } ;
}
/* permission tests */
if ( ! group - > permission_granted ( permission : : i_server_group_needed_member_add_power , permission_add_power , true ) ) {
if ( target_cldbid ! = this - > getClientDatabaseId ( ) ) {
if ( continue_on_error )
continue ;
return command_result { permission : : i_server_group_member_add_power } ;
}
if ( ! group - > permission_granted ( permission : : i_server_group_needed_member_add_power , permission_self_add_power , true ) ) {
if ( continue_on_error )
continue ;
return command_result { permission : : i_server_group_self_add_power } ;
}
}
target_groups . push_back ( std : : move ( group ) ) ;
}
}
applied_groups . reserve ( target_groups . size ( ) ) ;
if ( target_groups . empty ( ) ) return command_result { error : : ok } ;
else if ( target_groups . size ( ) = = 1 ) {
/* speed up thing, don't try to load any cache */
auto group = target_groups [ 0 ] ;
if ( group_manager - > hasServerGroupAssigned ( target_cldbid , group ) )
return command_result { error : : client_is_already_member_of_group } ;
group_manager - > addServerGroup ( target_cldbid , group ) ;
applied_groups . push_back ( group ) ;
} else {
group_manager - > enableCache ( target_cldbid ) ;
scope_exit_callback cache_disable { [ group_manager , target_cldbid ] {
group_manager - > disableCache ( target_cldbid ) ;
} } ;
for ( const auto & group : target_groups ) {
if ( group_manager - > hasServerGroupAssigned ( target_cldbid , group ) ) {
if ( continue_on_error )
continue ;
return command_result { error : : client_is_already_member_of_group } ;
}
group_manager - > addServerGroup ( target_cldbid , group ) ;
applied_groups . push_back ( group ) ;
}
}
2020-06-28 08:01:14 -04:00
std : : shared_ptr < ConnectedClient > connected_client { } ;
2020-01-26 12:04:38 -05:00
for ( const auto & _server : target_server ? std : : deque < shared_ptr < VirtualServer > > { target_server } : serverInstance - > getVoiceServerManager ( ) - > serverInstances ( ) ) {
2020-01-26 08:21:34 -05:00
for ( const auto & targetClient : _server - > findClientsByCldbId ( target_cldbid ) ) {
2020-06-28 08:01:14 -04:00
connected_client = targetClient ;
2020-01-26 08:21:34 -05:00
if ( _server - > notifyClientPropertyUpdates ( targetClient , _server - > groups - > update_server_group_property ( targetClient , true , targetClient - > getChannel ( ) ) ) ) {
for ( const auto & client : _server - > getClients ( ) ) {
if ( client - > isClientVisible ( targetClient , true ) | | client = = targetClient )
for ( const auto & group : applied_groups )
client - > notifyServerGroupClientAdd ( _this . lock ( ) , targetClient , group ) ;
}
if ( targetClient - > update_cached_permissions ( ) ) /* update cached calculated permissions */
targetClient - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
targetClient - > updateChannelClientProperties ( true , true ) ;
}
}
}
2020-06-28 08:01:14 -04:00
for ( const auto & group : applied_groups ) {
serverInstance - > action_logger ( ) - > group_assignment_logger . log_group_assignment_add ( target_server ? target_server - > getServerId ( ) : 0 ,
this - > ref ( ) , log : : GroupTarget : : SERVER ,
group - > groupId ( ) , group - > name ( ) ,
target_cldbid , connected_client ? connected_client - > getDisplayName ( ) : " "
) ;
}
2020-01-26 08:21:34 -05:00
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupDelClient ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 25 ) ;
auto target_server = cmd [ 0 ] . has ( " sid " ) & & cmd [ " sid " ] = = 0 ? nullptr : this - > server ;
auto group_manager = target_server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ;
auto target_cldbid = cmd [ " cldbid " ] . as < ClientDbId > ( ) ;
if ( ! serverInstance - > databaseHelper ( ) - > validClientDatabaseId ( target_server , cmd [ " cldbid " ] ) ) return command_result { error : : client_invalid_id , " invalid cldbid " } ;
auto needed_client_permission = this - > server - > calculate_permission ( permission : : i_client_needed_permission_modify_power , target_cldbid , ClientType : : CLIENT_TEAMSPEAK , 0 ) ;
if ( needed_client_permission . has_value ) {
if ( ! permission : : v2 : : permission_granted ( needed_client_permission , this - > calculate_permission ( permission : : i_client_permission_modify_power , 0 ) ) )
return command_result { permission : : i_client_needed_permission_modify_power } ;
}
vector < std : : shared_ptr < Group > > target_groups ;
vector < std : : shared_ptr < Group > > applied_groups ;
target_groups . reserve ( cmd . bulkCount ( ) ) ;
auto continue_on_error = cmd . hasParm ( " continueonerror " ) ;
{
auto permission_remove_power = this - > calculate_permission ( permission : : i_server_group_member_remove_power , - 1 ) ;
2020-04-18 18:23:18 -04:00
auto permission_self_remove_power = this - > calculate_permission ( permission : : i_server_group_self_remove_power , - 1 ) ;
2020-01-26 08:21:34 -05:00
for ( auto index = 0 ; index < cmd . bulkCount ( ) ; index + + ) {
auto group_id = cmd [ index ] [ " sgid " ] ;
if ( ! group_id . castable < GroupId > ( ) & & continue_on_error )
continue ;
auto gid = group_id . as < GroupId > ( ) ;
auto group = group_manager - > findGroup ( gid ) ;
if ( ! group ) {
if ( continue_on_error )
continue ;
return command_result { error : : group_invalid_id } ;
}
if ( ! target_server & & group - > target ( ) ! = GroupTarget : : GROUPTARGET_SERVER & & group - > type ( ) ! = GroupType : : GROUP_TYPE_QUERY )
return command_result { error : : group_invalid_id } ;
if ( find ( target_groups . begin ( ) , target_groups . end ( ) , group ) ! = target_groups . end ( ) ) {
if ( continue_on_error )
continue ;
return command_result { error : : parameter_invalid , " duplicate server group for id " + to_string ( gid ) } ;
}
/* permission tests */
if ( ! group - > permission_granted ( permission : : i_server_group_needed_member_remove_power , permission_remove_power , true ) ) {
if ( target_cldbid ! = this - > getClientDatabaseId ( ) ) {
if ( continue_on_error )
continue ;
return command_result { permission : : i_server_group_member_remove_power } ;
}
if ( ! group - > permission_granted ( permission : : i_server_group_needed_member_remove_power , permission_self_remove_power , true ) ) {
if ( continue_on_error )
continue ;
return command_result { permission : : i_server_group_self_remove_power } ;
}
}
target_groups . push_back ( std : : move ( group ) ) ;
}
}
applied_groups . reserve ( target_groups . size ( ) ) ;
if ( target_groups . empty ( ) ) return command_result { error : : ok } ;
else if ( target_groups . size ( ) = = 1 ) {
/* speed up thing, don't try to load any cache */
auto group = target_groups [ 0 ] ;
auto assignment = group_manager - > get_group_assignment ( target_cldbid , group ) ;
if ( ! assignment ) {
return command_result { error : : client_is_not_member_of_group } ;
}
if ( assignment - > server ! = ( target_server ? target_server - > getServerId ( ) : 0 ) ) {
return command_result { error : : group_not_assigned_over_this_server } ;
}
group_manager - > removeServerGroup ( target_cldbid , group ) ;
applied_groups . push_back ( group ) ;
} else {
group_manager - > enableCache ( target_cldbid ) ;
scope_exit_callback cache_disable { [ group_manager , target_cldbid ] {
group_manager - > disableCache ( target_cldbid ) ;
} } ;
for ( const auto & group : target_groups ) {
auto assignment = group_manager - > get_group_assignment ( target_cldbid , group ) ;
if ( ! assignment ) {
if ( continue_on_error )
continue ;
return command_result { error : : client_is_not_member_of_group } ;
}
if ( assignment - > server ! = ( target_server ? target_server - > getServerId ( ) : 0 ) ) {
if ( continue_on_error )
continue ;
return command_result { error : : group_not_assigned_over_this_server } ;
}
applied_groups . push_back ( group ) ;
group_manager - > removeServerGroup ( target_cldbid , group ) ;
}
}
2020-06-28 08:01:14 -04:00
std : : shared_ptr < ConnectedClient > connected_client { } ;
2020-01-26 12:04:38 -05:00
for ( const auto & _server : target_server ? std : : deque < shared_ptr < VirtualServer > > { target_server } : serverInstance - > getVoiceServerManager ( ) - > serverInstances ( ) ) {
2020-01-26 08:21:34 -05:00
for ( const auto & targetClient : _server - > findClientsByCldbId ( target_cldbid ) ) {
2020-06-28 08:01:14 -04:00
connected_client = targetClient ;
2020-04-29 04:34:22 -04:00
ConnectedLockedClient clock { targetClient } ;
if ( ! clock ) continue ;
2020-01-26 08:21:34 -05:00
if ( _server - > notifyClientPropertyUpdates ( targetClient , _server - > groups - > update_server_group_property ( targetClient , true , targetClient - > getChannel ( ) ) ) ) {
for ( const auto & client : _server - > getClients ( ) ) {
if ( client - > isClientVisible ( targetClient , true ) | | client = = targetClient )
for ( const auto & group : applied_groups )
client - > notifyServerGroupClientRemove ( _this . lock ( ) , targetClient , group ) ;
}
if ( targetClient - > update_cached_permissions ( ) ) /* update cached calculated permissions */
targetClient - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
targetClient - > updateChannelClientProperties ( true , true ) ;
}
}
}
2020-06-28 08:01:14 -04:00
for ( const auto & group : applied_groups ) {
serverInstance - > action_logger ( ) - > group_assignment_logger . log_group_assignment_remove ( target_server ? target_server - > getServerId ( ) : 0 ,
this - > ref ( ) , log : : GroupTarget : : SERVER ,
group - > groupId ( ) , group - > name ( ) ,
target_cldbid , connected_client ? connected_client - > getDisplayName ( ) : " "
) ;
}
2020-01-26 08:21:34 -05:00
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupPermList ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_virtualserver_servergroup_permission_list , 1 ) ;
auto serverGroup = ( this - > server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ) - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup ) return command_result { error : : group_invalid_id } ;
if ( this - > getType ( ) = = ClientType : : CLIENT_TEAMSPEAK & & this - > command_times . last_notify + this - > command_times . notify_timeout < system_clock : : now ( ) ) {
this - > sendTSPermEditorWarning ( ) ;
}
if ( ! this - > notifyGroupPermList ( serverGroup , cmd . hasParm ( " permsid " ) ) ) return command_result { error : : database_empty_result } ;
return command_result { error : : ok } ;
}
command_result ConnectedClient : : handleCommandServerGroupAddPerm ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
auto serverGroup = ( this - > server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ) - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup ) return command_result { error : : group_invalid_id } ;
if ( serverGroup - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : parameter_invalid } ;
ACTION_REQUIRES_GROUP_PERMISSION ( serverGroup , permission : : i_server_group_needed_modify_power , permission : : i_server_group_modify_power , 1 ) ;
2020-06-16 06:57:20 -04:00
/* We don't need this. The modify permissions only apply when creating/editing/renaming the groups itself
2020-01-26 08:21:34 -05:00
auto type = serverGroup - > type ( ) ;
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_querygroup , 1 ) ;
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_templates , 1 ) ;
}
2020-06-16 06:57:20 -04:00
*/
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
command : : bulk_parser : : PermissionBulksParser < true > pparser { cmd } ;
if ( ! pparser . validate ( this - > ref ( ) , 0 ) )
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
bool update_talk_power { false } , update_server_group_list { false } ;
2020-01-26 08:21:34 -05:00
auto permissions = serverGroup - > permissions ( ) ;
2020-05-07 15:28:15 -04:00
for ( const auto & ppermission : pparser . iterate_valid_permissions ( ) ) {
ppermission . apply_to ( serverGroup - > permissions ( ) , permission : : v2 : : PermissionUpdateType : : set_value ) ;
2020-06-28 08:01:14 -04:00
ppermission . log_update ( serverInstance - > action_logger ( ) - > permission_logger ,
this - > getServerId ( ) ,
this - > ref ( ) ,
log : : PermissionTarget : : SERVER_GROUP ,
permission : : v2 : : PermissionUpdateType : : set_value ,
serverGroup - > groupId ( ) , serverGroup - > name ( ) ,
0 , " "
) ;
2020-05-07 15:28:15 -04:00
update_server_group_list | = ppermission . is_group_property ( ) ;
update_talk_power | = ppermission . is_client_view_property ( ) ;
2020-01-26 08:21:34 -05:00
}
2020-05-07 15:28:15 -04:00
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
serverGroup - > apply_properties_from_permissions ( ) ;
//TODO may update for every server?
if ( this - > server ) {
auto lock = this - > _this . lock ( ) ;
auto server = this - > server ;
2020-05-07 15:28:15 -04:00
threads : : Thread ( [ update_talk_power , update_server_group_list , serverGroup , lock , server ] ( ) {
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
2020-05-07 15:28:15 -04:00
server - > forEachClient ( [ serverGroup , update_talk_power ] ( shared_ptr < ConnectedClient > cl ) {
2020-01-26 08:21:34 -05:00
if ( cl - > serverGroupAssigned ( serverGroup ) ) {
if ( cl - > update_cached_permissions ( ) ) /* update cached calculated permissions */
cl - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
2020-05-07 15:28:15 -04:00
if ( update_talk_power )
2020-01-26 08:21:34 -05:00
cl - > updateChannelClientProperties ( true , true ) ;
cl - > join_state_id + + ; /* join permission may changed, all channels need to be recalculate dif needed */
}
} ) ;
} ) . detach ( ) ;
}
2020-05-07 15:28:15 -04:00
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
}
command_result ConnectedClient : : handleCommandServerGroupDelPerm ( Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 5 ) ;
auto serverGroup = ( this - > server ? this - > server - > groups : serverInstance - > getGroupManager ( ) . get ( ) ) - > findGroup ( cmd [ " sgid " ] . as < GroupId > ( ) ) ;
if ( ! serverGroup ) return command_result { error : : group_invalid_id } ;
if ( serverGroup - > target ( ) ! = GROUPTARGET_SERVER ) return command_result { error : : parameter_invalid } ;
ACTION_REQUIRES_GROUP_PERMISSION ( serverGroup , permission : : i_server_group_needed_modify_power , permission : : i_server_group_modify_power , 1 ) ;
2020-06-16 06:57:20 -04:00
/* We don't need this. The modify permissions only apply when creating/editing/renaming the groups itself
2020-01-26 08:21:34 -05:00
auto type = serverGroup - > type ( ) ;
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_querygroup , 1 ) ;
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
ACTION_REQUIRES_GLOBAL_PERMISSION ( permission : : b_serverinstance_modify_templates , 1 ) ;
}
2020-06-16 06:57:20 -04:00
*/
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
command : : bulk_parser : : PermissionBulksParser < false > pparser { cmd } ;
if ( ! pparser . validate ( this - > ref ( ) , 0 ) )
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
bool update_talk_power { false } , update_server_group_list { false } ;
for ( const auto & ppermission : pparser . iterate_valid_permissions ( ) ) {
ppermission . apply_to ( serverGroup - > permissions ( ) , permission : : v2 : : PermissionUpdateType : : delete_value ) ;
2020-06-28 08:01:14 -04:00
ppermission . log_update ( serverInstance - > action_logger ( ) - > permission_logger ,
this - > getServerId ( ) ,
this - > ref ( ) ,
log : : PermissionTarget : : SERVER_GROUP ,
permission : : v2 : : PermissionUpdateType : : delete_value ,
serverGroup - > groupId ( ) , serverGroup - > name ( ) ,
0 , " "
) ;
2020-05-07 15:28:15 -04:00
update_server_group_list | = ppermission . is_group_property ( ) ;
update_talk_power | = ppermission . is_client_view_property ( ) ;
2020-01-26 08:21:34 -05:00
}
2020-05-07 15:28:15 -04:00
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
serverGroup - > apply_properties_from_permissions ( ) ;
if ( this - > server ) {
auto lock = this - > _this . lock ( ) ;
auto server = this - > server ;
2020-05-07 15:28:15 -04:00
threads : : Thread ( [ update_talk_power , update_server_group_list , serverGroup , lock , server ] ( ) {
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
2020-05-07 15:28:15 -04:00
server - > forEachClient ( [ serverGroup , update_talk_power ] ( shared_ptr < ConnectedClient > cl ) {
2020-01-26 08:21:34 -05:00
if ( cl - > serverGroupAssigned ( serverGroup ) ) {
if ( cl - > update_cached_permissions ( ) ) /* update cached calculated permissions */
cl - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
2020-05-07 15:28:15 -04:00
if ( update_talk_power )
2020-01-26 08:21:34 -05:00
cl - > updateChannelClientProperties ( true , true ) ;
cl - > join_state_id + + ; /* join permission may changed, all channels need to be recalculate dif needed */
}
} ) ;
} ) . detach ( ) ;
}
2020-05-07 15:28:15 -04:00
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
}
command_result ConnectedClient : : handleCommandServerGroupAutoAddPerm ( ts : : Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 25 ) ;
auto ref_server = this - > server ;
auto group_manager = ref_server ? this - > server - > groups : & * serverInstance - > getGroupManager ( ) ;
deque < shared_ptr < Group > > groups ;
for ( const auto & group : group_manager - > availableGroups ( false ) ) {
if ( group - > updateType ( ) = = cmd [ " sgtype " ] . as < permission : : PermissionValue > ( ) & & group - > target ( ) = = GROUPTARGET_SERVER ) {
if ( group - > permission_granted ( permission : : i_server_group_needed_modify_power , this - > calculate_permission ( permission : : i_server_group_modify_power , 0 ) , true ) ) {
auto type = group - > type ( ) ;
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_querygroup , 0 ) ) )
continue ;
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_templates , 0 ) ) )
continue ;
}
groups . push_back ( group ) ; //sgtype
}
}
}
if ( groups . empty ( ) )
return command_result { error : : ok } ;
2020-05-07 15:28:15 -04:00
command : : bulk_parser : : PermissionBulksParser < true > pparser { cmd } ;
if ( ! pparser . validate ( this - > ref ( ) , 0 ) )
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
bool update_clients { false } , update_server_group_list { false } ;
for ( const auto & ppermission : pparser . iterate_valid_permissions ( ) ) {
2020-06-28 08:01:14 -04:00
for ( const auto & serverGroup : groups ) {
2020-05-07 15:28:15 -04:00
ppermission . apply_to ( serverGroup - > permissions ( ) , permission : : v2 : : PermissionUpdateType : : set_value ) ;
2020-06-28 08:01:14 -04:00
ppermission . log_update ( serverInstance - > action_logger ( ) - > permission_logger ,
this - > getServerId ( ) ,
this - > ref ( ) ,
log : : PermissionTarget : : SERVER_GROUP ,
permission : : v2 : : PermissionUpdateType : : set_value ,
serverGroup - > groupId ( ) , serverGroup - > name ( ) ,
0 , " "
) ;
}
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
update_server_group_list | = ppermission . is_group_property ( ) ;
update_clients | = ppermission . is_client_view_property ( ) ;
2020-01-26 08:21:34 -05:00
}
2020-05-07 15:28:15 -04:00
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
for ( auto & group : groups )
group - > apply_properties_from_permissions ( ) ;
auto lock = this - > _this . lock ( ) ;
if ( ref_server ) {
2020-05-07 15:28:15 -04:00
threads : : Thread ( [ update_clients , update_server_group_list , groups , lock , ref_server ] ( ) {
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
ref_server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
2020-05-07 15:28:15 -04:00
ref_server - > forEachClient ( [ groups , update_clients ] ( shared_ptr < ConnectedClient > cl ) {
2020-01-26 08:21:34 -05:00
for ( const auto & serverGroup : groups ) {
if ( cl - > serverGroupAssigned ( serverGroup ) ) {
if ( cl - > update_cached_permissions ( ) ) { /* update cached calculated permissions */
cl - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
}
2020-05-07 15:28:15 -04:00
if ( update_clients ) {
2020-01-26 08:21:34 -05:00
cl - > updateChannelClientProperties ( true , true ) ;
}
cl - > join_state_id + + ; /* join permission may changed, all channels need to be recalculate if needed */
break ;
}
}
} ) ;
} ) . detach ( ) ;
}
2020-05-07 15:28:15 -04:00
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
}
command_result ConnectedClient : : handleCommandServerGroupAutoDelPerm ( ts : : Command & cmd ) {
CMD_RESET_IDLE ;
CMD_CHK_AND_INC_FLOOD_POINTS ( 25 ) ;
auto ref_server = this - > server ;
auto group_manager = ref_server ? this - > server - > groups : & * serverInstance - > getGroupManager ( ) ;
deque < shared_ptr < Group > > groups ;
for ( const auto & group : group_manager - > availableGroups ( false ) ) {
if ( group - > updateType ( ) = = cmd [ " sgtype " ] . as < permission : : PermissionValue > ( ) & & group - > target ( ) = = GROUPTARGET_SERVER ) {
if ( group - > permission_granted ( permission : : i_server_group_needed_modify_power , this - > calculate_permission ( permission : : i_server_group_modify_power , 0 ) , true ) ) {
auto type = group - > type ( ) ;
if ( type = = GroupType : : GROUP_TYPE_QUERY ) {
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_querygroup , 0 ) ) )
continue ;
} else if ( type = = GroupType : : GROUP_TYPE_TEMPLATE ) {
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_serverinstance_modify_templates , 0 ) ) )
continue ;
}
groups . push_back ( group ) ; //sgtype
}
}
}
if ( groups . empty ( ) ) return command_result { error : : ok } ;
2020-05-07 15:28:15 -04:00
command : : bulk_parser : : PermissionBulksParser < false > pparser { cmd } ;
if ( ! pparser . validate ( this - > ref ( ) , 0 ) )
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
bool update_clients { false } , update_server_group_list { false } ;
for ( const auto & ppermission : pparser . iterate_valid_permissions ( ) ) {
2020-06-28 08:01:14 -04:00
for ( const auto & serverGroup : groups ) {
2020-05-07 15:28:15 -04:00
ppermission . apply_to ( serverGroup - > permissions ( ) , permission : : v2 : : PermissionUpdateType : : delete_value ) ;
2020-06-28 08:01:14 -04:00
ppermission . log_update ( serverInstance - > action_logger ( ) - > permission_logger ,
this - > getServerId ( ) ,
this - > ref ( ) ,
log : : PermissionTarget : : SERVER_GROUP ,
permission : : v2 : : PermissionUpdateType : : delete_value ,
serverGroup - > groupId ( ) , serverGroup - > name ( ) ,
0 , " "
) ;
}
2020-01-26 08:21:34 -05:00
2020-05-07 15:28:15 -04:00
update_server_group_list | = ppermission . is_group_property ( ) ;
update_clients | = ppermission . is_client_view_property ( ) ;
2020-01-26 08:21:34 -05:00
}
2020-05-07 15:28:15 -04:00
if ( update_server_group_list ) {
2020-01-26 08:21:34 -05:00
for ( auto & group : groups )
group - > apply_properties_from_permissions ( ) ;
}
if ( ref_server ) {
auto lock = this - > _this . lock ( ) ;
2020-05-07 15:28:15 -04:00
threads : : Thread ( [ update_clients , update_server_group_list , groups , lock , ref_server ] ( ) {
if ( update_server_group_list )
2020-01-26 08:21:34 -05:00
ref_server - > forEachClient ( [ ] ( shared_ptr < ConnectedClient > cl ) {
cl - > notifyServerGroupList ( ) ;
} ) ;
2020-05-07 15:28:15 -04:00
ref_server - > forEachClient ( [ groups , update_clients ] ( shared_ptr < ConnectedClient > cl ) {
2020-01-26 08:21:34 -05:00
for ( const auto & serverGroup : groups ) {
if ( cl - > serverGroupAssigned ( serverGroup ) ) {
if ( cl - > update_cached_permissions ( ) ) /* update cached calculated permissions */
cl - > sendNeededPermissions ( false ) ; /* cached permissions had changed, notify the client */
2020-05-07 15:28:15 -04:00
if ( update_clients )
2020-01-26 08:21:34 -05:00
cl - > updateChannelClientProperties ( true , true ) ;
cl - > join_state_id + + ; /* join permission may changed, all channels need to be recalculate dif needed */
break ;
}
}
} ) ;
} ) . detach ( ) ;
}
2020-05-07 15:28:15 -04:00
return pparser . build_command_result ( ) ;
2020-01-26 08:21:34 -05:00
}
command_result ConnectedClient : : handleCommandServerGroupsByClientId ( Command & cmd ) {
CMD_RESET_IDLE ;
ClientDbId cldbid = cmd [ " cldbid " ] ;
if ( ! serverInstance - > databaseHelper ( ) - > validClientDatabaseId ( this - > server , cldbid ) ) return command_result { error : : client_invalid_id } ;
Command result ( this - > getExternalType ( ) = = CLIENT_TEAMSPEAK ? " notifyservergroupsbyclientid " : " " ) ;
int index = 0 ;
if ( this - > server ) {
for ( const auto & group : this - > server - > groups - > getAssignedServerGroups ( cldbid ) ) {
result [ index ] [ " name " ] = group - > group - > name ( ) ;
result [ index ] [ " sgid " ] = group - > group - > groupId ( ) ;
result [ index ] [ " cldbid " ] = cldbid ;
index + + ;
}
} else {
for ( const auto & group : serverInstance - > getGroupManager ( ) - > getAssignedServerGroups ( cldbid ) ) {
result [ index ] [ " name " ] = group - > group - > name ( ) ;
result [ index ] [ " sgid " ] = group - > group - > groupId ( ) ;
result [ index ] [ " cldbid " ] = cldbid ;
index + + ;
}
}
if ( index = = 0 ) return command_result { error : : database_empty_result } ;
this - > sendCommand ( result ) ;
return command_result { error : : ok } ;
}