]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/core/config.rb
Introduce BotConfigValue permissions, to protect particularly sensitive config option...
[user/henk/code/ruby/rbot.git] / lib / rbot / core / config.rb
1 #-- vim:sw=2:et\r
2 #++\r
3 \r
4 \r
5 class ConfigModule < CoreBotModule\r
6 \r
7   def save\r
8     @bot.config.save\r
9   end\r
10 \r
11   def handle_list(m, params)\r
12     modules = []\r
13     if params[:module]\r
14       @bot.config.items.each_key do |key|\r
15         mod, name = key.to_s.split('.')\r
16         next unless mod == params[:module]\r
17         modules.push key unless modules.include?(name)\r
18       end\r
19       if modules.empty?\r
20         m.reply "no such module #{params[:module]}"\r
21       else\r
22         m.reply modules.join(", ")\r
23       end\r
24     else\r
25       @bot.config.items.each_key do |key|\r
26         name = key.to_s.split('.').first\r
27         modules.push name unless modules.include?(name)\r
28       end\r
29       m.reply "modules: " + modules.join(", ")\r
30     end\r
31   end\r
32 \r
33   def handle_get(m, params)\r
34     key = params[:key].to_s.intern\r
35     unless @bot.config.items.has_key?(key)\r
36       m.reply "no such config key #{key}"\r
37       return\r
38     end\r
39     return if !@bot.auth.allow?(@bot.config.items[key].auth_path, m.source, m.replyto)\r
40     value = @bot.config.items[key].to_s\r
41     m.reply "#{key}: #{value}"\r
42   end\r
43 \r
44   def handle_desc(m, params)\r
45     key = params[:key].to_s.intern\r
46     unless @bot.config.items.has_key?(key)\r
47       m.reply "no such config key #{key}"\r
48     end\r
49     puts @bot.config.items[key].inspect\r
50     m.reply "#{key}: #{@bot.config.items[key].desc}"\r
51   end\r
52 \r
53   def handle_unset(m, params)\r
54     key = params[:key].to_s.intern\r
55     unless @bot.config.items.has_key?(key)\r
56       m.reply "no such config key #{key}"\r
57     end\r
58     return if !@bot.auth.allow?(@bot.config.items[key].auth_path, m.source, m.replyto)\r
59     @bot.config.items[key].unset\r
60     handle_get(m, params)\r
61     m.reply "this config change will take effect on the next restart" if @bot.config.items[key].requires_restart\r
62     m.reply "this config change will take effect on the next rescan" if @bot.config.items[key].requires_rescan\r
63   end\r
64 \r
65   def handle_set(m, params)\r
66     key = params[:key].to_s.intern\r
67     value = params[:value].join(" ")\r
68     unless @bot.config.items.has_key?(key)\r
69       m.reply "no such config key #{key}"\r
70       return\r
71     end\r
72     return if !@bot.auth.allow?(@bot.config.items[key].auth_path, m.source, m.replyto)\r
73     begin\r
74       @bot.config.items[key].set_string(value)\r
75     rescue ArgumentError => e\r
76       m.reply "failed to set #{key}: #{e.message}"\r
77       return\r
78     end\r
79     if @bot.config.items[key].requires_restart\r
80       m.reply "this config change will take effect on the next restart"\r
81     elsif @bot.config.items[key].requires_rescan\r
82       m.reply "this config change will take effect on the next rescan"\r
83     else\r
84       m.okay\r
85     end\r
86   end\r
87 \r
88   def handle_add(m, params)\r
89     key = params[:key].to_s.intern\r
90     value = params[:value]\r
91     unless @bot.config.items.has_key?(key)\r
92       m.reply "no such config key #{key}"\r
93       return\r
94     end\r
95     unless @bot.config.items[key].kind_of?(BotConfigArrayValue)\r
96       m.reply "config key #{key} is not an array"\r
97       return\r
98     end\r
99     return if !@bot.auth.allow?(@bot.config.items[key].auth_path, m.source, m.replyto)\r
100     begin\r
101       @bot.config.items[key].add(value)\r
102     rescue ArgumentError => e\r
103       m.reply "failed to add #{value} to #{key}: #{e.message}"\r
104       return\r
105     end\r
106     handle_get(m,{:key => key})\r
107     m.reply "this config change will take effect on the next restart" if @bot.config.items[key].requires_restart\r
108     m.reply "this config change will take effect on the next rescan" if @bot.config.items[key].requires_rescan\r
109   end\r
110 \r
111   def handle_rm(m, params)\r
112     key = params[:key].to_s.intern\r
113     value = params[:value]\r
114     unless @bot.config.items.has_key?(key)\r
115       m.reply "no such config key #{key}"\r
116       return\r
117     end\r
118     unless @bot.config.items[key].kind_of?(BotConfigArrayValue)\r
119       m.reply "config key #{key} is not an array"\r
120       return\r
121     end\r
122     return if !@bot.auth.allow?(@bot.config.items[key].auth_path, m.source, m.replyto)\r
123     begin\r
124       @bot.config.items[key].rm(value)\r
125     rescue ArgumentError => e\r
126       m.reply "failed to remove #{value} from #{key}: #{e.message}"\r
127       return\r
128     end\r
129     handle_get(m,{:key => key})\r
130     m.reply "this config change will take effect on the next restart" if @bot.config.items[key].requires_restart\r
131     m.reply "this config change will take effect on the next rescan" if @bot.config.items[key].requires_rescan\r
132   end\r
133 \r
134   def bot_save(m, param)\r
135     @bot.save\r
136     m.okay\r
137   end\r
138 \r
139   def bot_rescan(m, param)\r
140     m.reply "saving ..."\r
141     @bot.save\r
142     m.reply "rescanning ..."\r
143     @bot.rescan\r
144     m.reply "done. #{@bot.plugins.status(true)}"\r
145   end\r
146 \r
147   def bot_nick(m, param)\r
148     @bot.nickchg(param[:nick])\r
149   end\r
150 \r
151   def bot_status(m, param)\r
152     m.reply @bot.status\r
153   end\r
154 \r
155   # TODO is this one of the methods that disappeared when the bot was moved\r
156   # from the single-file to the multi-file registry?\r
157   #\r
158   #  def bot_reg_stat(m, param)\r
159   #    m.reply @registry.stat.inspect\r
160   #  end\r
161 \r
162   def bot_version(m, param)\r
163     m.reply  "I'm a v. #{$version} rubybot, (c) Tom Gilbert - http://linuxbrit.co.uk/rbot/"\r
164   end\r
165 \r
166   def handle_help(m, params)\r
167     m.reply help(params[:topic])\r
168   end\r
169 \r
170   def help(plugin, topic="")\r
171     case topic\r
172     when "list"\r
173       "config list => list configuration modules, config list <module> => list configuration keys for module <module>"\r
174     when "get"\r
175       "config get <key> => get configuration value for key <key>"\r
176     when "unset"\r
177       "reset key <key> to the default"\r
178     when "set"\r
179       "config set <key> <value> => set configuration value for key <key> to <value>"\r
180     when "desc"\r
181       "config desc <key> => describe what key <key> configures"\r
182     when "add"\r
183       "config add <value> to <key> => add value <value> to key <key> if <key> is an array"\r
184     when "rm"\r
185       "config rm <value> from <key> => remove value <value> from key <key> if <key> is an array"\r
186     else\r
187       "config module - bot configuration. usage: list, desc, get, set, unset, add, rm"\r
188     # else\r
189     #   "no help for config #{topic}"\r
190     end\r
191   end\r
192 \r
193 end\r
194 \r
195 conf = ConfigModule.new\r
196 \r
197 conf.map 'config list :module',\r
198   :action => 'handle_list',\r
199   :defaults => {:module => false},\r
200   :auth_path => 'show'\r
201 # TODO this one is presently a security risk, since the bot\r
202 # stores the master password in the config. Do we need auth levels\r
203 # on the BotConfig keys too?\r
204 conf.map 'config get :key',\r
205   :action => 'handle_get',\r
206   :auth_path => 'show'\r
207 conf.map 'config desc :key',\r
208   :action => 'handle_desc',\r
209   :auth_path => 'show'\r
210 conf.map 'config describe :key',\r
211   :action => 'handle_desc',\r
212   :auth_path => 'show'\r
213 \r
214 conf.map "save",\r
215   :action => 'bot_save'\r
216 conf.map "rescan",\r
217   :action => 'bot_rescan'\r
218 conf.map "nick :nick",\r
219   :action => 'bot_nick'\r
220 conf.map "status",\r
221   :action => 'bot_status',\r
222   :auth_path => 'show::status'\r
223 # TODO see above\r
224 #\r
225 # conf.map "registry stats",\r
226 #   :action => 'bot_reg_stat',\r
227 #   :auth_path => '!config::status'\r
228 conf.map "version",\r
229   :action => 'bot_version',\r
230   :auth_path => 'show::status'\r
231 \r
232 conf.map 'config set :key *value',\r
233   :action => 'handle_set',\r
234   :auth_path => 'edit'\r
235 conf.map 'config add :value to :key',\r
236   :action => 'handle_add',\r
237   :auth_path => 'edit'\r
238 conf.map 'config rm :value from :key',\r
239   :action => 'handle_rm',\r
240   :auth_path => 'edit'\r
241 conf.map 'config del :value from :key',\r
242   :action => 'handle_rm',\r
243   :auth_path => 'edit'\r
244 conf.map 'config delete :value from :key',\r
245   :action => 'handle_rm',\r
246   :auth_path => 'edit'\r
247 conf.map 'config unset :key',\r
248   :action => 'handle_unset',\r
249   :auth_path => 'edit'\r
250 conf.map 'config reset :key',\r
251   :action => 'handle_unset',\r
252   :auth_path => 'edit'\r
253 \r
254 conf.map 'config help :topic',\r
255   :action => 'handle_help',\r
256   :defaults => {:topic => false},\r
257   :auth_path => '!help!'\r
258 \r
259 conf.default_auth('*', false)\r
260 conf.default_auth('show::status', true)\r
261 # TODO these shouldn't be set here, we need a way to let the default\r
262 # permission be specified together with the BotConfigValue\r
263 conf.default_auth('key', true)\r
264 conf.default_auth('key::auth::password', false)\r
265 \r