Skip to content

Commit

Permalink
added specs for associations and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mkristian committed Jan 29, 2012
1 parent 16f3f88 commit 2d678f6
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 122 deletions.
71 changes: 18 additions & 53 deletions lib/ixtlan/guard/guard_ng.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def allowed_groups(resource_name, action, current_group_names)
# keep superuser in current_groups if in there
current_group_names - (blocked_groups - @superuser)
else
intersect(allowed, current_group_names)
allowed & current_group_names
end
end

Expand Down Expand Up @@ -101,86 +101,51 @@ def permissions(current_groups, &block)
perm = Node.new(:permission)
perm[:resource] = resource
perm[:actions] = nodes
defaults = actions.delete('defaults') || []
defaults = intersect(group_map.keys, defaults + @superuser) unless defaults.member?('*')
default_actions = actions.delete('defaults') || []
default_actions = group_map.keys & (default_actions + @superuser) unless default_actions.member?('*')
deny = if actions.size == 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])
# 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?('*')
if groups && group_names.member?('*')
group_map.values
else
names = intersect(group_map.keys, (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
if block
if block
if allowed_groups.size > 0
node.content.merge!(block.call(allowed_groups))
node.content.merge!(block.call(resource, action, allowed_groups) || {})
else
perm.content.merge!(block.call(group_map.values))
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(group_map.values))
perm.content.merge!(block.call(resource, nil, group_map.values) || {})
end
perms << perm
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

Expand Down
2 changes: 1 addition & 1 deletion lib/ixtlan/guard/guard_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def check(association = nil, &block)
association,
&block)
if association
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}##{association}'")
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}##{association.class}(#{association.id})'")
else
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}'")
end
Expand Down
112 changes: 72 additions & 40 deletions spec/guard_export_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def logger.debug(&block)
#allow nothing
{:permission=>{:resource=>"person", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"regions", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"users", :actions=>[], :deny=>false}}]
end
it 'should deny some without defaults but wildcard "*" actions' do
Expand All @@ -58,15 +60,17 @@ def logger.debug(&block)
:resource=>"no_defaults",
:actions=>
[{:action=>{:name=>"edit"}},
{:action=>{:name=>"show"}},
{:action=>{:name=>"index"}}],
{:action=>{:name=>"index"}},
{:action=>{:name=>"show"}}],
:deny=>false #allow
}
},
{:permission=>{:resource=>"only_defaults", :actions=>[], :deny=>true}},
#allow nothing
{:permission=>{:resource=>"person", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"regions", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"users", :actions=>[], :deny=>false}}]
end
it 'should allow "root"' do
Expand All @@ -77,6 +81,7 @@ def logger.debug(&block)
{:permission=>{:resource=>"no_defaults", :actions=>[], :deny=>true}},
{:permission=>{:resource=>"only_defaults", :actions=>[], :deny=>true}},
{:permission=>{:resource=>"person", :actions=>[], :deny=>true}},
{:permission=>{:resource=>"regions", :actions=>[], :deny=>true}},
{:permission=>{:resource=>"users", :actions=>[], :deny=>true}}]
end
it 'should allow with default group' do
Expand All @@ -88,8 +93,8 @@ def logger.debug(&block)
{:permission=>
{
:resource=>"defaults",
:actions=>[{:action=>{:name=>"destroy"}},
{:action=>{:name=>"show"}}],
:actions=>[{:action=>{:name=>"show"}},
{:action=>{:name=>"destroy"}}],
:deny=>true
}
},
Expand All @@ -104,8 +109,11 @@ def logger.debug(&block)
#allow nothing
{:permission=>{:resource=>"person", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"regions", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"users", :actions=>[], :deny=>false}}]
end
end

it 'should allow with non-default group' do
subject.permissions(['_admin']).sort { |n,m| n[:resource] <=> m[:resource] }.should == [
#allow nothing
Expand All @@ -116,8 +124,8 @@ def logger.debug(&block)
{
:resource=>"defaults",
:actions=>[{:action=>{:name=>"edit"}},
{:action=>{:name=>"show"}},
{:action=>{:name=>"index"}}],
{:action=>{:name=>"index"}},
{:action=>{:name=>"show"}}],
:deny=>false # allow
}
},
Expand All @@ -132,40 +140,64 @@ def logger.debug(&block)
#allow nothing
{:permission=>{:resource=>"person", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"regions", :actions=>[], :deny=>false}},
#allow nothing
{:permission=>{:resource=>"users", :actions=>[], :deny=>false}}]
end
end

# context '#permission_map' do
# it 'should export' do
# pending "check expectations before implementing specs"
# subject.permission_map(['admin']).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>{}, "index"=>{}}, "accounts"=>{"defaults"=>nil, "destroy"=>{}, "show"=>nil}}

# subject.permission_map(['manager']).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>nil, "index"=>{}}, "accounts"=>{"defaults"=>nil, "destroy"=>nil, "show"=>{}}}

# subject.permission_map(['manager', 'admin']).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>{}, "index"=>{}}, "accounts"=>{"defaults"=>nil, "destroy"=>{}, "show"=>{}}}

# subject.permission_map(['users']).should == {"users"=>{"defaults"=>{}}, "person"=>{"defaults"=>nil, "destroy"=>nil, "index"=>nil}, "accounts"=>{"defaults"=>nil, "destroy"=>nil, "show"=>nil}}
# end

# it 'should export with flavor' do
# pending "check expectations before implementing specs"

# flavors = { 'admin' => ['example', 'dummy'], 'manager' => ['example', 'master'] }

# domains = Proc.new do |groups|
# groups.collect do |g|
# flavors[g] || []
# end.flatten.uniq
# end

