class Irc::Bot::Auth::ManagerClass

This is the ManagerClass singleton, used to manage Irc::User/Irc::Bot::Auth::BotUser connections and everything

Attributes

bot[R]
botowner[R]
everyone[R]
maskdb[R]

Public Class Methods

new() click to toggle source

The instance manages two Hashes: one that maps Irc::Users onto BotUsers, and the other that maps usernames onto BotUser

# File lib/rbot/botuser.rb, line 663
def initialize
  @everyone = Auth::defaultbotuser
  @botowner = Auth::botowner
  bot_associate(nil)
end

Public Instance Methods

allow?(cmdtxt, user, chan=nil) click to toggle source

Checks if command cmd is allowed to User user on chan, optionally telling if the user is authorized

# File lib/rbot/botuser.rb, line 908
def allow?(cmdtxt, user, chan=nil)
  if permit?(user, cmdtxt, chan)
    return true
  else
    # cmds = cmdtxt.split('::')
    # @bot.say chan, "you don't have #{cmds.last} (#{cmds.first}) permissions here" if chan
    @bot.say chan, _("%{user}, you don't have '%{command}' permissions here") %
                  {:user=>user, :command=>cmdtxt} if chan
    return false
  end
end
autologin(user) click to toggle source

Tries to auto-login Irc::User user by looking at the known botusers that allow autologin and trying to login without a password

# File lib/rbot/botuser.rb, line 784
def autologin(user)
  ircuser = user.to_irc_user
  debug "Trying to autologin #{ircuser}"
  return @botusers[ircuser] if @botusers.has_key?(ircuser)
  bu = maskdb.find(ircuser)
  if bu
    debug "trying #{bu}"
    bu.login(ircuser) or raise '...what?!'
    @botusers[ircuser] = bu
    return bu
  end
  # Finally, create a transient if we're set to allow it
  if @bot.config['auth.autouser']
    bu = create_transient_botuser(ircuser)
    @botusers[ircuser] = bu
    return bu
  end
  return everyone
end
bot_associate(bot) click to toggle source
# File lib/rbot/botuser.rb, line 669
def bot_associate(bot)
  raise "Cannot associate with a new bot! Save first" if defined?(@has_changes) && @has_changes

  reset_hashes

  # Associated bot
  @bot = bot

  # This variable is set to true when there have been changes
  # to the botusers list, so that we know when to save
  @has_changes = false
end
changed?() click to toggle source
# File lib/rbot/botuser.rb, line 690
def changed?
  @has_changes
end
create_botuser(name, password=nil) click to toggle source

creates a new BotUser

# File lib/rbot/botuser.rb, line 742
def create_botuser(name, password=nil)
  n = BotUser.sanitize_username(name)
  k = n.to_sym
  raise "botuser #{n} exists" if include?(k)
  bu = BotUser.new(n)
  bu.password = password
  @allbotusers[k] = bu
  return bu
end
create_transient_botuser(user) click to toggle source

Creates a new transient BotUser associated with Irc::User user, automatically logging him in. Note that transient botuser creation can fail, typically if we don’t have the complete user netmask (e.g. for messages coming in from a linkbot)

# File lib/rbot/botuser.rb, line 809
def create_transient_botuser(user)
  ircuser = user.to_irc_user
  bu = everyone
  begin
    bu = BotUser.new(ircuser, :transient => true, :masks => ircuser)
    bu.login(ircuser)
  rescue
    warning "failed to create transient for #{user}"
    error $!
  end
  return bu
end
get_botuser(name) click to toggle source

returns the botuser with name name

# File lib/rbot/botuser.rb, line 753
def get_botuser(name)
  @allbotusers.fetch(BotUser.sanitize_username(name).to_sym)
end
include?(botusername) click to toggle source

checks if we know about a certain BotUser username

# File lib/rbot/botuser.rb, line 730
def include?(botusername)
  @allbotusers.has_key?(botusername.to_sym)
end
irc_to_botuser(ircuser) click to toggle source

Maps Irc::User to BotUser

# File lib/rbot/botuser.rb, line 735
def irc_to_botuser(ircuser)
  logged = @botusers[ircuser.to_irc_user]
  return logged if logged
  return autologin(ircuser)
