Class Irc::Bot::Auth::BotUser
In: lib/rbot/botuser.rb
Parent: Object
BasicUserMessage JoinMessage NamesMessage WhoisMessage ModeChangeMessage KickMessage MotdMessage QuitMessage BanlistMessage UserMessage NoSuchTargetMessage TopicMessage NickMessage WelcomeMessage UnknownMessage InviteMessage PartMessage NetmaskList UserList ArrayOf ChannelList Netmask User\n[lib/rbot/botuser.rb\nlib/rbot/irc.rb] Channel Singleton RfcCasemap StrictRfcCasemap AsciiCasemap Casemap PrivMessage NoticeMessage TokyoCabinet::BDB CIBDB Btree CIBtree Socket MessageQueue QueueRing Client DBHash\n[lib/rbot/registry/bdb.rb\nlib/rbot/registry/tc.rb] DBTree\n[lib/rbot/registry/bdb.rb\nlib/rbot/registry/tc.rb] Server NetmaskDb Bot\n[lib/rbot/botuser.rb\nlib/rbot/config.rb\nlib/rbot/ircbot.rb\nlib/rbot/language.rb\nlib/rbot/message.rb\nlib/rbot/messagemapper.rb\nlib/rbot/plugins.rb\nlib/rbot/rbotconfig.rb\nlib/rbot/registry/bdb.rb\nlib/rbot/registry/tc.rb] lib/rbot/ircsocket.rb lib/rbot/rfc2812.rb lib/rbot/registry/tc.rb lib/rbot/irc.rb lib/rbot/maskdb.rb lib/rbot/message.rb lib/rbot/messagemapper.rb lib/rbot/botuser.rb lib/rbot/registry/tc.rb (null) BotConfig PKGConfig ServerOrCasemap Irc dot/m_35_0.png

This is the basic class for bot users: they have a username, a password, a list of netmasks to match against, and a list of permissions. A BotUser can be marked as ‘transient’, usually meaning it‘s not intended for permanent storage. Transient BotUsers have lower priority than nontransient ones for autologin purposes.

To initialize a BotUser, you pass a username and an optional hash of options. Currently, only two options are recognized:

transient:true or false, determines if the BotUser is transient or permanent (default is false, permanent BotUser).

Transient BotUsers are initialized by prepending an asterisk (*) to the username, and appending a sanitized version of the object_id. The username can be empty. A random password is generated.

Permanent Botusers need the username as is, and no password is generated.

masks:an array of Netmasks to initialize the NetmaskList. This list is used as-is for permanent BotUsers.

Transient BotUsers will alter the list elements which are Irc::User by globbing the nick and any initial nonletter part of the ident.

The masks option is optional for permanent BotUsers, but obligatory (non-empty) for transients.

Methods

Attributes

login_by_mask  [W] 
netmasks  [R] 
password  [R] 
perm  [R] 
perm_temp  [R] 
transient  [W] 
username  [R] 

Public Class methods

Create a new BotUser with given username

[Source]

     # File lib/rbot/botuser.rb, line 284
284:       def initialize(username, options={})
285:         opts = {:transient => false}.merge(options)
286:         @transient = opts[:transient]
287: 
288:         if @transient
289:           @username = "*"
290:           @username << BotUser.sanitize_username(username) if username and not username.to_s.empty?
291:           @username << BotUser.sanitize_username(object_id)
292:           reset_password
293:           @login_by_mask=true
294:           @autologin=true
295:         else
296:           @username = BotUser.sanitize_username(username)
297:           @password = nil
298:           reset_login_by_mask
299:           reset_autologin
300:         end
301: 
302:         @netmasks = NetmaskList.new
303:         if opts.key?(:masks) and opts[:masks]
304:           masks = opts[:masks]
305:           masks = [masks] unless masks.respond_to?(:each)
306:           masks.each { |m|
307:             mask = m.to_irc_netmask
308:             if @transient and User === m
309:               mask.nick = "*"
310:               mask.host = m.host.dup
311:               mask.user = "*" + m.user.sub(/^\w?[^\w]+/,'')
312:             end
313:             add_netmask(mask) unless mask.to_s == "*"
314:           }
315:         end
316:         raise "must provide a usable mask for transient BotUser #{@username}" if @transient and @netmasks.empty?
317: 
318:         @perm = {}
319:         @perm_temp = {}
320:       end

This method sanitizes a username by chomping, downcasing and replacing any nonalphanumeric character with _

[Source]

     # File lib/rbot/botuser.rb, line 518
