- To support the SQL based admin rank system, I added a permission assignment panel, which is accessible to the people who have the PERMISSIONS permission. This panel can be used to add new admins, remove or edit the rank of existing admins.

Screenshot:
http://www.kamletos.si/permissions%20panel.PNG

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4878 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
baloh.matevz
2012-10-14 19:45:21 +00:00
parent 80d18c4b1e
commit 266f163879
9 changed files with 268 additions and 6 deletions

View File

@@ -286,4 +286,22 @@ proc/listclearnulls(list/list)
if(Li <= L.len)
return (result + L.Copy(Li, 0))
return (result + R.Copy(Ri, 0))
return (result + R.Copy(Ri, 0))
//Converts a bitfield to a list of numbers (or words if a wordlist is provided)
/proc/bitfield2list(bitfield = 0, list/wordlist)
var/list/r = list()
if(istype(wordlist,/list))
var/max = min(wordlist.len,16)
var/bit = 1
for(var/i=1, i<=max, i++)
if(bitfield & bit)
r += wordlist[i]
bit = bit << 1
else
for(var/bit=1, bit<=65535, bit = bit << 1)
if(bitfield & bit)
r += bit
return r

View File

@@ -205,3 +205,31 @@ var/forum_authenticated_group = "10"
// For FTP requests. (i.e. downloading runtime logs.)
// However it'd be ok to use for accessing attack logs and such too, which are even laggier.
var/fileaccess_timer = 1800 //Cannot access files by ftp until the game is finished setting up and stuff.
#define BUILDMODE 1
#define ADMIN 2
#define BAN 4
#define FUN 8
#define SERVER 16
#define ADMDEBUG 32
#define POSSESS 64
#define PERMISSIONS 128
//Keep this list synced with the #defines above
var/global/list/permissionwords = list("BUILDMODE", "ADMIN", "BAN", "FUN", "SERVER", "DEBUG", "POSSESS", "EDITPERMISSIONS")
//Please do not edit these values. The database assigning proper rights relies on this. You can add new values, just don't change existing ones.
//This list is separate from the list used ingame, so that one can be edited with little consequence. This one is tied to the database
//The database admins should be consulted before any edits to this list.
#define SQL_BUILDMODE 1
#define SQL_ADMIN 2
#define SQL_BAN 4
#define SQL_FUN 8
#define SQL_SERVER 16
#define SQL_DEBUG 32
#define SQL_POSSESS 64
#define SQL_PERMISSIONS 128
//Same rules apply to this list as to the values above. You can only add stuff to it.
var/global/list/permissionwords_sql = list("BUILDMODE", "ADMIN", "BAN", "FUN", "SERVER", "DEBUG", "POSSESS", "EDITPERMISSIONS")

View File

@@ -40,6 +40,7 @@
if(!need_update) return
clear_admin_verbs()
handle_permission_verbs()
switch(rank)
if("Game Master")

View File

@@ -19,6 +19,7 @@ var/list/admin_datums = list()
var/fakekey = null
var/ooccolor = "#b82e00"
var/sound_adminhelp = 0 //If set to 1 this will play a sound when adminhelps are received.
var/sql_permissions = 0 //Permissions for different admin command groups. Must not be editable ingame.
var/datum/marked_datum
@@ -84,6 +85,49 @@ var/list/admin_datums = list()
usr << "\red Unfortunatly there were no candidates available"
return
if(href_list["editadminpermissions"])
if(!usr.client)
return
var/adm_ckey = href_list["editadminckey"]
if(!adm_ckey)
usr << "\red no valid ckey"
return
if(!usr.client.holder || !(usr.client.holder.sql_permissions & PERMISSIONS))
usr << "\red You do not have permission to do this!"
message_admins("[key_name_admin(usr)] attempted to edit the admin permissions of [adm_ckey] without authentication!")
log_admin("[key_name(usr)] attempted to edit the admin permissions of [adm_ckey] without authentication!")
return
switch(href_list["editadminpermissions"])
if("permissions")
usr << "Currently unavailable since nothing runs off of permissions"
if("rank")
var/new_rank = input("Please, select a rank", "New rank for player", null, null) as null|anything in list("Game Master","Game Admin", "Trial Admin", "Admin Observer")
if(!new_rank)
return
message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin("[key_name(usr)] edited the admin rank of [adm_ckey] to [new_rank]")
log_admin_rank_modification(adm_ckey, new_rank)
if("remove")
if(alert("Are you sure you want to remove [adm_ckey]?","Message","Yes","Cancel") == "Yes")
message_admins("[key_name_admin(usr)] removed [adm_ckey] from the admins list")
log_admin("[key_name(usr)] removed [adm_ckey] from the admins list")
log_admin_rank_modification(adm_ckey, "Removed")
if("add")
var/new_ckey = input(usr,"New admin's ckey","Admin ckey", null) as text|null
if(!new_ckey)
return
var/new_rank = input("Please, select a rank", "New rank for player", null, null) as null|anything in list("Game Master","Game Admin", "Trial Admin", "Admin Observer")
if(!new_rank)
return
message_admins("[key_name_admin(usr)] added [new_ckey] as a new admin to the rank [new_rank]")
log_admin("[key_name(usr)] added [new_ckey] as a new admin to the rank [new_rank]")
log_admin_rank_modification(new_ckey, new_rank)
if(href_list["call_shuttle"])
if (src.rank in list("Trial Admin", "Badmin", "Game Admin", "Game Master"))
if( ticker.mode.name == "blob" )