end
load_array(ary, forced) click to toggle source
# File lib/rbot/botuser.rb, line 704
def load_array(ary, forced)
  unless ary
    warning "Tried to load an empty array"
    return
  end
  raise "Won't load with unsaved changes" if @has_changes and not forced
  reset_hashes
  ary.each { |x|
    raise TypeError, "#{x} should be a Hash" unless x.kind_of?(Hash)
    u = x[:username]
    unless include?(u)
      create_botuser(u)
    end
    get_botuser(u).from_hash(x)
    get_botuser(u).transient = false
  }
  @has_changes=false
end
login(user, botusername, pwd=nil) click to toggle source

Logs Irc::User user in to BotUser botusername with password pwd

raises an error if botusername is not a known BotUser username

It is possible to autologin by Netmask, on request

# File lib/rbot/botuser.rb, line 763
def login(user, botusername, pwd=nil)
  ircuser = user.to_irc_user
  n = BotUser.sanitize_username(botusername)
  k = n.to_sym
  raise "No such BotUser #{n}" unless include?(k)
  if @botusers.has_key?(ircuser)
    return true if @botusers[ircuser].username == n
    # TODO
    # @botusers[ircuser].logout(ircuser)
  end
  bu = @allbotusers[k]
  if bu.login(ircuser, pwd)
    @botusers[ircuser] = bu
    return true
  end
  return false
end
logout_transients(m) click to toggle source

Logs out any Irc::User matching Irc::Netmask m and logged in to a transient BotUser

# File lib/rbot/botuser.rb, line 825
def logout_transients(m)
  debug "to check: #{@botusers.keys.join ' '}"
  @botusers.keys.each do |iu|
    debug "checking #{iu.fullform} against #{m.fullform}"
    bu = @botusers[iu]
    bu.transient? or next
    iu.matches?(m) or next
    @botusers.delete(iu).autologin = false
  end
end
make_permanent(user, name) click to toggle source

Makes transient BotUser user into a permanent BotUser named name; if user is an Irc::User, act on the transient BotUser (if any) it’s logged in as

# File lib/rbot/botuser.rb, line 840
def make_permanent(user, name)
  buname = BotUser.sanitize_username(name)
  # TODO merge BotUser instead?
  raise "there's already a BotUser called #{name}" if include?(buname)

  tuser = nil
  case user
  when String, Irc::User
    tuser = irc_to_botuser(user)
  when BotUser
    tuser = user
  else
    raise TypeError, "sorry, don't know how to make #{user.class} into a permanent BotUser"
  end
  return nil unless tuser
  raise TypeError, "#{tuser} is not transient" unless tuser.transient?

  tuser.make_permanent(buname)
  @allbotusers[tuser.username.to_sym] = tuser

  return tuser
end
permit?(user, cmdtxt, channel=nil) click to toggle source

Checks if User user can do cmd on chan.

Permission are checked in this order, until a true or false is returned:

  • associated BotUser on chan

  • associated BotUser on all channels

  • everyone on chan

  • everyone on all channels

# File lib/rbot/botuser.rb, line 872
def permit?(user, cmdtxt, channel=nil)
  if user.class <= BotUser
    botuser = user
  else
    botuser = user.botuser
  end
  cmd = cmdtxt.to_irc_auth_command

  chan = channel
  case chan
  when User
    chan = "?"
  when Channel
    chan = chan.name
  end

  allow = nil

  allow = botuser.permit?(cmd, chan) if chan
  return allow unless allow.nil?
  allow = botuser.permit?(cmd)
  return allow unless allow.nil?

  unless botuser == everyone
    allow = everyone.permit?(cmd, chan) if chan
    return allow unless allow.nil?
    allow = everyone.permit?(cmd)
    return allow unless allow.nil?
  end

  raise "Could not check permission for user #{user.inspect} to run #{cmdtxt.inspect} on #{chan.inspect}"
end
reset_changed() click to toggle source
# File lib/rbot/botuser.rb, line 686
def reset_changed
  @has_changes = false
end
reset_hashes() click to toggle source

resets the hashes

# File lib/rbot/botuser.rb, line 695
def reset_hashes
  @botusers = Hash.new
  @maskdb = NetmaskDb.new
  @allbotusers = Hash.new
  [everyone, botowner].each do |x|
    @allbotusers[x.username.to_sym] = x
  end
end
save_array() click to toggle source
# File lib/rbot/botuser.rb, line 723
def save_array
  @allbotusers.values.map { |x|
    x.transient? ? nil : x.to_hash
  }.compact
end
set_changed() click to toggle source
# File lib/rbot/botuser.rb, line 682
def set_changed
  @has_changes = true
end