PageRenderTime 26ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/workhorse/config.rb

https://github.com/ganlron/Workhorse
Ruby | 403 lines | 357 code | 32 blank | 14 comment | 57 complexity | c61637ed6dc67f1522214a9088d24986 MD5 | raw file
  1. require 'rubygems'
  2. require 'eventmachine'
  3. require 'active_support/all'
  4. require 'configatron'
  5. module Workhorse
  6. module Config
  7. mattr_accessor :daemon, :base, :im, :handlers, :users, :muc_handles
  8. VERSION = "0.01"
  9. DESCRIPTION = "Action Handler library for Workhorse"
  10. def self.load_local_config(name)
  11. path = @wh_config.base.retrieve(name.to_sym,nil)
  12. if path
  13. if (File.exists?(path))
  14. @wh_config.configure_from_yaml( path )
  15. end
  16. end
  17. end
  18. def self.set_vars
  19. @@im = @wh_config.im
  20. @@base = @wh_config.base
  21. @@daemon = @wh_config.daemon
  22. @@handlers = @wh_config.handlers
  23. @@users = @wh_config.users
  24. @@muc_handles = @wh_config.muc_handles
  25. end
  26. def self.active_handler?(handle)
  27. self.handlers.retrieve(handle,false)
  28. end
  29. def self.user_defined?(user)
  30. dom,node,resource = self.split_jid(user.downcase)
  31. users = self.users.to_hash
  32. user = users[dom.to_sym][node.to_sym]
  33. return false if user.nil?
  34. return true
  35. end
  36. def self.superuser?(user)
  37. dom,node,resource = self.split_jid(user.downcase)
  38. users = self.users.to_hash
  39. user = users[dom.to_sym][node.to_sym]
  40. return false unless user
  41. return true if user[:allowed] == "all"
  42. return false
  43. end
  44. def self.muc_superuser?(user)
  45. muc_handle = self.link_muc(user)
  46. return false if muc_handle.nil?
  47. self.superuser?(muc_handle)
  48. end
  49. # Return an array of muc_handles linked to the JID
  50. def self.user_handles(user)
  51. muc_handles = self.muc_handles.to_hash
  52. user_handles = []
  53. muc_handles.each do |server,ss|
  54. ss.each do |handle,hs|
  55. user_handles.push(server.to_s + '/' + handle.to_s) if hs.downcase == user.downcase
  56. end
  57. end
  58. return user_handles
  59. end
  60. def self.user_allowed?(user)
  61. dom,node,resource = self.split_jid(user)
  62. users = self.users.to_hash
  63. user = users[dom.to_sym][node.to_sym]
  64. return false if user.nil?
  65. return false if user[:allowed].nil?
  66. return false if user[:allowed] == 'none'
  67. return true
  68. end
  69. def self.muc_user_allowed?(user)
  70. muc_handle = self.link_muc(user)
  71. return false if muc_handle.nil?
  72. self.user_allowed?(muc_handle)
  73. end
  74. def self.user_allowed_handler?(user,handler,command = nil)
  75. dom,node,resource = self.split_jid(user)
  76. users = self.users.to_hash
  77. user = users[dom.to_sym][node.to_sym]
  78. return false if user.nil?
  79. return true if user[:allowed] == 'all'
  80. return false if user[:handlers].nil?
  81. h = user[:handlers][handler.to_sym]
  82. return false if h.nil?
  83. return false if h[:allowed].nil?
  84. return true if h[:allowed] == 'all'
  85. if (command.nil?)
  86. return true if h[:allowed] == 'limited'
  87. else
  88. c = h[:commands]
  89. return false if c.nil?
  90. return false if c[command.to_sym].nil?
  91. return true if c[command.to_sym] == 'allowed'
  92. end
  93. return false
  94. end
  95. def self.muc_user_allowed_handler?(user,handler,command = nil)
  96. muc_handle = self.link_muc(user)
  97. return false if muc_handle.nil?
  98. self.user_allowed_handler?(muc_handle,handler,command)
  99. end
  100. def self.split_jid(user)
  101. jid = Jabber::JID.new(user)
  102. dom = jid.domain.gsub(/[\.\@]/, '_').downcase
  103. node = jid.node.gsub(/[\.\@]/, '_').downcase unless jid.node.nil?
  104. resource = jid.resource.gsub(/[\.\@]/, '_').downcase unless jid.resource.nil?
  105. return dom, node, resource
  106. end
  107. def self.link_muc(handle)
  108. dom,node,resource = self.split_jid(handle)
  109. muc_handles = self.muc_handles.to_hash
  110. return muc_handles[dom.to_sym][resource.to_sym]
  111. end
  112. def self.write_yaml_local_config(config_name=nil,config_hash=nil)
  113. return false unless config_name and config_hash
  114. path = self.base.retrieve(config_name.to_sym,nil)
  115. return false unless path
  116. if File.exists?(path) and File.writable?(path)
  117. File.open( path, 'w' ) do |out|
  118. YAML.dump( config_hash, out )
  119. end
  120. self.load_local_config(config_name)
  121. self.set_vars
  122. return true
  123. else
  124. return false
  125. end
  126. end
  127. def self.reload_users
  128. @wh_config.remove("users")
  129. @wh_config.remove("muc_handles")
  130. self.load_local_config("users_local_conf")
  131. self.set_vars
  132. end
  133. def self.add_user(user=nil)
  134. if user and user.match(/^[^@]+@[^@]+$/)
  135. if self.user_defined?(user)
  136. return false
  137. else
  138. lp,dom = user.downcase.gsub(/[^\w@]/,"_").split('@')
  139. u = WH::Config.users.to_hash
  140. m = WH::Config.muc_handles.to_hash
  141. u[dom.to_sym][lp.to_sym] = {
  142. :allowed => "none"
  143. }
  144. config = {
  145. :users => u,
  146. :muc_handles => m
  147. }
  148. if self.write_yaml_local_config("users_local_conf",config)
  149. return true
  150. else
  151. return false
  152. end
  153. end
  154. end
  155. end
  156. def self.rm_user(user=nil)
  157. if user and user.match(/^[^@]+@[^@]+$/)
  158. if !self.user_defined?(user)
  159. return false
  160. elsif self.superuser?(user)
  161. return false
  162. else
  163. # Remove any MUC handles first
  164. self.user_handles(user).each do |h|
  165. self.rm_handle(h)
  166. end
  167. lp,dom = user.downcase.gsub(/[^\w@]/,"_").split('@')
  168. u = WH::Config.users.to_hash
  169. m = WH::Config.muc_handles.to_hash
  170. u[dom.to_sym].delete(lp.to_sym)
  171. if u[dom.to_sym].empty?
  172. u.delete(dom.to_sym)
  173. end
  174. config = {
  175. :users => u,
  176. :muc_handles => m
  177. }
  178. if self.write_yaml_local_config("users_local_conf",config)
  179. self.reload_users
  180. return true
  181. else
  182. return false
  183. end
  184. end
  185. end
  186. end
  187. def self.add_handle(user=nil,handle=nil)
  188. return false unless user and handle
  189. # Don't allow super users to be toyed with
  190. return false if self.superuser?(user)
  191. if user.match(/^[^@]+@[^@]+$/) and handle.match(/^[^\/]+\/[^\/]+$/)
  192. if self.user_defined?(user)
  193. server,nick = handle.downcase.gsub(/[^\w\/]/,"_").split('/')
  194. u = WH::Config.users.to_hash
  195. m = WH::Config.muc_handles.to_hash
  196. m[server.to_sym][nick.to_sym] = user.to_s
  197. config = {
  198. :users => u,
  199. :muc_handles => m
  200. }
  201. if self.write_yaml_local_config("users_local_conf",config)
  202. return true
  203. else
  204. return false
  205. end
  206. else
  207. return false
  208. end
  209. else
  210. return false
  211. end
  212. end
  213. def self.rm_handle(handle=nil)
  214. return false unless handle
  215. if handle.match(/^[^\/]+\/[^\/]+$/)
  216. # Don't toy with super users
  217. return false if self.muc_superuser?(handle)
  218. server,nick = handle.downcase.gsub(/[^\w\/]/,"_").split('/')
  219. u = WH::Config.users.to_hash
  220. m = WH::Config.muc_handles.to_hash
  221. m[server.to_sym].delete(nick.to_sym)
  222. if m[server.to_sym].empty?
  223. m.delete(server.to_sym)
  224. end
  225. config = {
  226. :users => u,
  227. :muc_handles => m
  228. }
  229. if self.write_yaml_local_config("users_local_conf",config)
  230. self.reload_users
  231. return true
  232. else
  233. return false
  234. end
  235. else
  236. return false
  237. end
  238. end
  239. def self.add_access(user=nil,handler=nil,commands=[])
  240. if user and user.match(/^[^@]+@[^@]+$/) and handler
  241. if self.user_defined?(user) and self.active_handler?(handler)
  242. return true if self.superuser?(user)
  243. lp,dom = user.downcase.gsub(/[^\w@]/,"_").split('@')
  244. u = WH::Config.users.to_hash
  245. m = WH::Config.muc_handles.to_hash
  246. if commands.empty?
  247. hauth = {
  248. :allowed => "all"
  249. }
  250. else
  251. comms = {}
  252. commands.each do |c|
  253. comms[c.downcase.to_sym] = "allowed"
  254. end
  255. if u[dom.to_sym][lp.to_sym][:handlers] and u[dom.to_sym][lp.to_sym][:handlers][handler.downcase.to_sym] and u[dom.to_sym][lp.to_sym][:handlers][handler.downcase.to_sym][:commands]
  256. u[dom.to_sym][lp.to_sym][:handlers][handler.downcase.to_sym][:commands].each do |c,v|
  257. comms[c] = v
  258. end
  259. end
  260. hauth = {
  261. :allowed => "limited",
  262. :commands => comms
  263. }
  264. end
  265. u[dom.to_sym][lp.to_sym][:handlers] = {} unless u[dom.to_sym][lp.to_sym][:handlers]
  266. u[dom.to_sym][lp.to_sym][:handlers][handler.downcase.to_sym] = hauth
  267. u[dom.to_sym][lp.to_sym][:allowed] = "limited"
  268. config = {
  269. :users => u,
  270. :muc_handles => m
  271. }
  272. if self.write_yaml_local_config("users_local_conf",config)
  273. return true
  274. else
  275. return false
  276. end
  277. else
  278. return false
  279. end
  280. else
  281. return false
  282. end
  283. end
  284. def self.rm_access(user=nil,handler=nil,commands=[])
  285. if user
  286. # Don't allow super users to be toyed with
  287. return false if self.superuser?(user)
  288. # Remove the user if no handler is specified
  289. self.rm_user(user) unless handler
  290. return true unless self.user_defined?(user)
  291. return true unless self.user_allowed_handler?(user,handler.downcase)
  292. lp,dom = user.downcase.gsub(/[^\w@]/,"_").split('@')
  293. u = WH::Config.users.to_hash
  294. m = WH::Config.muc_handles.to_hash
  295. if commands.empty?
  296. # Remove complete access to the handler
  297. u[dom.to_sym][lp.to_sym][:handlers].delete(handler.downcase.to_sym)
  298. if u[dom.to_sym][lp.to_sym][:handlers].empty?
  299. # If we don't have any access left, user can be removed
  300. self.rm_user(user)
  301. end
  302. else
  303. # Just remove the commands that were provided
  304. commands.each do |c|
  305. next unless self.user_allowed_handler?(user,handler.downcase,c.downcase)
  306. u[dom.to_sym][lp.to_sym][:handlers][handler.downcase.to_sym][:commands].delete(c.to_sym)
  307. end
  308. end
  309. config = {
  310. :users => u,
  311. :muc_handles => m
  312. }
  313. if self.write_yaml_local_config("users_local_conf",config)
  314. self.reload_users
  315. return true
  316. else
  317. return false
  318. end
  319. else
  320. return false
  321. end
  322. end
  323. # Load default configuration
  324. @wh_config = configatron
  325. @wh_config.configure_from_hash({
  326. :daemon => {
  327. :user => 'workhorse',
  328. :group => 'workhorse',
  329. :client_syslog_facility => 'daemon'
  330. },
  331. :base => {
  332. :use_sudo => true,
  333. :sudo_path => '/usr/local/bin/sudo',
  334. :direct_default_response => false,
  335. :group_default_response => false,
  336. :workhorse_local_conf => File.join(File.dirname(__FILE__),'../../config/workhorse_local.yml'),
  337. :daemon_local_conf => File.join(File.dirname(__FILE__),'../../config/daemon_local.yml'),
  338. :handlers_local_conf => File.join(File.dirname(__FILE__),'../../config/handlers_local.yml'),
  339. :users_local_conf => File.join(File.dirname(__FILE__),'../../config/users_local.yml'),
  340. },
  341. :im => {
  342. :jid => 'username@staff.csolve.net',
  343. :domain => 'staff.csolve.net',
  344. :resource => 'Servers',
  345. :password => 'password',
  346. :channels => {
  347. 'allservers@conference.staff.csolve.net' => {
  348. :nick => 'nickname',
  349. :password => 'server4u'
  350. }
  351. }
  352. },
  353. :handlers => {
  354. :system => true,
  355. },
  356. :users => {
  357. },
  358. :muc_handles => {
  359. }
  360. })
  361. # Load workhorse local configuration
  362. self.load_local_config("workhorse_local_conf")
  363. # Load daemon local configuration
  364. self.load_local_config("daemon_local_conf")
  365. # Load handlers local configuration
  366. self.load_local_config("handlers_local_conf")
  367. # Load users local configuration
  368. self.load_local_config("users_local_conf")
  369. self.set_vars
  370. end
  371. end