]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/core/auth.rb
New Auth Framework: migrate userdata on permification
[user/henk/code/ruby/rbot.git] / lib / rbot / core / auth.rb
index c6c55aff07be4e3a947e3b18e0af9ba0528654db..d54e8177495c962f6b4aa38185ee12395692ba88 100644 (file)
@@ -110,7 +110,7 @@ class AuthModule < CoreBotModule
     rescue\r
       return m.reply(_("couldn't find botuser %{name}") % {:name => splits[-1]})\r
     end\r
-    return m.reply(_("you can't change permissions for %{username}") % {:username => user.username}) if user == @bot.auth.botowner\r
+    return m.reply(_("you can't change permissions for %{username}") % {:username => user.username}) if user.owner?\r
     splits.slice!(-2,2) if has_for\r
 \r
     cmds, locs, warns = parse_args(splits, setting)\r
@@ -156,10 +156,10 @@ class AuthModule < CoreBotModule
     begin\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
+        return m.reply(_("you are owner, you can do anything")) if user.owner?\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
+        return m.reply(_("owner can do anything")) if user.owner?\r
       end\r
     rescue\r
       return m.reply(_("couldn't find botuser %{name}") % {:name => params[:user]})\r
@@ -225,8 +225,7 @@ class AuthModule < CoreBotModule
 \r
   def auth_autologin(m, params)\r
     u = do_autologin(m.source)\r
-    case u.username\r
-    when 'everyone'\r
+    if u.default?\r
       m.reply _("I couldn't find anything to let you login automatically")\r
     else\r
       m.reply welcome(m.source)\r
@@ -238,10 +237,6 @@ class AuthModule < CoreBotModule
   end\r
 \r
   def auth_whoami(m, params)\r
