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.
@@ -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