# destruction\r
# * <code>user destroy _botuser_ _password_</code> would actually destroy\r
# _botuser_ if it was queued and the _password_ is correct\r
-# * user destruction can be done without changing botuser.rb by getting the\r
-# save_array for @bot.auth, manipulating it, and reloading it with @bot.auth.load_array\r
# * user copy\r
# * user rename\r
#\r
+# It should be fairly easy to implement all of this stuff by using\r
+# @bot.auth.load_array and @bot.auth.save_array: this means it can be tested\r
+# live and without any need to touch the rbot kernel file +botuser.rb+\r
+#\r
\r
\r
class AuthModule < CoreBotModule\r
return "user create <name> <password> : create botuser named <name> with password <password>. The password can be omitted, in which case a random one will be generated. The <name> should only contain alphanumeric characters and the underscore (_)"\r
when /^user list/\r
return "user list : lists all the botusers"\r
+ when /^user destroy/\r
+ return "user destroy <botuser> <password> : destroys <botuser>; this function #{Bold}must#{Bold} be called in two steps. On the first call, no password must be specified: <botuser> is then queued for destruction. On the second call, you must specify the correct password for <botuser>, and it will be destroyed. If you want to cancel the destruction, issue the command +user cancel destroy <botuser>+"\r
when /^user/\r
- return "user show, enable|disable, add|rm netmask, set, reset, tell, create, list"\r
+ return "user show, enable|disable, add|rm netmask, set, reset, tell, create, list, destroy"\r
else\r
return "#{name}: login, whoami, permission syntax, permissions, user"\r
end\r
def auth_list_users(m, params)\r
# TODO name regexp to filter results\r
list = @bot.auth.save_array.inject([]) { |list, x| list << x[:username] } - ['everyone', 'owner']\r
+ if defined?(@destroy_q)\r
+ list.map! { |x|\r
+ @destroy_q.include?(x) ? x + " (queued for destruction)" : x\r
+ }\r
+ end\r
return m.reply "I have no botusers other than the default ones" if list.empty?\r
return m.reply "Botuser#{'s' if list.length > 1}: #{list.join(', ')}"\r
end\r
\r
+ def auth_destroy_user(m, params)\r
+ @destroy_q = [] unless defined?(@destroy_q)\r
+ buname = params[:name]\r
+ returm m.reply "You can't destroy #{buname}" if ["everyone", "owner"].include?(buname)\r
+ cancel = m.message.split[1] == 'cancel'\r
+ password = params[:password]\r
+ buser_array = @bot.auth.save_array\r
+ buser_hash = buser_array.inject({}) { |h, u|\r
+ h[u[:username]] = u\r
+ h\r
+ }\r
+\r
+ return m.reply "No such botuser #{buname}" unless buser_hash.keys.include?(buname)\r
+\r
+ if cancel\r
+ if @destroy_q.include?(buname)\r
+ @destroy_q.delete(buname)\r
+ m.reply "#{buname} removed from the destruction queue"\r
+ else\r
+ m.reply "#{buname} was not queued for destruction"\r
+ end\r
+ return\r
+ end\r
+\r
+ if password.nil?\r
+ if @destroy_q.include?(buname)\r
+ rep = "#{buname} already queued for destruction"\r
+ else\r
+ @destroy_q << buname\r
+ rep = "#{buname} queued for destruction"\r
+ end\r
+ return m.reply rep + ", use #{Bold}user destroy #{buname} <password>#{Bold} to destroy it"\r
+ else\r
+ begin\r
+ return m.reply "#{buname} is not queued for destruction yet" unless @destroy_q.include?(buname)\r
+ return m.reply "wrong password for #{buname}" unless buser_hash[buname][:password] == password\r
+ buser_array.delete_if { |u|\r
+ u[:username] == buname\r
+ }\r
+ @destroy_q.delete(buname)\r
+ @bot.auth.load_array(buser_array, true)\r
+ rescue => e\r
+ return m.reply "failed: #{e}"\r
+ end\r
+ return m.reply "user #{buname} destroyed"\r
+ end\r
+\r
+ end\r
+\r
end\r
\r
auth = AuthModule.new\r
\r
-auth.map "user tell :user the password for :botuser",\r
- :action => 'auth_tell_password',\r
- :auth_path => 'user::tell'\r
-\r
auth.map "user create :name :password",\r
:action => 'auth_create_user',\r
:defaults => {:password => nil},\r
- :auth_path => 'user::create!'\r
+ :auth_path => 'user::manage::create!'\r
+\r
+auth.map "user cancel destroy :name :password",\r
+ :action => 'auth_destroy_user',\r
+ :defaults => { :password => nil },\r
+ :auth_path => 'user::manage::destroy::cancel!'\r
+\r
+auth.map "user destroy :name :password",\r
+ :action => 'auth_destroy_user',\r
+ :defaults => { :password => nil },\r
+ :auth_path => 'user::manage::destroy!'\r
+\r
+auth.default_auth("user::manage", false)\r
+\r
+auth.map "user tell :user the password for :botuser",\r
+ :action => 'auth_tell_password',\r
+ :auth_path => 'user::tell'\r
\r
auth.map "user list",\r
:action => 'auth_list_users',\r