]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/core/auth.rb
9a30dc0a90c9e42a06d4b5afc67300eea4f9476a
[user/henk/code/ruby/rbot.git] / lib / rbot / core / auth.rb
1 #-- vim:sw=2:et\r
2 #++\r
3 \r
4 \r
5 class AuthModule < CoreBotModule\r
6 \r
7   def initialize\r
8     super\r
9     load_array(:default, true)\r
10     debug "Initialized auth. Botusers: #{@bot.auth.save_array.inspect}"\r
11   end\r
12 \r
13   def save\r
14     save_array\r
15   end\r
16 \r
17   def save_array(key=:default)\r
18     if @bot.auth.changed?\r
19       @registry[key] = @bot.auth.save_array\r
20       @bot.auth.reset_changed\r
21       debug "saved botusers (#{key}): #{@registry[key].inspect}"\r
22     end\r
23   end\r
24 \r
25   def load_array(key=:default, forced=false)\r
26     debug "loading botusers (#{key}): #{@registry[key].inspect}"\r
27     @bot.auth.load_array(@registry[key], forced) if @registry.has_key?(key)\r
28   end\r
29 \r
30   # The permission parameters accept arguments with the following syntax:\r
31   #   cmd_path... [on #chan .... | in here | in private]\r
32   # This auxiliary method scans the array _ar_ to see if it matches\r
33   # the given syntax: it expects + or - signs in front of _cmd_path_\r
34   # elements when _setting_ = true\r
35   #\r
36   # It returns an array whose first element is the array of cmd_path,\r
37   # the second element is an array of locations and third an array of\r
38   # warnings occurred while parsing the strings\r
39   #\r
40   def parse_args(ar, setting)\r
41     cmds = []\r
42     locs = []\r
43     warns = []\r
44     doing_cmds = true\r
45     next_must_be_chan = false\r
46     want_more = false\r
47     last_idx = 0\r
48     ar.each_with_index { |x, i|\r
49       if doing_cmds # parse cmd_path\r
50         # check if the list is done\r
51         if x == "on" or x == "in"\r
52           doing_cmds = false\r
53           next_must_be_chan = true if x == "on"\r
54           next\r
55         end\r
56         if "+-".include?(x[0])\r
57           warns << ArgumentError("please do not use + or - in front of command #{x} when resetting") unless setting\r
58         else\r
59           warns << ArgumentError("+ or - expected in front of #{x}") if setting\r
60         end\r
61         cmds << x\r
62       else # parse locations\r
63         if x[-1].chr == ','\r
64           want_more = true\r
65         else\r
66           want_more = false\r
67         end\r
68         case next_must_be_chan\r
69         when false\r
70           locs << x.gsub(/^here$/,'_').gsub(/^private$/,'?')\r
71         else\r
72           warns << ArgumentError("#{x} doesn't look like a channel name") unless @bot.server.supports[:chantypes].include?(x[0])\r
73           locs << x\r
74         end\r
75         unless wants_more\r
76           last_idx = i\r
77           break\r
78         end\r
79       end\r
80     }\r
81     warns << "trailing comma" if wants_more\r
82     warns << "you probably forgot a comma" unless last_idx == ar.length - 1\r
83     return cmds, locs, warns\r
84   end\r
85 \r
86   def auth_set(m, params)\r
87     cmds, locs, warns = parse_args(params[:args])\r
88     errs = warns.select { |w| w.class <= Exception }\r
89     unless errs.empty?\r
90       m.reply "couldn't satisfy your request: #{errs.join(',')}"\r
91       return\r
92     end\r
93     user = params[:user].sub(/^all$/,"everyone")\r
94     begin\r
95       bu = @bot.auth.get_botuser(user)\r
96     rescue\r
97       m.reply "couldn't find botuser #{user}"\r
98       return\r
99     end\r
100     if locs.empty?\r
101       locs << "*"\r
102     end\r
103     begin\r
104       locs.each { |loc|\r
105         ch = loc\r
106         if m.private?\r
107           ch = "?" if loc == "_"\r
108         else\r
109           ch = m.target.to_s if loc == "_"\r
110         end\r
111         cmds.each { |setval|\r
112           val = setval[0].chr == '+'\r
113           cmd = setval[1..-1]\r
114           bu.set_permission(cmd, val, ch)\r
115         }\r
116       }\r
117     rescue => e\r
118       m.reply "Something went wrong while trying to set the permissions"\r
119       raise\r
120     end\r
121     @bot.auth.set_changed\r
122     debug "User #{user} permissions changed"\r
123     m.reply "Ok, #{user} now also has permissions #{params[:args].join(' ')}"\r
124   end\r
125 \r
126   def auth_login(m, params)\r
127     begin\r
128       if params[:password]\r
129         li = @bot.auth.login(m.source, params[:botuser], params[:password])\r
130       else\r
131         li = @bot.auth.login(m.source, params[:botuser], params[:password], true)\r
132       end\r
133       case li\r
134       when true\r
135         m.reply "welcome, #{@bot.auth.irc_to_botuser(m.source).username}"\r
136         @bot.auth.set_changed\r
137       else\r
138         m.reply "sorry, can't do"\r
139       end\r
140     rescue => e\r
141       m.reply "couldn't login: #{e}"\r
142       raise\r
143     end\r
144   end\r
145 \r
146 end\r
147 \r
148 auth = AuthModule.new\r
149 \r
150 auth.map "permissions set *args for :user",\r
151   :action => 'auth_set',\r
152   :auth_path => ':edit::set:'\r
153 \r
154 auth.map "permissions reset *args for :user",\r
155   :action => 'auth_reset',\r
156   :auth_path => ':edit::reset:'\r
157 \r
158 auth.map "login :botuser :password",\r
159   :action => 'auth_login',\r
160   :public => false,\r
161   :defaults => { :password => nil },\r
162   :auth_path => '!login!'\r
163 \r
164 auth.map "login :botuser",\r
165   :action => 'auth_login',\r
166   :defaults => { :password => nil },\r
167   :auth_path => '!login!'\r
168 \r
169 auth.default_auth('*', false)\r
170 \r