View File

@@ -0,0 +1,12 @@
//Before this proc is called, the holder variable must already be set, with the proper rank, level and permissions set.
//This proc also DOES NOT CLEAR EXISTING ADMIN VERBS
/client/proc/handle_permission_verbs()
if(!holder || !holder.rank || !holder.sql_permissions)
return
if(holder.sql_permissions & PERMISSIONS)
verbs += /client/proc/edit_admin_permissions

View File

@@ -0,0 +1,127 @@
/client/proc/edit_admin_permissions()
set category = "Admin"
set name = "Permissions Panel"
set desc = "Edit admin permissions"
if(!holder)
return
holder.edit_admin_permissions()
/datum/admins/proc/edit_admin_permissions()
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.sql_permissions & PERMISSIONS))
usr << "\red You do not have permission to do this!"
return
var/user = sqlfdbklogin
var/pass = sqlfdbkpass
var/db = sqlfdbkdb
var/address = sqladdress
var/port = sqlport
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]")
if(!dbcon.IsConnected())
usr << "\red Failed to establish database connection"
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin ORDER BY rank, ckey")
select_query.Execute()
var/output = "<div align='center'><h1>Current admins</h1>"
output += "<a href=\"byond://?src=\ref[src];editadminpermissions=add;editadminckey=none\">Add new admin</a>"
output += "<table width='90%' bgcolor='#e3e3e3' cellpadding='5' cellspacing='0'>"
output += "<tr>"
output += "<th width='125'><b>CKEY</b></th>"
output += "<th width='125'><b>RANK</b></th>"
output += "<th width='25'><b>LEVEL</b></th>"
output += "<th width='75'><b>PERMISSIONS</b></th>"
output += "<th width='150'><b>OPTIONS</b></th>"
output += "</tr>"
var/color1 = "#f4f4f4"
var/color2 = "#e7e7e7"
var/i = 1 //Used to determine the color of each row
while(select_query.NextRow())
i = !i
var/adm_ckey = select_query.item[1]
var/adm_rank = select_query.item[2]
var/adm_level = select_query.item[3]
var/adm_flags = text2num(select_query.item[4])
output += "<tr bgcolor='[(i % 2) ? color1 : color2]'>"
output += "<td align='center'><b>[adm_ckey]</b></td>"
output += "<td align='center'><b>[adm_rank]</b></td>"
output += "<td align='center'>[adm_level]</td>"
var/list/permissionlist = bitfield2list(adm_flags, permissionwords_sql)
output += "<td align='center'>"
for(var/word in permissionlist)
output += "[word]<BR>"
output += "</td>"
output += "<td align='center'><font size='2'>"
//Options
output += "<a href=\"byond://?src=\ref[src];editadminpermissions=permissions;editadminckey=[adm_ckey]\">PERMISSIONS</a><br>"
output += "<a href=\"byond://?src=\ref[src];editadminpermissions=rank;editadminckey=[adm_ckey]\">RANK</a><br>"
output += "<a href=\"byond://?src=\ref[src];editadminpermissions=remove;editadminckey=[adm_ckey]\">REMOVE</a>"
output += "</font></td>"
output += "</tr>"
output += "</table></div>"
usr << browse(output,"window=editadminpermissions;size=600x500")
/datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank)
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.sql_permissions & PERMISSIONS))
usr << "\red You do not have permission to do this!"
return
var/user = sqlfdbklogin
var/pass = sqlfdbkpass
var/db = sqlfdbkdb
var/address = sqladdress
var/port = sqlport
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[db]:[address]:[port]","[user]","[pass]")
if(!dbcon.IsConnected())
usr << "\red Failed to establish database connection"
return
if(!adm_ckey || !new_rank)
return
if(!istext(adm_ckey) || !istext(new_rank))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM erro_admin WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
var/admin_id
while(select_query.NextRow())
new_admin = 0
admin_id = text2num(select_query.item[1])
if(new_admin)
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
usr << "\blue New admin added."
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
usr << "\blue Admin rank changed."