518:       def BotUser.sanitize_username(name)
519:         candidate = name.to_s.chomp.downcase.gsub(/[^a-z0-9]/,"_")
520:         raise "sanitized botusername #{candidate} too short" if candidate.length < 3
521:         return candidate
522:       end

Public Instance methods

Adds a Netmask

[Source]

     # File lib/rbot/botuser.rb, line 463
463:       def add_netmask(mask)
464:         m = mask.to_irc_netmask
465:         @netmasks << m
466:         if self.autologin?
467:           Auth.manager.maskdb.add(self, m)
468:           Auth.manager.logout_transients(m) if self.permanent?
469:         end
470:       end

[Source]

     # File lib/rbot/botuser.rb, line 245
245:       def autologin=(vnew)
246:         vold = @autologin
247:         @autologin = vnew
248:         if vold && !vnew
249:           @netmasks.each { |n| Auth.manager.maskdb.remove(self, n) }
250:         elsif vnew && !vold
251:           @netmasks.each { |n| Auth.manager.maskdb.add(self, n) }
252:         end
253:       end

Do we allow automatic logging in?

[Source]

     # File lib/rbot/botuser.rb, line 373
373:       def autologin?
374:         @autologin
375:       end

Check if the current BotUser is the default one

[Source]

     # File lib/rbot/botuser.rb, line 636
636:       def default?
637:         return DefaultBotUserClass === self
638:       end

Removes a Netmask

[Source]

     # File lib/rbot/botuser.rb, line 474
474:       def delete_netmask(mask)
475:         m = mask.to_irc_netmask
476:         @netmasks.delete(m)
477:         Auth.manager.maskdb.remove(self, m) if self.autologin?
478:       end

Restore from hash

[Source]

     # File lib/rbot/botuser.rb, line 378
378:       def from_hash(h)
379:         @username = h[:username] if h.has_key?(:username)
380:         @password = h[:password] if h.has_key?(:password)
381:         @login_by_mask = h[:login_by_mask] if h.has_key?(:login_by_mask)
382:         @autologin = h[:autologin] if h.has_key?(:autologin)
383:         if h.has_key?(:netmasks)
384:           @netmasks = h[:netmasks]
385:           debug @netmasks
386:           @netmasks.each { |n| Auth.manager.maskdb.add(self, n) } if @autologin
387:           debug @netmasks
388:         end
389:         @perm = h[:perm] if h.has_key?(:perm)
390:       end

Inspection

[Source]

     # File lib/rbot/botuser.rb, line 323
323:       def inspect
324:         str = self.__to_s__[0..-2]
325:         str << " (transient)" if @transient
326:         str << ":"
327:         str << " @username=#{@username.inspect}"
328:         str << " @netmasks=#{@netmasks.inspect}"
329:         str << " @perm=#{@perm.inspect}"
330:         str << " @perm_temp=#{@perm_temp.inspect}" unless @perm_temp.empty?
331:         str << " @login_by_mask=#{@login_by_mask}"
332:         str << " @autologin=#{@autologin}"
333:         str << ">"
334:       end

This method checks if BotUser has a Netmask that matches user

[Source]

     # File lib/rbot/botuser.rb, line 491
491:       def knows?(usr)
492:         user = usr.to_irc_user
493:         !!@netmasks.find { |n| user.matches? n }
494:       end

This method gets called when User user wants to log in. It returns true or false depending on whether the password is right. If it is, the Netmask of the user is added to the list of acceptable Netmask unless it‘s already matched.

[Source]

     # File lib/rbot/botuser.rb, line 500
500:       def login(user, password=nil)
501:         if password == @password or (password.nil? and (@login_by_mask || @autologin) and knows?(user))
502:           add_netmask(user) unless knows?(user)
503:           debug "#{user} logged in as #{self.inspect}"
504:           return true
505:         else
506:           return false
507:         end
508:       end

Do we allow logging in without providing the password?

[Source]

     # File lib/rbot/botuser.rb, line 355
355:       def login_by_mask?
356:         @login_by_mask
357:       end

Make the BotUser permanent

[Source]

     # File lib/rbot/botuser.rb, line 271
271:       def make_permanent(name)
272:         raise TypeError, "permanent already" if permanent?
273:         @username = BotUser.sanitize_username(name)
274:         @transient = false
275:         reset_autologin
276:         reset_password # or not?
277:         @netmasks.dup.each do |m|
278:           delete_netmask(m)
279:           add_netmask(m.generalize)
280:         end
281:       end

Check if the current BotUser is the owner

