lib/ixtlan/guard.rb in ixtlan-guard-0.1.0 vs lib/ixtlan/guard.rb in ixtlan-guard-0.4.0
- old
+ new
@@ -1,159 +2 @@
-require 'logger'
-module Ixtlan
- class ControllerGuard
-
- attr_accessor :name, :action_map, :aliases
-
- def initialize(name)
- @name = name.sub(/_guard$/, '').to_sym
- class_name = name.split(/\//).collect { |part| part.split("_").each { |pp| pp.capitalize! }.join }.join("::")
- Object.const_get(class_name).new(self)
- end
-
- def name=(name)
- @name = name.to_sym
- end
-
- def aliases=(map)
- @aliases = symbolize(map)
- end
-
- def action_map=(map)
- @action_map = symbolize(map)
- end
-
- private
-
- def symbolize(h)
- result = {}
-
- h.each do |k, v|
- if v.is_a?(Hash)
- result[k.to_sym] = symbolize_keys(v) unless v.size == 0
- elsif v.is_a?(Array)
- val = []
- v.each {|vv| val << vv.to_sym }
- result[k.to_sym] = val
- else
- result[k.to_sym] = v.to_sym
- end
- end
-
- result
- end
-
- end
-
- class Guard
-
- attr_accessor :logger, :guard_dir, :superuser, :block
-
- def initialize(logger = Logger.new(STDOUT), superuser = :root, guard_dir = File.join("app", "guards"), &block)
- @map = {}
- @aliases = {}
-
- @block =
- if block
- block
- else
- Proc.new do |controller|
- # get the groups of the current_user
- user = controller.send(:current_user) if controller.respond_to? :current_user
- user.groups if user
- end
- end
- @logger = logger
- @superuser = superuser
- @guard_dir = guard_dir
- end
-
- def setup
- if File.exists?(@guard_dir)
- Dir.new(guard_dir).to_a.each do |f|
- if f.match(".rb$")
- require(File.join(guard_dir, f))
- controller_guard = ControllerGuard.new(f.sub(/.rb$/, ''))
- register(controller_guard)
- end
- end
- logger.debug("initialized guard . . .")
- else
- raise GuardException.new("guard directory #{guard_dir} not found, skip loading")
- end
- end
-
- private
-
- def register(controller_guard)
- msg = controller_guard.action_map.collect{ |k,v| "\n\t#{k} => [#{v.join(',')}]"}
- @logger.debug("#{controller_guard.name} guard: #{msg}")
- @map[controller_guard.name] = controller_guard.action_map
- @aliases[controller_guard.name] = controller_guard.aliases || {}
- end
-
- public
-
- def block_groups(groups)
- @blocked = (groups || []).collect { |g| g.to_sym}
- end
-
- def blocked
- @blocked ||= []
- end
-
- def current_user_restricted?(controller)
- groups = @block.call(controller)
- if groups
-p groups
-p blocked
-p groups.select { |g| !blocked.member?(g.to_sym) }
- groups.select { |g| !blocked.member?(g.to_sym) }.size < groups.size
- else
- nil
- end
- end
-
- def check(controller, resource, action, &block)
- groups = @block.call(controller)
- if groups.nil?
- @logger.debug("check #{resource}##{action}: not authenticated")
- return true
- end
- resource = resource.to_sym
- action = action.to_sym
- if (@map.key? resource)
- action = @aliases[resource][action] || action
- allowed = @map[resource][action]
- if (allowed.nil?)
- @logger.warn("unknown action '#{action}' for controller '#{resource}'")
- raise ::Ixtlan::GuardException.new("unknown action '#{action}' for controller '#{resource}'")
- else
- allowed << @superuser unless allowed.member? @superuser
- allow_all_groups = allowed.member?(:*)
- if(allow_all_groups && block.nil?)
- @logger.debug("check #{resource}##{action}: allowed for all")
- return true
- else
- groups.each do |group|
- if (allow_all_groups || allowed.member?(group.to_sym)) && !blocked.member?(group.to_sym)
- if(block.nil? || block.call(group))
- @logger.debug("check #{resource}##{action}: true")
- return true
- end
- end
- end
- end
- @logger.debug("check #{resource}##{action}: false")
- return false
- end
- else
- @logger.warn("unknown controller for '#{resource}'")
- raise ::Ixtlan::GuardException.new("unknown controller for '#{resource}'")
- end
- end
- end
-
- class GuardException < Exception; end
- class PermissionDenied < GuardException; end
-end
-
+require 'ixtlan/guard/guard'