aclatraz 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,26 @@
1
1
  module Aclatraz
2
2
  module Helpers
3
- def pack(prefix, object=nil)
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
- "#{prefix}"
11
+ "#{owner}"
7
12
  when Class
8
- "#{prefix}/#{object.name}"
13
+ "#{owner}/#{object.name}"
9
14
  else
10
- "#{prefix}/#{object.class.name}/#{object.id}"
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
@@ -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
- class Base
8
- include Aclatraz::Helpers
9
- end
10
- end
11
- end
6
+ end # Store
7
+ end # Aclatraz
@@ -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 backend"
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 < Base
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
@@ -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
- ROLE_SUFFIXES = /(_(of|at|on|by|for|in))?(\?|\!)\Z/
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
- def initialize(suspect)
10
- @suspect = suspect
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
- end
13
-
14
- class Yes < Base
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 =~ ROLE_SUFFIXES
18
- setter = meth[-1].chr == "!"
19
- role = meth.gsub(ROLE_SUFFIXES, '')
20
- if setter
21
- suspect.assign_role!(*args.unshift(role))
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
- def method_missing(meth, *args, &blk)
36
- meth = meth.to_s
37
- if meth =~ ROLE_SUFFIXES
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
- end
52
- end
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
- ACL_ROLE_SUFFIXES = /(_(of|at|on|by|for|in))?\Z/
60
-
61
- def acl_suspect?
146
+ def acl_suspect? # :nodoc:
62
147
  true
63
148
  end
64
149
 
65
- def has_role?(role, object=nil)
66
- Aclatraz.store.check(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), self, object)
67
- end
68
-
69
- def assign_role!(role, object=nil)
70
- Aclatraz.store.set(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), self, object)
71
- end
72
-
73
- def delete_role!(role, object=nil)
74
- Aclatraz.store.delete(role.to_s.gsub(ACL_ROLE_SUFFIXES, ''), self, object)
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
- Aclatraz.store.roles(self)
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
@@ -1,10 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Aclatraz ACL" do
4
- before(:all) { Aclatraz.store(:redis, "redis://localhost:6379/0") }
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 }
@@ -1,148 +1,205 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Aclatraz guard" do
4
- include Aclatraz::Guard
4
+ before(:all) { Aclatraz.init(:redis, "redis://localhost:6379/0") }
5
+ let(:suspect) { @foo ||= StubSuspect.new }
5
6
 
6
- before(:all) { Aclatraz.store(:redis, "redis://localhost:6379/0") }
7
- let(:foo) { @foo ||= StubSuspect.new }
8
- let(:target) { StubTarget.new }
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
- suspects :foo do
11
- allow :role1
12
- deny :role2
13
- on :bar do
14
- allow :role3
15
- deny :role4 => StubTarget
16
- end
17
- on :bla do
18
- deny :role3
19
- allow :role2 => :target
20
- allow :role6 => 'bar'
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
- on :deny_all do
23
- deny all
36
+ guarded_class.suspects do
37
+ allow :role5
24
38
  end
25
- on :allow_all do
26
- allow all
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
- lambda { guard!(:bar) }.should_not raise_error(access_denied)
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!(:bla) }.should raise_error(access_denied)
63
- foo.is_not.role3!
64
- foo.is.role1!
65
- lambda { guard!(:bla) }.should_not raise_error(access_denied)
66
- foo.is_not.role1!
67
- lambda { guard!(:bla) }.should raise_error(access_denied)
68
- foo.is.role2!(target)
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
- foo.is_not.role5!
83
- foo.is_not.role4!(StubTarget)
84
- lambda { guard!(:bar, :bla) }.should raise_error(access_denied)
85
- foo.is.role1!
86
- lambda { guard!(:bar, :bla) }.should_not raise_error(access_denied)
87
- foo.is.role4!(StubTarget)
88
- lambda { guard!(:bar, :bla) }.should raise_error(access_denied)
89
- foo.is.role2!(target)
90
- lambda { guard!(:bar, :bla) }.should_not raise_error(access_denied)
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!(:allow_all) }.should_not raise_error(access_denied)
93
- lambda { guard!(:deny_all) }.should raise_error(access_denied)
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
- lambda { guard!(:bar, :allow_all, :bla) }.should_not raise_error(access_denied)
96
- foo.is_not.role2!(target)
97
- lambda { guard!(:bar, :allow_all, :bla) }.should_not raise_error(access_denied)
98
- foo.is.role3!
99
- lambda { guard!(:bar, :allow_all, :bla) }.should raise_error(access_denied)
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
- foo.is_not.role3!
102
- lambda { guard!(:bar, :deny_all, :bla) }.should raise_error(access_denied)
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
- it "#check_permissions should raise InvalidPermission error" do
111
- lambda { guard! }.should raise_error(Aclatraz::InvalidPermission)
112
- end
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
- describe "invalid suspect" do
116
- suspects('bar') { }
117
-
118
- it "#guard! should raise InvalidSuspect error" do
119
- lambda { guard! }.should raise_error(Aclatraz::InvalidSuspect)
120
- end
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
- describe "suspect object is symbol" do
124
- suspects(:foo) {}
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
- it "#current_suspect" do
127
- current_suspect.should == foo
128
- end
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
- describe "suspect object is string" do
132
- suspects('foo') {}
133
-
134
- it "#current_suspect" do
135
- @foo = StubSuspect.new
136
- current_suspect.should == @foo
137
- end
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
- describe "suspect object includes Suspect class" do
155
+ it "when given suspect is an object then #suspect should refence to it" do
141
156
  bar = StubSuspect.new
142
- suspects(bar) {}
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
- it "#current_suspect" do
145
- current_suspect.should == bar
176
+ class BarChild < FooParent
177
+ suspects do
178
+ deny :nested1
179
+ allow :nested3
180
+ end
146
181
  end
147
- end
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