imdb plugin: character lookup by actor and movie
[rbot] / data / rbot / plugins / nickserv.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Nickserv management plugin for rbot
5 #
6 # Author:: Tom Gilbert (giblet) <tom@linuxbrit.co.uk>
7 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
8 #
9 # Copyright:: (C) 2002-2005 Tom Gilbert
10 # Copyright:: (C) 2006 Tom Gilbert, Giuseppe Bilotta
11 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
12 #
13 # Automatically lookup nicks in @registry and identify when asked
14 #
15 # Takes over proper nick if required and nick is registered
16
17 # TODO:: allow custom IDENTIFY and GHOST names
18 #
19 # FIXME:: identified? status returns false after a rescan, even if the bot
20 #         previously identified successfully
21
22 class NickServPlugin < Plugin
23   
24   BotConfig.register BotConfigStringValue.new('nickserv.name',
25     :default => "nickserv", :requires_restart => false,
26     :desc => "Name of the nick server (all lowercase)")
27
28   BotConfig.register BotConfigStringValue.new('nickserv.ident_request',
29     :default => "IDENTIFY", :requires_restart => false,
30     :on_change => Proc.new { |bot, v| bot.plugins.delegate "set_ident_request", v },
31     :desc => "String to look for to see if the nick server is asking us to identify")
32   BotConfig.register BotConfigStringValue.new('nickserv.nick_avail',
33     :default => "not (currently )?online|killed|recovered|disconnesso|libero",
34     :requires_restart => false,
35     :on_change => Proc.new { |bot, v| bot.plugins.delegate "set_nick_avail", v },
36     :desc => "String to look for to see if the nick server is informing us that our nick is now available")
37   BotConfig.register BotConfigStringValue.new('nickserv.identified_string',
38     :default => "(Password|Contrase|Mot de passe).+(acce[pt]t|r[ie]cog?n).+(identif|r[ie]cog?n)",
39     :requires_restart => false,
40     :on_change => Proc.new { |bot, v| bot.plugins.delegate "set_identified_string", v },
41     :desc => "String to look for to see if the nick server is informing us that we have identified successfully")
42
43   BotConfig.register BotConfigBooleanValue.new('nickserv.wants_nick',
44     :default => false, :requires_restart => false,
45     :desc => "Set to false if the nick server doesn't expect the nick as a parameter in the identify command")
46
47   BotConfig.register BotConfigIntegerValue.new('nickserv.wait',
48     :default => 30, :validate => Proc.new { |v| v > 0 }, :requires_restart => false,
49     :desc => "Seconds to wait after sending a message to nickserv, e.g. after ghosting")
50
51   def help(plugin, topic="")
52     case topic
53     when ""
54       return "nickserv plugin: handles nickserv protected IRC nicks. topics password, register, identify, listnicks"
55     when "password"
56       return "nickserv password [<nick>] <passwd>: remember the password for nick <nick> and use it to identify in future"
57     when "register"
58       return "nickserv register [<password> [<email>]]: register the current nick, choosing a random password unless <password> is supplied - current nick must not already be registered for this to work. Also specify email if required by your services"
59     when "identify"
60       return "nickserv identify: identify with nickserv - shouldn't be needed - bot should identify with nickserv immediately on request - however this could be useful after splits or service disruptions, or when you just set the password for the current nick"
61     when "listnicks"
62       return "nickserv listnicks: lists nicknames and associated password the bot knows about - you will need config level auth access to do this one and it will reply by privmsg only"
63     end
64   end
65   
66   def genpasswd
67     return Irc::Auth.random_password
68   end
69
70   def set_ident_request(val)
71     @ident_request = Regexp.new(val)
72   end
73
74   def set_nick_avail(val)
75     @nick_avail = Regexp.new(val)
76   end
77
78   def set_identified_string(val)
79     @identified_string = Regexp.new(val)
80   end
81
82   def initialize
83     super
84     # this plugin only wants to store strings!
85     class << @registry
86       def store(val)
87         val
88       end
89       def restore(val)
90         val
91       end
92     end
93     set_ident_request(@bot.config['nickserv.ident_request'])
94     set_nick_avail(@bot.config['nickserv.nick_avail'])
95     set_identified_string(@bot.config['nickserv.identified_string'])
96     @identified = false
97   end
98
99   # Returns the nickserv name
100   def ns_nick
101     @bot.config['nickserv.name']
102   end
103
104   # say something to nickserv
105   def ns_say(msg)
106     @bot.say ns_nick, msg
107   end
108
109   def password(m, params)
110     nick = params[:nick] || @bot.nick
111     passwd = params[:passwd]
112     if nick == @bot.nick
113       ns_say "SET PASSWORD #{passwd}"
114     else
115       m.reply "I'm only changing this in my database, I won't inform #{ns_nick} of the change"
116     end
117     @registry[nick] = passwd
118     m.okay
119   end
120
121   def nick_register(m, params)
122     passwd = params[:passwd] ? params[:passwd] : genpasswd
123     message = "REGISTER #{passwd}"
124     message += " #{params[:email]}" if params[:email]
125     ns_say message
126     @registry[@bot.nick] = passwd
127     m.okay
128   end
129
130   def listnicks(m, params)
131     if @registry.length > 0
132       @registry.each {|k,v|
133         @bot.say m.sourcenick, "#{k} => #{v}"
134       }
135     else
136       m.reply "none known"
137     end
138   end
139
140   def do_identify(nick=@bot.nick)
141     if @registry.has_key?(nick)
142       if @bot.config['nickserv.wants_nick']
143         ns_say "IDENTIFY #{nick} #{@registry[nick]}"
144       else
145         if nick == @bot.nick
146           ns_say "IDENTIFY #{@registry[nick]}"
147         else
148           # We cannot identify for different nicks if we can't use the nickname ...
149           return false
150         end
151       end
152       return true
153     end
154     return nil
155   end
156
157   def identify(m, params)
158     ided = do_identify
159     case ided
160     when true
161       m.okay
162     when false
163       m.reply "I cannot identify for a this nick"
164     when nil
165       m.reply "I dunno the nickserv password for the nickname #{@bot.nick} :("
166     else
167       m.reply "uh ... something went wrong ..."
168     end
169   end
170   
171   def connect
172     @identified = false
173     do_identify
174   end
175   
176   def nicktaken(nick)
177     if @registry.has_key?(nick)
178       ns_say "GHOST #{nick} #{@registry[nick]}"
179     end
180   end
181
182   def listen(m)
183     return unless(m.kind_of? NoticeMessage)
184     return unless m.source.downcase == ns_nick.downcase
185
186     case m.message
187     when @ident_request
188       debug "nickserv asked us to identify for nick #{@bot.nick}"
189       do_identify
190     when @nick_avail
191       debug "our nick seems to be free now"
192       @bot.nickchg @bot.config['irc.nick']
193     when @identified_string
194       debug "we identified successfully to nickserv"
195       @identified = true
196       @bot.plugins.delegate('identified')
197     end
198   end
199
200   def identified?
201     return @identified
202   end
203
204 end
205 plugin = NickServPlugin.new
206 plugin.map 'nickserv password [:nick] :passwd', :action => "password"
207 plugin.map 'nickserv register :passwd :email', :action => 'nick_register',
208            :defaults => {:passwd => false, :email => false}
209 plugin.map 'nickserv listnicks', :action => "listnicks"
210 plugin.map 'nickserv identify', :action => "identify"
211
212 plugin.default_auth('*', false)
213