3 # globmask:: glob to test with
4 # netmask:: netmask to test against
5 # Compare a netmask with a standard IRC glob, e.g foo!bar@baz.com would
6 # match *!*@baz.com, foo!*@*, *!bar@*, etc.
7 def Irc.netmaskmatch(globmask, netmask)
8 regmask = globmask.gsub(/\*/, ".*?")
9 return true if(netmask =~ /#{regmask}/)
13 # check if a string is an actual IRC hostmask
19 # User-level authentication to allow/disallow access to bot commands based
20 # on hostmask and userlevel.
22 BotConfig.register('auth.password', :type => BotConfig::Password, :default => "Your password for maxing your auth with the bot (used to associate new hostmasks with your owner-status etc)")
24 # create a new IrcAuth instance.
25 # bot:: associated bot class
30 if(File.exist?("#{@bot.botclass}/users.rbot"))
31 IO.foreach("#{@bot.botclass}/users.rbot") do |line|
32 if(line =~ /\s*(\d+)\s*(\S+)/)
39 if(File.exist?("#{@bot.botclass}/levels.rbot"))
40 IO.foreach("#{@bot.botclass}/levels.rbot") do |line|
41 if(line =~ /\s*(\d+)\s*(\S+)/)
44 @levels[command] = level
50 # save current users and levels to files.
51 # levels are written to #{botclass}/levels.rbot
52 # users are written to #{botclass}/users.rbot
54 Dir.mkdir("#{@bot.botclass}") if(!File.exist?("#{@bot.botclass}"))
55 File.open("#{@bot.botclass}/users.rbot", "w") do |file|
56 @users.each do |key, value|
57 file.puts "#{value} #{key}"
60 File.open("#{@bot.botclass}/levels.rbot", "w") do |file|
61 @levels.each do |key, value|
62 file.puts "#{value} #{key}"
67 # command:: command user wishes to perform
68 # mask:: hostmask of user
69 # tell:: optional recipient for "insufficient auth" message
71 # returns true if user with hostmask +mask+ is permitted to perform
72 # +command+ optionally pass tell as the target for the "insufficient auth"
73 # message, if the user is not authorised
74 def allow?(command, mask, tell=nil)
75 auth = userlevel(mask)
76 if(auth >= @levels[command])
79 debug "#{mask} is not allowed to perform #{command}"
80 @bot.say tell, "insufficient \"#{command}\" auth (have #{auth}, need #{@levels[command]})" if tell
85 # add user with hostmask matching +mask+ with initial auth level +level+
86 def useradd(mask, level)
92 # mask:: mask of user to remove
93 # remove user with mask +mask+
100 # command:: command to adjust
101 # level:: new auth level for the command
102 # set required auth level of +command+ to +level+
103 def setlevel(command, level)
104 @levels[command] = level
108 # mask:: mask of user
109 # returns the authlevel of user with mask +mask+
110 # finds the matching user which has the highest authlevel (so you can have
111 # a default level of 5 for *!*@*, and yet still give higher levels to
113 # go through hostmask list, find match with _highest_ level (all users
116 @users.each {|user,userlevel|
117 if(Irc.netmaskmatch(user, mask))
118 level = userlevel if userlevel > level
124 # return all currently defined commands (for which auth is required) and
125 # their required authlevels
127 reply = "Current levels are:"
128 @levels.sort.each {|a|
131 reply += " #{key}(#{value})"
136 # return all currently defined users and their authlevels
138 reply = "Current users are:"
139 @users.sort.each {|a|
142 reply += " #{key}(#{value})"
151 return "setlevel <command> <level> => Sets required level for <command> to <level> (private addressing only)"
153 return "useradd <mask> <level> => Add user <mask> at level <level> (private addressing only)"
155 return "userdel <mask> => Remove user <mask> (private addressing only)"
157 return "auth <masterpw> => Recognise your hostmask as bot master (private addressing only)"
159 return "levels => list commands and their required levels (private addressing only)"
161 return "users => list users and their levels (private addressing only)"
163 return "Auth module (User authentication) topics: setlevel, useradd, userdel, auth, levels, users"
169 if(m.address? && m.private?)
171 when (/^setlevel\s+(\S+)\s+(\d+)$/)
172 if(@bot.auth.allow?("auth", m.source, m.replyto))
173 @bot.auth.setlevel($1, $2.to_i)
174 m.reply "level for #$1 set to #$2"
176 when (/^useradd\s+(\S+)\s+(\d+)/)
177 if(@bot.auth.allow?("auth", m.source, m.replyto))
178 @bot.auth.useradd($1, $2.to_i)
179 m.reply "added user #$1 at level #$2"
181 when (/^userdel\s+(\S+)/)
182 if(@bot.auth.allow?("auth", m.source, m.replyto))
183 @bot.auth.userdel($1)
184 m.reply "user #$1 is gone"
186 when (/^auth\s+(\S+)/)
187 if($1 == @bot.config["auth.password"])
188 @bot.auth.useradd(Regexp.escape(m.source), 1000)
189 m.reply "Identified, security level maxed out"
191 m.reply "incorrect password"
194 m.reply @bot.auth.showlevels if(@bot.auth.allow?("config", m.source, m.replyto))
196 m.reply @bot.auth.showusers if(@bot.auth.allow?("config", m.source, m.replyto))