rend-acl 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -22,4 +22,4 @@ Rend-Acl is a port of [Zend_Acl](http://framework.zend.com/manual/1.12/en/zend.a
22
22
 
23
23
  ## Acknowledgements
24
24
  * This project is **not** associated with, or endorsed by, Zend Technologies USA, Inc., nor any of its contributors.
25
- * Rend's modular design was heavily influced by [RSpec](https://github.com/rspec/rspec) approach.
25
+ * Rend's modular design was heavily influced by [RSpec](https://github.com/rspec/rspec)'s approach.
data/lib/rend/acl.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rend/core'
2
+
2
3
  require 'rend/acl/version'
3
4
  require 'rend/acl/exception'
4
5
  require 'rend/acl/role'
@@ -76,7 +77,7 @@ module Rend
76
77
  # @param Rend::Acl::Role|string role
77
78
  # @uses Rend::Acl::Role::Registry::get!()
78
79
  # @return Rend::Acl::Role
79
- def role(role)
80
+ def role!(role)
80
81
  role_registry.get!(role)
81
82
  end
82
83
 
@@ -174,14 +175,14 @@ module Rend
174
175
 
175
176
  resource_id = resource.id
176
177
 
177
- raise Rend::Acl::Exception, "Resource id 'resource_id' already exists in the ACL" if has?(resource_id)
178
+ raise Rend::Acl::Exception, "Resource id 'resource_id' already exists in the ACL" if has_resource?(resource_id)
178
179
 
179
180
  resource_parent = nil
180
181
 
181
182
  if parent
182
183
  begin
183
184
  resource_parent_id = (parent.class <= Rend::Acl::Resource) ? parent.id : parent
184
- resource_parent = get!(resource_parent_id)
185
+ resource_parent = resource!(resource_parent_id)
185
186
  rescue Rend::Acl::Exception
186
187
  raise Rend::Acl::Exception, "Parent Resource id 'resource_parent_id' does not exist"
187
188
  end
@@ -200,9 +201,9 @@ module Rend
200
201
  # @throws Rend::Acl::Exception
201
202
  # @return Rend::Acl::Resource
202
203
 
203
- def get!(resource)
204
+ def resource!(resource)
204
205
  resource_id = (resource.class <= Rend::Acl::Resource) ? resource.id : resource.to_s
205
- raise Rend::Acl::Exception, "Resource 'resource_id' not found" unless has?(resource)
206
+ raise Rend::Acl::Exception, "Resource 'resource_id' not found" unless has_resource?(resource)
206
207
  @_resources[resource_id][:instance]
207
208
  end
208
209
 
@@ -212,7 +213,7 @@ module Rend
212
213
  #
213
214
  # @param Rend::Acl::Resource|string resource
214
215
  # @return boolean
215
- def has?(resource)
216
+ def has_resource?(resource)
216
217
  resource_id = (resource.class <= Rend::Acl::Resource) ? resource.id : resource.to_s
217
218
  @_resources.keys.include?(resource_id)
218
219
  end
@@ -230,9 +231,9 @@ module Rend
230
231
  # @param boolean onlyParent
231
232
  # @throws Rend_Acl_Resource_Registry_Exception
232
233
  # @return boolean
233
- def inherits?(resource, inherit, only_parent = false)
234
- resource_id = get!(resource).id
235
- inherit_id = get!(inherit).id
234
+ def inherits_resource?(resource, inherit, only_parent = false)
235
+ resource_id = resource!(resource).id
236
+ inherit_id = resource!(inherit).id
236
237
 
237
238
  if @_resources[resource_id][:parent]
238
239
  parent_id = @_resources[resource_id][:parent].id
@@ -256,8 +257,8 @@ module Rend
256
257
  # @param Rend::Acl::Resource|string resource
257
258
  # @throws Rend::Acl::Exception
258
259
  # @return Rend::Acl Provides a fluent interface
259
- def remove!(resource)
260
- resource_id = get!(resource).id
260
+ def remove_resource!(resource)
261
+ resource_id = resource!(resource).id
261
262
  resources_removed = [resource_id]
262
263
 
263
264
  if resource_parent = @_resources[resource_id][:parent]
@@ -265,7 +266,7 @@ module Rend
265
266
  end
266
267
 
267
268
  @_resources[resource_id][:children].each do |child_id, child|
268
- remove!(child_id)
269
+ remove_resource!(child_id)
269
270
  resources_removed.push(child_id)
270
271
  end
271
272
 
@@ -285,7 +286,7 @@ module Rend
285
286
  # Removes all Resources
286
287
  #
287
288
  # @return Rend::Acl Provides a fluent interface
288
- def remove_all!
289
+ def remove_resource_all!
289
290
  @_resources.each do |resource_id, resource|
290
291
  @_rules[:by_resource_id].each do |resource_id_current, rules|
291
292
  @_rules[:by_resource_id].delete(resource_id_current) if resource_id == resource_id_current
@@ -402,12 +403,12 @@ module Rend
402
403
  resources = Array(resources)
403
404
  resources << nil if resources.empty?
404
405
  resources = resources.reduce([]) do |seed, resource|
405
- seed << (resource ? get!(resource) : nil)
406
+ seed << (resource ? resource!(resource) : nil)
406
407
  end
407
408
  else
408
409
  # this might be used later if resource iteration is required
409
- all_resources = @_resources.reduce([]) do |seed, resource|
410
- seed << resource[:instance]
410
+ all_resources = @_resources.values.reduce([]) do |seed, r_target|
411
+ seed << r_target[:instance]
411
412
  end
412
413
  end
413
414
 
@@ -428,8 +429,8 @@ module Rend
428
429
  roles.each do |role|
429
430
  rules = _rules(resource, role, true)
430
431
  if privileges.empty?
431
- rules[:all_privileges][:type] = type
432
- rules[:by_privilege_id] = {} unless rules.has_key?(:by_privilege_id)
432
+ rules[:all_privileges] = {:type => type}
433
+ rules[:by_privilege_id] = {} unless rules.has_key?(:by_privilege_id)
433
434
  else
434
435
  privileges.each do |privilege|
435
436
  rules[:by_privilege_id][privilege] = {:type => type}
@@ -468,7 +469,6 @@ module Rend
468
469
  end
469
470
  next
470
471
  end
471
-
472
472
  if rules[:all_privileges].has_key?(:type) && rules[:all_privileges][:type] == type
473
473
  rules.delete(:all_privileges)
474
474
  end
@@ -564,18 +564,21 @@ module Rend
564
564
  if resource
565
565
  # keep track of originally called resource
566
566
  @_is_allowed_resource = resource
567
- resource = get!(resource)
567
+ resource = resource!(resource)
568
568
  unless @_is_allowed_resource.class <= Rend::Acl::Resource
569
569
  @_is_allowed_resource = resource
570
570
  end
571
571
  end
572
572
 
573
+
573
574
  if privilege.nil?
574
575
  # query on all privileges
575
576
  loop do # loop terminates at :all_resources pseudo-parent
576
577
  # depth-first search on role if it is not :all_roles pseudo-parent
577
- result = _role_dfs_all_privileges(role, resource)
578
- return result if role && result
578
+ if !role.nil? && !(result = _role_dfs_all_privileges(role, resource)).nil?
579
+ return result
580
+ end
581
+
579
582
 
580
583
  # look for rule on :all_roles psuedo-parent
581
584
  rules = _rules(resource, nil)
@@ -592,16 +595,14 @@ module Rend
592
595
  resource = @_resources[resource.id][:parent]
593
596
  end
594
597
  else
595
- # IN HERE
596
598
  @_is_allowed_privilege = privilege
597
599
  # query on one privilege
598
600
  loop do # loop terminates at :all_resources pseudo-parent
599
601
  # depth-first search on role if it is not :all_roles pseudo-parent
600
- if nil != role && nil != (result = _role_dfs_one_privilege(role, resource, privilege))
602
+ if !role.nil? && !(result = _role_dfs_one_privilege(role, resource, privilege)).nil?
601
603
  return result
602
604
  end
603
605
 
604
-
605
606
  # look for rule on 'allRoles' pseudo-parent
606
607
  if nil != (rule_type = _rule_type(resource, nil, privilege))
607
608
  return TYPE_ALLOW == rule_type
@@ -635,7 +636,7 @@ module Rend
635
636
  # @param Rend::Acl::Resource resource
636
637
  # @return boolean|nil
637
638
  def _role_dfs_all_privileges(role, resource = nil)
638
- type_hint! Rend::Acl::Role, role, :is_required => true
639
+ type_hint! Rend::Acl::Role, role, :is_required => true
639
640
  type_hint! Rend::Acl::Resource, resource
640
641
 
641
642
  dfs = {:visited => {}, :stack => []}
@@ -9,6 +9,10 @@ module Rend
9
9
  @id = id.to_s
10
10
  end
11
11
 
12
+ def to_s
13
+ @id
14
+ end
15
+
12
16
  end
13
17
  end
14
18
  end
data/lib/rend/acl/role.rb CHANGED
@@ -1,17 +1,18 @@
1
1
  require 'rend/acl/role/registry'
2
+
2
3
  module Rend
3
4
  class Acl
4
5
  class Role
5
6
 
6
7
  # Unique id of Role
7
8
  attr_reader :id # @var string
8
- # attr_accessor :parents -- future
9
- # attr_accessor :children -- future
10
9
 
11
10
  def initialize(id)
12
11
  @id = id.to_s
13
- # @parents = {} -- future
14
- # @children = {} -- future
12
+ end
13
+
14
+ def to_s
15
+ @id
15
16
  end
16
17
 
17
18
  end
@@ -1,7 +1,7 @@
1
1
  module Rend
2
2
  class Acl
3
3
  module Version
4
- STRING = "0.0.2"
4
+ STRING = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
data/test/test_acl.rb CHANGED
@@ -3,207 +3,998 @@ require 'rend/acl'
3
3
 
4
4
  class AclTest < Test::Unit::TestCase
5
5
 
6
- # See: http://framework.zend.com/manual/1.12/en/zend.acl.introduction.html#zend.acl.introduction.roles
7
- def test_multiple_inheritance_among_roles
6
+ def setup
8
7
  @acl = Rend::Acl.new
9
- @acl.add_role!('guest').add_role!('member').add_role!('admin')
8
+ end
10
9
 
11
- parents = %w[guest member admin]
12
- @acl.add_role! 'Daniel Doezema', parents
10
+ def test_storing_acl_data_for_persistence_with_marshal
11
+ assert_use_case_1 Marshal.load( Marshal.dump(use_case_1) )
12
+ end
13
13
 
14
- @acl.add_resource!('gold')
14
+ def test_storing_acl_data_for_persistence_with_yaml
15
+ require 'yaml'
16
+ assert_use_case_1 YAML.load( YAML.dump(use_case_1) )
17
+ end
15
18
 
16
- @acl.deny!('guest', 'gold')
17
- @acl.allow!('member', 'gold')
19
+ def test_acl_user_case_1
20
+ assert_use_case_1(use_case_1)
21
+ end
22
+
23
+ # ==== Orignal Zend_Acl Tests Below
18
24
 
19
- assert_equal true, @acl.allowed?('Daniel Doezema', 'gold')
25
+ # Ensures that basic addition and retrieval of a single Role works
26
+ def test_role_registry_add_and_get_one
27
+ role_guest = Rend::Acl::Role.new('guest')
28
+ @acl.add_role!(role_guest)
29
+ assert_equal role_guest, @acl.role!(role_guest.id)
20
30
  end
21
31
 
22
- # http://framework.zend.com/manual/1.12/en/zend.acl.introduction.html#zend.acl.introduction.role_registry
23
- def test_registering_roles
24
- @acl = Rend::Acl.new
25
- guest_role = Rend::Acl::Role.new('guest')
26
- @acl.add_role! guest_role
27
- @acl.add_role! Rend::Acl::Role.new('staff'), guest_role
28
- @acl.add_role! Rend::Acl::Role.new('editor'), 'staff'
29
- @acl.add_role! Rend::Acl::Role.new('administrator')
32
+ # Ensures that basic addition and retrieval of a single Resource works
33
+ def test_role_add_and_get_one_by_string
34
+ role = @acl.add_role!('area').role!('area')
35
+ assert_kind_of Rend::Acl::Role, role
36
+ assert_equal 'area', role.id
37
+ end
30
38
 
31
- # Guest may only view content
32
- @acl.allow! guest_role, nil, 'view'
39
+ # # Ensures that basic removal of a single Role works
40
+ def test_role_registry_remove_one
41
+ role_guest = Rend::Acl::Role.new('guest')
42
+ @acl.add_role!(role_guest).remove_role!(role_guest)
43
+ assert_equal false, @acl.has_role?(role_guest)
44
+ end
33
45
 
34
- # Staff inherits view privilege from guest, but also needs additional
35
- # privileges
36
- @acl.allow! 'staff', nil, %w[edit submit revise]
46
+ # Ensures that an exception is thrown when a non-existent Role is specified for removal
47
+ def test_role_registry_remove_one_non_existent
48
+ assert_raises Rend::Acl::Role::Registry::Exception do
49
+ @acl.remove_role!('nonexistent')
50
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon removing a non-existent Role')
51
+ end
52
+ end
37
53
 
38
- # Editor inherits view, edit, submit, and revise privileges from
39
- # staff, but also needs additional privileges
40
- @acl.allow! 'editor', nil, %w[publish archive delete]
54
+ # # Ensures that removal of all Roles works
55
+ def test_role_registry_remove_all
56
+ role_guest = Rend::Acl::Role.new('guest')
57
+ @acl.add_role!(role_guest).remove_role_all!
58
+ assert_equal false, @acl.has_role?(role_guest)
59
+ end
41
60
 
42
- # Administrator inherits nothing, but is allowed all privileges
43
- @acl.allow! 'administrator'
61
+ # Ensures that an exception is thrown when a non-existent Role is specified as a parent upon Role addition
62
+ def test_role_registry_add_inherits_non_existent
63
+ assert_raises Rend::Acl::Role::Registry::Exception do
64
+ @acl.add_role!(Rend::Acl::Role.new('guest'), 'nonexistent')
65
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon specifying a non-existent parent')
66
+ end
67
+ end
44
68
 
69
+ # Ensures that an exception is thrown when a non-existent Role is specified to each parameter of inherits
70
+ def test_role_registry_inherits_non_existent
71
+ role_guest = Rend::Acl::Role.new('guest')
72
+ @acl.add_role!(role_guest)
73
+ assert_raises Rend::Acl::Role::Registry::Exception do
74
+ @acl.inherits_role?('nonexistent', role_guest)
75
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon specifying a non-existent child Role')
76
+ end
77
+ assert_raises Rend::Acl::Role::Registry::Exception do
78
+ @acl.inherits_role?(role_guest, 'nonexistent')
79
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon specifying a non-existent parent Role')
80
+ end
81
+ end
45
82
 
46
- assert_equal true, @acl.allowed?('guest', nil, 'view')
47
- assert_equal false, @acl.allowed?('staff', nil, 'publish')
48
- assert_equal true, @acl.allowed?('staff', nil, 'revise')
49
- assert_equal true, @acl.allowed?('editor', nil, 'view') # allowed because of inheritance from guest
50
- assert_equal false, @acl.allowed?('editor', nil, 'update') # denied because no allow rule for 'update'
51
- assert_equal true, @acl.allowed?('administrator', nil, 'view') # allowed because administrator is allowed all privileges
52
- assert_equal true, @acl.allowed?('administrator') # allowed because administrator is allowed all privileges
53
- assert_equal true, @acl.allowed?('administrator', nil, 'update') # allowed because administrator is allowed all privileges
83
+ # Tests basic Role inheritance
84
+ def test_role_registry_inherits
85
+ role_guest = Rend::Acl::Role.new('guest')
86
+ role_member = Rend::Acl::Role.new('member')
87
+ role_editor = Rend::Acl::Role.new('editor')
88
+
89
+ role_registry = Rend::Acl::Role::Registry.new
90
+ role_registry.add!(role_guest)
91
+ role_registry.add!(role_member, role_guest.id)
92
+ role_registry.add!(role_editor, role_member)
93
+
94
+ assert_equal 0, role_registry.parents(role_guest).length
95
+
96
+ role_member_parents = role_registry.parents(role_member)
97
+ assert_equal 1, role_member_parents.length
98
+ assert_equal true, role_member_parents.has_key?('guest')
99
+
100
+ role_editor_parents = role_registry.parents(role_editor)
101
+ assert_equal 1, role_editor_parents.length
102
+ assert_equal true, role_editor_parents.has_key?('member')
103
+ assert_equal true, role_registry.inherits?(role_member, role_guest, true)
104
+ assert_equal true, role_registry.inherits?(role_editor, role_member, true)
105
+ assert_equal true, role_registry.inherits?(role_editor, role_guest)
106
+ assert_equal false, role_registry.inherits?(role_guest, role_member)
107
+ assert_equal false, role_registry.inherits?(role_member, role_editor)
108
+ assert_equal false, role_registry.inherits?(role_guest, role_editor)
109
+
110
+ role_registry.remove!(role_member)
111
+ assert_equal 0, role_registry.parents(role_editor).length
112
+ assert_equal false, role_registry.inherits?(role_editor, role_guest)
54
113
  end
55
114
 
56
- # http://framework.zend.com/manual/1.12/en/zend.acl.introduction.html#zend.acl.introduction.role_registry
57
- def test_precise_access_controls
58
- @acl = Rend::Acl.new
59
- guest_role = Rend::Acl::Role.new('guest')
60
- @acl.add_role! guest_role
61
- @acl.add_role! Rend::Acl::Role.new('staff'), guest_role
62
- @acl.add_role! Rend::Acl::Role.new('editor'), 'staff'
63
- @acl.add_role! Rend::Acl::Role.new('administrator')
115
+ # Tests basic Role multiple inheritance
116
+ def test_role_registry_inherits_multiple
117
+ role_parent0 = Rend::Acl::Role.new('parent0')
118
+ role_parent1 = Rend::Acl::Role.new('parent1')
119
+ role_child = Rend::Acl::Role.new('child')
120
+
121
+ role_registry = Rend::Acl::Role::Registry.new
122
+ role_registry.add!(role_parent0)
123
+ role_registry.add!(role_parent1)
124
+ role_registry.add!(role_child, [role_parent0, role_parent1])
125
+
126
+ role_child_parents = role_registry.parents(role_child)
127
+ assert_equal 2, role_child_parents.length
128
+ role_child_parents.each_with_index do |(role_parent_id, role_parent), i|
129
+ assert_equal "parent#{i}", role_parent_id
130
+ end
131
+ assert_equal true, role_registry.inherits?(role_child, role_parent0)
132
+ assert_equal true, role_registry.inherits?(role_child, role_parent1)
133
+
134
+ role_registry.remove!(role_parent0)
135
+ role_child_parents = role_registry.parents(role_child)
136
+ assert_equal 1, role_child_parents.length
137
+ assert_equal true, role_child_parents.has_key?('parent1')
138
+ assert_equal true, role_registry.inherits?(role_child, role_parent1)
139
+ end
64
140
 
65
- # Guest may only view content
66
- @acl.allow! guest_role, nil, 'view'
141
+ # Ensures that the same Role cannot be registered more than once to the registry
142
+ def test_role_registry_duplicate
143
+ role_guest = Rend::Acl::Role.new('guest')
144
+ role_registry = Rend::Acl::Role::Registry.new
145
+ assert_raises Rend::Acl::Role::Registry::Exception do
146
+ role_registry.add!(role_guest).add!(role_guest)
147
+ flunk('Expected exception not thrown upon adding same Role twice')
148
+ end
149
+ end
67
150
 
68
- # Staff inherits view privilege from guest, but also needs additional
69
- # privileges
70
- @acl.allow! 'staff', nil, %w[edit submit revise]
151
+ # Ensures that two Roles having the same ID cannot be registered
152
+ def test_role_registry_duplicate_id
153
+ role_guest1 = Rend::Acl::Role.new('guest')
154
+ role_guest2 = Rend::Acl::Role.new('guest')
155
+ role_registry = Rend::Acl::Role::Registry.new
156
+ assert_raises Rend::Acl::Role::Registry::Exception do
157
+ role_registry.add!(role_guest1).add!(role_guest2)
158
+ flunk('Expected exception not thrown upon adding same Role twice')
159
+ end
160
+ end
71
161
 
72
- # Editor inherits view, edit, submit, and revise privileges from
73
- # staff, but also needs additional privileges
74
- @acl.allow! 'editor', nil, %w[publish archive delete]
162
+ # Ensures that basic addition and retrieval of a single Resource works
163
+ def test_resource_add_and_get_one
164
+ resource_area = Rend::Acl::Resource.new('area')
165
+ @acl.add_resource!(resource_area)
75
166
 
76
- # Administrator inherits nothing, but is allowed all privileges
77
- @acl.allow! 'administrator'
167
+ resource = @acl.resource!(resource_area.id)
168
+ assert_equal resource_area, resource
78
169
 
79
- # The new marketing group inherits permissions from staff
80
- @acl.add_role!(Rend::Acl::Role.new('marketing'), 'staff')
170
+ resource = @acl.resource!(resource_area)
171
+ assert_equal resource_area, resource
172
+ end
81
173
 
82
- # === Create Resources for the rules ===
174
+ # Ensures that basic addition and retrieval of a single Resource works
175
+ def test_resource_add_and_get_one_by_string
176
+ @acl.add_resource!('area')
83
177
 
84
- # newsletter
85
- @acl.add_resource!(Rend::Acl::Resource.new('newsletter'))
178
+ resource = @acl.resource!('area')
179
+ assert_kind_of Rend::Acl::Resource, resource
180
+ assert_equal 'area', resource.id
181
+ end
86
182
 
87
- # news
88
- @acl.add_resource!(Rend::Acl::Resource.new('news'))
183
+ # Ensures that basic removal of a single Resource works
184
+ def test_resource_remove_one
185
+ resource_area = Rend::Acl::Resource.new('area')
186
+ @acl.add_resource!(resource_area).remove_resource!(resource_area)
187
+ assert_equal false, @acl.has_resource?(resource_area)
188
+ end
89
189
 
90
- # latest news
91
- @acl.add_resource!(Rend::Acl::Resource.new('latest'), 'news')
190
+ # Ensures that an exception is thrown when a non-existent Resource is specified for removal
191
+ def test_resource_remove_one_non_existent
192
+ assert_raises Rend::Acl::Exception do
193
+ @acl.remove_resource!('nonexistent')
194
+ flunk('Expected Rend::Acl::Exception not thrown upon removing a non-existent Resource')
195
+ end
196
+ end
92
197
 
93
- # announcement news
94
- @acl.add_resource!(Rend::Acl::Resource.new('announcement'), 'news')
198
+ # Ensures that removal of all Resources works
199
+ def test_resource_remove_all
200
+ resource_area = Rend::Acl::Resource.new('area')
201
+ @acl.add_resource!(resource_area).remove_resource_all!
202
+ assert_equal false, @acl.has_resource?(resource_area)
203
+ end
95
204
 
96
- # === Setting up access ====
205
+ # Ensures that an exception is thrown when a non-existent Resource is specified as a parent upon Resource addition
206
+ def test_resource_add_inherits_non_existent
207
+ assert_raises Rend::Acl::Exception do
208
+ @acl.add_resource!(Rend::Acl::Resource.new('area'), 'nonexistent')
209
+ flunk('Expected Rend::Acl::Exception not thrown upon specifying a non-existent parent')
210
+ end
211
+ end
97
212
 
98
- # Marketing must be able to publish and archive newsletters and the latest news
99
- @acl.allow!('marketing', ['newsletter', 'latest'], ['publish', 'archive'])
213
+ # Ensures that an exception is thrown when a non-existent Resource is specified to each parameter of inherits
214
+ def test_resource_inherits_non_existent
215
+ resource_area = Rend::Acl::Resource.new('area')
216
+ @acl.add_resource!(resource_area)
217
+ assert_raises Rend::Acl::Exception do
218
+ @acl.inherits_resource?('nonexistent', resource_area)
219
+ flunk('Expected Rend::Acl::Exception not thrown upon specifying a non-existent child Resource')
220
+ end
221
+ assert_raises Rend::Acl::Exception do
222
+ @acl.inherits_resource?(resource_area, 'nonexistent')
223
+ flunk('Expected Rend::Acl::Exception not thrown upon specifying a non-existent parent Resource')
224
+ end
225
+ end
100
226
 
101
- # Staff (and marketing, by inheritance), are denied permission to revise the latest news
102
- @acl.deny!('staff', 'latest', 'revise')
227
+ # Tests basic Resource inheritance
228
+ def test_resource_inherits
229
+ resource_city = Rend::Acl::Resource.new('city')
230
+ resource_building = Rend::Acl::Resource.new('building')
231
+ resource_room = Rend::Acl::Resource.new('room')
232
+
233
+ @acl.add_resource!(resource_city)
234
+ @acl.add_resource!(resource_building, resource_city.id)
235
+ @acl.add_resource!(resource_room, resource_building)
236
+
237
+ assert_equal true, @acl.inherits_resource?(resource_building, resource_city, true)
238
+ assert_equal true, @acl.inherits_resource?(resource_room, resource_building, true)
239
+ assert_equal true, @acl.inherits_resource?(resource_room, resource_city)
240
+ assert_equal false, @acl.inherits_resource?(resource_city, resource_building)
241
+ assert_equal false, @acl.inherits_resource?(resource_building, resource_room)
242
+ assert_equal false, @acl.inherits_resource?(resource_city, resource_room)
243
+
244
+ @acl.remove_resource!(resource_building)
245
+ assert_equal false, @acl.has_resource?(resource_room)
246
+ end
103
247
 
104
- # Everyone (including administrators) are denied permission to archive news announcements
105
- @acl.deny!(nil, 'announcement', 'archive')
248
+ # Ensures that the same Resource cannot be added more than once
249
+ def test_resource_duplicate
250
+ assert_raises Rend::Acl::Exception do
251
+ resource_area = Rend::Acl::Resource.new('area')
252
+ @acl.add_resource!(resource_area)
253
+ @acl.add_resource!(resource_area)
254
+ flunk('Expected exception not thrown upon adding same Resource twice')
255
+ end
256
+ end
106
257
 
258
+ # Ensures that two Resources having the same ID cannot be added
259
+ def test_resource_duplicate_id
260
+ assert_raises Rend::Acl::Exception do
261
+ resource_area1 = Rend::Acl::Resource.new('area')
262
+ resource_area2 = Rend::Acl::Resource.new('area')
263
+ @acl.add_resource!(resource_area1)
264
+ @acl.add_resource!(resource_area2)
265
+ flunk('Expected exception not thrown upon adding two Resources with same ID')
266
+ end
267
+ end
107
268
 
108
- # === Testing ===
269
+ # Ensures that an exception is thrown when a non-existent Role and Resource parameters are specified to is_allowed
270
+ def test_is_allowed_non_existent
271
+ assert_raises Rend::Acl::Role::Registry::Exception do
272
+ @acl.allowed?('nonexistent')
273
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon non-existent Role')
274
+ end
275
+ assert_raises Rend::Acl::Exception do
276
+ @acl.allowed?(nil, 'nonexistent')
277
+ flunk('Expected Rend::Acl::Exception not thrown upon non-existent Resource')
278
+ end
279
+ end
109
280
 
110
- assert_equal false, @acl.allowed?('staff' , 'newsletter' , 'publish') # denied
111
- assert_equal true, @acl.allowed?('marketing' , 'newsletter' , 'publish') # allowed
112
- assert_equal false, @acl.allowed?('staff' , 'latest' , 'publish') # denied
113
- assert_equal true, @acl.allowed?('marketing' , 'latest' , 'publish') # allowed
114
- assert_equal true, @acl.allowed?('marketing' , 'latest' , 'archive') # allowed
115
- assert_equal false, @acl.allowed?('marketing' , 'latest' , 'revise') # denied
116
- assert_equal false, @acl.allowed?('editor' , 'announcement' , 'archive') # denied
117
- assert_equal false, @acl.allowed?('administrator' , 'announcement' , 'archive') # denied
281
+ # Ensures that by default, Zend_Acl denies access to everything by all
282
+ def test_default_deny
283
+ assert_equal false, @acl.allowed?
284
+ end
118
285
 
119
- # === Removing Access Controls ===
120
- # To remove one or more access rules from the ACL, simply use the available removeAllow()
121
- # or removeDeny() methods. As with allow() and deny(), you may provide a NULL value to indicate
122
- # application to all roles, resources, and/or privileges:
286
+ # Ensures that ACL-wide rules (all Roles, Resources, and privileges) work properly
287
+ def test_default_rule_set
288
+ @acl.allow!
289
+ assert_equal true, @acl.allowed?
290
+ @acl.deny!
291
+ assert_equal false, @acl.allowed?
292
+ end
123
293
 
124
- # Remove the denial of revising latest news to staff (and marketing, by inheritance)
125
- @acl.remove_deny!('staff', 'latest', 'revise')
126
- assert_equal true, @acl.allowed?('marketing', 'latest', 'revise')
294
+ # Ensures that by default, Zend_Acl denies access to a privilege on anything by all
295
+ def test_default_privilege_deny
296
+ assert_equal false, @acl.allowed?(nil, nil, 'some_privilege')
297
+ end
127
298
 
128
- # Remove the allowance of publishing and archiving newsletters to marketing
129
- @acl.remove_allow!('marketing', 'newsletter', ['publish', 'archive'])
130
- assert_equal false, @acl.allowed?('marketing', 'newsletter', 'publish')
131
- assert_equal false, @acl.allowed?('marketing', 'newsletter', 'archive')
299
+ # Ensures that ACL-wide rules apply to privileges
300
+ def test_default_rule_set_privilege
301
+ @acl.allow!
302
+ assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
303
+ @acl.deny!
304
+ assert_equal false, @acl.allowed?(nil, nil, 'some_privilege')
305
+ end
132
306
 
133
- # === Modifying Access Controls ===
134
- # Privileges may be modified incrementally as indicated above, but a NIL
135
- # value for the privileges overrides such incremental changes:
307
+ # Ensures that a privilege allowed for all Roles upon all Resources works properly
308
+ def test_privilege_allow
309
+ @acl.allow!(nil, nil, 'some_privilege')
310
+ assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
311
+ end
136
312
 
137
- # Allow marketing all permissions upon the latest news
138
- @acl.allow!('marketing', 'latest')
139
- assert_equal true, @acl.allowed?('marketing', 'latest', 'publish') # allowed
140
- assert_equal true, @acl.allowed?('marketing', 'latest', 'archive') # allowed
141
- assert_equal true, @acl.allowed?('marketing', 'latest', 'anything') # allowed
313
+ # Ensures that a privilege denied for all Roles upon all Resources works properly
314
+ def test_privilege_deny
315
+ @acl.allow!
316
+ @acl.deny!(nil, nil, 'some_privilege')
317
+ assert_equal false, @acl.allowed?(nil, nil, 'some_privilege')
142
318
  end
143
319
 
144
- def test_storing_acl_data_for_persistence_with_marshal
145
- @acl = Rend::Acl.new
146
- guest_role = Rend::Acl::Role.new('guest')
147
- @acl.add_role! guest_role
148
- @acl.add_role! Rend::Acl::Role.new('staff'), guest_role
149
- @acl.add_role! Rend::Acl::Role.new('editor'), 'staff'
150
- @acl.add_role! Rend::Acl::Role.new('administrator')
320
+ # Ensures that multiple privileges work properly
321
+ def test_privileges
322
+ @acl.allow!(nil, nil, ['p1', 'p2', 'p3'])
323
+ assert_equal true, @acl.allowed?(nil, nil, 'p1')
324
+ assert_equal true, @acl.allowed?(nil, nil, 'p2')
325
+ assert_equal true, @acl.allowed?(nil, nil, 'p3')
326
+ assert_equal false, @acl.allowed?(nil, nil, 'p4')
327
+
328
+ @acl.deny!(nil, nil, 'p1')
329
+ assert_equal false, @acl.allowed?(nil, nil, 'p1')
330
+
331
+ @acl.deny!(nil, nil, ['p2', 'p3'])
332
+ assert_equal false, @acl.allowed?(nil, nil, 'p2')
333
+ assert_equal false, @acl.allowed?(nil, nil, 'p3')
334
+ end
335
+
336
+ # # [NOT IMPLEMENTED YET] Ensures that assertions on privileges work properly
337
+ # def test_privilege_assert
338
+ # @acl.allow!(nil, nil, 'some_privilege', Rend::Acl::Mock_assertion.new(true))
339
+ # assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
340
+ # @acl.allow!(nil, nil, 'some_privilege', Rend::Acl::Mock_assertion.new(false))
341
+ # assert_equal false, @acl.allowed?(nil, nil, 'some_privilege')
342
+ # end
343
+
344
+ # Ensures that by default, Zend_Acl denies access to everything for a particular Role
345
+ def test_role_default_deny
346
+ role_guest = Rend::Acl::Role.new('guest')
347
+ @acl.add_role!(role_guest)
348
+ assert_equal false, @acl.allowed?(role_guest)
349
+ end
350
+
351
+ # Ensures that ACL-wide rules (all Resources and privileges) work properly for a particular Role
352
+ def test_role_default_rule_set
353
+ role_guest = Rend::Acl::Role.new('guest')
354
+ @acl.add_role!(role_guest)
355
+ @acl.allow!(role_guest)
356
+ assert_equal true, @acl.allowed?(role_guest)
357
+ @acl.deny!(role_guest)
358
+ assert_equal false, @acl.allowed?(role_guest)
359
+ end
360
+
361
+ # Ensures that by default, Zend_Acl denies access to a privilege on anything for a particular Role
362
+ def test_role_default_privilege_deny
363
+ role_guest = Rend::Acl::Role.new('guest')
364
+ @acl.add_role!(role_guest)
365
+ assert_equal false, @acl.allowed?(role_guest, nil, 'some_privilege')
366
+ end
367
+
368
+ # Ensures that ACL-wide rules apply to privileges for a particular Role
369
+ def test_role_default_rule_set_privilege
370
+ role_guest = Rend::Acl::Role.new('guest')
371
+ @acl.add_role!(role_guest)
372
+ @acl.allow!(role_guest)
373
+ assert_equal true, @acl.allowed?(role_guest, nil, 'some_privilege')
374
+ @acl.deny!(role_guest)
375
+ assert_equal false, @acl.allowed?(role_guest, nil, 'some_privilege')
376
+ end
377
+
378
+ # Ensures that a privilege allowed for a particular Role upon all Resources works properly
379
+ def test_role_privilege_allow
380
+ role_guest = Rend::Acl::Role.new('guest')
381
+ @acl.add_role!(role_guest)
382
+ @acl.allow!(role_guest, nil, 'some_privilege')
383
+ assert_equal true, @acl.allowed?(role_guest, nil, 'some_privilege')
384
+ end
385
+
386
+ # Ensures that a privilege denied for a particular Role upon all Resources works properly
387
+ def test_role_privilege_deny
388
+ role_guest = Rend::Acl::Role.new('guest')
389
+ @acl.add_role!(role_guest)
390
+ @acl.allow!(role_guest)
391
+ @acl.deny!(role_guest, nil, 'some_privilege')
392
+ assert_equal false, @acl.allowed?(role_guest, nil, 'some_privilege')
393
+ end
394
+
395
+ # Ensures that multiple privileges work properly for a particular Role
396
+ def test_role_privileges
397
+ role_guest = Rend::Acl::Role.new('guest')
398
+ @acl.add_role!(role_guest)
399
+ @acl.allow!(role_guest, nil, ['p1', 'p2', 'p3'])
400
+ assert_equal true, @acl.allowed?(role_guest, nil, 'p1')
401
+ assert_equal true, @acl.allowed?(role_guest, nil, 'p2')
402
+ assert_equal true, @acl.allowed?(role_guest, nil, 'p3')
403
+ assert_equal false, @acl.allowed?(role_guest, nil, 'p4')
404
+ @acl.deny!(role_guest, nil, 'p1')
405
+ assert_equal false, @acl.allowed?(role_guest, nil, 'p1')
406
+ @acl.deny!(role_guest, nil, ['p2', 'p3'])
407
+ assert_equal false, @acl.allowed?(role_guest, nil, 'p2')
408
+ assert_equal false, @acl.allowed?(role_guest, nil, 'p3')
409
+ end
410
+
411
+ # Ensures that removing the default deny rule results in default deny rule
412
+ def test_remove_default_deny
413
+ assert_equal false, @acl.allowed?
414
+ @acl.remove_deny!
415
+ assert_equal false, @acl.allowed?
416
+ end
417
+
418
+
419
+ # Ensures that removing the default allow rule results in default deny rule being assigned
420
+ def test_remove_default_allow
421
+ @acl.allow!
422
+ assert_equal true, @acl.allowed?
423
+ @acl.remove_allow!
424
+ assert_equal false, @acl.allowed?
425
+ end
426
+
427
+ # Ensures that removing non-existent default allow rule does nothing
428
+ def test_remove_default_allow_non_existent
429
+ @acl.remove_allow!
430
+ assert_equal false, @acl.allowed?
431
+ end
432
+
433
+ # Ensures that removing non-existent default deny rule does nothing
434
+ def test_remove_default_deny_non_existent
435
+ @acl.allow!
436
+ @acl.remove_deny!
437
+ assert_equal true, @acl.allowed?
438
+ end
439
+
440
+ # # Ensure that basic rule removal works
441
+ def test_rules_remove
442
+ @acl.allow!(nil, nil, ['privilege1', 'privilege2'])
443
+ assert_equal false, @acl.allowed?
444
+ assert_equal true, @acl.allowed?(nil, nil, 'privilege1')
445
+ assert_equal true, @acl.allowed?(nil, nil, 'privilege2')
446
+
447
+ @acl.remove_allow!(nil, nil, 'privilege1')
448
+ assert_equal false, @acl.allowed?(nil, nil, 'privilege1')
449
+ assert_equal true, @acl.allowed?(nil, nil, 'privilege2')
450
+ end
451
+
452
+ # # Ensures that removal of a Role results in its rules being removed
453
+ def test_rule_role_remove
454
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
455
+ @acl.allow!('guest')
456
+ assert_equal true, @acl.allowed?('guest')
457
+
458
+ @acl.remove_role!('guest')
459
+ assert_raises Rend::Acl::Role::Registry::Exception do
460
+ @acl.allowed?('guest')
461
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon is_allowed on non-existent Role')
462
+ end
463
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
464
+ assert_equal false, @acl.allowed?('guest')
465
+ end
466
+
467
+ # Ensures that removal of all Roles results in Role-specific rules being removed
468
+ def test_rule_role_remove_all
469
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
470
+ @acl.allow!('guest')
471
+ assert_equal true, @acl.allowed?('guest')
472
+ @acl.remove_role_all!
473
+ assert_raises Rend::Acl::Role::Registry::Exception do
474
+ @acl.allowed?('guest')
475
+ flunk('Expected Rend::Acl::Role::Registry::Exception not thrown upon is_allowed on non-existent Role')
476
+ end
477
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
478
+ assert_equal false, @acl.allowed?('guest')
479
+ end
480
+
481
+ # Ensures that removal of a Resource results in its rules being removed
482
+ def test_rules_resource_remove
483
+ @acl.add_resource!(Rend::Acl::Resource.new('area'))
484
+ @acl.allow!(nil, 'area')
485
+ assert_equal true, @acl.allowed?(nil, 'area')
486
+ @acl.remove_resource!('area')
487
+ assert_raises Rend::Acl::Exception do
488
+ @acl.allowed?(nil, 'area')
489
+ flunk('Expected Rend::Acl::Exception not thrown upon is_allowed on non-existent Resource')
490
+ end
491
+ @acl.add_resource!(Rend::Acl::Resource.new('area'))
492
+ assert_equal false, @acl.allowed?(nil, 'area')
493
+ end
494
+
495
+ # Ensures that removal of all Resources results in Resource-specific rules being removed
496
+ def test_rules_resource_remove_all
497
+ @acl.add_resource!(Rend::Acl::Resource.new('area'))
498
+ @acl.allow!(nil, 'area')
499
+ assert_equal true, @acl.allowed?(nil, 'area')
500
+ @acl.remove_resource_all!
501
+ assert_raises Rend::Acl::Exception do
502
+ @acl.allowed?(nil, 'area')
503
+ flunk('Expected Rend::Acl::Exception not thrown upon is_allowed on non-existent Resource')
504
+ end
505
+ @acl.add_resource!(Rend::Acl::Resource.new('area'))
506
+ assert_equal false, @acl.allowed?(nil, 'area')
507
+ end
508
+
509
+ # Ensures that an example for a content management system is operable
510
+ def test_cms_example
511
+ # Add some roles to the Role registry
512
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
513
+ @acl.add_role!(Rend::Acl::Role.new('staff'), 'guest') # staff inherits permissions from guest
514
+ @acl.add_role!(Rend::Acl::Role.new('editor'), 'staff') # editor inherits permissions from staff
515
+ @acl.add_role!(Rend::Acl::Role.new('administrator'))
151
516
 
152
517
  # Guest may only view content
153
- @acl.allow! guest_role, nil, 'view'
518
+ @acl.allow!('guest', nil, 'view')
154
519
 
155
- # Staff inherits view privilege from guest, but also needs additional
156
- # privileges
157
- @acl.allow! 'staff', nil, %w[edit submit revise]
520
+ # Staff inherits view privilege from guest, but also needs additional privileges
521
+ @acl.allow!('staff', nil, ['edit', 'submit', 'revise'])
158
522
 
159
- # Editor inherits view, edit, submit, and revise privileges from
160
- # staff, but also needs additional privileges
161
- @acl.allow! 'editor', nil, %w[publish archive delete]
523
+ # Editor inherits view, edit, submit, and revise privileges, but also needs additional privileges
524
+ @acl.allow!('editor', nil, ['publish', 'archive', 'delete'])
162
525
 
163
- # Administrator inherits nothing, but is allowed all privileges
164
- @acl.allow! 'administrator'
526
+ # Administrator inherits nothing but is allowed all privileges
527
+ @acl.allow!('administrator')
165
528
 
166
- # The new marketing group inherits permissions from staff
529
+ # Access control checks based on above permission sets
530
+ assert_equal true, @acl.allowed?('guest', nil, 'view')
531
+ assert_equal false, @acl.allowed?('guest', nil, 'edit')
532
+ assert_equal false, @acl.allowed?('guest', nil, 'submit')
533
+ assert_equal false, @acl.allowed?('guest', nil, 'revise')
534
+ assert_equal false, @acl.allowed?('guest', nil, 'publish')
535
+ assert_equal false, @acl.allowed?('guest', nil, 'archive')
536
+ assert_equal false, @acl.allowed?('guest', nil, 'delete')
537
+ assert_equal false, @acl.allowed?('guest', nil, 'unknown')
538
+ assert_equal false, @acl.allowed?('guest')
539
+
540
+ assert_equal true, @acl.allowed?('staff', nil, 'view')
541
+ assert_equal true, @acl.allowed?('staff', nil, 'edit')
542
+ assert_equal true, @acl.allowed?('staff', nil, 'submit')
543
+ assert_equal true, @acl.allowed?('staff', nil, 'revise')
544
+ assert_equal false, @acl.allowed?('staff', nil, 'publish')
545
+ assert_equal false, @acl.allowed?('staff', nil, 'archive')
546
+ assert_equal false, @acl.allowed?('staff', nil, 'delete')
547
+ assert_equal false, @acl.allowed?('staff', nil, 'unknown')
548
+ assert_equal false, @acl.allowed?('staff')
549
+
550
+ assert_equal true, @acl.allowed?('editor', nil, 'view')
551
+ assert_equal true, @acl.allowed?('editor', nil, 'edit')
552
+ assert_equal true, @acl.allowed?('editor', nil, 'submit')
553
+ assert_equal true, @acl.allowed?('editor', nil, 'revise')
554
+ assert_equal true, @acl.allowed?('editor', nil, 'publish')
555
+ assert_equal true, @acl.allowed?('editor', nil, 'archive')
556
+ assert_equal true, @acl.allowed?('editor', nil, 'delete')
557
+ assert_equal false, @acl.allowed?('editor', nil, 'unknown')
558
+ assert_equal false, @acl.allowed?('editor')
559
+
560
+ assert_equal true, @acl.allowed?('administrator', nil, 'view')
561
+ assert_equal true, @acl.allowed?('administrator', nil, 'edit')
562
+ assert_equal true, @acl.allowed?('administrator', nil, 'submit')
563
+ assert_equal true, @acl.allowed?('administrator', nil, 'revise')
564
+ assert_equal true, @acl.allowed?('administrator', nil, 'publish')
565
+ assert_equal true, @acl.allowed?('administrator', nil, 'archive')
566
+ assert_equal true, @acl.allowed?('administrator', nil, 'delete')
567
+ assert_equal true, @acl.allowed?('administrator', nil, 'unknown')
568
+ assert_equal true, @acl.allowed?('administrator')
569
+
570
+ # Some checks on specific areas, which inherit access controls from the root ACL node
571
+ @acl.add_resource!(Rend::Acl::Resource.new('newsletter'))
572
+ @acl.add_resource!(Rend::Acl::Resource.new('pending'), 'newsletter')
573
+ @acl.add_resource!(Rend::Acl::Resource.new('gallery'))
574
+ @acl.add_resource!(Rend::Acl::Resource.new('profiles'), 'gallery')
575
+ @acl.add_resource!(Rend::Acl::Resource.new('config'))
576
+ @acl.add_resource!(Rend::Acl::Resource.new('hosts'), 'config')
577
+
578
+ assert_equal true, @acl.allowed?('guest', 'pending', 'view')
579
+ assert_equal true, @acl.allowed?('staff', 'profiles', 'revise')
580
+ assert_equal true, @acl.allowed?('staff', 'pending', 'view')
581
+ assert_equal true, @acl.allowed?('staff', 'pending', 'edit')
582
+ assert_equal false, @acl.allowed?('staff', 'pending', 'publish')
583
+ assert_equal false, @acl.allowed?('staff', 'pending')
584
+ assert_equal false, @acl.allowed?('editor', 'hosts', 'unknown')
585
+ assert_equal true, @acl.allowed?('administrator', 'pending')
586
+
587
+ # Add a new group, marketing, which bases its permissions on staff
167
588
  @acl.add_role!(Rend::Acl::Role.new('marketing'), 'staff')
168
589
 
169
- # === Create Resources for the rules ===
590
+ # Refine the privilege sets for more specific needs
170
591
 
171
- # newsletter
172
- @acl.add_resource!(Rend::Acl::Resource.new('newsletter'))
592
+ # Allow marketing to publish and archive newsletters
593
+ @acl.allow!('marketing', 'newsletter', ['publish', 'archive'])
173
594
 
174
- # news
595
+ # Allow marketing to publish and archive latest news
175
596
  @acl.add_resource!(Rend::Acl::Resource.new('news'))
176
-
177
- # latest news
178
597
  @acl.add_resource!(Rend::Acl::Resource.new('latest'), 'news')
598
+ @acl.allow!('marketing', 'latest', ['publish', 'archive'])
599
+
600
+ # Deny staff (and marketing, by inheritance) rights to revise latest news
601
+ @acl.deny!('staff', 'latest', 'revise')
179
602
 
180
- # announcement news
603
+ # Deny everyone access to archive news announcements
181
604
  @acl.add_resource!(Rend::Acl::Resource.new('announcement'), 'news')
605
+ @acl.deny!(nil, 'announcement', 'archive')
606
+
607
+ # Access control checks for the above refined permission sets
608
+ assert_equal true, @acl.allowed?('marketing', nil, 'view')
609
+ assert_equal true, @acl.allowed?('marketing', nil, 'edit')
610
+ assert_equal true, @acl.allowed?('marketing', nil, 'submit')
611
+ assert_equal true, @acl.allowed?('marketing', nil, 'revise')
612
+ assert_equal false, @acl.allowed?('marketing', nil, 'publish')
613
+ assert_equal false, @acl.allowed?('marketing', nil, 'archive')
614
+ assert_equal false, @acl.allowed?('marketing', nil, 'delete')
615
+ assert_equal false, @acl.allowed?('marketing', nil, 'unknown')
616
+ assert_equal false, @acl.allowed?('marketing')
617
+
618
+ assert_equal true, @acl.allowed?('marketing', 'newsletter', 'publish')
619
+ assert_equal false, @acl.allowed?('staff', 'pending', 'publish')
620
+ assert_equal true, @acl.allowed?('marketing', 'pending', 'publish')
621
+ assert_equal true, @acl.allowed?('marketing', 'newsletter', 'archive')
622
+ assert_equal false, @acl.allowed?('marketing', 'newsletter', 'delete')
623
+ assert_equal false, @acl.allowed?('marketing', 'newsletter')
624
+
625
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'publish')
626
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'archive')
627
+ assert_equal false, @acl.allowed?('marketing', 'latest', 'delete')
628
+ assert_equal false, @acl.allowed?('marketing', 'latest', 'revise')
629
+ assert_equal false, @acl.allowed?('marketing', 'latest')
630
+
631
+ assert_equal false, @acl.allowed?('marketing', 'announcement', 'archive')
632
+ assert_equal false, @acl.allowed?('staff', 'announcement', 'archive')
633
+ assert_equal false, @acl.allowed?('administrator', 'announcement', 'archive')
634
+
635
+ assert_equal false, @acl.allowed?('staff', 'latest', 'publish')
636
+ assert_equal false, @acl.allowed?('editor', 'announcement', 'archive')
637
+
638
+ # Remove some previous permission specifications
639
+
640
+ # Marketing can no longer publish and archive newsletters
641
+ @acl.remove_allow!('marketing', 'newsletter', ['publish', 'archive'])
642
+
643
+ # Marketing can no longer archive the latest news
644
+ @acl.remove_allow!('marketing', 'latest', 'archive')
645
+
646
+ # Now staff (and marketing, by inheritance) may revise latest news
647
+ @acl.remove_deny!('staff', 'latest', 'revise')
648
+
649
+ # Access control checks for the above refinements
650
+
651
+ assert_equal false, @acl.allowed?('marketing', 'newsletter', 'publish')
652
+ assert_equal false, @acl.allowed?('marketing', 'newsletter', 'archive')
653
+ assert_equal false, @acl.allowed?('marketing', 'latest', 'archive')
654
+ assert_equal true, @acl.allowed?('staff', 'latest', 'revise')
655
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'revise')
656
+
657
+ # Grant marketing all permissions on the latest news
658
+ @acl.allow!('marketing', 'latest')
659
+
660
+ # Access control checks for the above refinement
661
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'archive')
662
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'publish')
663
+ assert_equal true, @acl.allowed?('marketing', 'latest', 'edit')
664
+ assert_equal true, @acl.allowed?('marketing', 'latest')
665
+
666
+ end
667
+
668
+ # [NOT IMPLEMENTED YET] Ensures that the default rule obeys its assertion
669
+ # def test_default_assert
670
+ # @acl.deny!(nil, nil, nil, Rend::Acl::Mock_assertion.new(false))
671
+ # assert_equal true, @acl.allowed?
672
+ # assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
673
+ # end
674
+
675
+ # Ensures that the only_parents argument to inherits_role? works
676
+ # @group ZF-2502
677
+ def test_role_inheritance_supports_checking_only_parents
678
+ @acl.add_role!(Rend::Acl::Role.new('grandparent'))
679
+ @acl.add_role!(Rend::Acl::Role.new('parent'), 'grandparent')
680
+ @acl.add_role!(Rend::Acl::Role.new('child'), 'parent')
681
+ assert_equal false, @acl.inherits_role?('child', 'grandparent', true)
682
+ end
683
+
684
+ # Returns an array of registered roles
685
+ # @expected_exception PHPUnit_Framework_Error
686
+ # @group ZF-5638
687
+ # Porter Note: Seems like an odd test... investigate more
688
+ def test_get_registered_roles
689
+ @acl.add_role!('developer')
690
+
691
+ roles = @acl.roles
692
+ assert_kind_of Array, roles
693
+ assert_equal false, roles.empty?
694
+ end
695
+
696
+ # Confirm that deleting a role after allowing access to all roles
697
+ # raise undefined index error
698
+ # @group ZF-5700
699
+ # Porter Note: Seems like an odd test... investigate more
700
+ def test_removing_role_after_it_was_allowed_access_to_all_resources_gives_error
701
+ @acl.add_role!(Rend::Acl::Role.new('test0'))
702
+ @acl.add_role!(Rend::Acl::Role.new('test1'))
703
+ @acl.add_role!(Rend::Acl::Role.new('test2'))
704
+ @acl.add_resource!(Rend::Acl::Resource.new('Test'))
705
+
706
+ @acl.allow!(nil,'Test','xxx')
707
+
708
+ # error test
709
+ @acl.remove_role!('test0')
710
+
711
+ # Check after fix
712
+ assert_equal false, @acl.has_role?('test0')
713
+ end
714
+
715
+ # @group ZF-8039
716
+ # Meant to test for the (in)existance of this notice:
717
+ # "Notice: Undefined index: all_privileges in lib/Zend/Acl.php on line 682"
718
+ # Porter Note: Seems like an odd test... investigate more
719
+ def test_method_remove_allow_does_not_throw_notice
720
+ acl = Rend::Acl.new
721
+ acl.add_role!('admin')
722
+ acl.add_resource!('blog')
723
+ acl.allow!('admin', 'blog', 'read')
724
+ acl.remove_allow!(['admin'], ['blog'], nil)
725
+ end
726
+
727
+ def test_role_object_implements_to_string
728
+ role = Rend::Acl::Role.new('_foo_bar_')
729
+ assert_equal '_foo_bar_', role.to_s
730
+ end
731
+
732
+ def test_resource_object_implements_to_string
733
+ resource = Rend::Acl::Resource.new('_foo_bar_')
734
+ assert_equal '_foo_bar_', resource.to_s
735
+ end
736
+
737
+
738
+ # @group ZF-8468
739
+ def test_roles
740
+ assert_equal [], @acl.roles
741
+
742
+ role_guest = Rend::Acl::Role.new('guest')
743
+ @acl.add_role!(role_guest)
744
+ @acl.add_role!(Rend::Acl::Role.new('staff'), role_guest)
745
+ @acl.add_role!(Rend::Acl::Role.new('editor'), 'staff')
746
+ @acl.add_role!(Rend::Acl::Role.new('administrator'))
747
+
748
+ expected = %w[guest staff editor administrator]
749
+ assert_equal expected, @acl.roles
750
+ end
751
+
752
+ # @group ZF-8468
753
+ def test_resources
754
+ assert_equal [], @acl.resources
755
+
756
+ @acl.add_resource!(Rend::Acl::Resource.new('some_resource'))
757
+ @acl.add_resource!(Rend::Acl::Resource.new('some_other_resource'))
758
+
759
+ expected = ['some_resource', 'some_other_resource']
760
+ assert_equal expected, @acl.resources
761
+ end
762
+
763
+ # @group ZF-9643
764
+ def test_remove_allow_with_nil_resource_after_resource_specific_rules_applies_to_all_resources
765
+ @acl.add_role!('guest')
766
+ @acl.add_resource!('blogpost')
767
+ @acl.add_resource!('newsletter')
768
+ @acl.allow!('guest', 'blogpost', 'read')
769
+ @acl.allow!('guest', 'newsletter', 'read')
770
+ assert_equal true, @acl.allowed?('guest', 'blogpost', 'read')
771
+ assert_equal true, @acl.allowed?('guest', 'newsletter', 'read')
772
+
773
+ @acl.remove_allow!('guest', 'newsletter', 'read')
774
+ assert_equal true, @acl.allowed?('guest', 'blogpost', 'read')
775
+ assert_equal false, @acl.allowed?('guest', 'newsletter', 'read')
776
+
777
+ @acl.remove_allow!('guest', nil, 'read')
778
+ assert_equal false, @acl.allowed?('guest', 'blogpost', 'read')
779
+ assert_equal false, @acl.allowed?('guest', 'newsletter', 'read')
780
+
781
+ # ensure allow nil/all resoures works
782
+ @acl.allow!('guest', nil, 'read')
783
+ assert_equal true, @acl.allowed?('guest', 'blogpost', 'read')
784
+ assert_equal true, @acl.allowed?('guest', 'newsletter', 'read')
785
+ end
786
+
787
+ # @group ZF-9643
788
+ def test_remove_deny_with_nil_resource_after_resource_specific_rules_applies_to_all_resources
789
+ @acl.add_role!('guest')
790
+ @acl.add_resource!('blogpost')
791
+ @acl.add_resource!('newsletter')
792
+
793
+ @acl.allow!
794
+ @acl.deny!('guest', 'blogpost', 'read')
795
+ @acl.deny!('guest', 'newsletter', 'read')
796
+ assert_equal false, @acl.allowed?('guest', 'blogpost', 'read')
797
+ assert_equal false, @acl.allowed?('guest', 'newsletter', 'read')
798
+
799
+ @acl.remove_deny!('guest', 'newsletter', 'read')
800
+ assert_equal false, @acl.allowed?('guest', 'blogpost', 'read')
801
+ assert_equal true, @acl.allowed?('guest', 'newsletter', 'read')
802
+
803
+ @acl.remove_deny!('guest', nil, 'read')
804
+ assert_equal true, @acl.allowed?('guest', 'blogpost', 'read')
805
+ assert_equal true, @acl.allowed?('guest', 'newsletter', 'read')
806
+
807
+ # ensure deny nil/all resources works
808
+ @acl.deny!('guest', nil, 'read')
809
+ assert_equal false, @acl.allowed?('guest', 'blogpost', 'read')
810
+ assert_equal false, @acl.allowed?('guest', 'newsletter', 'read')
811
+ end
812
+
813
+ # Ensures that for a particular Role, a deny rule on a specific Resource is honored before an allow rule on the entire ACL
814
+ def test_role_default_allow_rule_with_resource_deny_rule
815
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
816
+ @acl.add_role!(Rend::Acl::Role.new('staff'), 'guest')
817
+ @acl.add_resource!(Rend::Acl::Resource.new('area1'))
818
+ @acl.add_resource!(Rend::Acl::Resource.new('area2'))
819
+ @acl.deny!
820
+ @acl.allow!('staff')
821
+ @acl.deny!('staff', ['area1', 'area2'])
822
+ assert_equal false, @acl.allowed?('staff', 'area1')
823
+ end
824
+
825
+ # Ensures that for a particular Role, a deny rule on a specific privilege is honored before an allow rule on the entire ACL
826
+ def test_role_default_allow_rule_with_privilege_deny_rule
827
+ @acl.add_role!(Rend::Acl::Role.new('guest'))
828
+ @acl.add_role!(Rend::Acl::Role.new('staff'), 'guest')
829
+ @acl.deny!
830
+ @acl.allow!('staff')
831
+ @acl.deny!('staff', nil, ['privilege1', 'privilege2'])
832
+ assert_equal false, @acl.allowed?('staff', nil, 'privilege1')
833
+ end
834
+
835
+ # @group ZF-10649
836
+ def test_allow_and_deny_with_nil_for_resources_will_apply_to_all_resources
837
+ @acl.add_role!('guest')
838
+ @acl.add_resource!('blogpost')
839
+
840
+ @acl.allow!('guest')
841
+ assert_equal true, @acl.allowed?('guest')
842
+ assert_equal true, @acl.allowed?('guest', 'blogpost')
843
+ assert_equal true, @acl.allowed?('guest', 'blogpost', 'read')
844
+
845
+ @acl.deny!('guest')
846
+ assert_equal false, @acl.allowed?('guest')
847
+ assert_equal false, @acl.allowed?('guest', 'blogpost')
848
+ assert_equal false, @acl.allowed?('guest', 'blogpost', 'read')
849
+ end
850
+
851
+ #### [TESTS TO BE IMPLEMENTED LATER] ####
852
+
853
+ # # Ensures that assertions on privileges work properly for a particular Role
854
+ # def test_role_privilege_assert
855
+ # role_guest = Rend::Acl::Role.new('guest')
856
+ # @acl.add_role!(role_guest)
857
+ # .allow!(role_guest, nil, 'some_privilege', Rend::Acl::Mock_assertion.new(true))
858
+ # assert_equal true, @acl.allowed?(role_guest, nil, 'some_privilege')
859
+ # @acl.allow!(role_guest, nil, 'some_privilege', Rend::Acl::Mock_assertion.new(false))
860
+ # assert_equal false, @acl.allowed?(role_guest, nil, 'some_privilege')
861
+ # end
862
+
863
+ # # Ensures that removing the default deny rule results in assertion method being removed
864
+ # def test_remove_default_deny_assert
865
+ # @acl.deny!(nil, nil, nil, Rend::Acl::Mock_assertion.new(false))
866
+ # assert_equal true, @acl.allowed?
867
+ # @acl.remove_deny
868
+ # assert_equal false, @acl.allowed?
869
+ # end
870
+
871
+
872
+ # # @group ZF-1721
873
+ # def test_acl_assertions_get_proper_role_when_inheritence_is_used
874
+ # acl = this._load_use_case1
875
+
876
+ # user = Rend::Acl::Role.new('publisher')
877
+ # blog_post = Rend::Acl::Resource.new('blog_post')
878
+
879
+ # # @var Zend_Acl_Use_case1_User_is_blog_post_owner_assertion
880
+ # assertion = acl.custom_assertion
881
+
882
+ # assert_equal true, acl.is_allowed(user, blog_post, 'modify')
883
+
884
+ # assert_equal 'publisher', assertion.last_assert_role.id
885
+
886
+ # end
887
+
888
+ # # @group ZF-1722
889
+ # def test_acl_assertions_get_original_is_allowed_objects
890
+ # acl = this._load_use_case1
891
+
892
+ # user = Rend::Acl_Use_case1::User.new
893
+ # blog_post = Rend::Acl_Use_case1::Blog_post.new
894
+
895
+ # assert_equal true, acl.is_allowed(user, blog_post, 'view')
896
+
897
+ # /**
898
+ # * @var Zend_Acl_Use_case1_User_is_blog_post_owner_assertion
899
+ # */
900
+ # assertion = acl.custom_assertion
901
+
902
+ # assertion.assert_return_value = true
903
+ # user.role = 'contributor'
904
+ # assert_equal true, acl.is_allowed(user, blog_post, 'modify'), 'Assertion should return true'
905
+ # assertion.assert_return_value = false
906
+ # assert_equal false, acl.is_allowed(user, blog_post, 'modify'), 'Assertion should return false'
907
+
908
+ # # check to see if the last assertion has the proper objets
909
+ # assert_kind_of Zend_Acl_Use_case1_User, assertion.last_assert_role, 'Assertion did not recieve proper role object'
910
+ # assert_kind_of Zend_Acl_Use_case1_Blog_post, assertion.last_assert_resource, 'Assertion did not recieve proper resource object'
911
+
912
+ # end
913
+
914
+ # # @group ZF-7973
915
+ # def test_acl_passes_privilege_to_assert_class {
916
+ # require_once dirname(__FILE__) . '/_files/Assertion_z_f7973.php'
917
+ # assertion = Rend::Acl_Acl_test::Assertion_z_f7973.new
918
+
919
+ # acl = Rend::Acl.new
920
+ # acl.add_role!('role')
921
+ # acl.add_resource!('resource')
922
+ # acl.allow!('role',nil,nil,assertion)
923
+ # allowed = acl.is_allowed('role','resource','privilege',assertion)
924
+
925
+ # assert_equal true, allowed
926
+ # end
927
+
928
+
929
+ protected
930
+
931
+ # def use_case_2
932
+ # @acl.add_role!('guest')
933
+ # @acl.add_role!('contributor', 'guest')
934
+ # @acl.add_role!('publisher', 'contributor')
935
+ # @acl.add_role!('admin')
936
+ # @acl.add_resource!('blogPost')
937
+ # @acl.allow!('guest', 'blogPost', 'view')
938
+ # @acl.allow!('contributor', 'blogPost', 'contribute')
939
+ # @acl.allow!('contributor', 'blogPost', 'modify', @acl.customAssertion)
940
+ # @acl.allow!('publisher', 'blogPost', 'publish')
941
+ # end
942
+
943
+ # http:#framework.zend.com/manual/1.12/en/zend.acl.introduction.html#zend.acl.introduction.role_registry
944
+ def use_case_1
945
+ acl = Rend::Acl.new
946
+
947
+ guest_role = Rend::Acl::Role.new('guest')
948
+
949
+ acl.add_role! guest_role
950
+ acl.add_role! Rend::Acl::Role.new('staff'), guest_role
951
+ acl.add_role! Rend::Acl::Role.new('editor'), 'staff'
952
+ acl.add_role! Rend::Acl::Role.new('administrator')
953
+
954
+ # Guest may only view content
955
+ acl.allow! guest_role, nil, 'view'
956
+
957
+ # Staff inherits view privilege from guest, but also needs additional privileges
958
+ acl.allow! 'staff', nil, %w[edit submit revise]
959
+
960
+ # Editor inherits view, edit, submit, and revise privileges from staff, but also needs additional privileges
961
+ acl.allow! 'editor', nil, %w[publish archive delete]
962
+
963
+ # Administrator inherits nothing, but is allowed all privileges
964
+ acl.allow! 'administrator'
965
+
966
+ # Add new marketing group that inherits permissions from staff
967
+ acl.add_role!(Rend::Acl::Role.new('marketing'), 'staff')
968
+
969
+ # == Create Resources for the rules ===
970
+
971
+ acl.add_resource!(Rend::Acl::Resource.new('newsletter'))
972
+ acl.add_resource!(Rend::Acl::Resource.new('news'))
973
+ acl.add_resource!(Rend::Acl::Resource.new('latest'), 'news')
974
+ acl.add_resource!(Rend::Acl::Resource.new('announcement'), 'news')
182
975
 
