class Irc::Bot::Auth::BotUser

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.

Attributes

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

Public Class Methods

new(username, options={}) click to toggle source

Create a new BotUser with given username

# File lib/rbot/botuser.rb, line 285
def initialize(username, options={})
  opts = {:transient => false}.merge(options)
  @transient = opts[:transient]

  if @transient
    @username = "*"
    @username << BotUser.sanitize_username(username) if username and not username.to_s.empty?
    @username << BotUser.sanitize_username(object_id)
    reset_password
    @login_by_mask=true
    @autologin=true
  else
    @username = BotUser.sanitize_username(username)
    @password = nil
    reset_login_by_mask
    reset_autologin
  end

  @netmasks = NetmaskList.new
  if opts.key?(:masks) and opts[:masks]
    masks = opts[:masks]
    masks = [masks] unless masks.respond_to?(:each)
    masks.each { |m|
      mask = m.to_irc_netmask
      if @transient and User === m
        mask.nick = "*"
        mask.host = m.host.dup
        mask.user = "*" + m.user.sub(/^\w?[^\w]+/,'')
      end
      add_netmask(mask) unless mask.to_s == "*"
    }
  end
  raise "must provide a usable mask for transient BotUser #{@username}" if @transient and @netmasks.empty?

  @perm = {}
  @perm_temp = {}
end
sanitize_username(name) click to toggle source

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

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

Public Instance Methods

autologin=(vnew) click to toggle source
# File lib/rbot/botuser.rb, line 246
def autologin=(vnew)
  vold = @autologin
  @autologin = vnew
  if vold && !vnew
    @netmasks.each { |n| Auth.manager.maskdb.remove(self, n) }
  elsif vnew && !vold
    @netmasks.each { |n| Auth.manager.maskdb.add(self, n) }
  end
end
autologin?() click to toggle source

Do we allow automatic logging in?

# File lib/rbot/botuser.rb, line 374
def autologin?
  @autologin
end
default?() click to toggle source

Check if the current BotUser is the default one

# File lib/rbot/botuser.rb, line 637
def default?
  return DefaultBotUserClass === self
end
from_hash(h) click to toggle source

Restore from hash

# File lib/rbot/botuser.rb, line 379
def from_hash(h)
  @username = h[:username] if h.has_key?(:username)
  @password = h[:password] if h.has_key?(:password)
  @login_by_mask = h[:login_by_mask] if h.has_key?(:login_by_mask)
  @autologin = h[:autologin] if h.has_key?(:autologin)
  if h.has_key?(:netmasks)
    @netmasks = h[:netmasks]
    debug @netmasks
    @netmasks.each { |n| Auth.manager.maskdb.add(self, n) } if @autologin
    debug @netmasks
  end
  @perm = h[:perm] if h.has_key?(:perm)
end
inspect() click to toggle source

Inspection

# File lib/rbot/botuser.rb, line 324
def inspect
  str = self.__to_s__[0..-2]
  str << " (transient)" if @transient
  str << ":"
  str << " @username=#{@username.inspect}"
  str << " @netmasks=#{@netmasks.inspect}"
  str << " @perm=#{@perm.inspect}"
  str << " @perm_temp=#{@perm_temp.inspect}" unless @perm_temp.empty?
  str << " @login_by_mask=#{@login_by_mask}"
  str << " @autologin=#{@autologin}"
  str << ">"
end
knows?(usr) click to toggle source

This method checks if BotUser has a Netmask that matches user

# File lib/rbot/botuser.rb, line 492
def knows?(usr)
  user = usr.to_irc_user
  !!@netmasks.find { |n| user.matches? n }
end
login(user, password=nil) click to toggle source

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.

# File lib/rbot/botuser.rb, line 501
def login(user, password=nil)
  if password == @password or (password.nil? and (@login_by_mask || @autologin) and knows?(user))
    add_netmask(user) unless knows?(user)
    debug "#{user} logged in as #{self.inspect}"
    return true
  else
    return false
  end
end
login_by_mask?() click to toggle source

Do we allow logging in without providing the password?

# File lib/rbot/botuser.rb, line 356
def login_by_mask?
  @login_by_mask
end
make_permanent(name) click to toggle source

Make the BotUser permanent

# File lib/rbot/botuser.rb, line 272
def make_permanent(name)
  raise TypeError, "permanent already" if permanent?
  @username = BotUser.sanitize_username(name)
  @transient = false
  reset_autologin
  reset_password # or not?
  @netmasks.dup.each do |m|
    delete_netmask(m)
    add_netmask(m.generalize)
  end
end
owner?() click to toggle source

Check if the current BotUser is the owner

