aclatraz 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +21 -0
- data/README.rdoc +221 -57
- data/Rakefile +9 -2
- data/TODO.rdoc +6 -0
- data/VERSION +1 -1
- data/aclatraz.gemspec +88 -0
- data/examples/dinner.rb +71 -0
- data/lib/aclatraz.rb +34 -12
- data/lib/aclatraz/acl.rb +82 -7
- data/lib/aclatraz/guard.rb +139 -57
- data/lib/aclatraz/helpers.rb +14 -6
- data/lib/aclatraz/store.rb +3 -7
- data/lib/aclatraz/store/redis.rb +11 -11
- data/lib/aclatraz/suspect.rb +157 -57
- data/spec/aclatraz/acl_spec.rb +8 -3
- data/spec/aclatraz/guard_spec.rb +178 -121
- data/spec/aclatraz/stores_spec.rb +1 -26
- data/spec/aclatraz/suspect_spec.rb +25 -25
- data/spec/aclatraz_spec.rb +16 -2
- data/spec/alcatraz_bm.rb +54 -0
- data/spec/spec_helper.rb +7 -0
- metadata +12 -5
data/lib/aclatraz/helpers.rb
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
module Aclatraz
|
2
2
|
module Helpers
|
3
|
-
|
3
|
+
# Pack given permission data.
|
4
|
+
#
|
5
|
+
# pack(10) # => "10"
|
6
|
+
# pack(10, "FooClass") # => "10/FooClass"
|
7
|
+
# pack(10, FooClass.new) # => "10/FooClass/{foo_object_ID}"
|
8
|
+
def pack(owner, object=nil)
|
4
9
|
case object
|
5
10
|
when nil
|
6
|
-
"#{
|
11
|
+
"#{owner}"
|
7
12
|
when Class
|
8
|
-
"#{
|
13
|
+
"#{owner}/#{object.name}"
|
9
14
|
else
|
10
|
-
"#{
|
15
|
+
"#{owner}/#{object.class.name}/#{object.id}"
|
11
16
|
end
|
12
17
|
end
|
13
18
|
|
19
|
+
# Given underscored word, returns camelized version of it.
|
20
|
+
#
|
21
|
+
# camelize(foo_bar_bla) # => "FooBarBla"
|
14
22
|
def camelize(str)
|
15
23
|
str.split('_').map {|w| w.capitalize}.join
|
16
24
|
end
|
17
|
-
end
|
18
|
-
end
|
25
|
+
end # Helpers
|
26
|
+
end # Aclatraz
|
data/lib/aclatraz/store.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
module Aclatraz
|
2
2
|
module Store
|
3
|
-
#autoload :Memcached, 'aclatraz/store/memcached'
|
4
3
|
autoload :Redis, 'aclatraz/store/redis'
|
4
|
+
#autoload :Memcached, 'aclatraz/store/memcached'
|
5
5
|
#autoload :TokyoCabinet, 'aclatraz/store/tokyocabinet'
|
6
|
-
|
7
|
-
|
8
|
-
include Aclatraz::Helpers
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
6
|
+
end # Store
|
7
|
+
end # Aclatraz
|
data/lib/aclatraz/store/redis.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
begin
|
2
2
|
require 'redis'
|
3
3
|
rescue LoadError
|
4
|
-
raise "You must install redis to use the Redis store
|
4
|
+
raise "You must install the redis gem to use the Redis store"
|
5
5
|
end
|
6
6
|
|
7
7
|
module Aclatraz
|
8
8
|
module Store
|
9
|
-
class Redis
|
9
|
+
class Redis
|
10
|
+
include Aclatraz::Helpers
|
11
|
+
|
10
12
|
ROLES_KEY = "aclatraz.roles"
|
11
13
|
MEMBER_ROLES_KEY = "member.%s.roles"
|
12
14
|
|
13
|
-
def initialize(*args)
|
15
|
+
def initialize(*args) # :nodoc:
|
14
16
|
@backend = ::Redis.new(*args)
|
15
17
|
end
|
16
18
|
|
@@ -24,10 +26,6 @@ module Aclatraz
|
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
27
|
-
def permissions(role)
|
28
|
-
@backend.smembers(role.to_s)
|
29
|
-
end
|
30
|
-
|
31
29
|
def roles(member=nil)
|
32
30
|
if member
|
33
31
|
@backend.hkeys(MEMBER_ROLES_KEY % member.id.to_s)
|
@@ -37,7 +35,9 @@ module Aclatraz
|
|
37
35
|
end
|
38
36
|
|
39
37
|
def check(role, owner, object=nil)
|
40
|
-
@backend.sismember(role.to_s, pack(owner.id, object))
|
38
|
+
@backend.sismember(role.to_s, pack(owner.id, object)) or begin
|
39
|
+
object && !object.is_a?(Class) ? check(role, owner, object.class) : false
|
40
|
+
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def delete(role, owner, object=nil)
|
@@ -47,6 +47,6 @@ module Aclatraz
|
|
47
47
|
def clear
|
48
48
|
@backend.flushdb
|
49
49
|
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
50
|
+
end # Redis
|
51
|
+
end # Store
|
52
|
+
end # Aclatraz
|
data/lib/aclatraz/suspect.rb
CHANGED
@@ -1,90 +1,190 @@
|
|
1
1
|
module Aclatraz
|
2
2
|
module Suspect
|
3
|
+
class Roles
|
4
|
+
# These suffixes will be ignored while checking permission.
|
5
|
+
ACL_ROLE_SUFFIXES = /(_(of|at|on|by|for|in))?\Z/
|
6
|
+
|
7
|
+
# Permissions will be checked for this object.
|
8
|
+
attr_reader :suspect
|
9
|
+
|
10
|
+
def initialize(suspect) # :nodoc:
|
11
|
+
@suspect = suspect
|
12
|
+
end
|
13
|
+
|
14
|
+
# Check if current object has assigned given role.
|
15
|
+
#
|
16
|
+
# ==== Examples
|
17
|
+
#
|
18
|
+
# suspect.roles.assign(:foo)
|
19
|
+
# suspect.roles.has?(:foo) # => true
|
20
|
+
# suspect.roles.has?(:bar) # => false
|
21
|
+
def has?(role, object=nil)
|
22
|
+
Aclatraz.store.check(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), suspect, object)
|
23
|
+
end
|
24
|
+
alias_method :check?, :has?
|
25
|
+
|
26
|
+
# Assigns given role to current object.
|
27
|
+
#
|
28
|
+
# ==== Examples
|
29
|
+
#
|
30
|
+
# suspect.roles.has?(:foo) # => false
|
31
|
+
# suspect.roles.assign(:foo)
|
32
|
+
# suspect.roles.has?(:foo) # => true
|
33
|
+
def assign(role, object=nil)
|
34
|
+
Aclatraz.store.set(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), suspect, object)
|
35
|
+
end
|
36
|
+
alias_method :add, :assign
|
37
|
+
alias_method :append, :assign
|
38
|
+
|
39
|
+
# Removes given role from current object.
|
40
|
+
#
|
41
|
+
# ==== Examples
|
42
|
+
#
|
43
|
+
# suspect.roles.assign(:foo)
|
44
|
+
# suspect.roles.has?(:foo) # => true
|
45
|
+
# suspect.roles.delete(:foo)
|
46
|
+
# suspect.roles.has?(:foo) # => false
|
47
|
+
def delete(role, object=nil)
|
48
|
+
Aclatraz.store.delete(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), suspect, object)
|
49
|
+
end
|
50
|
+
alias_method :remove, :delete
|
51
|
+
|
52
|
+
# Returns list of roles assigned to current object.
|
53
|
+
#
|
54
|
+
# ==== Examples
|
55
|
+
#
|
56
|
+
# suspect.roles.assign(:foo)
|
57
|
+
# suspect.roles.assign(:bar)
|
58
|
+
# suspect.roles.all # => ["foo", "bar"]
|
59
|
+
def all
|
60
|
+
Aclatraz.store.roles(self)
|
61
|
+
end
|
62
|
+
alias_method :list, :all
|
63
|
+
end # Roles
|
64
|
+
|
3
65
|
class SemanticRoles
|
4
|
-
class Base
|
5
|
-
|
6
|
-
|
7
|
-
attr_reader :suspect
|
66
|
+
class Base < Aclatraz::Suspect::Roles
|
67
|
+
# Role name can have following formats:
|
68
|
+
ROLE_FORMAT = /(_(of|at|on|by|for|in))?(\?|\!)\Z/
|
8
69
|
|
9
|
-
|
10
|
-
|
70
|
+
# Check if specified suspect have assigned given role. If true, then
|
71
|
+
# given block will be executed.
|
72
|
+
def reader(*args, &blk)
|
73
|
+
authorized = has?(*args)
|
74
|
+
blk.call if authorized && block_given?
|
75
|
+
authorized
|
11
76
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
77
|
+
|
78
|
+
# Assigns given role to specified suspect.
|
79
|
+
def writer(*args)
|
80
|
+
assign(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Provides syntactic sugars for checking and assigning roles.
|
84
|
+
#
|
85
|
+
# ==== Examples
|
86
|
+
#
|
87
|
+
# checking permissions...
|
88
|
+
# manager?
|
89
|
+
# owner_of?(object)
|
90
|
+
# manager_of?(Class)
|
91
|
+
# responsible_for?(object)
|
92
|
+
#
|
93
|
+
# writing permissions...
|
94
|
+
# responsible_for!(object)
|
95
|
+
# manager!
|
96
|
+
#
|
97
|
+
# ==== Accepted method names
|
98
|
+
#
|
99
|
+
# * role_name
|
100
|
+
# * role_name<strong>_of</strong>
|
101
|
+
# * role_name<strong>_at</strong>
|
102
|
+
# * role_name<strong>_by</strong>
|
103
|
+
# * role_name<strong>_in</strong>
|
104
|
+
# * role_name<strong>_on</strong>
|
105
|
+
# * role_name<strong>_for</strong>
|
106
|
+
|
15
107
|
def method_missing(meth, *args, &blk)
|
16
108
|
meth = meth.to_s
|
17
|
-
if meth =~
|
18
|
-
|
19
|
-
role
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
authorized = suspect.has_role?(*args.unshift(role.to_sym))
|
24
|
-
blk.call if authorized && block_given?
|
25
|
-
authorized
|
26
|
-
end
|
109
|
+
if meth =~ ROLE_FORMAT
|
110
|
+
write = meth[-1].chr == "!"
|
111
|
+
role = meth.gsub(ROLE_FORMAT, '')
|
112
|
+
args.unshift(role.to_sym)
|
113
|
+
write ? writer(*args) : reader(*args, &blk)
|
27
114
|
else
|
28
115
|
# super doesn't work here, so...
|
29
116
|
raise NoMethodError, "undefined local variable or method method `#{meth}' for #{inspect}:#{self.class.name}"
|
30
117
|
end
|
31
118
|
end
|
32
|
-
end
|
119
|
+
end # Base
|
120
|
+
|
121
|
+
class Yes < Base
|
122
|
+
# nothing to do, only syntactic sugar...
|
123
|
+
end # Yes
|
33
124
|
|
34
125
|
class Not < Base
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
deleter = meth[-1].chr == "!"
|
39
|
-
role = meth.gsub(ROLE_SUFFIXES, '')
|
40
|
-
if deleter
|
41
|
-
suspect.delete_role!(*args.unshift(role))
|
42
|
-
else
|
43
|
-
authorized = suspect.has_role?(*args.unshift(role.to_sym))
|
44
|
-
blk.call if !authorized && block_given?
|
45
|
-
!authorized
|
46
|
-
end
|
47
|
-
else
|
48
|
-
raise NoMethodError, "undefined local variable or method method `#{meth}' for #{inspect}:#{self.class.name}"
|
49
|
-
end
|
126
|
+
# Deletes given role from suspected object.
|
127
|
+
def writer(*args)
|
128
|
+
delete(*args)
|
50
129
|
end
|
51
|
-
|
52
|
-
|
130
|
+
|
131
|
+
# Check if specified suspect have assigned given role. If don't, then
|
132
|
+
# given block will be executed and +true+ returned.
|
133
|
+
def reader(*args, &blk)
|
134
|
+
authorized = has?(*args)
|
135
|
+
blk.call if !authorized && block_given?
|
136
|
+
!authorized
|
137
|
+
end
|
138
|
+
end # Not
|
139
|
+
end # SemanticRoles
|
53
140
|
|
54
|
-
def self.included(base)
|
141
|
+
def self.included(base) # :nodoc:
|
55
142
|
base.send :include, InstanceMethods
|
56
143
|
end
|
57
144
|
|
58
145
|
module InstanceMethods
|
59
|
-
|
60
|
-
|
61
|
-
def acl_suspect?
|
146
|
+
def acl_suspect? # :nodoc:
|
62
147
|
true
|
63
148
|
end
|
64
149
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
|
150
|
+
# Allows to manage roles assigned to current object.
|
151
|
+
#
|
152
|
+
# ==== Examples
|
153
|
+
#
|
154
|
+
# roles.assign(:foo)
|
155
|
+
# roles.has?(:foo) # => true
|
156
|
+
# roles.delete(:foo)
|
157
|
+
# roles.has?(:foo) # => false
|
158
|
+
# roles.assign(:foo, ClassName)
|
159
|
+
# roles.assign(:foo, object)
|
77
160
|
def roles
|
78
|
-
|
161
|
+
@roles ||= Roles.new(self)
|
79
162
|
end
|
80
163
|
|
164
|
+
# Port to semantic roles management.
|
165
|
+
#
|
166
|
+
# ==== Examples
|
167
|
+
#
|
168
|
+
# roles.is.foo! # equivalent to `roles.assign(:foo)`
|
169
|
+
# roles.is.foo? # => true
|
170
|
+
# roles.is.manager_of!(ClassName) # equivalent to `roles.assign(:manager, ClassName)`
|
171
|
+
# rikes.is.manager_of?(ClassName) # => true
|
81
172
|
def is
|
82
173
|
@acl_is ||= SemanticRoles::Yes.new(self)
|
83
174
|
end
|
84
175
|
|
176
|
+
# Port to semantic roles management.
|
177
|
+
#
|
178
|
+
# ==== Examples
|
179
|
+
#
|
180
|
+
# roles.is_not.foo! # equivalent to `roles.delete(:foo)`
|
181
|
+
# roles.is.foo? # => false
|
182
|
+
# roles.is_not.foo? # => true
|
183
|
+
# roles.is.manager_of!(ClassName) # equivalent to `roles.delete(:manager, ClassName)`
|
184
|
+
# roles.is.manager_of?(ClassName) # => flase
|
85
185
|
def is_not
|
86
186
|
@acl_is_not ||= SemanticRoles::Not.new(self)
|
87
187
|
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
188
|
+
end # InstanceMethods
|
189
|
+
end # Suspect
|
190
|
+
end # Aclatraz
|
data/spec/aclatraz/acl_spec.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Aclatraz ACL" do
|
4
|
-
before(:all) { Aclatraz.
|
4
|
+
before(:all) { Aclatraz.init(:redis, "redis://localhost:6379/0") }
|
5
|
+
|
6
|
+
it "should properly store suspect" do
|
7
|
+
acl = Aclatraz::ACL.new(:bar) {}
|
8
|
+
acl.suspect.should == :bar
|
9
|
+
end
|
5
10
|
|
6
11
|
it "should properly store flat access control lists" do
|
7
|
-
acl = Aclatraz::ACL.new {}
|
12
|
+
acl = Aclatraz::ACL.new(:foo) {}
|
8
13
|
acl.actions[:_].allow :foo
|
9
14
|
acl.permissions[:foo].should be_true
|
10
15
|
acl.actions[:_].deny :foo
|
@@ -14,7 +19,7 @@ describe "Aclatraz ACL" do
|
|
14
19
|
end
|
15
20
|
|
16
21
|
it "should allow for define seperated lists which are inherit from main block" do
|
17
|
-
acl = Aclatraz::ACL.new do
|
22
|
+
acl = Aclatraz::ACL.new(:foo) do
|
18
23
|
allow :foo
|
19
24
|
on(:spam) { allow :spam }
|
20
25
|
on(:eggs) { allow :eggs }
|
data/spec/aclatraz/guard_spec.rb
CHANGED
@@ -1,148 +1,205 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Aclatraz guard" do
|
4
|
-
|
4
|
+
before(:all) { Aclatraz.init(:redis, "redis://localhost:6379/0") }
|
5
|
+
let(:suspect) { @foo ||= StubSuspect.new }
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
subject { Class.new(StubGuarded) }
|
8
|
+
|
9
|
+
it "#acl_guard? should be true" do
|
10
|
+
subject.acl_guard?.should be_true
|
11
|
+
end
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
it "should properly guard permissions" do
|
14
|
+
guarded_class = subject
|
15
|
+
guarded_class.name = "test1"
|
16
|
+
|
17
|
+
guarded_class.suspects suspect do
|
18
|
+
allow :role1
|
19
|
+
deny :role2
|
20
|
+
on :bar do
|
21
|
+
allow :role3
|
22
|
+
deny :role4 => StubTarget
|
23
|
+
end
|
24
|
+
on :bla do
|
25
|
+
deny :role3
|
26
|
+
allow :role2 => :target
|
27
|
+
allow :role6 => 'bar'
|
28
|
+
end
|
29
|
+
on :deny_all do
|
30
|
+
deny all
|
31
|
+
end
|
32
|
+
on :allow_all do
|
33
|
+
allow all
|
34
|
+
end
|
21
35
|
end
|
22
|
-
|
23
|
-
|
36
|
+
guarded_class.suspects do
|
37
|
+
allow :role5
|
24
38
|
end
|
25
|
-
|
26
|
-
|
39
|
+
|
40
|
+
guarded_class.class_eval do
|
41
|
+
def target; @target = StubTarget.new; end
|
27
42
|
end
|
28
|
-
allow :role5
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should properly store name of suspected object" do
|
32
|
-
self.class.acl_suspect.should == :foo
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should properly store permissions" do
|
36
|
-
self.class.acl_permissions.should be_kind_of(Aclatraz::ACL)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should properly guard permissions" do
|
40
|
-
access_denied = Aclatraz::AccessDenied
|
41
|
-
|
42
|
-
lambda { guard! }.should raise_error(access_denied)
|
43
|
-
foo.is.role1!
|
44
|
-
lambda { guard! }.should_not raise_error(access_denied)
|
45
|
-
foo.is.role2!
|
46
|
-
lambda { guard! }.should raise_error(access_denied)
|
47
|
-
foo.is.role5!
|
48
|
-
lambda { guard! }.should_not raise_error(access_denied)
|
49
43
|
|
50
|
-
|
51
|
-
foo.is_not.role5!
|
52
|
-
lambda { guard!(:bar) }.should raise_error(access_denied)
|
53
|
-
foo.is_not.role2!
|
54
|
-
lambda { guard!(:bar) }.should_not raise_error(access_denied)
|
55
|
-
foo.is_not.role1!
|
56
|
-
lambda { guard!(:bar) }.should raise_error(access_denied)
|
57
|
-
foo.is.role3!
|
58
|
-
lambda { guard!(:bar) }.should_not raise_error(access_denied)
|
59
|
-
foo.is.role4!(StubTarget)
|
60
|
-
lambda { guard!(:bar) }.should raise_error(access_denied)
|
44
|
+
guarded = guarded_class.new
|
61
45
|
|
62
|
-
lambda { guard!
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
lambda { guard!(:bla) }.should_not raise_error(access_denied)
|
70
|
-
foo.is_not.role2!(target)
|
71
|
-
@bar = StubTarget.new
|
72
|
-
foo.is.role6!(@bar)
|
73
|
-
lambda { guard!(:bla) }.should_not raise_error(access_denied)
|
74
|
-
foo.is.role3!
|
75
|
-
lambda { guard!(:bla) }.should_not raise_error(access_denied)
|
76
|
-
foo.is_not.role6!(@bar)
|
77
|
-
foo.is.role5!
|
78
|
-
lambda { guard!(:bla) }.should raise_error(access_denied)
|
79
|
-
foo.is_not.role3!
|
80
|
-
lambda { guard!(:bla) }.should_not raise_error(access_denied)
|
46
|
+
lambda { guarded.guard! }.should raise_error(Aclatraz::AccessDenied)
|
47
|
+
suspect.is.role1!
|
48
|
+
lambda { guarded.guard! }.should_not raise_error(Aclatraz::AccessDenied)
|
49
|
+
suspect.is.role2!
|
50
|
+
lambda { guarded.guard! }.should raise_error(Aclatraz::AccessDenied)
|
51
|
+
suspect.is.role5!
|
52
|
+
lambda { guarded.guard! }.should_not raise_error(Aclatraz::AccessDenied)
|
81
53
|
|
82
|
-
|
83
|
-
|
84
|
-
lambda { guard!(:bar
|
85
|
-
|
86
|
-
lambda { guard!(:bar
|
87
|
-
|
88
|
-
lambda { guard!(:bar
|
89
|
-
|
90
|
-
lambda { guard!(:bar
|
54
|
+
lambda { guarded.guard!(:bar) }.should_not raise_error(Aclatraz::AccessDenied)
|
55
|
+
suspect.is_not.role5!
|
56
|
+
lambda { guarded.guard!(:bar) }.should raise_error(Aclatraz::AccessDenied)
|
57
|
+
suspect.is_not.role2!
|
58
|
+
lambda { guarded.guard!(:bar) }.should_not raise_error(Aclatraz::AccessDenied)
|
59
|
+
suspect.is_not.role1!
|
60
|
+
lambda { guarded.guard!(:bar) }.should raise_error(Aclatraz::AccessDenied)
|
61
|
+
suspect.is.role3!
|
62
|
+
lambda { guarded.guard!(:bar) }.should_not raise_error(Aclatraz::AccessDenied)
|
63
|
+
suspect.is.role4!(StubTarget)
|
64
|
+
lambda { guarded.guard!(:bar) }.should raise_error(Aclatraz::AccessDenied)
|
91
65
|
|
92
|
-
lambda { guard!(:
|
93
|
-
|
66
|
+
lambda { guarded.guard!(:bla) }.should raise_error(Aclatraz::AccessDenied)
|
67
|
+
suspect.is_not.role3!
|
68
|
+
suspect.is.role1!
|
69
|
+
lambda { guarded.guard!(:bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
70
|
+
suspect.is_not.role1!
|
71
|
+
lambda { guarded.guard!(:bla) }.should raise_error(Aclatraz::AccessDenied)
|
72
|
+
suspect.is.role2!(guarded.target)
|
73
|
+
lambda { guarded.guard!(:bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
74
|
+
suspect.is_not.role2!(guarded.target)
|
75
|
+
bar = StubTarget.new
|
76
|
+
guarded.instance_variable_set('@bar', bar)
|
77
|
+
suspect.is.role6!(bar)
|
78
|
+
lambda { guarded.guard!(:bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
79
|
+
suspect.is.role3!
|
80
|
+
lambda { guarded.guard!(:bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
81
|
+
suspect.is_not.role6!(bar)
|
82
|
+
suspect.is.role5!
|
83
|
+
lambda { guarded.guard!(:bla) }.should raise_error(Aclatraz::AccessDenied)
|
84
|
+
suspect.is_not.role3!
|
85
|
+
lambda { guarded.guard!(:bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
94
86
|
|
95
|
-
|
96
|
-
|
97
|
-
lambda { guard!(:bar, :
|
98
|
-
|
99
|
-
lambda { guard!(:bar, :
|
87
|
+
suspect.is_not.role5!
|
88
|
+
suspect.is_not.role4!(StubTarget)
|
89
|
+
lambda { guarded.guard!(:bar, :bla) }.should raise_error(Aclatraz::AccessDenied)
|
90
|
+
suspect.is.role1!
|
91
|
+
lambda { guarded.guard!(:bar, :bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
92
|
+
suspect.is.role4!(StubTarget)
|
93
|
+
lambda { guarded.guard!(:bar, :bla) }.should raise_error(Aclatraz::AccessDenied)
|
94
|
+
suspect.is.role2!(guarded.target)
|
95
|
+
lambda { guarded.guard!(:bar, :bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
100
96
|
|
101
|
-
|
102
|
-
lambda { guard!(:
|
103
|
-
foo.is.role2!(target)
|
104
|
-
lambda { guard!(:bar, :deny_all, :bla) }.should_not raise_error(access_denied)
|
105
|
-
end
|
106
|
-
|
107
|
-
describe "ivalid permission" do
|
108
|
-
suspects(:foo) { allow Object.new }
|
97
|
+
lambda { guarded.guard!(:allow_all) }.should_not raise_error(Aclatraz::AccessDenied)
|
98
|
+
lambda { guarded.guard!(:deny_all) }.should raise_error(Aclatraz::AccessDenied)
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
|
100
|
+
lambda { guarded.guard!(:bar, :allow_all, :bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
101
|
+
suspect.is_not.role2!(guarded.target)
|
102
|
+
lambda { guarded.guard!(:bar, :allow_all, :bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
103
|
+
suspect.is.role3!
|
104
|
+
lambda { guarded.guard!(:bar, :allow_all, :bla) }.should raise_error(Aclatraz::AccessDenied)
|
105
|
+
|
106
|
+
suspect.is_not.role3!
|
107
|
+
lambda { guarded.guard!(:bar, :deny_all, :bla) }.should raise_error(Aclatraz::AccessDenied)
|
108
|
+
suspect.is.role2!(guarded.target)
|
109
|
+
lambda { guarded.guard!(:bar, :deny_all, :bla) }.should_not raise_error(Aclatraz::AccessDenied)
|
110
|
+
|
111
|
+
lambda { guarded.guard! { deny :role2 => :target } }.should raise_error(Aclatraz::AccessDenied)
|
113
112
|
end
|
114
113
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
114
|
+
it "when invalid permission given then #guard! should raise InvalidPermission error" do
|
115
|
+
guarded_class = subject
|
116
|
+
guarded_class.name = "test2"
|
117
|
+
guarded_class.suspects(suspect) { allow Object.new }
|
118
|
+
guarded = guarded_class.new
|
119
|
+
lambda { guarded.guard! }.should raise_error(Aclatraz::InvalidPermission)
|
121
120
|
end
|
122
121
|
|
123
|
-
|
124
|
-
|
122
|
+
it "when invalid suspect given then #guard! should raise InvalidSuspect error" do
|
123
|
+
guarded_class = subject
|
124
|
+
guarded_class.name = "test3"
|
125
|
+
guarded_class.suspects('bar') { }
|
126
|
+
guarded = guarded_class.new
|
127
|
+
lambda { guarded.guard! }.should raise_error(Aclatraz::InvalidSuspect)
|
128
|
+
end
|
125
129
|
|
126
|
-
|
127
|
-
|
128
|
-
|
130
|
+
it "when ACL is not defined then #guard! should raise UndefinedAccessControlList error" do
|
131
|
+
guarded_class = subject
|
132
|
+
guarded_class.name = "test4"
|
133
|
+
guarded = guarded_class.new
|
134
|
+
lambda { guarded.guard! }.should raise_error(Aclatraz::UndefinedAccessControlList)
|
129
135
|
end
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
|
137
|
+
it "when given suspect name is symbol then #suspect should reference to instance method" do
|
138
|
+
guarded_class = subject
|
139
|
+
guarded_class.name = "test5"
|
140
|
+
guarded_class.suspects(:foo) {}
|
141
|
+
guarded = guarded_class.new
|
142
|
+
guarded.class.class_eval { def foo; @foo ||= StubSuspect.new; end }
|
143
|
+
guarded.suspect.should == guarded.foo
|
144
|
+
end
|
145
|
+
|
146
|
+
it "when given suspect name is string #suspect should reference to instance variable" do
|
147
|
+
guarded_class = subject
|
148
|
+
guarded_class.name = "test6"
|
149
|
+
guarded_class.suspects('foo') {}
|
150
|
+
guarded = guarded_class.new
|
151
|
+
guarded.instance_variable_set("@foo", StubSuspect.new)
|
152
|
+
guarded.suspect.should == guarded.instance_variable_get("@foo")
|
138
153
|
end
|
139
154
|
|
140
|
-
|
155
|
+
it "when given suspect is an object then #suspect should refence to it" do
|
141
156
|
bar = StubSuspect.new
|
142
|
-
|
157
|
+
guarded_class = subject
|
158
|
+
guarded_class.name = "test7"
|
159
|
+
guarded_class.suspects(bar) {}
|
160
|
+
guarded = guarded_class.new
|
161
|
+
guarded.suspect.should == bar
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "inherited guards" do
|
165
|
+
class FooParent
|
166
|
+
include Aclatraz::Guard
|
167
|
+
|
168
|
+
suspects :user do
|
169
|
+
allow :nested1
|
170
|
+
deny :nested2
|
171
|
+
end
|
172
|
+
|
173
|
+
def user; @user ||= StubSuspect.new; end
|
174
|
+
end
|
143
175
|
|
144
|
-
|
145
|
-
|
176
|
+
class BarChild < FooParent
|
177
|
+
suspects do
|
178
|
+
deny :nested1
|
179
|
+
allow :nested3
|
180
|
+
end
|
146
181
|
end
|
147
|
-
|
182
|
+
|
183
|
+
it "should work properly" do
|
184
|
+
foo = FooParent.new
|
185
|
+
bar = BarChild.new
|
186
|
+
|
187
|
+
lambda { foo.guard! }.should raise_error(Aclatraz::AccessDenied)
|
188
|
+
foo.user.is.nested1!
|
189
|
+
lambda { foo.guard! }.should_not raise_error(Aclatraz::AccessDenied)
|
190
|
+
foo.user.is.nested2!
|
191
|
+
lambda { foo.guard! }.should raise_error(Aclatraz::AccessDenied)
|
192
|
+
|
193
|
+
bar.user.is_not.nested1!
|
194
|
+
bar.user.is_not.nested2!
|
195
|
+
|
196
|
+
lambda { bar.guard! }.should raise_error(Aclatraz::AccessDenied)
|
197
|
+
bar.user.is.nested1!
|
198
|
+
lambda { bar.guard! }.should raise_error(Aclatraz::AccessDenied)
|
199
|
+
bar.user.is.nested2!
|
200
|
+
lambda { bar.guard! }.should raise_error(Aclatraz::AccessDenied)
|
201
|
+
bar.user.is.nested3!
|
202
|
+
lambda { bar.guard! }.should_not raise_error(Aclatraz::AccessDenied)
|
203
|
+
end
|
204
|
+
end
|
148
205
|
end
|