183
976
  # === Setting up access ====
184
977
 
185
978
  # Marketing must be able to publish and archive newsletters and the latest news
186
- @acl.allow!('marketing', ['newsletter', 'latest'], ['publish', 'archive'])
979
+ acl.allow!('marketing', ['newsletter', 'latest'], ['publish', 'archive'])
187
980
 
188
981
  # Staff (and marketing, by inheritance), are denied permission to revise the latest news
189
- @acl.deny!('staff', 'latest', 'revise')
982
+ acl.deny!('staff', 'latest', 'revise')
190
983
 
191
984
  # Everyone (including administrators) are denied permission to archive news announcements
192
- @acl.deny!(nil, 'announcement', 'archive')
985
+ acl.deny!(nil, 'announcement', 'archive')
193
986
 
194
- encoded_acl = Marshal.dump(@acl)
195
- decoded_acl = Marshal.load(encoded_acl)
196
-
197
- # === Testing ===
198
-
199
- assert_equal false, decoded_acl.allowed?('staff' , 'newsletter' , 'publish') # denied
200
- assert_equal true, decoded_acl.allowed?('marketing' , 'newsletter' , 'publish') # allowed
201
- assert_equal false, decoded_acl.allowed?('staff' , 'latest' , 'publish') # denied
202
- assert_equal true, decoded_acl.allowed?('marketing' , 'latest' , 'publish') # allowed
203
- assert_equal true, decoded_acl.allowed?('marketing' , 'latest' , 'archive') # allowed
204
- assert_equal false, decoded_acl.allowed?('marketing' , 'latest' , 'revise') # denied
205
- assert_equal false, decoded_acl.allowed?('editor' , 'announcement' , 'archive') # denied
206
- assert_equal false, decoded_acl.allowed?('administrator' , 'announcement' , 'archive') # denied
987
+ acl
988
+ end
207
989
 
990
+ def assert_use_case_1(acl)
991
+ assert_equal false, acl.allowed?('staff' , 'newsletter' , 'publish') # denied
992
+ assert_equal true, acl.allowed?('marketing' , 'newsletter' , 'publish') # allowed
993
+ assert_equal false, acl.allowed?('staff' , 'latest' , 'publish') # denied
994
+ assert_equal true, acl.allowed?('marketing' , 'latest' , 'publish') # allowed
995
+ assert_equal true, acl.allowed?('marketing' , 'latest' , 'archive') # allowed
996
+ assert_equal false, acl.allowed?('marketing' , 'latest' , 'revise') # denied
997
+ assert_equal false, acl.allowed?('editor' , 'announcement' , 'archive') # denied
998
+ assert_equal false, acl.allowed?('administrator' , 'announcement' , 'archive') # denied
208
999
  end
209
1000
  end