mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-28 22:47:59 +01:00
Make DB admin ranks more useful (#29906)
* Make DB admin ranks more useful * Avoid error message when cancelling permission toggle, allow adding localhost admins as real admins. * Lint. * Don't SQL error when a previously-unseen player connects. * Use ckey of permission editor, not mob name. * Strikethrough * Order in the list. * Deadmin, readmin, and 2fa. * Correct merge error --------- Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
@@ -48,41 +48,119 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
|
||||
testing(msg)
|
||||
#endif
|
||||
|
||||
/proc/reload_one_admin(admin_ckey, silent = FALSE)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>Admin reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload an admin via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload an admin via advanced proc-call")
|
||||
return
|
||||
|
||||
// Make sure it's actually in ckey format.
|
||||
admin_ckey = ckey(admin_ckey)
|
||||
|
||||
// Remove any existing permissions.
|
||||
var/datum/admins/admin_datum = GLOB.admin_datums[admin_ckey]
|
||||
if(admin_datum)
|
||||
qdel(admin_datum)
|
||||
|
||||
if(admin_ckey in (GLOB.de_admins + GLOB.de_mentors))
|
||||
if(!silent)
|
||||
message_admins("<span class='notice'>Admin permissions for [admin_ckey] will reload when they re-admin.</span>")
|
||||
return
|
||||
|
||||
if(admin_ckey in GLOB.directory)
|
||||
var/client/admin = GLOB.directory[admin_ckey]
|
||||
var/localhosted = admin.try_localhost_autoadmin()
|
||||
if(localhosted)
|
||||
if(!silent)
|
||||
message_admins("<span class='notice'>Admin permissions for [admin_ckey] reloaded. Full permissions granted as they are currently connected from localhost.</span>")
|
||||
return
|
||||
|
||||
if(GLOB.configuration.admin.use_database_admins)
|
||||
var/datum/db_query/get_admin = SSdbcore.NewQuery({"
|
||||
SELECT
|
||||
-- Use the display_rank if set, otherwise the name of their permissions_rank.
|
||||
IFNULL(admin.display_rank, admin_ranks.name),
|
||||
-- Permissions start with their admin rank permissions (if any)
|
||||
(IFNULL(admin_ranks.default_permissions, 0)
|
||||
-- Then add in any extra permissions they've been granted.
|
||||
| admin.extra_permissions)
|
||||
-- And exclude any permissions they've had removed.
|
||||
& ~admin.removed_permissions
|
||||
FROM admin
|
||||
-- We want all admins, and admin_ranks where available.
|
||||
LEFT OUTER JOIN admin_ranks
|
||||
ON admin.permissions_rank = admin_ranks.id
|
||||
WHERE admin.ckey=:admin_ckey"}, list(
|
||||
"admin_ckey" = admin_ckey
|
||||
))
|
||||
if(!get_admin.warn_execute())
|
||||
qdel(get_admin)
|
||||
return
|
||||
|
||||
if(get_admin.NextRow())
|
||||
var/rank = get_admin.item[1]
|
||||
var/rights = get_admin.item[2]
|
||||
if(rights == 0)
|
||||
// If you have no rights, you don't get an admin datum.
|
||||
qdel(get_admin)
|
||||
if(!silent)
|
||||
message_admins("<span class='notice'>Admin permissions for [admin_ckey] have been reloaded.</span>")
|
||||
return
|
||||
admin_datum = new(rank, rights, admin_ckey)
|
||||
qdel(get_admin)
|
||||
else
|
||||
var/rank = GLOB.configuration.admin.ckey_rank_map[admin_ckey]
|
||||
|
||||
// Load permissions associated with this rank
|
||||
var/rights = GLOB.admin_ranks[rank]
|
||||
|
||||
// Create their admin datum.
|
||||
admin_datum = new /datum/admins(rank, rights, admin_ckey)
|
||||
|
||||
// Set up their permissions.
|
||||
if(admin_datum)
|
||||
admin_datum.associate(GLOB.directory[admin_ckey])
|
||||
|
||||
if(admin_ckey in GLOB.directory)
|
||||
var/client/admin = GLOB.directory[admin_ckey]
|
||||
to_chat(admin, "Holder? [admin.holder] Permissions? [admin.holder?.rights]")
|
||||
if(!silent)
|
||||
message_admins("<span class='notice'>Admin permissions for [admin_ckey] have been reloaded.</span>")
|
||||
|
||||
/proc/load_admins(run_async = FALSE)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>Admin reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload admins via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload admins via advanced proc-call")
|
||||
return
|
||||
//clear the datums references
|
||||
|
||||
// Revoke all permissions.
|
||||
var/list/localhost_admins = list()
|
||||
for(var/datum/admins/admin_datum in GLOB.admin_datums)
|
||||
if(admin_datum.is_localhost_autoadmin && admin_datum.owner)
|
||||
localhost_admins += admin_datum.owner
|
||||
qdel(admin_datum)
|
||||
GLOB.admin_datums.Cut()
|
||||
for(var/client/C in GLOB.admins)
|
||||
C.hide_verbs()
|
||||
C.holder = null
|
||||
GLOB.admins.Cut()
|
||||
|
||||
// Remove all profiler access
|
||||
// Just to be double-sure, revoke all profiler access
|
||||
for(var/A in world.GetConfig("admin"))
|
||||
world.SetConfig("APP/admin", A, null)
|
||||
|
||||
if(!GLOB.configuration.admin.use_database_admins)
|
||||
load_admin_ranks()
|
||||
|
||||
//process each line seperately
|
||||
for(var/iterator_key in GLOB.configuration.admin.ckey_rank_map)
|
||||
var/ckey = ckey(iterator_key) // Snip out formatting
|
||||
var/rank = GLOB.configuration.admin.ckey_rank_map[iterator_key]
|
||||
for(var/ckey in GLOB.configuration.admin.ckey_rank_map)
|
||||
var/rank = GLOB.configuration.admin.ckey_rank_map[ckey]
|
||||
|
||||
//load permissions associated with this rank
|
||||
// Load permissions associated with this rank
|
||||
var/rights = GLOB.admin_ranks[rank]
|
||||
|
||||
//create the admin datum and store it for later use
|
||||
// Create their admin datum.
|
||||
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
||||
|
||||
if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES
|
||||
world.SetConfig("APP/admin", ckey, "role=admin")
|
||||
|
||||
//find the client for a ckey if they are connected and associate them with the new admin datum
|
||||
// Set up their admin permissions.
|
||||
D.associate(GLOB.directory[ckey])
|
||||
|
||||
else
|
||||
@@ -93,34 +171,47 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
|
||||
load_admins()
|
||||
return
|
||||
|
||||
var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, admin_rank, level, flags FROM admin")
|
||||
if(!query.warn_execute(async=run_async))
|
||||
qdel(query)
|
||||
var/datum/db_query/get_admins = SSdbcore.NewQuery({"
|
||||
SELECT
|
||||
admin.ckey,
|
||||
-- Use the display_rank if set, otherwise the name of their permissions_rank.
|
||||
IFNULL(admin.display_rank, admin_ranks.name),
|
||||
-- Permissions start with their admin rank permissions (if any)
|
||||
(IFNULL(admin_ranks.default_permissions, 0)
|
||||
-- Then add in any extra permissions they've been granted.
|
||||
| admin.extra_permissions)
|
||||
-- And exclude any permissions they've had removed.
|
||||
& ~admin.removed_permissions
|
||||
FROM admin
|
||||
-- We want all admins, and admin_ranks where available.
|
||||
LEFT OUTER JOIN admin_ranks
|
||||
ON admin.permissions_rank = admin_ranks.id"})
|
||||
if(!get_admins.warn_execute(async=run_async))
|
||||
qdel(get_admins)
|
||||
return
|
||||
|
||||
while(query.NextRow())
|
||||
var/ckey = query.item[1]
|
||||
var/rank = query.item[2]
|
||||
if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes.
|
||||
|
||||
var/rights = query.item[4]
|
||||
if(istext(rights)) rights = text2num(rights)
|
||||
while(get_admins.NextRow())
|
||||
var/ckey = get_admins.item[1]
|
||||
var/rank = get_admins.item[2]
|
||||
var/rights = get_admins.item[3]
|
||||
if(rights == 0)
|
||||
// If you have no rights, you don't get an admin datum.
|
||||
continue
|
||||
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
|
||||
|
||||
if(D.rights & R_DEBUG || D.rights & R_VIEWRUNTIMES) // Grants profiler access to anyone with R_DEBUG or R_VIEWRUNTIMES
|
||||
world.SetConfig("APP/admin", ckey, "role=admin")
|
||||
|
||||
//find the client for a ckey if they are connected and associate them with the new admin datum
|
||||
// Set up their admin permissions.
|
||||
D.associate(GLOB.directory[ckey])
|
||||
qdel(get_admins)
|
||||
|
||||
qdel(query)
|
||||
|
||||
if(!GLOB.admin_datums)
|
||||
if(!length(GLOB.admin_datums))
|
||||
log_world("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
|
||||
GLOB.configuration.admin.use_database_admins = FALSE
|
||||
load_admins()
|
||||
return
|
||||
|
||||
for(var/client/localhost_admin in localhost_admins)
|
||||
localhost_admin.try_localhost_autoadmin()
|
||||
|
||||
#ifdef TESTING
|
||||
var/msg = "Admins Built:\n"
|
||||
for(var/ckey in GLOB.admin_datums)
|
||||
|
||||
Reference in New Issue
Block a user