View File

@@ -4,12 +4,14 @@ var/list/forbidden_varedit_object_types = list(
/datum/feedback_variable //Prevents people messing with feedback gathering
)
/*
/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world)
set category = "Debug"
set name = "Edit Variables"
set desc="(target) Edit a target item's variables"
src.modify_variables(O)
feedback_add_details("admin_verb","EDITV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
*/
/client/proc/cmd_modify_ticker_variables()
set category = "Debug"

View File

@@ -189,7 +189,6 @@ Starting up. [time2text(world.timeofday, "hh:mm.ss")]
/world/proc/load_motd()
join_motd = file2text("config/motd.txt")
/world/proc/load_admins()
if(config.admin_legacy_system)
//Legacy admin system uses admins.txt
@@ -228,14 +227,43 @@ Starting up. [time2text(world.timeofday, "hh:mm.ss")]
load_admins()
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level FROM erro_admin")
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin")
query.Execute()
while(query.NextRow())
var/adminckey = query.item[1]
var/adminrank = query.item[2]
var/adminlevel = query.item[3]
if(istext(adminlevel))
adminlevel = text2num(adminlevel)
var/permissions = query.item[4]
if(istext(permissions))
permissions = text2num(permissions)
//This list of stuff translates the permission defines the database uses to the permission structure that the game uses.
var/permissions_actual = 0
if(permissions & SQL_BUILDMODE)
permissions_actual |= BUILDMODE
if(permissions & SQL_ADMIN)
permissions_actual |= ADMIN
if(permissions & SQL_BAN)
permissions_actual |= BAN
if(permissions & SQL_FUN)
permissions_actual |= FUN
if(permissions & SQL_SERVER)
permissions_actual |= SERVER
if(permissions & SQL_DEBUG)
permissions_actual |= ADMDEBUG
if(permissions & SQL_POSSESS)
permissions_actual |= POSSESS
if(permissions & SQL_PERMISSIONS)
permissions_actual |= PERMISSIONS
if(adminrank == "Removed")
return //This person was de-adminned. They are only in the admin list for archive purposes.
var/datum/admins/AD = new /datum/admins(adminrank)
AD.level = adminlevel
AD.level = adminlevel //Legacy support for old verbs
AD.sql_permissions = permissions_actual
admins[adminckey] = AD
if(!admins)
@@ -244,8 +272,6 @@ Starting up. [time2text(world.timeofday, "hh:mm.ss")]
load_admins()
return
/world/proc/load_configuration()
config = new /datum/configuration()
config.load("config/config.txt")

View File

@@ -93,6 +93,7 @@
#define FILE_DIR "code/modules"
#define FILE_DIR "code/modules/admin"
#define FILE_DIR "code/modules/admin/DB ban"
#define FILE_DIR "code/modules/admin/permissionverbs"
#define FILE_DIR "code/modules/admin/verbs"
#define FILE_DIR "code/modules/assembly"
#define FILE_DIR "code/modules/awaymissions"
@@ -205,6 +206,7 @@
#define FILE_DIR "icons/vending_icons"
#define FILE_DIR "interface"
#define FILE_DIR "maps"
#define FILE_DIR "maps/backup"
#define FILE_DIR "maps/RandomZLevels"
#define FILE_DIR "sound"
#define FILE_DIR "sound/AI"
@@ -820,6 +822,8 @@
#include "code\modules\admin\player_panel.dm"
#include "code\modules\admin\ToRban.dm"
#include "code\modules\admin\DB ban\functions.dm"
#include "code\modules\admin\permissionverbs\assignment.dm"
#include "code\modules\admin\permissionverbs\permissionedit.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminjump.dm"
#include "code\modules\admin\verbs\adminpm.dm"