#-- vim:sw=2:et\r
#++\r
-\r
+#\r
+# :title: rbot auth management from IRC\r
+#\r
+# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>\r
+# Copyright:: (C) 2006,2007 Giuseppe Bilotta\r
+# License:: GPL v2\r
\r
class AuthModule < CoreBotModule\r
\r
splits = params[:args]\r
\r
has_for = splits[-2] == "for"\r
- return usage unless has_for\r
+ return usage(m) unless has_for\r
\r
begin\r
user = @bot.auth.get_botuser(splits[-1].sub(/^all$/,"everyone"))\r
\r
def auth_view_perm(m, params)\r
begin\r
- user = @bot.auth.get_botuser(params[:user].sub(/^all$/,"everyone"))\r
+ if params[:user].nil?\r
+ user = get_botusername_for(m.source)\r
+ return m.reply("you are owner, you can do anything") if user == @bot.auth.botwoner\r
+ else\r
+ user = @bot.auth.get_botuser(params[:user].sub(/^all$/,"everyone"))\r
+ return m.reply("owner can do anything") if user.username == "owner" \r
+ end\r
rescue\r
return m.reply("couldn't find botuser #{params[:user]}")\r
end\r
"welcome, #{get_botusername_for(user)}"\r
end\r
\r
+ def auth_auth(m, params)\r
+ params[:botuser] = 'owner'\r
+ auth_login(m,params)\r
+ end\r
+\r
def auth_login(m, params)\r
begin\r
case @bot.auth.login(m.source, params[:botuser], params[:password])\r
m.reply rep\r
end\r
\r
- def help(plugin, topic="")\r
- case topic\r
- when /^login/\r
+ def help(cmd, topic="")\r
+ case cmd\r
+ when "login"\r
return "login [<botuser>] [<pass>]: logs in to the bot as botuser <botuser> with password <pass>. When using the full form, you must contact the bot in private. <pass> can be omitted if <botuser> allows login-by-mask and your netmask is among the known ones. if <botuser> is omitted too autologin will be attempted"\r
- when /^whoami/\r
+ when "whoami"\r
return "whoami: names the botuser you're linked to"\r
- when /^permission syntax/\r
- return "a permission is specified as module::path::to::cmd; when you want to enable it, prefix it with +; when you want to disable it, prefix it with -; when using the +reset+ command, do not use any prefix"\r
when /^permission/\r
- return "permissions (re)set <permission> [in <channel>] for <user>: sets or resets the permissions for botuser <user> in channel <channel> (use ? to change the permissions for private addressing)"\r
- when /^user show/\r
- return "user show <what> : shows info about the user; <what> can be any of autologin, login-by-mask, netmasks"\r
- when /^user (en|dis)able/\r
- return "user enable|disable <what> : turns on or off <what> (autologin, login-by-mask)"\r
- when /^user set/\r
- return "user set password <blah> : sets the user password to <blah>; passwords can only contain upper and lowercase letters and numbers, and must be at least 4 characters long"\r
- when /^user (add|rm)/\r
- return "user add|rm netmask <mask> : adds/removes netmask <mask> from the list of netmasks known to the botuser you're linked to"\r
- when /^user reset/\r
- return "user reset <what> : resets <what> to the default values. <what> can be +netmasks+ (the list will be emptied), +autologin+ or +login-by-mask+ (will be reset to the default value) or +password+ (a new one will be generated and you'll be told in private)"\r
- when /^user tell/\r
- return "user tell <who> the password for <botuser> : contacts <who> in private to tell him/her the password for <botuser>"\r
- when /^user create/\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, destroy"\r
+ case topic\r
+ when "syntax"\r
+ return "a permission is specified as module::path::to::cmd; when you want to enable it, prefix it with +; when you want to disable it, prefix it with -; when using the +reset+ command, do not use any prefix"\r
+ when "set", "reset", "[re]set", "(re)set"\r
+ return "permissions [re]set <permission> [in <channel>] for <user>: sets or resets the permissions for botuser <user> in channel <channel> (use ? to change the permissions for private addressing)"\r
+ when "view"\r
+ return "permissions view [for <user>]: display the permissions for user <user>"\r
+ else\r
+ return "topics: syntax, (re)set, view"\r
+ end\r
+ when "user"\r
+ case topic\r
+ when "show"\r
+ return "user show <what> : shows info about the user; <what> can be any of autologin, login-by-mask, netmasks"\r
+ when /^(en|dis)able/\r
+ return "user enable|disable <what> : turns on or off <what> (autologin, login-by-mask)"\r
+ when "set"\r
+ return "user set password <blah> : sets the user password to <blah>; passwords can only contain upper and lowercase letters and numbers, and must be at least 4 characters long"\r
+ when "add", "rm"\r
+ return "user add|rm netmask <mask> : adds/removes netmask <mask> from the list of netmasks known to the botuser you're linked to"\r
+ when "reset"\r
+ return "user reset <what> : resets <what> to the default values. <what> can be +netmasks+ (the list will be emptied), +autologin+ or +login-by-mask+ (will be reset to the default value) or +password+ (a new one will be generated and you'll be told in private)"\r
+ when "tell"\r
+ return "user tell <who> the password for <botuser> : contacts <who> in private to tell him/her the password for <botuser>"\r
+ when "create"\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 "list"\r
+ return "user list : lists all the botusers"\r
+ when "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
+ else\r
+ return "user show, enable|disable, add|rm netmask, set, reset, tell, create, list, destroy"\r
+ end\r
else\r
- return "#{name}: login, whoami, permission syntax, permissions, user"\r
+ return "#{name}: login, whoami, permission syntax, permissions [re]set, permissions view, user"\r
end\r
end\r
\r
\r
has_to = what[-2] == "to"\r
if has_to\r
- exportfile = what[-1]\r
+ exportfile = "#{@bot.botclass}/#{what[-1]}"\r
what.slice!(-2,2)\r
end\r
\r
\r
m.reply "exporting to #{exportfile} ..."\r
begin\r
+ # m.reply yaml_hash.inspect\r
File.open(exportfile, "w") do |file|\r
file.puts YAML::dump(yaml_hash)\r
end\r
m.reply "done"\r
end\r
\r
+ def auth_import(m, params)\r
+\r
+ importfile = "#{@bot.botclass}/new-auth.users"\r
+\r
+ what = params[:things]\r
+\r
+ has_from = what[-2] == "from"\r
+ if has_from\r
+ importfile = "#{@bot.botclass}/#{what[-1]}"\r
+ what.slice!(-2,2)\r
+ end\r
+\r
+ what.delete("all")\r
+\r
+ m.reply "reading #{importfile} ..."\r
+ begin\r
+ yaml_hash = YAML::load_file(importfile)\r
+ rescue => e\r
+ m.reply "failed to import from: #{e}"\r
+ debug e.backtrace.dup.unshift(e.inspect).join("\n")\r
+ return\r
+ end\r
+\r
+ # m.reply yaml_hash.inspect\r
+\r
+ m.reply "selecting data to import ..."\r
+\r
+ if what.empty?\r
+ we_want = yaml_hash\r
+ else\r
+ we_want = yaml_hash.delete_if { |key, val|\r
+ not what.include?(key)\r
+ }\r
+ end\r
+\r
+ m.reply "parsing data from import ..."\r
+\r
+ buser_hash = {}\r
+\r
+ begin\r
+ yaml_hash.each { |k, val|\r
+ buser_hash[k] = { :username => k }\r
+ val.each { |kk, v|\r
+ case kk\r
+ when :netmasks\r
+ buser_hash[k][kk] = []\r
+ v.each { |nm|\r
+ buser_hash[k][kk] << nm[:fullform].to_irc_netmask(:casemap => nm[:casemap].to_irc_casemap).to_irc_netmask(:server => @bot.server)\r
+ }\r
+ else\r
+ buser_hash[k][kk] = v\r
+ end\r
+ }\r
+ }\r
+ rescue => e\r
+ m.reply "failed to parse data: #{e}"\r
+ debug e.backtrace.dup.unshift(e.inspect).join("\n")\r
+ return\r
+ end\r
+\r
+ # m.reply buser_hash.inspect\r
+\r
+ org_buser_array = @bot.auth.save_array\r
+ org_buser_hash = org_buser_array.inject({}) { |h, u|\r
+ h[u[:username]] = u\r
+ h\r
+ }\r
+\r
+ # TODO we may want to do a(n optional) key-by-key merge\r
+ #\r
+ org_buser_hash.merge!(buser_hash)\r
+ new_buser_array = org_buser_hash.values\r
+ @bot.auth.load_array(new_buser_array, true)\r
+ @bot.auth.set_changed\r
+\r
+ m.reply "done"\r
+ end\r
+\r
end\r
\r
auth = AuthModule.new\r
:defaults => { :things => ['all'] },\r
:auth_path => ':manage:fedex:'\r
\r
-# auth.map "user import",\r
-# :action => 'auth_import',\r
-# :auth_path => ':manage:fedex:'\r
+auth.map "user import *things",\r
+ :action => 'auth_import',\r
+ :auth_path => ':manage:fedex:'\r
\r
auth.map "user create :name :password",\r
:action => 'auth_create_user',\r
:defaults => {:password => nil},\r
:auth_path => ':manage:'\r
\r
-auth.map "user cancel destroy :name :password",\r
+auth.map "user [cancel] destroy :name :password",\r
:action => 'auth_destroy_user',\r
:defaults => { :password => nil },\r
:auth_path => ':manage::destroy:'\r
\r
-auth.map "user destroy :name :password",\r
- :action => 'auth_destroy_user',\r
- :defaults => { :password => nil },\r
- :auth_path => ':manage:'\r
-\r
-auth.map "user copy :source :dest",\r
+auth.map "user copy :source [to] :dest",\r
:action => 'auth_copy_ren_user',\r
:auth_path => ':manage:'\r
\r
-auth.map "user rename :source :dest",\r
+auth.map "user rename :source [to] :dest",\r
:action => 'auth_copy_ren_user',\r
:auth_path => ':manage:'\r
\r
:action => 'auth_whoami',\r
:auth_path => '!*!'\r
\r
+auth.map "auth :password",\r
+ :action => 'auth_auth',\r
+ :public => false,\r
+ :auth_path => '!login!'\r
+\r
auth.map "login :botuser :password",\r
:action => 'auth_login',\r
:public => false,\r
:action => 'auth_edit_perm',\r
:auth_path => ':edit::reset:'\r
\r
-auth.map "permissions view for :user",\r
+auth.map "permissions view [for :user]",\r
:action => 'auth_view_perm',\r
:auth_path => '::'\r
\r