Class: Irc::Bot::Auth::ManagerClass
- Includes:
- Singleton
- Defined in:
- lib/rbot/botuser.rb,
lib/rbot/core/remote.rb
Overview
We extend the ManagerClass to handle remote logins
Constant Summary collapse
- MAX_SESSION_ID =
2**128 - 1
Instance Attribute Summary collapse
-
#bot ⇒ Object
readonly
Returns the value of attribute bot.
-
#botowner ⇒ Object
readonly
Returns the value of attribute botowner.
-
#everyone ⇒ Object
readonly
Returns the value of attribute everyone.
-
#maskdb ⇒ Object
readonly
Returns the value of attribute maskdb.
Instance Method Summary collapse
-
#allow?(cmdtxt, user, chan = nil) ⇒ Boolean
Checks if command cmd is allowed to User user on chan, optionally telling if the user is authorized.
-
#autologin(user) ⇒ Object
Tries to auto-login Irc::User user by looking at the known botusers that allow autologin and trying to login without a password.
- #bot_associate(bot) ⇒ Object
- #changed? ⇒ Boolean
-
#create_botuser(name, password = nil) ⇒ Object
creates a new BotUser.
-
#create_transient_botuser(user) ⇒ Object
Creates a new transient BotUser associated with Irc::User user, automatically logging him in.
-
#get_botuser(name) ⇒ Object
returns the botuser with name name.
-
#include?(botusername) ⇒ Boolean
checks if we know about a certain BotUser username.
-
#initialize ⇒ ManagerClass
constructor
The instance manages two
Hash
es: one that mapsIrc::User
s ontoBotUser
s, and the other that maps usernames ontoBotUser
. -
#irc_to_botuser(ircuser) ⇒ Object
Maps
Irc::User
to BotUser. - #load_array(ary, forced) ⇒ Object
-
#login(user, botusername, pwd = nil) ⇒ Object
Logs Irc::User user in to BotUser botusername with password pwd.
-
#logout_transients(m) ⇒ Object
Logs out any Irc::User matching Irc::Netmask m and logged in to a transient BotUser.
-
#make_permanent(user, name) ⇒ Object
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.
-
#permit?(user, cmdtxt, channel = nil) ⇒ Boolean
Checks if User user can do cmd on chan.
-
#remote_login(botusername, pwd) ⇒ Object
Creates a session id when the given password matches the given botusername.
-
#remote_user(session_id) ⇒ Object
Returns the botuser associated with the given session id.
- #reset_changed ⇒ Object
-
#reset_hashes ⇒ Object
resets the hashes.
- #save_array ⇒ Object
- #set_changed ⇒ Object
Constructor Details
#initialize ⇒ ManagerClass
The instance manages two Hash
es: one that maps Irc::User
s onto BotUser
s, and the other that maps usernames onto BotUser
662 663 664 665 666 |
# File 'lib/rbot/botuser.rb', line 662 def initialize @everyone = Auth::defaultbotuser @botowner = Auth::botowner bot_associate(nil) end |
Instance Attribute Details
#bot ⇒ Object (readonly)
Returns the value of attribute bot.
657 658 659 |
# File 'lib/rbot/botuser.rb', line 657 def bot @bot end |
#botowner ⇒ Object (readonly)
Returns the value of attribute botowner.
656 657 658 |
# File 'lib/rbot/botuser.rb', line 656 def botowner @botowner end |
#everyone ⇒ Object (readonly)
Returns the value of attribute everyone.
655 656 657 |
# File 'lib/rbot/botuser.rb', line 655 def everyone @everyone end |
#maskdb ⇒ Object (readonly)
Returns the value of attribute maskdb.
654 655 656 |
# File 'lib/rbot/botuser.rb', line 654 def maskdb @maskdb end |
Instance Method Details
#allow?(cmdtxt, user, chan = nil) ⇒ Boolean
Checks if command cmd is allowed to User user on chan, optionally telling if the user is authorized
907 908 909 910 911 912 913 914 915 916 917 |
# File 'lib/rbot/botuser.rb', line 907 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) ⇒ Object
Tries to auto-login Irc::User user by looking at the known botusers that allow autologin and trying to login without a password
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
# File 'lib/rbot/botuser.rb', line 783 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) ⇒ Object
668 669 670 671 672 673 674 675 676 677 678 679 |
# File 'lib/rbot/botuser.rb', line 668 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? ⇒ Boolean
689 690 691 |
# File 'lib/rbot/botuser.rb', line 689 def changed? @has_changes end |
#create_botuser(name, password = nil) ⇒ Object
creates a new BotUser
741 742 743 744 745 746 747 748 749 |
# File 'lib/rbot/botuser.rb', line 741 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) ⇒ Object
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)
808 809 810 811 812 813 814 815 816 817 818 819 |
# File 'lib/rbot/botuser.rb', line 808 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) ⇒ Object
returns the botuser with name name
752 753 754 |
# File 'lib/rbot/botuser.rb', line 752 def get_botuser(name) @allbotusers.fetch(BotUser.sanitize_username(name).to_sym) end |
#include?(botusername) ⇒ Boolean
checks if we know about a certain BotUser username
729 730 731 |
# File 'lib/rbot/botuser.rb', line 729 def include?(botusername) @allbotusers.has_key?(botusername.to_sym) end |
#irc_to_botuser(ircuser) ⇒ Object
Maps Irc::User
to BotUser
734 735 736 737 738 |
# File 'lib/rbot/botuser.rb', line 734 def irc_to_botuser(ircuser) logged = @botusers[ircuser.to_irc_user] return logged if logged return autologin(ircuser) end |
#load_array(ary, forced) ⇒ Object
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 |
# File 'lib/rbot/botuser.rb', line 703 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) ⇒ Object
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
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 |
# File 'lib/rbot/botuser.rb', line 762 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) ⇒ Object
Logs out any Irc::User matching Irc::Netmask m and logged in to a transient BotUser
824 825 826 827 828 829 830 831 832 833 |
# File 'lib/rbot/botuser.rb', line 824 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) ⇒ Object
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
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 |
# File 'lib/rbot/botuser.rb', line 839 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) ⇒ Boolean
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
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 |
# File 'lib/rbot/botuser.rb', line 871 def permit?(user, cmdtxt, channel=nil) if user.class <= BotUser botuser = user else botuser = irc_to_botuser(user) 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 |
#remote_login(botusername, pwd) ⇒ Object
Creates a session id when the given password matches the given botusername
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/rbot/core/remote.rb', line 46 def remote_login(botusername, pwd) @remote_users = Hash.new unless defined? @remote_users n = BotUser.sanitize_username(botusername) k = n.to_sym raise "No such BotUser #{n}" unless include?(k) bu = @allbotusers[k] if bu.remote_login(pwd) raise "ran out of session ids!" if @remote_users.length == MAX_SESSION_ID session_id = rand(MAX_SESSION_ID) while @remote_users.has_key?(session_id) session_id = rand(MAX_SESSION_ID) end @remote_users[session_id] = bu return session_id end return false end |
#remote_user(session_id) ⇒ Object
Returns the botuser associated with the given session id
65 66 67 68 69 70 71 72 73 |
# File 'lib/rbot/core/remote.rb', line 65 def remote_user(session_id) return everyone unless session_id return nil unless defined? @remote_users if @remote_users.has_key?(session_id) return @remote_users[session_id] else return nil end end |
#reset_changed ⇒ Object
685 686 687 |
# File 'lib/rbot/botuser.rb', line 685 def reset_changed @has_changes = false end |
#reset_hashes ⇒ Object
resets the hashes
694 695 696 697 698 699 700 701 |
# File 'lib/rbot/botuser.rb', line 694 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 ⇒ Object
722 723 724 725 726 |
# File 'lib/rbot/botuser.rb', line 722 def save_array @allbotusers.values.map { |x| x.transient? ? nil : x.to_hash }.compact end |
#set_changed ⇒ Object
681 682 683 |
# File 'lib/rbot/botuser.rb', line 681 def set_changed @has_changes = true end |