[Source]

     # File lib/rbot/botuser.rb, line 641
641:       def owner?
642:         return BotOwnerClass === self
643:       end

This method sets the password if the proposed new password is valid

[Source]

     # File lib/rbot/botuser.rb, line 394
394:       def password=(pwd=nil)
395:         pass = pwd.to_s
396:         if pass.empty?
397:           reset_password
398:         else
399:           begin
400:             raise InvalidPassword, "#{pass} contains invalid characters" if pass !~ /^[\x21-\x7e]+$/
401:             raise InvalidPassword, "#{pass} too short" if pass.length < 4
402:             @password = pass
403:           rescue InvalidPassword => e
404:             raise e
405:           rescue => e
406:             raise InvalidPassword, "Exception #{e.inspect} while checking #{pass.inspect} (#{pwd.inspect})"
407:           end
408:         end
409:       end

Sets if the BotUser is permanent or not

[Source]

     # File lib/rbot/botuser.rb, line 266
266:       def permanent=(bool)
267:         @transient=!bool
268:       end

Checks if the BotUser is permanent (not transient)

[Source]

     # File lib/rbot/botuser.rb, line 261
261:       def permanent?
262:         !@transient
263:       end

Checks if BotUser is allowed to do something on channel chan, or on all channels if chan is nil

[Source]

     # File lib/rbot/botuser.rb, line 447
447:       def permit?(cmd, chan=nil)
448:         if chan
449:           k = chan.to_s.to_sym
450:         else
451:           k = :*
452:         end
453:         allow = nil
454:         pt = @perm.merge @perm_temp
455:         if pt.has_key?(k)
456:           allow = pt[k].permit?(cmd)
457:         end
458:         return allow
459:       end

Reset the autologin option

[Source]

     # File lib/rbot/botuser.rb, line 367
367:       def reset_autologin
368:         @autologin = Auth.manager.bot.config['auth.autologin'] unless defined?(@autologin)
369:       end

Reset the login-by-mask option

[Source]

     # File lib/rbot/botuser.rb, line 361
361:       def reset_login_by_mask
362:         @login_by_mask = Auth.manager.bot.config['auth.login_by_mask'] unless defined?(@login_by_mask)
363:       end

Reset Netmasks, clearing @netmasks

[Source]

     # File lib/rbot/botuser.rb, line 482
482:       def reset_netmasks
483:         @netmasks.each { |m|
484:           Auth.manager.maskdb.remove(self, m) if self.autologin?
485:         }
486:         @netmasks.clear
487:       end

Resets the password by creating a new onw

[Source]

     # File lib/rbot/botuser.rb, line 412
412:       def reset_password
413:         @password = Auth.random_password
414:       end

Resets the permission for command cmd on channel chan

[Source]

     # File lib/rbot/botuser.rb, line 426
426:       def reset_permission(cmd, chan ="*")
427:         set_permission(cmd, nil, chan)
428:       end

Resets the temporary permission for command cmd on channel chan

[Source]

     # File lib/rbot/botuser.rb, line 440
440:       def reset_temp_permission(cmd, chan ="*")
441:         set_temp_permission(cmd, nil, chan)
442:       end

Sets the permission for command cmd to val on channel chan

[Source]

     # File lib/rbot/botuser.rb, line 418
418:       def set_permission(cmd, val, chan="*")
419:         k = chan.to_s.to_sym
420:         @perm[k] = PermissionSet.new unless @perm.has_key?(k)
421:         @perm[k].set_permission(cmd, val)
422:       end

Sets the temporary permission for command cmd to val on channel chan

[Source]

     # File lib/rbot/botuser.rb, line 432
432:       def set_temp_permission(cmd, val, chan="*")
433:         k = chan.to_s.to_sym
434:         @perm_temp[k] = PermissionSet.new unless @perm_temp.has_key?(k)
435:         @perm_temp[k].set_permission(cmd, val)
436:       end

Convert into a hash

[Source]

     # File lib/rbot/botuser.rb, line 342
342:       def to_hash
343:         {
344:           :username => @username,
345:           :password => @password,
346:           :netmasks => @netmasks,
347:           :perm => @perm,
348:           :login_by_mask => @login_by_mask,
349:           :autologin => @autologin,
350:         }
351:       end

In strings

[Source]

     # File lib/rbot/botuser.rb, line 337
337:       def to_s
338:         @username
339:       end

Checks if the BotUser is transient

[Source]

     # File lib/rbot/botuser.rb, line 256
256:       def transient?
257:         @transient
258:       end

[Validate]