rend-acl 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.coveralls.yml +1 -0
- data/.travis.yml +6 -0
- data/Changelog.md +12 -1
- data/Gemfile +4 -0
- data/README.md +91 -4
- data/lib/rend/acl.rb +144 -181
- data/lib/rend/acl/mock_assertion.rb +0 -28
- data/lib/rend/acl/version.rb +1 -1
- data/rend-acl.gemspec +3 -3
- data/test/helper.rb +14 -0
- data/test/support/failing_assertion.rb +7 -0
- data/test/support/mock_assertion.rb +23 -0
- data/test/support/passing_assertion.rb +7 -0
- data/test/test_acl.rb +106 -18
- data/test/test_documentation_examples.rb +25 -0
- data/wiki/pages/resources.md +37 -0
- metadata +24 -11
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
ADDED
data/Changelog.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### Version 0.0.5 - June 24th, 2013
|
4
|
+
|
5
|
+
* Testing
|
6
|
+
* Added `Minitest` gem as development dependency
|
7
|
+
* Removed `Turn` gem development dependency.
|
8
|
+
* Added Travis CI.
|
9
|
+
* Added Coveralls.
|
10
|
+
|
11
|
+
* Documentation
|
12
|
+
* Added `/wiki/pages` directories.
|
13
|
+
|
3
14
|
### Version 0.0.4 - June 11th, 2013
|
4
15
|
|
5
16
|
* Assertions
|
@@ -20,7 +31,7 @@
|
|
20
31
|
|
21
32
|
* `:role`
|
22
33
|
* `:resource`
|
23
|
-
* `:
|
34
|
+
* `:privilege`
|
24
35
|
* `:assertion` -- _Not utilized in `.allowed?()` method._
|
25
36
|
|
26
37
|
### Version <= 0.0.3
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,25 +1,112 @@
|
|
1
1
|
# Rend Acl
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/veloper/rend-acl.png?branch=master)](https://travis-ci.org/veloper/rend-acl)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/veloper/rend-acl/badge.png)](https://coveralls.io/r/veloper/rend-acl)
|
5
|
+
[![Dependency Status](https://gemnasium.com/veloper/rend-acl.png)](https://gemnasium.com/veloper/rend-acl)
|
6
|
+
|
3
7
|
Rend-Acl is a port of [Zend_Acl](http://framework.zend.com/manual/1.12/en/zend.acl.html) with modifications made to bring the api more inline with Ruby conventions.
|
4
8
|
|
9
|
+
## Introduction
|
10
|
+
Rend-Acl provides a lightweight and flexible access control list (ACL) implementation for privileges management. In general, an application may utilize such ACL's to control access to certain protected objects by other requesting objects.
|
11
|
+
|
12
|
+
For the purposes of this documentation:
|
13
|
+
|
14
|
+
* A **Role** is an object that may request access to a Resource or Privilege.
|
15
|
+
* _(e.g., "Passenger", "Driver", "Mechanic")_
|
16
|
+
* A **Resource** is an object to which access is controlled.
|
17
|
+
* _(e.g., "Car", "Boat", "Train")_
|
18
|
+
* A **Privilege** is an _(optional)_ level of control which enables further refinement.
|
19
|
+
* _(e.g., "Drive", "Sell", "Repair")_
|
20
|
+
|
21
|
+
Through use of an ACL an application may control how roles are granted access to resources and privilages.
|
22
|
+
|
23
|
+
### Still Lost?
|
24
|
+
These terms and concepts become easier to understand when translated into plain english...
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
@acl.allow! :role => "Driver", :resource => "Car"
|
28
|
+
```
|
29
|
+
> __Translation:__ Allow a **Driver** full-access to the **Car**.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
@acl.allow! :role => "Driver", :resource => "Car", :privilege => "Sell"
|
33
|
+
```
|
34
|
+
> __Translation:__ Allow a **Driver** to **Sell** the **Car**.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
@acl.allow! :role => "Mechanic", :privilege => "Repair"
|
38
|
+
```
|
39
|
+
> __Translation:__ Allow a **Mechanic** to **Repair** anything.
|
40
|
+
|
41
|
+
|
42
|
+
## Basic Usage Example
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# ==> Require Rend ACL
|
46
|
+
require 'rend/acl'
|
47
|
+
|
48
|
+
# ==> Initialize ACL Object
|
49
|
+
@acl = Rend::Acl.new
|
50
|
+
|
51
|
+
# ==> Add Roles & Resources to ACL
|
52
|
+
@acl.add! :role => ["Passenger", "Driver", "Mechanic"],
|
53
|
+
:resource => ["Car", "Boat", "Train"]
|
54
|
+
|
55
|
+
# ==> Declare Rules - Note: When conflicts occur the last rule always wins!
|
56
|
+
|
57
|
+
# Translation: Allow the "Driver" Role full-access to the "Car" Resource.
|
58
|
+
@acl.allow! :role => "Driver", :resource => "Car"
|
59
|
+
|
60
|
+
# Translation: Allow the "Mechanic" Role the privilege to "Repair" any Resource.
|
61
|
+
@acl.allow! :role => "Mechanic", :privilege => "Repair"
|
62
|
+
|
63
|
+
# Translation: Allow all Roles the privilege to "Look" at any Resource.
|
64
|
+
@acl.allow! :privilege => "Look"
|
65
|
+
|
66
|
+
# Translation: Deny all Roles any access to the "Train" Resource.
|
67
|
+
@acl.deny! :resource => "Train"
|
68
|
+
|
69
|
+
# ==> Querying
|
70
|
+
@acl.allowed?(:role => "Driver", :resource => "Car") # TRUE
|
71
|
+
@acl.allowed?(:role => "Passenger", :resource => "Car") # FALSE
|
72
|
+
@acl.allowed?(:role => "Mechanic", :resource => "Car") # FALSE
|
73
|
+
@acl.allowed?(:role => "Mechanic", :privilege => "Repair") # TRUE
|
74
|
+
@acl.allowed?(:role => "Passenger", :privilege => "Look") # TRUE
|
75
|
+
@acl.allowed?(:role => "Passenger", :resource => "Train") # FALSE
|
76
|
+
@acl.allowed?(:role => "Mechanic", :resource => "Train", :privilege => "Repair") # FALSE
|
77
|
+
```
|
78
|
+
|
5
79
|
## Installation
|
6
80
|
|
81
|
+
Install this gem directly using...
|
82
|
+
|
7
83
|
gem install rend-acl
|
8
84
|
|
85
|
+
... or simply include it in your project's `Gemfile` ...
|
86
|
+
|
87
|
+
gem 'rend-acl', '~> 0.0.5'
|
88
|
+
|
89
|
+
## Requirements
|
90
|
+
|
91
|
+
* Ruby >= 1.9.2
|
92
|
+
|
9
93
|
## Contributing
|
10
94
|
|
11
95
|
1. Fork it
|
12
96
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
13
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
97
|
+
3. Commit your changes **(with passing tests please!)** (`git commit -am 'Add some feature'`)
|
14
98
|
4. Push to the branch (`git push origin my-new-feature`)
|
15
99
|
5. Create new Pull Request
|
100
|
+
6. ???
|
101
|
+
7. Profit!
|
16
102
|
|
17
103
|
## Licensing
|
18
104
|
|
19
|
-
* All ported Ruby code and
|
105
|
+
* All ported Ruby code and associated 'Rend' gems are under a simple [New-BSD License](http://dan.doezema.com/licenses/new-bsd).
|
20
106
|
* Original PHP code is licensed under [Zend's New-BSD License](http://framework.zend.com/license/).
|
21
107
|
* This license can be found in `./ZEND_FRAMEWORK_LICENSE.txt`
|
22
108
|
|
23
109
|
## Acknowledgements
|
24
|
-
|
25
|
-
*
|
110
|
+
|
111
|
+
* This project is **NOT** associated with, or endorsed by, Zend Technologies USA, Inc., nor any of its contributors.
|
112
|
+
* Rend's modular design was heavily influenced by [RSpec](https://github.com/rspec/rspec)'s approach.
|
data/lib/rend/acl.rb
CHANGED
@@ -372,9 +372,6 @@ module Rend
|
|
372
372
|
privileges = options.fetch(:privilege, nil)
|
373
373
|
assertion = options.fetch(:assertion, nil)
|
374
374
|
end
|
375
|
-
roles = nil if roles == :all
|
376
|
-
resources = nil if resources == :all
|
377
|
-
privileges = nil if privileges == :all
|
378
375
|
|
379
376
|
type_hint! Rend::Acl::Assertion, assertion
|
380
377
|
|
@@ -397,9 +394,6 @@ module Rend
|
|
397
394
|
privileges = options.fetch(:privilege, nil)
|
398
395
|
assertion = options.fetch(:assertion, nil)
|
399
396
|
end
|
400
|
-
roles = nil if roles == :all
|
401
|
-
resources = nil if resources == :all
|
402
|
-
privileges = nil if privileges == :all
|
403
397
|
|
404
398
|
type_hint! Rend::Acl::Assertion, assertion
|
405
399
|
|
@@ -421,9 +415,6 @@ module Rend
|
|
421
415
|
privileges = options.fetch(:privilege, nil)
|
422
416
|
assertion = options.fetch(:assertion, nil)
|
423
417
|
end
|
424
|
-
roles = nil if roles == :all
|
425
|
-
resources = nil if resources == :all
|
426
|
-
privileges = nil if privileges == :all
|
427
418
|
|
428
419
|
set_rule!(OP_REMOVE, TYPE_ALLOW, roles, resources, privileges, assertion)
|
429
420
|
end
|
@@ -443,9 +434,6 @@ module Rend
|
|
443
434
|
privileges = options.fetch(:privilege, nil)
|
444
435
|
assertion = options.fetch(:assertion, nil)
|
445
436
|
end
|
446
|
-
roles = nil if roles == :all
|
447
|
-
resources = nil if resources == :all
|
448
|
-
privileges = nil if privileges == :all
|
449
437
|
|
450
438
|
set_rule!(OP_REMOVE, TYPE_DENY, roles, resources, privileges, assertion)
|
451
439
|
end
|
@@ -491,166 +479,38 @@ module Rend
|
|
491
479
|
# @uses Rend::Acl::get!()
|
492
480
|
# @return Rend::Acl Provides a fluent interface
|
493
481
|
def set_rule!(operation, type, roles = nil, resources = nil, privileges = nil, assertion = nil)
|
494
|
-
|
482
|
+
type_hint! Rend::Acl::Assertion, assertion
|
495
483
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
end
|
484
|
+
# ensure that the rule type is valid normalize input to uppercase
|
485
|
+
if type != TYPE_ALLOW && type != TYPE_DENY
|
486
|
+
raise Rend::Acl::Exception, "Unsupported rule type must be either '#{TYPE_ALLOW}' or '#{TYPE_DENY}'"
|
487
|
+
end
|
501
488
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
roles = [nil]
|
507
|
-
end
|
508
|
-
roles = roles.reduce([]) do |seed, role|
|
509
|
-
seed << (role ? role_registry.get!(role) : nil)
|
510
|
-
end
|
489
|
+
# ensure that all specified Roles exist normalize input to array of Role objects or nil
|
490
|
+
roles = Array(roles)
|
491
|
+
roles << nil if roles.empty?
|
492
|
+
roles = roles.reduce([]) {|seed, role| seed << (role ? role_registry.get!(role) : nil)}
|
511
493
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
end
|
519
|
-
else
|
520
|
-
# this might be used later if resource iteration is required
|
521
|
-
all_resources = @_resources.values.reduce([]) do |seed, r_target|
|
522
|
-
seed << r_target[:instance]
|
523
|
-
end
|
524
|
-
end
|
525
|
-
|
526
|
-
# normalize privileges to array
|
527
|
-
if privileges.nil?
|
528
|
-
privileges = []
|
529
|
-
elsif !privileges.is_a?(Array)
|
530
|
-
privileges = [privileges]
|
531
|
-
end
|
494
|
+
# ensure that all specified Resources exist normalize input to array of Resource objects or nil
|
495
|
+
if resources
|
496
|
+
resources = Array(resources)
|
497
|
+
resources << nil if resources.empty?
|
498
|
+
resources = resources.reduce([]) {|seed, resource| seed << (resource ? resource!(resource) : nil)}
|
499
|
+
end
|
532
500
|
|
533
|
-
|
534
|
-
|
535
|
-
# add to the rules
|
536
|
-
when OP_ADD
|
537
|
-
if resources
|
538
|
-
# this block will iterate the provided resources
|
539
|
-
resources.each do |resource|
|
540
|
-
roles.each do |role|
|
541
|
-
rules = _rules(resource, role, true)
|
542
|
-
if privileges.empty?
|
543
|
-
rules[:all_privileges] = {
|
544
|
-
:type => type,
|
545
|
-
:assertion => assertion
|
546
|
-
}
|
547
|
-
rules[:by_privilege_id] = {} unless rules.has_key?(:by_privilege_id)
|
548
|
-
else
|
549
|
-
privileges.each do |privilege|
|
550
|
-
rules[:by_privilege_id][privilege] = {
|
551
|
-
:type => type,
|
552
|
-
:assertion => assertion
|
553
|
-
}
|
554
|
-
end
|
555
|
-
end
|
556
|
-
end
|
557
|
-
end
|
558
|
-
else
|
559
|
-
# this block will apply to all resources in a global rule
|
560
|
-
roles.each do |role|
|
561
|
-
rules = _rules(nil, role, true)
|
562
|
-
if privileges.empty?
|
563
|
-
rules[:all_privileges] = {
|
564
|
-
:type => type,
|
565
|
-
:assertion => assertion
|
566
|
-
}
|
567
|
-
else
|
568
|
-
privileges.each do |privilege|
|
569
|
-
rules[:by_privilege_id][privilege] = {
|
570
|
-
:type => type,
|
571
|
-
:assertion => assertion
|
572
|
-
}
|
573
|
-
end
|
574
|
-
end
|
575
|
-
end
|
576
|
-
end
|
577
|
-
# remove from the rules
|
578
|
-
when OP_REMOVE
|
579
|
-
if resources
|
580
|
-
# this block will iterate the provided resources
|
581
|
-
resources.each do |resource|
|
582
|
-
roles.each do |role|
|
583
|
-
rules = _rules(resource, role)
|
584
|
-
next if rules.nil?
|
585
|
-
if privileges.empty?
|
586
|
-
if resource.nil? && role.nil?
|
587
|
-
if rules[:all_privileges][:type] == type
|
588
|
-
rules.replace({
|
589
|
-
:all_privileges => {
|
590
|
-
:type => TYPE_DENY,
|
591
|
-
:assertion => nil
|
592
|
-
},
|
593
|
-
:by_privilege_id => {}
|
594
|
-
})
|
595
|
-
end
|
596
|
-
next
|
597
|
-
end
|
598
|
-
if rules[:all_privileges].has_key?(:type) && rules[:all_privileges][:type] == type
|
599
|
-
rules.delete(:all_privileges)
|
600
|
-
end
|
601
|
-
else
|
602
|
-
privileges.each do |privilege|
|
603
|
-
if rules[:by_privilege_id].has_key?(privilege) && rules[:by_privilege_id][privilege][:type] == type
|
604
|
-
rules[:by_privilege_id].delete(privilege)
|
605
|
-
end
|
606
|
-
end
|
607
|
-
end
|
608
|
-
end
|
609
|
-
end
|
610
|
-
else
|
611
|
-
# this block will apply to all resources in a global rule
|
612
|
-
roles.each do |role|
|
613
|
-
|
614
|
-
# since nil (all resources) was passed to this set_role!() call, we need
|
615
|
-
# clean up all the rules for the global allResources, as well as the indivually
|
616
|
-
# set resources (per privilege as well)
|
617
|
-
[nil].concat(all_resources).each do |resource|
|
618
|
-
rules = _rules(resource, role, true)
|
619
|
-
next if rules.nil?
|
620
|
-
if privileges.empty?
|
621
|
-
if role.nil?
|
622
|
-
if rules[:all_privileges][:type] == type
|
623
|
-
rules.replace({
|
624
|
-
:all_privileges => {
|
625
|
-
:type => TYPE_DENY,
|
626
|
-
:assertion => nil
|
627
|
-
},
|
628
|
-
:by_privilege_id => {}
|
629
|
-
})
|
630
|
-
end
|
631
|
-
next
|
632
|
-
end
|
633
|
-
|
634
|
-
if rules[:all_privileges].has_key?(:type) && rules[:all_privileges][:type] == type
|
635
|
-
rules.delete(:all_privileges)
|
636
|
-
end
|
637
|
-
else
|
638
|
-
privileges.each do |privilege|
|
639
|
-
if rules[:by_privilege_id].has_key?(privilege) && rules[:by_privilege_id][privilege][:type] == type
|
640
|
-
rules[:by_privilege_id].delete(privilege)
|
641
|
-
end
|
642
|
-
end
|
643
|
-
end
|
644
|
-
end
|
645
|
-
end
|
646
|
-
end
|
647
|
-
else
|
648
|
-
raise Rend::Acl::Exception, "Unsupported operation must be either '#{OP_ADD}' or '#{OP_REMOVE}'"
|
649
|
-
end
|
501
|
+
# normalize privileges to array
|
502
|
+
privileges = Array(privileges).compact
|
650
503
|
|
651
|
-
|
504
|
+
case operation
|
505
|
+
when OP_ADD then _add_rule!(type, roles, resources, privileges, assertion)
|
506
|
+
when OP_REMOVE then _remove_rule!(type, roles, resources, privileges, assertion)
|
507
|
+
else
|
508
|
+
raise Rend::Acl::Exception, "Unsupported operation must be either '#{OP_ADD}' or '#{OP_REMOVE}'"
|
652
509
|
end
|
653
510
|
|
511
|
+
self
|
512
|
+
end
|
513
|
+
|
654
514
|
# Returns true if and only if the Role has access to the Resource
|
655
515
|
#
|
656
516
|
# The role and resource parameters may be references to, or the string identifiers for,
|
@@ -691,11 +551,6 @@ module Rend
|
|
691
551
|
privilege = options.fetch(:privilege, nil)
|
692
552
|
end
|
693
553
|
|
694
|
-
# Readability
|
695
|
-
role = nil if role == :all
|
696
|
-
resource = nil if resource == :all
|
697
|
-
privilege = nil if privilege == :all
|
698
|
-
|
699
554
|
if role
|
700
555
|
# keep track of originally called role
|
701
556
|
@_is_allowed_role = role
|
@@ -758,6 +613,11 @@ module Rend
|
|
758
613
|
end
|
759
614
|
end
|
760
615
|
|
616
|
+
# Inverse of allowed? method
|
617
|
+
def denied?(*args)
|
618
|
+
!allowed?(*args)
|
619
|
+
end
|
620
|
+
|
761
621
|
# Returns the Role registry for this ACL
|
762
622
|
#
|
763
623
|
# If no Role registry has been created yet, a new default Role registry
|
@@ -768,6 +628,27 @@ module Rend
|
|
768
628
|
@_role_registry ||= Rend::Acl::Role::Registry.new
|
769
629
|
end
|
770
630
|
|
631
|
+
# Returns an array of registered roles.
|
632
|
+
#
|
633
|
+
# Note that this method does not return instances of registered roles,
|
634
|
+
# but only the role identifiers.
|
635
|
+
#
|
636
|
+
# @return array of registered roles
|
637
|
+
def roles
|
638
|
+
role_registry.roles.keys
|
639
|
+
end
|
640
|
+
|
641
|
+
# @return array of registered resources
|
642
|
+
def resources
|
643
|
+
@_resources.keys
|
644
|
+
end
|
645
|
+
|
646
|
+
# == PROTECTED ================================================================================
|
647
|
+
|
648
|
+
protected
|
649
|
+
|
650
|
+
# =============================================================================================
|
651
|
+
|
771
652
|
# Performs a depth-first search of the Role DAG, starting at role, in order to find a rule
|
772
653
|
# allowing/denying role access to all privileges upon resource
|
773
654
|
#
|
@@ -1000,19 +881,101 @@ module Rend
|
|
1000
881
|
visitor[:by_role_id][role.id]
|
1001
882
|
end
|
1002
883
|
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
884
|
+
def _add_rule!(type, roles, resources, privileges, assertion)
|
885
|
+
if resources
|
886
|
+
# this block will iterate the provided resources
|
887
|
+
resources.each do |resource|
|
888
|
+
roles.each do |role|
|
889
|
+
rules = _rules(resource, role, true)
|
890
|
+
if privileges.empty?
|
891
|
+
rules[:all_privileges] = {:type => type, :assertion => assertion}
|
892
|
+
rules[:by_privilege_id] = {} unless rules.has_key?(:by_privilege_id)
|
893
|
+
else
|
894
|
+
privileges.each do |privilege|
|
895
|
+
rules[:by_privilege_id][privilege] = {:type => type, :assertion => assertion}
|
896
|
+
end
|
897
|
+
end
|
898
|
+
end
|
899
|
+
end
|
900
|
+
else
|
901
|
+
# this block will apply to all resources in a global rule
|
902
|
+
roles.each do |role|
|
903
|
+
rules = _rules(nil, role, true)
|
904
|
+
if privileges.empty?
|
905
|
+
rules[:all_privileges] = {:type => type, :assertion => assertion}
|
906
|
+
else
|
907
|
+
privileges.each do |privilege|
|
908
|
+
rules[:by_privilege_id][privilege] = {:type => type, :assertion => assertion}
|
909
|
+
end
|
910
|
+
end
|
911
|
+
end
|
912
|
+
end
|
1011
913
|
end
|
1012
914
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
915
|
+
def _remove_rule!(type, roles, resources, privileges, assertion)
|
916
|
+
if resources
|
917
|
+
# this block will iterate the provided resources
|
918
|
+
resources.each do |resource|
|
919
|
+
roles.each do |role|
|
920
|
+
rules = _rules(resource, role)
|
921
|
+
next if rules.nil?
|
922
|
+
if privileges.empty?
|
923
|
+
if resource.nil? && role.nil?
|
924
|
+
if rules[:all_privileges][:type] == type
|
925
|
+
rules.replace({
|
926
|
+
:all_privileges => {
|
927
|
+
:type => TYPE_DENY,
|
928
|
+
:assertion => nil
|
929
|
+
},
|
930
|
+
:by_privilege_id => {}
|
931
|
+
})
|
932
|
+
end
|
933
|
+
next
|
934
|
+
end
|
935
|
+
rules.delete(:all_privileges) if rules[:all_privileges][:type] == type
|
936
|
+
else
|
937
|
+
privileges.each do |privilege|
|
938
|
+
if rules[:by_privilege_id].has_key?(privilege) && rules[:by_privilege_id][privilege][:type] == type
|
939
|
+
rules[:by_privilege_id].delete(privilege)
|
940
|
+
end
|
941
|
+
end
|
942
|
+
end
|
943
|
+
end
|
944
|
+
end
|
945
|
+
else
|
946
|
+
all_resources = @_resources.values.reduce([]) {|seed, r_target| seed << r_target[:instance]}
|
947
|
+
|
948
|
+
# this block will apply to all resources in a global rule
|
949
|
+
roles.each do |role|
|
950
|
+
|
951
|
+
# since nil (all resources) was passed to this set_role!() call, we need
|
952
|
+
# clean up all the rules for the global all_resources, as well as the indivually
|
953
|
+
# set resources (per privilege as well)
|
954
|
+
[nil].concat(all_resources).each do |resource|
|
955
|
+
rules = _rules(resource, role, true)
|
956
|
+
next if rules.nil?
|
957
|
+
if privileges.empty?
|
958
|
+
if role.nil?
|
959
|
+
if rules[:all_privileges][:type] == type
|
960
|
+
rules.replace(:all_privileges => {:type => TYPE_DENY, :assertion => nil}, :by_privilege_id => {})
|
961
|
+
end
|
962
|
+
next
|
963
|
+
end
|
964
|
+
|
965
|
+
if rules[:all_privileges].has_key?(:type) && rules[:all_privileges][:type] == type
|
966
|
+
rules.delete(:all_privileges)
|
967
|
+
end
|
968
|
+
else
|
969
|
+
privileges.each do |privilege|
|
970
|
+
if rules[:by_privilege_id].has_key?(privilege) && rules[:by_privilege_id][privilege][:type] == type
|
971
|
+
rules[:by_privilege_id].delete(privilege)
|
972
|
+
end
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
end
|
977
|
+
end
|
1016
978
|
end
|
979
|
+
|
1017
980
|
end
|
1018
981
|
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# Not a required file -- used for testing
|
2
|
-
module Rend
|
3
|
-
class Acl
|
4
|
-
class MockAssertion < Rend::Acl::Assertion
|
5
|
-
|
6
|
-
attr_reader :last_acl
|
7
|
-
attr_reader :last_role
|
8
|
-
attr_reader :last_resource
|
9
|
-
attr_reader :last_privilege
|
10
|
-
|
11
|
-
attr_accessor :pass
|
12
|
-
|
13
|
-
def initialize(pass = nil, &block)
|
14
|
-
self.pass = block_given? ? block : pass
|
15
|
-
end
|
16
|
-
|
17
|
-
def pass=(value)
|
18
|
-
@pass = value.is_a?(Proc) ? value : lambda {|acl, role, resource, privilege| value}
|
19
|
-
end
|
20
|
-
|
21
|
-
def pass?(acl, role = nil, resource = nil, privilege = nil)
|
22
|
-
@last_acl, @last_role, @last_resource, @last_privilege = acl, role, resource, privilege
|
23
|
-
pass.call(acl, role, resource, privilege)
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/rend/acl/version.rb
CHANGED
data/rend-acl.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Rend::Acl::Version::STRING
|
9
9
|
spec.authors = ["Daniel Doezema"]
|
10
10
|
spec.email = ["daniel.doezema@gmail.com"]
|
11
|
-
spec.description = "A port of Zend_Acl with modifications made to bring the
|
11
|
+
spec.description = "A port of Zend_Acl with modifications made to bring the API more inline with Ruby conventions."
|
12
12
|
spec.summary = "rend-acl-#{Rend::Acl::Version::STRING}"
|
13
13
|
spec.homepage = "https://github.com/veloper/rend-acl"
|
14
14
|
spec.license = "New-BSD"
|
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
23
|
spec.add_development_dependency "rake"
|
24
|
-
spec.add_development_dependency "
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.0.5"
|
25
25
|
|
26
|
-
dependency_gems = ['rend-core']
|
27
26
|
|
27
|
+
dependency_gems = ['rend-core']
|
28
28
|
dependency_gems.each do |gem_name|
|
29
29
|
if Rend::Acl::Version::STRING =~ /[a-zA-Z]+/
|
30
30
|
spec.add_runtime_dependency "#{gem_name}", "= #{Rend::Acl::Version::STRING}"
|
data/test/helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# https://coveralls.io Integration
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
|
5
|
+
# Gem
|
6
|
+
require 'rend/acl'
|
7
|
+
|
8
|
+
# Testing Support
|
9
|
+
require 'support/mock_assertion'
|
10
|
+
require 'support/passing_assertion'
|
11
|
+
require 'support/failing_assertion'
|
12
|
+
|
13
|
+
# Autorun tests
|
14
|
+
require "minitest/autorun"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class MockAssertion < Rend::Acl::Assertion
|
2
|
+
|
3
|
+
attr_reader :last_acl
|
4
|
+
attr_reader :last_role
|
5
|
+
attr_reader :last_resource
|
6
|
+
attr_reader :last_privilege
|
7
|
+
|
8
|
+
attr_accessor :pass
|
9
|
+
|
10
|
+
def initialize(pass = nil, &block)
|
11
|
+
self.pass = block_given? ? block : pass
|
12
|
+
end
|
13
|
+
|
14
|
+
def pass=(value)
|
15
|
+
@pass = value.is_a?(Proc) ? value : lambda {|acl, role, resource, privilege| value}
|
16
|
+
end
|
17
|
+
|
18
|
+
def pass?(acl, role = nil, resource = nil, privilege = nil)
|
19
|
+
@last_acl, @last_role, @last_resource, @last_privilege = acl, role, resource, privilege
|
20
|
+
pass.call(acl, role, resource, privilege)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/test/test_acl.rb
CHANGED
@@ -1,28 +1,35 @@
|
|
1
|
-
require '
|
2
|
-
require 'rend/acl'
|
3
|
-
require 'rend/acl/mock_assertion'
|
4
|
-
require 'yaml'
|
5
|
-
begin; require 'turn/autorun'; rescue LoadError; end
|
1
|
+
require 'helper'
|
6
2
|
|
7
|
-
|
8
|
-
class AclTest < Test::Unit::TestCase
|
3
|
+
class AclTest < Minitest::Test
|
9
4
|
|
10
5
|
def setup
|
11
6
|
@acl = Rend::Acl.new
|
12
7
|
end
|
13
8
|
|
9
|
+
def test_access_is_limited_by_privilege
|
10
|
+
@acl.add! :role => "driver", :resource => "car"
|
11
|
+
@acl.allow! :role => "driver", :resource => "car", :privilege => "sell"
|
12
|
+
assert_equal false, @acl.allowed?("driver", "car")
|
13
|
+
assert_equal true, @acl.allowed?("driver", "car", "sell")
|
14
|
+
end
|
15
|
+
|
14
16
|
def test_storing_acl_data_for_persistence_with_marshal
|
15
|
-
|
17
|
+
assert_use_case_2 Marshal.load( Marshal.dump(use_case_2) )
|
16
18
|
end
|
17
19
|
|
18
20
|
def test_storing_acl_data_for_persistence_with_yaml
|
19
|
-
|
21
|
+
require 'yaml'
|
22
|
+
assert_use_case_2 YAML.load( YAML.dump(use_case_2) )
|
20
23
|
end
|
21
24
|
|
22
25
|
def test_use_case_1
|
23
26
|
assert_use_case_1(use_case_1)
|
24
27
|
end
|
25
28
|
|
29
|
+
def test_use_case_2
|
30
|
+
assert_use_case_2(use_case_2)
|
31
|
+
end
|
32
|
+
|
26
33
|
def test_add_raises_argument_error_with_no_args
|
27
34
|
assert_raises ArgumentError do
|
28
35
|
@acl.add!
|
@@ -138,7 +145,54 @@ class AclTest < Test::Unit::TestCase
|
|
138
145
|
assert @acl.inherits_resource? "room", "building"
|
139
146
|
end
|
140
147
|
|
141
|
-
|
148
|
+
def test_alternate_syntax_hash_syntax
|
149
|
+
@acl.add!(
|
150
|
+
:resource => %w[car motorcycle plane boat bike],
|
151
|
+
:role => ["valet", "owner", "thief", "me"]
|
152
|
+
)
|
153
|
+
@acl.allow! :resource => "bike"
|
154
|
+
@acl.allow! :privilege => "clean"
|
155
|
+
@acl.allow! :role => "valet", :resource => %w[car motorcycle], :privilege => %w[park open]
|
156
|
+
@acl.allow! :role => "thief", :resource => %w[car motorcycle boat]
|
157
|
+
@acl.allow! :role => "owner"
|
158
|
+
|
159
|
+
# Nil permutations for :role, :resource, :privilege
|
160
|
+
assert_equal true, @acl.allowed?(:role => "owner")
|
161
|
+
assert_equal true, @acl.allowed?(:role => "owner", :resource => nil)
|
162
|
+
assert_equal true, @acl.allowed?(:role => "owner", :resource => nil, :privilege => nil)
|
163
|
+
assert_equal true, @acl.allowed?(:resource => "bike")
|
164
|
+
assert_equal true, @acl.allowed?(:resource => "bike", :role => nil)
|
165
|
+
assert_equal true, @acl.allowed?(:resource => "bike", :role => nil, :privilege => nil)
|
166
|
+
assert_equal true, @acl.allowed?(:privilege => "clean")
|
167
|
+
assert_equal true, @acl.allowed?(:privilege => "clean", :resource => nil)
|
168
|
+
assert_equal true, @acl.allowed?(:privilege => "clean", :resource => nil, :role => nil)
|
169
|
+
|
170
|
+
# Spot Checks
|
171
|
+
assert_equal true, @acl.allowed?(:role => "valet", :privilege => "clean")
|
172
|
+
assert_equal true, @acl.allowed?(:role => "valet", :resource => "bike")
|
173
|
+
assert_equal true, @acl.allowed?(:role => "valet", :resource => "car", :privilege => "park")
|
174
|
+
assert_equal true, @acl.allowed?(:role => "valet", :resource => "car", :privilege => "open")
|
175
|
+
assert_equal true, @acl.allowed?(:role => "valet", :resource => "motorcycle", :privilege => "park")
|
176
|
+
assert_equal true, @acl.allowed?(:role => "valet", :resource => "motorcycle", :privilege => "open")
|
177
|
+
assert_equal false, @acl.allowed?(:role => "valet", :privilege => "park")
|
178
|
+
assert_equal false, @acl.allowed?(:role => "valet", :privilege => "open")
|
179
|
+
assert_equal false, @acl.allowed?(:role => "valet", :resource => "plane", :privilege => "park")
|
180
|
+
assert_equal false, @acl.allowed?(:role => "valet", :resource => "plane", :privilege => "open")
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_denied_method_is_inverse_of_allowed_method
|
184
|
+
acl = use_case_1
|
185
|
+
assert_equal true, acl.denied?('staff' , 'newsletter' , 'publish') # allowed
|
186
|
+
assert_equal false, acl.denied?('marketing' , 'newsletter' , 'publish') # denied
|
187
|
+
assert_equal true, acl.denied?('staff' , 'latest' , 'publish') # allowed
|
188
|
+
assert_equal false, acl.denied?('marketing' , 'latest' , 'publish') # denied
|
189
|
+
assert_equal false, acl.denied?('marketing' , 'latest' , 'archive') # denied
|
190
|
+
assert_equal true, acl.denied?('marketing' , 'latest' , 'revise') # allowed
|
191
|
+
assert_equal true, acl.denied?('editor' , 'announcement' , 'archive') # allowed
|
192
|
+
assert_equal true, acl.denied?('administrator' , 'announcement' , 'archive') # allowed
|
193
|
+
end
|
194
|
+
|
195
|
+
# == Tests From Zend_Acl Suite Below ==
|
142
196
|
|
143
197
|
# Ensures that basic addition and retrieval of a single Role works
|
144
198
|
def test_role_registry_add_and_get_one
|
@@ -616,6 +670,26 @@ class AclTest < Test::Unit::TestCase
|
|
616
670
|
assert_equal false, @acl.allowed?(nil, 'area')
|
617
671
|
end
|
618
672
|
|
673
|
+
def test_basic_example
|
674
|
+
@acl = Rend::Acl.new
|
675
|
+
|
676
|
+
@acl.add! :role => ["Passenger", "Driver", "Mechanic"], :resource => ["Car", "Boat", "Train"]
|
677
|
+
|
678
|
+
@acl.allow! :role => "Driver", :resource => "Car"
|
679
|
+
@acl.allow! :role => "Mechanic", :privilege => "Repair"
|
680
|
+
@acl.allow! :privilege => "Look" # Allow any role the ability to Look at any resource.
|
681
|
+
@acl.deny! :resource => "Train" # Deny all roles access to the Train resource.
|
682
|
+
|
683
|
+
|
684
|
+
assert_equal true, @acl.allowed?(:role => "Driver", :resource => "Car")
|
685
|
+
assert_equal false, @acl.allowed?(:role => "Passenger", :resource => "Car")
|
686
|
+
assert_equal false, @acl.allowed?(:role => "Mechanic", :resource => "Car")
|
687
|
+
assert_equal true, @acl.allowed?(:role => "Mechanic", :privilege => "Repair")
|
688
|
+
assert_equal true, @acl.allowed?(:role => "Passenger", :privilege => "Look")
|
689
|
+
assert_equal false, @acl.allowed?(:role => "Passenger", :resource => "Train")
|
690
|
+
assert_equal false, @acl.allowed?(:role => "Mechanic", :resource => "Train", :privilege => "Repair")
|
691
|
+
end
|
692
|
+
|
619
693
|
# Ensures that an example for a content management system is operable
|
620
694
|
def test_cms_example
|
621
695
|
# Add some roles to the Role registry
|
@@ -777,7 +851,7 @@ class AclTest < Test::Unit::TestCase
|
|
777
851
|
|
778
852
|
# Ensures that the default rule obeys its assertion
|
779
853
|
def test_default_assert
|
780
|
-
@acl.deny!(nil, nil, nil,
|
854
|
+
@acl.deny!(nil, nil, nil, MockAssertion.new(false))
|
781
855
|
assert_equal true, @acl.allowed?
|
782
856
|
assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
|
783
857
|
end
|
@@ -958,10 +1032,10 @@ class AclTest < Test::Unit::TestCase
|
|
958
1032
|
|
959
1033
|
# Ensures that assertions on privileges work properly
|
960
1034
|
def test_privilege_assert
|
961
|
-
@acl.allow!(nil, nil, 'some_privilege',
|
1035
|
+
@acl.allow!(nil, nil, 'some_privilege', MockAssertion.new(true))
|
962
1036
|
assert_equal true, @acl.allowed?(nil, nil, 'some_privilege')
|
963
1037
|
|
964
|
-
@acl.allow!(nil, nil, 'some_privilege',
|
1038
|
+
@acl.allow!(nil, nil, 'some_privilege', MockAssertion.new(false))
|
965
1039
|
assert_equal false, @acl.allowed?(nil, nil, 'some_privilege')
|
966
1040
|
end
|
967
1041
|
|
@@ -970,16 +1044,16 @@ class AclTest < Test::Unit::TestCase
|
|
970
1044
|
role_guest = Rend::Acl::Role.new('guest')
|
971
1045
|
@acl.add_role!(role_guest)
|
972
1046
|
|
973
|
-
@acl.allow!(role_guest, nil, 'some_privilege',
|
1047
|
+
@acl.allow!(role_guest, nil, 'some_privilege', MockAssertion.new(true))
|
974
1048
|
assert_equal true, @acl.allowed?(role_guest, nil, 'some_privilege')
|
975
1049
|
|
976
|
-
@acl.allow!(role_guest, nil, 'some_privilege',
|
1050
|
+
@acl.allow!(role_guest, nil, 'some_privilege', MockAssertion.new(false))
|
977
1051
|
assert_equal false, @acl.allowed?(role_guest, nil, 'some_privilege')
|
978
1052
|
end
|
979
1053
|
|
980
1054
|
# # Ensures that removing the default deny rule results in assertion method being removed
|
981
1055
|
def test_remove_default_deny_assert
|
982
|
-
@acl.deny!(nil, nil, nil,
|
1056
|
+
@acl.deny!(nil, nil, nil, MockAssertion.new(false))
|
983
1057
|
assert_equal true, @acl.allowed?
|
984
1058
|
@acl.remove_deny!
|
985
1059
|
assert_equal false, @acl.allowed?
|
@@ -988,7 +1062,7 @@ class AclTest < Test::Unit::TestCase
|
|
988
1062
|
|
989
1063
|
# @group ZF-1721
|
990
1064
|
def test_acl_assertions_get_proper_role_when_inheritence_is_used
|
991
|
-
assertion =
|
1065
|
+
assertion = MockAssertion.new(true)
|
992
1066
|
|
993
1067
|
@acl.add! :role => ['guest', {'contributor' => 'guest'}, {'publisher' => 'contributor'}, 'admin'], :resource => 'blog_post'
|
994
1068
|
|
@@ -1008,7 +1082,7 @@ class AclTest < Test::Unit::TestCase
|
|
1008
1082
|
|
1009
1083
|
# @group ZF-7973
|
1010
1084
|
def test_acl_passes_privilege_to_assert_class
|
1011
|
-
assertion =
|
1085
|
+
assertion = MockAssertion.new do |acl, role, resource, privilege|
|
1012
1086
|
privilege == "read"
|
1013
1087
|
end
|
1014
1088
|
|
@@ -1078,4 +1152,18 @@ class AclTest < Test::Unit::TestCase
|
|
1078
1152
|
assert_equal false, acl.allowed?('editor' , 'announcement' , 'archive') # denied
|
1079
1153
|
assert_equal false, acl.allowed?('administrator' , 'announcement' , 'archive') # denied
|
1080
1154
|
end
|
1155
|
+
|
1156
|
+
def use_case_2
|
1157
|
+
acl = use_case_1
|
1158
|
+
acl.allow! :privilege => 'passing_assertion', :assertion => PassingAssertion.new
|
1159
|
+
acl.allow! :privilege => 'failing_assertion', :assertion => FailingAssertion.new
|
1160
|
+
acl
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def assert_use_case_2(acl)
|
1164
|
+
assert_use_case_1(acl)
|
1165
|
+
assert_equal true, acl.allowed?(nil, nil, 'passing_assertion') # allowed
|
1166
|
+
assert_equal false, acl.allowed?(nil, nil, 'failing_assertion') # denied
|
1167
|
+
end
|
1168
|
+
|
1081
1169
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class DocumentationExamplesTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@acl = Rend::Acl.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_wiki_resource_inheritance_example
|
10
|
+
city_resource = Rend::Acl::Resource.new("city")
|
11
|
+
building_resource = Rend::Acl::Resource.new("building")
|
12
|
+
|
13
|
+
@acl.add_resource!(city_resource)
|
14
|
+
@acl.add_resource!(building_resource, city_resource)
|
15
|
+
|
16
|
+
mayor_role = Rend::Acl::Role.new("mayor")
|
17
|
+
@acl.add_role!(mayor_role)
|
18
|
+
|
19
|
+
@acl.allow! :role => mayor_role, :resource => city_resource
|
20
|
+
|
21
|
+
assert_equal true, @acl.allowed?(:role => mayor_role, :resource => city_resource)
|
22
|
+
assert_equal true, @acl.allowed?(:role => mayor_role, :resource => building_resource)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
A ***Resource*** is simply an object to which access is controlled.
|
2
|
+
|
3
|
+
## Resource Class
|
4
|
+
Rend-Acl provides the `Rend::Acl::Resource` class as a basic resource implementation for developers to use and/or extend as needed.
|
5
|
+
|
6
|
+
|
7
|
+
## Tree Structure
|
8
|
+
Rend-Acl provides a tree structure to which multiple resources can be added. Since resources are stored in such a tree structure, they can be organized from the general (toward the tree root) to the specific (toward the tree leaves). Queries on a specific resource will automatically search the resource's hierarchy for rules assigned to ancestor resources, allowing for simple inheritance of rules.
|
9
|
+
|
10
|
+
|
11
|
+
## Resource Inheritance
|
12
|
+
For example, if a default ***rule*** is to be applied to each ***building*** in a ***city***, one would simply assign the ***rule*** to the ***city***, instead of assigning the same ***rule*** to each ***building***. Some ***building***s may require exceptions to such a ***rule***, however, and this can be achieved in Rend-Acl by assigning such exception ***rule***s to each ***building*** that requires such an exception. A ***resource*** may inherit from only one parent ***resource***, though this parent ***resource*** can have its own parent ***resource***, etc.
|
13
|
+
|
14
|
+
### Example
|
15
|
+
```ruby
|
16
|
+
@acl = Rend::Acl.new
|
17
|
+
|
18
|
+
# Define Resources
|
19
|
+
city_resource = Rend::Acl::Resource.new("city")
|
20
|
+
building_resource = Rend::Acl::Resource.new("building")
|
21
|
+
|
22
|
+
# Add Resources to ACL
|
23
|
+
@acl.add_resource!(city_resource)
|
24
|
+
@acl.add_resource!(building_resource, city_resource) # Inheritance from city_resource
|
25
|
+
|
26
|
+
# Define & Add Roles
|
27
|
+
mayor_role = Rend::Acl::Role.new("mayor")
|
28
|
+
@acl.add_role!(mayor_role)
|
29
|
+
|
30
|
+
# Define Rules
|
31
|
+
@acl.allow! :role => mayor_role, :resource => city_resource
|
32
|
+
|
33
|
+
# Querying
|
34
|
+
@acl.allowed? :role => mayor_role, :resource => city_resource # => TRUE, via explicitly set rule.
|
35
|
+
@acl.allowed? :role => mayor_role, :resource => building_resource # => TRUE, via resource rule inheritance
|
36
|
+
```
|
37
|
+
> **Associated Test:** `rend-acl/test/test_documentation_examples.rb#test_wiki_resource_inheritance_example`
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rend-acl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -44,21 +44,21 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: minitest
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 5.0.5
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 5.0.5
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: rend-core
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,7 +75,7 @@ dependencies:
|
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: 0.0.0
|
78
|
-
description: A port of Zend_Acl with modifications made to bring the
|
78
|
+
description: A port of Zend_Acl with modifications made to bring the API more inline
|
79
79
|
with Ruby conventions.
|
80
80
|
email:
|
81
81
|
- daniel.doezema@gmail.com
|
@@ -83,7 +83,9 @@ executables: []
|
|
83
83
|
extensions: []
|
84
84
|
extra_rdoc_files: []
|
85
85
|
files:
|
86
|
+
- .coveralls.yml
|
86
87
|
- .gitignore
|
88
|
+
- .travis.yml
|
87
89
|
- Changelog.md
|
88
90
|
- Gemfile
|
89
91
|
- LICENSE.txt
|
@@ -100,7 +102,13 @@ files:
|
|
100
102
|
- lib/rend/acl/role/registry/exception.rb
|
101
103
|
- lib/rend/acl/version.rb
|
102
104
|
- rend-acl.gemspec
|
105
|
+
- test/helper.rb
|
106
|
+
- test/support/failing_assertion.rb
|
107
|
+
- test/support/mock_assertion.rb
|
108
|
+
- test/support/passing_assertion.rb
|
103
109
|
- test/test_acl.rb
|
110
|
+
- test/test_documentation_examples.rb
|
111
|
+
- wiki/pages/resources.md
|
104
112
|
homepage: https://github.com/veloper/rend-acl
|
105
113
|
licenses:
|
106
114
|
- New-BSD
|
@@ -116,7 +124,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
124
|
version: '0'
|
117
125
|
segments:
|
118
126
|
- 0
|
119
|
-
hash:
|
127
|
+
hash: 4151355783385604233
|
120
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
129
|
none: false
|
122
130
|
requirements:
|
@@ -125,12 +133,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
133
|
version: '0'
|
126
134
|
segments:
|
127
135
|
- 0
|
128
|
-
hash:
|
136
|
+
hash: 4151355783385604233
|
129
137
|
requirements: []
|
130
138
|
rubyforge_project:
|
131
139
|
rubygems_version: 1.8.25
|
132
140
|
signing_key:
|
133
141
|
specification_version: 3
|
134
|
-
summary: rend-acl-0.0.
|
142
|
+
summary: rend-acl-0.0.5
|
135
143
|
test_files:
|
144
|
+
- test/helper.rb
|
145
|
+
- test/support/failing_assertion.rb
|
146
|
+
- test/support/mock_assertion.rb
|
147
|
+
- test/support/passing_assertion.rb
|
136
148
|
- test/test_acl.rb
|
149
|
+
- test/test_documentation_examples.rb
|