]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/nickserv.rb
chucknorris: read gzip stream before passing it to YAML.load
[user/henk/code/ruby/rbot.git] / 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   Config.register Config::StringValue.new('nickserv.name',
25     :default => "nickserv", :requires_restart => false,
26     :desc => _("Name of the nick server (all lowercase)"))
27
28   Config.register Config::StringValue.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   Config.register Config::StringValue.new('nickserv.nick_avail',
33     :default => "not (currently )?online|killed|ghosted|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   Config.register Config::StringValue.new('nickserv.identified_string',
38     :default => "((Password|Contrase|Mot de passe).+(acce[pt]t|r[ie]cog?n).+)?(you|tu|vous|now|adesso).+(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   Config.register Config::BooleanValue.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   Config.register Config::IntegerValue.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::Bot::Auth.random_password
68   end
69
70   def set_ident_request(val)
71     @ident_request = Regexp.new(val, true)
72   end
73
74   def set_nick_avail(val)
75     @nick_avail = Regexp.new(val, true)
76   end
77
78   def set_identified_string(val)
79     @identified_string = Regexp.new(val, true)
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") % {:ns_nick => ns_nick})
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 %{botnick} :(") % {:botnick => @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 notice(m)
183     return unless m.source.downcase == ns_nick.downcase
184
185     case m.message
186     when @ident_request
187       debug "nickserv asked us to identify for nick #{@bot.nick}"
188       do_identify
189     when @nick_avail
190       debug "our nick seems to be free now"
191       @bot.nickchg @bot.config['irc.nick']
192     when @identified_string
193       debug "we identified successfully to nickserv"
194       @identified = true
195       @bot.plugins.delegate('identified')
196     end
197   end
198
199   def identified?
200     return @identified
201   end
202
203 end
204 plugin = NickServPlugin.new
205 plugin.map 'nickserv password [:nick] :passwd', :action => "password"
206 plugin.map 'nickserv register :passwd :email', :action => 'nick_register',
207            :defaults => {:passwd => false, :email => false}
208 plugin.map 'nickserv listnicks', :action => "listnicks"
209 plugin.map 'nickserv identify', :action => "identify"
210
211 plugin.default_auth('*', false)
212