Permalink
Browse files

use groups instead of names. get association to work with rails.

  • Loading branch information...
1 parent 0a51b8c commit 16f3f88cfbef214d52fe4b60e7d0420c8c1e8e5c @mkristian committed Dec 15, 2011
@@ -4,6 +4,8 @@ module Ixtlan
module Guard
class GuardNG
+ attr_reader :superuser
+
def initialize(options = {})
options[:guards_dir] ||= File.expand_path(".")
@superuser = [(options[:superuser] || "root").to_s]
@@ -31,45 +33,67 @@ def logger
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)
+ intersect(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|
@@ -78,12 +102,12 @@ def permissions(current_groups, flavors = {})
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])
+ defaults = intersect(group_map.keys, defaults + @superuser) unless defaults.member?('*')
deny = if actions.size == 0
- defaults.member?('*') || current_groups.member?(@superuser[0])
+ # no actions
+ # deny = false: !defaults.member?('*')
+ # deny = true: defaults.member?('*') || current_group_names.member?(@superuser[0])
+ defaults.member?('*') || group_map.keys.member?(@superuser[0])
else
# actions
# deny = false : defaults == []
@@ -95,61 +119,73 @@ def permissions(current_groups, flavors = {})
node = Node.new(:action)
allowed_groups =
if groups && groups.member?('*')
- current_groups
+ group_map.values
else
- intersect(current_groups, (groups || []) + @superuser)
+ names = intersect(group_map.keys, (groups || []) + @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(allowed_groups))
+ else
+ perm.content.merge!(block.call(group_map.values))
+ end
+ end
nodes << node
end
end
+ if block && actions.size == 0 && deny
+ perm.content.merge!(block.call(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
+ # def permission_map(current_groups, associations = {})
+ # # 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 = {}
+ # associations.each do |a, block|
+ # asso = block.call(allowed_groups)
+ # f[a] = asso if asso.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
+
+ def union(set1, set2)
+ set1 - set2 + set2
+ end
end
class Node < Hash
-
+
+ attr_reader :content
+
def initialize(name)
map = super
@content = {}
@@ -12,9 +12,7 @@ module GroupsMethod
def groups_for_current_user
if respond_to?(:current_user) && current_user
- current_user.groups.collect do |group|
- group.name
- end
+ current_user.groups
else
[]
end
@@ -37,23 +35,25 @@ def guard
Rails.application.config.guard
end
- def check(flavor = nil, &block)
- group_method = respond_to?(:current_user_group_names) ? :current_user_group_names : :groups_for_current_user
+ def check(association = nil, &block)
+ group_method = respond_to?(:current_user_groups) ? :current_user_groups : :groups_for_current_user
unless guard.allowed?(params[:controller],
params[:action],
send(group_method),
- flavor,
+ association,
&block)
- if flavor
- raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}##{flavor}'")
+ if association
+ raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}##{association}'")
else
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}'")
end
end
true
end
+ alias :authorize :check
def authorization
+ warn "DEPRECATED: use 'authorize' instead"
check
end
end
@@ -23,7 +23,7 @@ class Railtie < Rails::Railtie
app.config.guard = Ixtlan::Guard::GuardNG.new(options)
::ActionController::Base.send(:include, Ixtlan::ActionController::Guard)
- ::ActionController::Base.send(:before_filter, :authorization)
+ ::ActionController::Base.send(:before_filter, :authorize)
::ActionView::Base.send(:include, Ixtlan::Allowed)
end
View
@@ -9,7 +9,7 @@
$source2 = File.join(File.dirname(__FILE__), "guards", "users2_guard.yml")
$logger = Logger.new(STDOUT)
def $logger.debug(&block)
- info("\n\t[debug] " + block.call)
+# info("\n\t[debug] " + block.call)
end
describe Ixtlan::Guard::GuardNG do
Oops, something went wrong.

0 comments on commit 16f3f88

Please sign in to comment.