# subject.permission_map(['admin'], 'domains' => domains).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>{'domains'=>["example", "dummy"]}, "index"=>{'domains'=>["example", "dummy"]}}, "accounts"=>{"defaults"=>nil, "destroy"=>{'domains'=>["example", "dummy"]}, "show"=>nil}}

# subject.permission_map(['manager'], 'domains' => domains).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>nil, "index"=>{"domains"=>["example", "master"]}}, "accounts"=>{"defaults"=>nil, "destroy"=>nil, "show"=>{"domains"=>["example", "master"]}}}

# subject.permission_map(['manager', 'admin'], 'domains' => domains).should == {"users"=>{"defaults"=>nil}, "person"=>{"defaults"=>nil, "destroy"=>{"domains"=>["example", "dummy"]}, "index"=>{"domains"=>["example", "master", "dummy"]}}, "accounts"=>{"defaults"=>nil, "destroy"=>{"domains"=>["example", "dummy"]}, "show"=>{"domains"=>["example", "master"]}}}

# subject.permission_map(['users'], 'domains' => domains).should == {"users"=>{"defaults"=>{}}, "person"=>{"defaults"=>nil, "destroy"=>nil, "index"=>nil}, "accounts"=>{"defaults"=>nil, "destroy"=>nil, "show"=>nil}}
# end
# end
it 'should allow with association' do
group = Object.new
def group.name
"region"
end
subject.permissions([group])do |resource, action, groups|
if resource == 'regions'
case action
when 'show'
{:associations => [:europe, :asia]}
else
{}
end
else
{}
end
end.sort { |n,m| n[:resource] <=> m[:resource] }.should == [
#allow nothing
{:permission=>{:resource=>"accounts", :actions=>[], :deny=>false}},
# allow anything but index
{:permission=>
{
:resource=>"allow_all_defaults",
:actions=>[{:action=>{:name=>"index"}}],
:deny=>true
}
},
{:permission=>
{
:resource=>"defaults",
:actions=>[{:action=>{:name=>"index"}}],
:deny=>false # allow
}
},
{:permission=>
{
:resource=>"no_defaults",
:actions=>[{:action=>{:name=>"index"}}],
:deny=>false #allow
}
},
{:permission=>{:resource=>"only_defaults", :actions=>[], :deny=>true}},
#allow nothing
{:permission=>{:resource=>"person", :actions=>[], :deny=>false}},

{:permission=>
{:resource=>"regions",
:actions=>
[{:action=>{:name=>"show", :associations=>[:europe, :asia]}},
{:action=>{:name=>"create"}}],
:deny=>false}},
#allow nothing
{:permission=>{:resource=>"users", :actions=>[], :deny=>false}}]
end
end
end
64 changes: 36 additions & 28 deletions spec/guard_with_associations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,48 +47,39 @@ def logger.debug(&block)
end

it 'should add associations to node' do
subject.permissions([Group.new('admin', [:german, :french])]) do |groups|
subject.permissions([Group.new('admin', [:german, :french])]) do |resource, action, groups|
if groups && groups.first && groups.first.name == 'admin'
{ :domains => groups.first.domains }
else
{}
end
end.should ==
end.sort { |m,n| m[:resource] <=> n[:resource]}.should ==
[{
:permission=>{
:resource=>"person",
:actions=> [{:action=>{
:domains=>[:german, :french],
:name=>"destroy"}},
{:action=>{
:domains=>[:german, :french],
:name=>"index"}}],
:deny=>false}},
:resource=>"accounts",
:actions=>[{:action=>{
:name=>"destroy",
:domains=>[:german, :french]}}],
:deny=>false}},
{
:permission=>{
:resource=>"accounts",
:actions=>[{:action=>{
:domains=>[:german, :french],
:name=>"destroy"}}],
:deny=>false}},
:resource=>"allow_all_defaults",
:actions=>[{:action=>{:name=>"index"}}],
:deny=>true,
:domains=>[:german, :french]}},
{
:permission=>{
:resource=>"defaults",
:actions=>[{:action=>{
:domains=>[:german, :french],
:name=>"index"}}],
:name=>"index",
:domains=>[:german, :french]}}],
:deny=>false}},
{
:permission=>{
:resource=>"no_defaults",
:actions=>[{:action=>{
:domains=>[:german, :french],
:name=>"index"}}],
:deny=>false}},
{
:permission=>{
:resource=>"users",
:actions=>[],
:name=>"index",
:domains=>[:german, :french]}}],
:deny=>false}},
{
:permission=>{
Expand All @@ -98,9 +89,26 @@ def logger.debug(&block)
:deny=>true}},
{
:permission=>{
:resource=>"allow_all_defaults",
:domains=>[:german, :french],
:actions=>[{:action=>{:name=>"index"}}],
:deny=>true}}]
:resource=>"person",
:actions=> [{:action=>{
:name=>"destroy",
:domains=>[:german, :french]}},
{:action=>{
:name=>"index",
:domains=>[:german, :french]}}],
:deny=>false}},
{
:permission=>{
:resource=>"regions",
:actions=>[
{:action=>{:name=>"show", :domains=>[:german, :french]}},
{:action=>{:name=>"create", :domains=>[:german, :french]}}
],
:deny=>false}},
{
:permission=>{
:resource=>"users",
:actions=>[],
:deny=>false}}]
end
end
8 changes: 8 additions & 0 deletions spec/guards/regions_guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
regions:
show:
- admin
# not sure if that stays like this
- region: [regions]
create:
- admin
- region

0 comments on commit 2d678f6

Please sign in to comment.