# File lib/rbot/botuser.rb, line 642
def owner?
  return BotOwnerClass === self
end
password=(pwd=nil) click to toggle source

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

# File lib/rbot/botuser.rb, line 395
def password=(pwd=nil)
  pass = pwd.to_s
  if pass.empty?
    reset_password
  else
    begin
      raise InvalidPassword, "#{pass} contains invalid characters" if pass !~ /^[\x21-\x7e]+$/
      raise InvalidPassword, "#{pass} too short" if pass.length < 4
      @password = pass
    rescue InvalidPassword => e
      raise e
    rescue => e
      raise InvalidPassword, "Exception #{e.inspect} while checking #{pass.inspect} (#{pwd.inspect})"
    end
  end
end
permanent=(bool) click to toggle source

Sets if the BotUser is permanent or not

# File lib/rbot/botuser.rb, line 267
def permanent=(bool)
  @transient=!bool
end
permanent?() click to toggle source

Checks if the BotUser is permanent (not transient)

# File lib/rbot/botuser.rb, line 262
def permanent?
  !@transient
end
permit?(cmd, chan=nil) click to toggle source

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

# File lib/rbot/botuser.rb, line 448
def permit?(cmd, chan=nil)
  if chan
    k = chan.to_s.to_sym
  else
    k = :*
  end
  allow = nil
  pt = @perm.merge @perm_temp
  if pt.has_key?(k)
    allow = pt[k].permit?(cmd)
  end
  return allow
end
reset_autologin() click to toggle source

Reset the autologin option

# File lib/rbot/botuser.rb, line 368
def reset_autologin
  @autologin = Auth.manager.bot.config['auth.autologin'] unless defined?(@autologin)
end
reset_login_by_mask() click to toggle source

Reset the login-by-mask option

# File lib/rbot/botuser.rb, line 362
def reset_login_by_mask
  @login_by_mask = Auth.manager.bot.config['auth.login_by_mask'] unless defined?(@login_by_mask)
end
reset_netmasks() click to toggle source

Reset Netmasks, clearing @netmasks

# File lib/rbot/botuser.rb, line 483
def reset_netmasks
  @netmasks.each { |m|
    Auth.manager.maskdb.remove(self, m) if self.autologin?
  }
  @netmasks.clear
end
reset_password() click to toggle source

Resets the password by creating a new onw

# File lib/rbot/botuser.rb, line 413
def reset_password
  @password = Auth.random_password
end
reset_permission(cmd, chan ="*") click to toggle source

Resets the permission for command cmd on channel chan

# File lib/rbot/botuser.rb, line 427
def reset_permission(cmd, chan ="*")
  set_permission(cmd, nil, chan)
end
reset_temp_permission(cmd, chan ="*") click to toggle source

Resets the temporary permission for command cmd on channel chan

# File lib/rbot/botuser.rb, line 441
def reset_temp_permission(cmd, chan ="*")
  set_temp_permission(cmd, nil, chan)
end
set_permission(cmd, val, chan="*") click to toggle source

Sets the permission for command cmd to val on channel chan

# File lib/rbot/botuser.rb, line 419
def set_permission(cmd, val, chan="*")
  k = chan.to_s.to_sym
  @perm[k] = PermissionSet.new unless @perm.has_key?(k)
  @perm[k].set_permission(cmd, val)
end
set_temp_permission(cmd, val, chan="*") click to toggle source

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

# File lib/rbot/botuser.rb, line 433
def set_temp_permission(cmd, val, chan="*")
  k = chan.to_s.to_sym
  @perm_temp[k] = PermissionSet.new unless @perm_temp.has_key?(k)
  @perm_temp[k].set_permission(cmd, val)
end
to_hash() click to toggle source

Convert into a hash

# File lib/rbot/botuser.rb, line 343
def to_hash
  {
    :username => @username,
    :password => @password,
    :netmasks => @netmasks,
    :perm => @perm,
    :login_by_mask => @login_by_mask,
    :autologin => @autologin,
  }
end
to_s() click to toggle source

In strings

# File lib/rbot/botuser.rb, line 338
def to_s
  @username
end
transient?() click to toggle source

Checks if the BotUser is transient

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

Private Instance Methods

add_netmask(mask) click to toggle source

Adds a Netmask

# File lib/rbot/botuser.rb, line 464
def add_netmask(mask)
  m = mask.to_irc_netmask
  @netmasks << m
  if self.autologin?
    Auth.manager.maskdb.add(self, m)
    Auth.manager.logout_transients(m) if self.permanent?
  end
end
delete_netmask(mask) click to toggle source

Removes a Netmask

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