You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
6.7 KiB

  1. GLOBAL_LIST_EMPTY(admin_datums)
  2. GLOBAL_PROTECT(admin_datums)
  3. GLOBAL_LIST_EMPTY(protected_admins)
  4. GLOBAL_PROTECT(protected_admins)
  5. GLOBAL_VAR_INIT(href_token, GenerateToken())
  6. GLOBAL_PROTECT(href_token)
  7. /datum/admins
  8. var/datum/admin_rank/rank
  9. var/target
  10. var/name = "nobody's admin datum (no rank)" //Makes for better runtimes
  11. var/client/owner = null
  12. var/fakekey = null
  13. var/datum/marked_datum
  14. var/spamcooldown = 0
  15. var/admincaster_screen = 0 //TODO: remove all these 5 variables, they are completly unacceptable
  16. var/datum/newscaster/feed_message/admincaster_feed_message = new /datum/newscaster/feed_message
  17. var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
  18. var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
  19. var/admin_signature
  20. var/href_token
  21. var/deadmined
  22. /datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected)
  23. if(IsAdminAdvancedProcCall())
  24. var/msg = " has tried to elevate permissions!"
  25. message_admins("[key_name_admin(usr)][msg]")
  26. log_admin("[key_name(usr)][msg]")
  27. if (!target) //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins
  28. QDEL_IN(src, 0)
  29. CRASH("Admin proc call creation of admin datum")
  30. return
  31. if(!ckey)
  32. QDEL_IN(src, 0)
  33. CRASH("Admin datum created without a ckey")
  34. if(!istype(R))
  35. QDEL_IN(src, 0)
  36. CRASH("Admin datum created without a rank")
  37. target = ckey
  38. name = "[ckey]'s admin datum ([R])"
  39. rank = R
  40. admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
  41. href_token = GenerateToken()
  42. if(R.rights & R_DEBUG) //grant profile access
  43. world.SetConfig("APP/admin", ckey, "role=admin")
  44. //only admins with +ADMIN start admined
  45. if(protected)
  46. GLOB.protected_admins[target] = src
  47. if (force_active || (R.rights & R_AUTOADMIN))
  48. activate()
  49. else
  50. deactivate()
  51. /datum/admins/Destroy()
  52. if(IsAdminAdvancedProcCall())
  53. var/msg = " has tried to elevate permissions!"
  54. message_admins("[key_name_admin(usr)][msg]")
  55. log_admin("[key_name(usr)][msg]")
  56. return QDEL_HINT_LETMELIVE
  57. . = ..()
  58. /datum/admins/proc/activate()
  59. if(IsAdminAdvancedProcCall())
  60. var/msg = " has tried to elevate permissions!"
  61. message_admins("[key_name_admin(usr)][msg]")
  62. log_admin("[key_name(usr)][msg]")
  63. return
  64. GLOB.deadmins -= target
  65. GLOB.admin_datums[target] = src
  66. deadmined = FALSE
  67. if (GLOB.directory[target])
  68. associate(GLOB.directory[target]) //find the client for a ckey if they are connected and associate them with us
  69. /datum/admins/proc/deactivate()
  70. if(IsAdminAdvancedProcCall())
  71. var/msg = " has tried to elevate permissions!"
  72. message_admins("[key_name_admin(usr)][msg]")
  73. log_admin("[key_name(usr)][msg]")
  74. return
  75. GLOB.deadmins[target] = src
  76. GLOB.admin_datums -= target
  77. deadmined = TRUE
  78. var/client/C
  79. if ((C = owner) || (C = GLOB.directory[target]))
  80. disassociate()
  81. C.verbs += /client/proc/readmin
  82. /datum/admins/proc/associate(client/C)
  83. if(IsAdminAdvancedProcCall())
  84. var/msg = " has tried to elevate permissions!"
  85. message_admins("[key_name_admin(usr)][msg]")
  86. log_admin("[key_name(usr)][msg]")
  87. return
  88. if(istype(C))
  89. if(C.ckey != target)
  90. var/msg = " has attempted to associate with [target]'s admin datum"
  91. message_admins("[key_name_admin(C)][msg]")
  92. log_admin("[key_name(C)][msg]")
  93. return
  94. if (deadmined)
  95. activate()
  96. owner = C
  97. owner.holder = src
  98. owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system
  99. owner.verbs -= /client/proc/readmin
  100. GLOB.admins |= C
  101. /datum/admins/proc/disassociate()
  102. if(IsAdminAdvancedProcCall())
  103. var/msg = " has tried to elevate permissions!"
  104. message_admins("[key_name_admin(usr)][msg]")
  105. log_admin("[key_name(usr)][msg]")
  106. return
  107. if(owner)
  108. GLOB.admins -= owner
  109. owner.remove_admin_verbs()
  110. owner.holder = null
  111. owner = null
  112. /datum/admins/proc/check_for_rights(rights_required)
  113. if(rights_required && !(rights_required & rank.rights))
  114. return 0
  115. return 1
  116. /datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
  117. if(!other)
  118. return 1 //they have no rights
  119. if(rank.rights == R_EVERYTHING)
  120. return 1 //we have all the rights
  121. if(src == other)
  122. return 1 //you always have more rights than yourself
  123. if(rank.rights != other.rank.rights)
  124. if( (rank.rights & other.rank.rights) == other.rank.rights )
  125. return 1 //we have all the rights they have and more
  126. return 0
  127. /datum/admins/vv_edit_var(var_name, var_value)
  128. return FALSE //nice try trialmin
  129. /*
  130. checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
  131. if rights_required == 0, then it simply checks if they are an admin.
  132. if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
  133. generally it would be used like so:
  134. /proc/admin_proc()
  135. if(!check_rights(R_ADMIN))
  136. return
  137. to_chat(world, "you have enough rights!", confidential = TRUE)
  138. NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call
  139. you will have to do something like if(client.rights & R_ADMIN) yourself.
  140. */
  141. /proc/check_rights(rights_required, show_msg=1)
  142. if(usr && usr.client)
  143. if (check_rights_for(usr.client, rights_required))
  144. return 1
  145. else
  146. if(show_msg)
  147. to_chat(usr, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</font>", confidential = TRUE)
  148. return 0
  149. //probably a bit iffy - will hopefully figure out a better solution
  150. /proc/check_if_greater_rights_than(client/other)
  151. if(usr && usr.client)
  152. if(usr.client.holder)
  153. if(!other || !other.holder)
  154. return 1
  155. return usr.client.holder.check_if_greater_rights_than_holder(other.holder)
  156. return 0
  157. //This proc checks whether subject has at least ONE of the rights specified in rights_required.
  158. /proc/check_rights_for(client/subject, rights_required)
  159. if(subject && subject.holder)
  160. return subject.holder.check_for_rights(rights_required)
  161. return 0
  162. /proc/GenerateToken()
  163. . = ""
  164. for(var/I in 1 to 32)
  165. . += "[rand(10)]"
  166. /proc/RawHrefToken(forceGlobal = FALSE)
  167. var/tok = GLOB.href_token
  168. if(!forceGlobal && usr)
  169. var/client/C = usr.client
  170. if(!C)
  171. CRASH("No client for HrefToken()!")
  172. var/datum/admins/holder = C.holder
  173. if(holder)
  174. tok = holder.href_token
  175. return tok
  176. /proc/HrefToken(forceGlobal = FALSE)
  177. return "admin_token=[RawHrefToken(forceGlobal)]"
  178. /proc/HrefTokenFormField(forceGlobal = FALSE)
  179. return "<input type='hidden' name='admin_token' value='[RawHrefToken(forceGlobal)]'>"