lib/ixtlan/guard/guard_ng.rb in ixtlan-guard-0.7.0 vs lib/ixtlan/guard/guard_ng.rb in ixtlan-guard-0.7.2
- old
+ new
@@ -2,10 +2,12 @@
module Ixtlan
module Guard
class GuardNG
+ attr_reader :superuser
+
def initialize(options = {})
options[:guards_dir] ||= File.expand_path(".")
@superuser = [(options[:superuser] || "root").to_s]
@config = Config.new(options)
@logger = options[:logger]
@@ -29,128 +31,127 @@
require 'logger'
Logger.new(STDOUT)
end
end
- def allowed_groups(resource, action, current_groups)
- allowed = @config.allowed_groups(resource, action) - blocked_groups + @superuser
+ def allowed_groups(resource_name, action, current_group_names)
+ allowed = @config.allowed_groups(resource_name, action) - blocked_groups + @superuser
if allowed.member?('*')
- current_groups - (blocked_groups - @superuser)
+ # keep superuser in current_groups if in there
+ current_group_names - (blocked_groups - @superuser)
else
- intersect(allowed, current_groups)
+ allowed & current_group_names
end
end
- def allowed?(resource, action, current_groups, flavor = nil, &block)
- current_groups = current_groups.collect { |g| g.to_s }
- allowed_groups = self.allowed_groups(resource, action, current_groups)
- logger.debug { "guard #{resource}##{action}: #{allowed_groups.size > 0}" }
- if allowed_groups.size > 0
- if block
- g = allowed_groups.detect do |group|
- block.call(group).member?(flavor)
- end
- logger.debug do
- if g
- "found group #{g} for #{flavor}"
- else
- "no group found for #{flavor}"
- end
- end
- g != nil
+ def group_map(current_groups)
+ names = current_groups.collect do |g|
+ key = case g
+ when String
+ g
+ when Symbol
+ g.to_s
+ else
+ g.name.to_s
+ end
+ [key, g]
+ end
+ Hash[*(names.flatten)]
+ end
+ private :group_map
+
+ def allowed?(resource_name, action, current_groups, association = nil, &block)
+ group_map = group_map(current_groups)
+ allowed_group_names = allowed_groups(resource_name, action, group_map.keys)
+ logger.debug { "guard #{resource_name}##{action}: #{allowed_group_names.size > 0}" }
+ if allowed_group_names.size > 0
+ if block || association
+ group_allowed?(group_map, allowed_group_names, association, &block)
else
true
end
else
- unless @config.has_guard?(resource)
- raise ::Ixtlan::Guard::GuardException.new("no guard config for '#{resource}'")
+ unless @config.has_guard?(resource_name)
+ raise ::Ixtlan::Guard::GuardException.new("no guard config for '#{resource_name}'")
else
false
end
end
end
- def permissions(current_groups, flavors = {})
+ def group_allowed?(group_map, allowed_group_names, association, &block)
+ g = allowed_group_names.detect do |group_name|
+ block.call(group_map[group_name], association)
+ end if association && block
+ logger.debug do
+ if g
+ "found group #{g} for #{association}"
+ else
+ "no group found for #{association}"
+ end
+ end
+ g != nil
+ end
+
+ def permissions(current_groups, &block)
+ group_map = group_map(current_groups)
perms = []
m = @config.map_of_all
m.each do |resource, actions|
nodes = []
perm = Node.new(:permission)
perm[:resource] = resource
perm[:actions] = nodes
- defaults = actions.delete('defaults') || []
- defaults = intersect(current_groups, defaults + @superuser) unless defaults.member?('*')
- # no actions
- # deny = false: !defaults.member?('*')
- # deny = true: defaults.member?('*') || current_groups.member?(@superuser[0])
+ default_actions = actions.delete('defaults') || []
+ default_actions = group_map.keys & (default_actions + @superuser) unless default_actions.member?('*')
deny = if actions.size == 0
- defaults.member?('*') || current_groups.member?(@superuser[0])
+ # no actions
+ # deny = false: !default_actions.member?('*')
+ # deny = true: default_actions.member?('*') || current_group_names.member?(@superuser[0])
+ default_actions.member?('*') || group_map.keys.member?(@superuser[0]) || !group_map.keys.detect {|g| default_actions.member? g }.nil?
else
# actions
- # deny = false : defaults == []
- # deny = true : defaults.member?('*')
- defaults.size != 0 || defaults.member?('*')
+ # deny = false : default_actions == []
+ # deny = true : default_actions.member?('*')
+ default_actions.size != 0 || default_actions.member?('*')
end
perm[:deny] = deny
actions.each do |action, groups|
+ group_names = groups.collect { |g| g.is_a?(Hash) ? g.keys : g }.flatten if groups
node = Node.new(:action)
allowed_groups =
- if groups && groups.member?('*')
- current_groups
+ if groups && group_names.member?('*')
+ group_map.values
else
- intersect(current_groups, (groups || []) + @superuser)
+ names = group_map.keys & ((group_names || []) + @superuser)
+ names.collect { |name| group_map[name] }
end
if (deny && allowed_groups.size == 0) || (!deny && allowed_groups.size > 0)
node[:name] = action
-# f = {}
-# flavors.each do |fl, block|
-# f[fl] = block.call(allowed_groups)
-# end
-# node[:flavors] = f if f.size > 0
+ if block
+ if allowed_groups.size > 0
+ node.content.merge!(block.call(resource, action, allowed_groups) || {})
+ else
+ perm.content.merge!(block.call(resource, action, group_map.values) || {})
+ end
+ end
nodes << node
end
end
+ # TODO is that right like this ?
+ # only default_actions, i.e. no actions !!!
+ if block && actions.size == 0 && deny
+ perm.content.merge!(block.call(resource, nil, group_map.values) || {})
+ end
perms << perm
end
perms
end
-
- def permission_map(current_groups, flavors = {})
- # TODO fix it - think first !!
- perms = {}
- m = @config.map_of_all
- m.each do |resource, actions|
- nodes = {}
- actions.each do |action, groups|
- if action == 'defaults'
- nodes[action] = {}
- else
- allowed_groups = intersect(current_groups, (groups || []) + @superuser)
- if allowed_groups.size > 0
- f = {}
- flavors.each do |fl, block|
- flav = block.call(allowed_groups)
- f[fl] = flav if flav.size > 0
- end
- nodes[action] = f
- else
- nodes[action] = nil # indicates not default action
- end
- end
- end
- perms[resource] = nodes if nodes.size > 0
- end
- perms
- end
-
- private
-
- def intersect(set1, set2)
- set1 - (set1 - set2)
- end
end
class Node < Hash
-
+
+ attr_reader :content
+
def initialize(name)
map = super
@content = {}
merge!({ name => @content })
end