Guest User

Untitled

a guest
Mar 8th, 2018
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.64 KB | None | 0 0
  1. Index: lib/rbot/botuser.rb
  2. ===================================================================
  3. --- lib/rbot/botuser.rb (revision 1211)
  4. +++ lib/rbot/botuser.rb (working copy)
  5. @@ -9,6 +9,7 @@
  6.  
  7. require 'singleton'
  8. require 'set'
  9. +require 'rbot/maskdb'
  10.  
  11. # This would be a good idea if it was failproof, but the truth
  12. # is that other methods can indirectly modify the hash. *sigh*
  13. @@ -240,9 +241,18 @@
  14. # when modifying data
  15. attr_reader :data
  16. attr_writer :login_by_mask
  17. - attr_writer :autologin
  18. attr_writer :transient
  19.  
  20. + def autologin=(vnew)
  21. + vold = @autologin
  22. + @autologin = vnew
  23. + if vold && !vnew
  24. + @netmasks.each { |n| Auth.manager.maskdb.remove(self, n) }
  25. + elsif vnew && !vold
  26. + @netmasks.each { |n| Auth.manager.maskdb.add(self, n) }
  27. + end
  28. + end
  29. +
  30. # Checks if the BotUser is transient
  31. def transient?
  32. @transient
  33. @@ -363,10 +373,13 @@
  34. def from_hash(h)
  35. @username = h[:username] if h.has_key?(:username)
  36. @password = h[:password] if h.has_key?(:password)
  37. - @netmasks = h[:netmasks] if h.has_key?(:netmasks)
  38. - @perm = h[:perm] if h.has_key?(:perm)
  39. @login_by_mask = h[:login_by_mask] if h.has_key?(:login_by_mask)
  40. @autologin = h[:autologin] if h.has_key?(:autologin)
  41. + if h.has_key?(:netmasks)
  42. + @netmasks = h[:netmasks]
  43. + @netmasks.each { |n| Auth.manager.maskdb.add(self, n) } if @autologin
  44. + end
  45. + @perm = h[:perm] if h.has_key?(:perm)
  46. @data.replace(h[:data]) if h.has_key?(:data)
  47. end
  48.  
  49. @@ -427,7 +440,9 @@
  50. # Adds a Netmask
  51. #
  52. def add_netmask(mask)
  53. - @netmasks << mask.to_irc_netmask
  54. + m = mask.to_irc_netmask
  55. + @netmasks << m
  56. + Auth.manager.maskdb.add(self, m) if self.autologin?
  57. end
  58.  
  59. # Removes a Netmask
  60. @@ -435,26 +450,14 @@
  61. def delete_netmask(mask)
  62. m = mask.to_irc_netmask
  63. @netmasks.delete(m)
  64. + Auth.manager.maskdb.remove(self, m) if self.autologin?
  65. end
  66.  
  67. - # Removes all <code>Netmask</code>s
  68. - #
  69. - def reset_netmasks
  70. - @netmasks = NetmaskList.new
  71. - end
  72. -
  73. # This method checks if BotUser has a Netmask that matches _user_
  74. #
  75. def knows?(usr)
  76. user = usr.to_irc_user
  77. - known = false
  78. - @netmasks.each { |n|
  79. - if user.matches?(n)
  80. - known = true
  81. - break
  82. - end
  83. - }
  84. - return known
  85. + [email protected] { |n| user.matches? n }
  86. end
  87.  
  88. # This method gets called when User _user_ wants to log in.
  89. @@ -550,12 +553,6 @@
  90. return true
  91. end
  92.  
  93. - # Resets the NetmaskList
  94. - def reset_netmasks
  95. - super
  96. - add_netmask("*!*@*")
  97. - end
  98. -
  99. # DefaultBotUser will check the default_perm after checking
  100. # the global ones
  101. # or on all channels if _chan_ is nil
  102. @@ -608,6 +605,7 @@
  103.  
  104. include Singleton
  105.  
  106. + attr_reader :maskdb
  107. attr_reader :everyone
  108. attr_reader :botowner
  109. attr_reader :bot
  110. @@ -649,10 +647,11 @@
  111. # resets the hashes
  112. def reset_hashes
  113. @botusers = Hash.new
  114. + @maskdb = NetmaskDb.new
  115. @allbotusers = Hash.new
  116. - [everyone, botowner].each { |x|
  117. + [everyone, botowner].each do |x|
  118. @allbotusers[x.username.to_sym] = x
  119. - }
  120. + end
  121. @transients = Set.new
  122. end
  123.  
  124. @@ -740,14 +739,12 @@
  125. ircuser = user.to_irc_user
  126. debug "Trying to autologin #{ircuser}"
  127. return @botusers[ircuser] if @botusers.has_key?(ircuser)
  128. - @allbotusers.each { |n, bu|
  129. - debug "Checking with #{n}"
  130. - return bu if bu.autologin? and login(ircuser, n)
  131. - }
  132. - # Check with transient users
  133. - @transients.each { |bu|
  134. - return bu if bu.login(ircuser)
  135. - }
  136. + bu = maskdb.find(ircuser)
  137. + if bu
  138. + debug "trying #{bu}"
  139. + bu.login(ircuser) or raise '...what?!'
  140. + return bu
  141. + end
  142. # Finally, create a transient if we're set to allow it
  143. if @bot.config['auth.autouser']
  144. bu = create_transient_botuser(ircuser)
  145. Index: lib/rbot/maskdb.rb
  146. ===================================================================
  147. --- lib/rbot/maskdb.rb (revision 0)
  148. +++ lib/rbot/maskdb.rb (revision 0)
  149. @@ -0,0 +1,160 @@
  150. +module Irc
  151. + class NetmaskDb
  152. + # helper backend class: generic nested radix tree
  153. + class Tree
  154. + attr_reader :pre, :chi
  155. +
  156. + def initialize(pre = '', chi = Hash.new)
  157. + @pre = pre
  158. + @chi = chi
  159. + end
  160. +
  161. + def add(val, *prefs)
  162. + str = prefs.shift or raise 'empty prefs'
  163. + @pre = str if @chi.empty?
  164. +
  165. + n = 0
  166. + @pre.size.times do
  167. + break if @pre[n] != str[n]
  168. + n += 1
  169. + end
  170. +
  171. + rest = str.slice(n .. -1)
  172. +
  173. + if n != @pre.size
  174. + prest = @pre.slice!(n .. -1)
  175. + pc = prest.slice! 0
  176. + @chi = {pc => Tree.new(prest, @chi)}
  177. + end
  178. +
  179. + c = rest.slice!(0)
  180. +
  181. + if c
  182. + (@chi[c] ||= Tree.new).add(val, rest, *prefs)
  183. + else
  184. + if prefs.empty?
  185. + (@chi[''] ||= Array.new).push val
  186. + else
  187. + (@chi[''] ||= Tree.new).add(val, *prefs)
  188. + end
  189. + end
  190. + end
  191. +
  192. + def empty?
  193. + @chi.empty?
  194. + end
  195. +
  196. + def remove(*prefs, &block)
  197. + str = prefs.shift or raise 'empty prefs?'
  198. + return nil unless @pre.empty? or str.index(@pre) == 0
  199. + c = str.slice(@pre.size) || ''
  200. + return nil unless @chi.include? c
  201. + if c == ''
  202. + if prefs.empty?
  203. + @chi[c].reject!(&block)
  204. + else
  205. + @chi[c].remove(*prefs, &block)
  206. + end
  207. + else
  208. + @chi[c].remove(str.slice((@pre.size + 1) .. -1), *prefs, &block)
  209. + end
  210. + @chi.delete(c) if @chi[c].empty?
  211. +
  212. + if @chi.size == 1
  213. + k = @chi.keys.shift
  214. + return nil if k == ''
  215. + @pre << k << @chi[k].pre
  216. + @chi = @chi[k].chi
  217. + end
  218. + end
  219. +
  220. + def find(*prefs)
  221. + str = prefs.shift or raise 'empty prefs?'
  222. + self.find_helper(str, *prefs) + self.find_helper(str.reverse, *prefs)
  223. + end
  224. +
  225. + protected
  226. + def find_helper(*prefs)
  227. + str = prefs.shift or raise 'empty prefs?'
  228. + return [] unless @pre.empty? or str.index(@pre) == 0
  229. + # puts "#{self.inspect}: #{str} == #{@pre} pfx matched"
  230. + matches = []
  231. + elsif Array === @chi['']
  232. + matches = @chi['']
  233. + else
  234. + matches = @chi[''].find(*prefs)
  235. + end
  236. +
  237. + c = str.slice(@pre.size)
  238. +
  239. + more = []
  240. + if c and @chi.include?(c)
  241. + more = @chi[c].find_helper(str.slice((@pre.size + 1) .. -1), *prefs)
  242. + end
  243. + return more + matches
  244. + end
  245. + end
  246. +
  247. + # api wrapper for netmasks
  248. +
  249. + def initialize
  250. + @tree = Tree.new
  251. + end
  252. +
  253. + def cook_component(str)
  254. + s = (str && !str.empty?) ? str : '*'
  255. + l = s.index(/[\?\*]/)
  256. + if l
  257. + l2 = s.size - s.rindex(/[\?\*]/) - 1
  258. + if l2 > l
  259. + s = s.reverse
  260. + l = l2
  261. + end
  262. +
  263. + return (l > 0) ? s.slice(0 .. (l - 1)) : ''
  264. + else
  265. + return s
  266. + end
  267. + end
  268. +
  269. + def mask2keys(m)
  270. + [m.host, m.user, m.nick].map { |c| cook_component(c) }
  271. + end
  272. +
  273. + def add(user, *masks)
  274. + masks.each do |m|
  275. + debug "adding user #{user} with mask #{m}"
  276. + @tree.add([user, m], *mask2keys(m))
  277. + end
  278. + end
  279. +
  280. + def remove(user, mask)
  281. + debug "trying to remove user #{user} with mask #{mask}"
  282. + @tree.remove(*mask2keys(m)) do |val|
  283. + val[0] == user and val[1].fullform == mask.fullform
  284. + end
  285. + end
  286. +
  287. + def metric(iu, bu, mask)
  288. + ret = nil
  289. + if iu.matches? mask
  290. + ret = iu.fullform.length - mask.fullform.length
  291. + ret += 10 if bu.transient?
  292. + end
  293. + return ret
  294. + end
  295. +
  296. + def find(iu)
  297. + debug "find(#{iu.fullform})"
  298. + matches = @tree.find(iu.host, iu.user, iu.nick).uniq.map do |val|
  299. + m = metric(iu, *val)
  300. + m ? [val[0], m] : nil
  301. + end.compact.sort { |a, b| a[1] <=> a[1] }
  302. + debug "matches: " + (matches.map do |m|
  303. + "#{m[0].username}: [#{m[1]}]"
  304. + end.join(', '))
  305. + return matches.empty? ? nil : matches[0][0]
  306. + end
  307. + end
  308. +end
Add Comment
Please, Sign In to add comment