-    rep = ""\r
-    # if m.public?\r
-    #   rep << m.source.nick << ", "\r
-    # end\r
     m.reply _("you are %{who}") % {\r
       :who => get_botusername_for(m.source).gsub(\r
                 /^everyone$/, _("no one that I know")).gsub(\r
@@ -249,12 +244,27 @@ class AuthModule < CoreBotModule
     }\r
   end\r
 \r
+  def auth_whois(m, params)\r
+    return auth_whoami(m, params) if !m.public?\r
+    u = m.channel.users[params[:user]]\r
+\r
+    return m.reply("I don't see anyone named '#{params[:user]}' here") unless u\r
+\r
+    m.reply _("#{params[:user]} is %{who}") % {\r
+      :who => get_botusername_for(u).gsub(\r
+                /^everyone$/, _("no one that I know")).gsub(\r
+                /^owner$/, _("my boss"))\r
+    }\r
+  end\r
+\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
       return _("whoami: names the botuser you're linked to")\r
+    when "who"\r
+      return _("who is <user>: names the botuser <user> is linked to")\r
     when /^permission/\r
       case topic\r
       when "syntax"\r
@@ -290,9 +300,13 @@ class AuthModule < CoreBotModule
         return _("user topics: show, enable|disable, add|rm netmask, set, reset, tell, create, list, destroy")\r
       end\r
     when "auth"\r
-      return _("auth <masterpassword>: log in as the bot owner; other commands: login, whoami, permission syntax, permissions [re]set, permissions view, user")\r
+      return _("auth <masterpassword>: log in as the bot owner; other commands: login, whoami, permission syntax, permissions [re]set, permissions view, user, meet, hello")\r
+    when "meet"\r
+      return _("meet <nick> [as <user>]: creates a bot user for nick, calling it user (defaults to the nick itself)")\r
+    when "hello"\r
+      return _("hello: creates a bot user for the person issuing the command")\r
     else\r
-      return _("auth commands: auth, login, whoami, permission[s], user")\r
+      return _("auth commands: auth, login, whoami, who, permission[s], user, meet, hello")\r
     end\r
   end\r
 \r
@@ -334,10 +348,12 @@ class AuthModule < CoreBotModule
     butarget = botuser\r
 \r
     has_for = splits[-2] == "for"\r
-    butarget = @bot.auth.get_botuser(splits[-1]) if has_for\r
-    return m.reply(_("you can't mess with %{user}") % {:user => butarget.username}) \\r
-           if butarget == @bot.auth.botowner && botuser != butarget\r
-    splits.slice!(-2,2) if has_for\r
+    if has_for\r
+      butarget = @bot.auth.get_botuser(splits[-1]) rescue nil\r
+      return m.reply(_("no such bot user %{user}") % {:user => splits[-1]}) unless butarget\r
+      splits.slice!(-2,2)\r
+    end\r
+    return m.reply(_("you can't mess with %{user}") % {:user => butarget.username}) if butarget.owner? && botuser != butarget\r
 \r
     bools = [:autologin, :"login-by-mask"]\r
     can_set = [:password]\r
@@ -345,11 +361,12 @@ class AuthModule < CoreBotModule
     can_reset = bools + can_set + can_addrm\r
     can_show = can_reset + ["perms"]\r
 \r
+    begin\r
     case cmd.to_sym\r
 \r
     when :show\r
-      return _("you can't see the properties of %{user}") %\r
-             {:user => butarget.username} if botuser != butarget &&\r
+      return m.reply(_("you can't see the properties of %{user}") %\r
+             {:user => butarget.username}) if botuser != butarget &&\r
                                                !botuser.permit?("auth::show::other")\r
 \r
       case splits[1]\r
@@ -390,7 +407,7 @@ class AuthModule < CoreBotModule
       return m.reply("#{butarget.username} #{str.join('; ')}")\r
 \r
     when :enable, :disable\r
-      return m.reply(_("you can't change the default user")) if butarget == @bot.auth.everyone && !botuser.permit?("auth::edit::other::default")\r
+      return m.reply(_("you can't change the default user")) if butarget.default? && !botuser.permit?("auth::edit::other::default")\r
       return m.reply(_("you can't edit %{user}") % {:user => butarget.username}) if butarget != botuser && !botuser.permit?("auth::edit::other")\r
 \r
       return m.reply(need_args(cmd)) unless splits[1]\r
@@ -418,7 +435,7 @@ class AuthModule < CoreBotModule
 \r
     when :set\r
       return m.reply(_("you can't change the default user")) if\r
-             butarget == @bot.auth.everyone && !botuser.permit?("auth::edit::default")\r
+             butarget.default? && !botuser.permit?("auth::edit::default")\r
       return m.reply(_("you can't edit %{user}") % {:user=>butarget.username}) if\r
              butarget != botuser && !botuser.permit?("auth::edit::other")\r
 \r
@@ -436,7 +453,7 @@ class AuthModule < CoreBotModule
 \r
     when :reset\r
       return m.reply(_("you can't change the default user")) if\r
-             butarget == @bot.auth.everyone && !botuser.permit?("auth::edit::default")\r
+             butarget.default? && !botuser.permit?("auth::edit::default")\r
       return m.reply(_("you can't edit %{user}") % {:user=>butarget.username}) if\r
              butarget != botuser && !botuser.permit?("auth::edit::other")\r
 \r
@@ -468,7 +485,7 @@ class AuthModule < CoreBotModule
 \r
     when :add, :rm, :remove, :del, :delete\r
       return m.reply(_("you can't change the default user")) if\r
-             butarget == @bot.auth.everyone && !botuser.permit?("auth::edit::default")\r
+             butarget.default? && !botuser.permit?("auth::edit::default")\r
       return m.reply(_("you can't edit %{user}") % {:user => butarget.username}) if\r
              butarget != botuser && !botuser.permit?("auth::edit::other")\r
 \r
@@ -484,7 +501,9 @@ class AuthModule < CoreBotModule
       splits[2..-1].each { |mask|\r
         begin\r
           butarget.send(method, mask.to_irc_netmask(:server => @bot.server))\r
-        rescue\r
+        rescue => e\r
+          debug "failed with #{e.message}"\r
+          debug e.backtrace.join("\n")\r
           failed << mask\r
         end\r
       }\r
@@ -495,6 +514,47 @@ class AuthModule < CoreBotModule
     else\r
       m.reply _("sorry, I don't know how to %{request}") % {:request => m.message}\r
     end\r
+    rescue => e\r
+      m.reply _("couldn't %{cmd}: %{exception}") % {:cmd => cmd, :exception => e}\r
+    end\r
+  end\r
+\r
+  def auth_meet(m, params)\r
+    nick = params[:nick]\r
+    if !nick\r
+      # we are actually responding to a 'hello' command\r
+      unless m.botuser.transient?\r
+        m.reply @bot.lang.get('hello_X') % m.botuser\r
+        return\r
+      end\r
+      nick = m.sourcenick\r
+      irc_user = m.source\r
+    else\r
+      # m.channel is always an Irc::Channel because the command is either\r
+      # public-only 'meet' or private/public 'hello' which was handled by\r
+      # the !nick case, so this shouldn't fail\r
+      irc_user = m.channel.users[nick]\r
+      return m.reply("I don't see anyone named '#{nick}' here") unless irc_user\r
+    end\r
+    # BotUser name\r
+    buname = params[:user] || nick\r
+    begin\r
+      call_event(:botuser,:pre_perm, {:irc_user => irc_user, :bot_user => buname})\r
+      met = @bot.auth.make_permanent(irc_user, buname)\r
+      @bot.auth.set_changed\r
+      call_event(:botuser,:post_perm, {:irc_user => irc_user, :bot_user => buname})\r
+      m.reply @bot.lang.get('hello_X') % met\r
+      @bot.say nick, _("you are now registered as %{buname}. I created a random password for you : %{pass} and you can change it at any time by telling me 'user set password <password>' in private" % {\r
+        :buname => buname,\r
+        :pass => met.password\r
+      })\r
+    rescue RuntimeError\r
+      # or can this happen for other cases too?\r
+      # TODO autologin if forced\r
+      m.reply _("but I already know %{buname}" % {:buname => buname})\r
+    rescue => e\r
+      m.reply _("I had problems meeting %{nick}: %{e}" % { :nick => nick, :e => e })\r
+    end\r
   end\r
 \r
   def auth_tell_password(m, params)\r
@@ -528,7 +588,7 @@ class AuthModule < CoreBotModule
 \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
+    list = @bot.auth.save_array.inject([]) { |list, x| ['everyone', 'owner'].include?(x[:username]) ? list : list << x[:username] }\r
     if defined?(@destroy_q)\r
       list.map! { |x|\r
         @destroy_q.include?(x) ? x + _(" (queued for destruction)") : x\r
@@ -625,13 +685,17 @@ class AuthModule < CoreBotModule
 \r
       @bot.auth.load_array(buser_array, true)\r
       @bot.auth.set_changed\r
+      call_event(:botuser, copying ? :copy : :rename, :source => source, :dest => dest)\r
     rescue => e\r
       return m.reply(_("failed: %{exception}") % {:exception=>e})\r
     end\r
-    return m.reply(_("botuser %{source} copied to %{dest}") %\r
-           {:source=>source, :dest=>dest}) if copying\r
-    return m.reply(_("botuser %{source} renamed to %{dest}") %\r
+    if copying\r
+      m.reply(_("botuser %{source} copied to %{dest}") %\r
            {:source=>source, :dest=>dest})\r
+    else\r
+      m.reply(_("botuser %{source} renamed to %{dest}") %\r
+           {:source=>source, :dest=>dest})\r
+    end\r
 \r
   end\r
 \r
@@ -816,7 +880,16 @@ auth.map "user rename :source [to] :dest",
   :action => 'auth_copy_ren_user',\r
   :auth_path => ':manage:'\r
 \r
+auth.map "meet :nick [as :user]",\r
+  :action => 'auth_meet',\r
+  :auth_path => 'user::manage', :private => false\r
+\r
+auth.map "hello",\r
+  :action => 'auth_meet',\r
+  :auth_path => 'user::manage::meet'\r
+\r
 auth.default_auth("user::manage", false)\r
+auth.default_auth("user::manage::meet::hello", true)\r
 \r
 auth.map "user tell :user the password for :botuser",\r
   :action => 'auth_tell_password',\r
@@ -836,6 +909,10 @@ auth.map "whoami",
   :action => 'auth_whoami',\r
   :auth_path => '!*!'\r
 \r
+auth.map "who is :user",\r
+  :action => 'auth_whois',\r
+  :auth_path => '!*!'\r
+\r
 auth.map "auth :password",\r
   :action => 'auth_auth',\r
   :public => false,\r