class Irc::Bot::Auth::ManagerClass
This is the ManagerClass
singleton, used to manage Irc::User
/Irc::Bot::Auth::BotUser connections and everything
Attributes
Public Class Methods
The instance manages two Hash
es: one that maps Irc::User
s onto BotUser
s, 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
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
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
# 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
# File lib/rbot/botuser.rb, line 690 def changed? @has_changes end
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
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
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
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
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
# 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
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
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
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
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
# File lib/rbot/botuser.rb, line 686 def reset_changed @has_changes = false end
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
# File lib/rbot/botuser.rb, line 723 def save_array @allbotusers.values.map { |x| x.transient? ? nil : x.to_hash }.compact end
# File lib/rbot/botuser.rb, line 682 def set_changed @has_changes = true end