iq-acl 1.0.5 → 1.1.1
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.rdoc +27 -15
- data/VERSION +1 -1
- data/iq-acl.gemspec +2 -2
- data/lib/iq/acl/basic.rb +56 -32
- data/test/iq/acl_test.rb +155 -23
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -18,28 +18,40 @@ This aim of this gem is to provide a series of classes to handle common ACL requ
|
|
18
18
|
# You could alternatively read rights from a YAML file
|
19
19
|
auth = IQ::ACL::Basic.new(YAML.load_file('rights.yml'))
|
20
20
|
|
21
|
-
auth.
|
22
|
-
auth.
|
23
|
-
auth.
|
24
|
-
auth.
|
25
|
-
auth.
|
26
|
-
auth.
|
27
|
-
auth.
|
28
|
-
auth.
|
29
|
-
auth.
|
30
|
-
auth.
|
31
|
-
auth.
|
32
|
-
auth.
|
33
|
-
|
34
|
-
A block may be given to <tt>
|
21
|
+
auth.authenticate! 'guest', 'projects' #=> raises IQ::ACL::AccessDeniedError
|
22
|
+
auth.authenticate! 'jonny', 'projects' #=> 'rw'
|
23
|
+
auth.authenticate! 'billy', 'projects' #=> raises IQ::ACL::AccessDeniedError
|
24
|
+
auth.authenticate! 'terry', 'projects' #=> 'r'
|
25
|
+
auth.authenticate! 'guest', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
|
26
|
+
auth.authenticate! 'jonny', 'projects/private' #=> 'rw'
|
27
|
+
auth.authenticate! 'billy', 'projects/private' #=> 'rw'
|
28
|
+
auth.authenticate! 'terry', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
|
29
|
+
auth.authenticate! 'guest', 'projects/public' #=> 'r'
|
30
|
+
auth.authenticate! 'jonny', 'projects/public' #=> 'r'
|
31
|
+
auth.authenticate! 'billy', 'projects/public' #=> 'r'
|
32
|
+
auth.authenticate! 'terry', 'projects/public' #=> 'rw
|
33
|
+
|
34
|
+
A block may be given to <tt>authenticate!</tt> that should return true if
|
35
35
|
the yielded rights are adequate for the user, for example the following
|
36
36
|
will raise an IQ::ACL::AccessDeniedError as 'terry' does not have write access
|
37
37
|
to the 'projects' path. If 'terry' had write access to the 'projects'
|
38
38
|
path, the exception would not be thrown.
|
39
39
|
|
40
|
-
auth.
|
40
|
+
auth.authenticate! 'terry', 'projects' do |rights|
|
41
41
|
rights.include?('w')
|
42
42
|
end
|
43
|
+
|
44
|
+
In the previous examples, strings are used to identify the user, however
|
45
|
+
user may be any object. This becomes quite powerful as you could use the
|
46
|
+
objects returned from an ORM such as ActiveRecord. Also the rights in the
|
47
|
+
previous examples were strings, however these may be of any type also,
|
48
|
+
again allowing powerful solutions to be built e.g.
|
49
|
+
|
50
|
+
user = User.find_by_email('jamie@example.com')
|
51
|
+
auth = IQ::ACL::Basic.new('projects/*' => { user => user.roles })
|
52
|
+
auth.authenticate!(user, 'projects/some-project') do |roles|
|
53
|
+
roles.find_by_name('project_editor')
|
54
|
+
end
|
43
55
|
|
44
56
|
== Note on Patches/Pull Requests
|
45
57
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.1
|
data/iq-acl.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{iq-acl}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jamie Hill, SonicIQ Ltd."]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-06-02}
|
13
13
|
s.description = %q{IQ::ACL provides a super simple way of implementing access control.}
|
14
14
|
s.email = %q{jamie@soniciq.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/iq/acl/basic.rb
CHANGED
@@ -6,80 +6,104 @@
|
|
6
6
|
# @example
|
7
7
|
# # Create an instance of the basic class, supplying rights as a hash, note
|
8
8
|
# # that asterisks are used as wildcards.
|
9
|
-
# auth = IQ::ACL::Basic.new(
|
9
|
+
# auth = IQ::ACL::Basic.new(
|
10
10
|
# '*' => { 'terry' => 'r' },
|
11
11
|
# 'projects' => { 'jonny' => 'rw' },
|
12
12
|
# 'projects/private' => { 'billy' => 'rw', 'terry' => nil },
|
13
13
|
# 'projects/public' => { 'terry' => 'rw', '*' => 'r' }
|
14
|
-
#
|
14
|
+
# )
|
15
15
|
#
|
16
|
-
# # You could alternatively read rights from a YAML file
|
16
|
+
# # You could alternatively read rights from a YAML file.
|
17
17
|
# auth = IQ::ACL::Basic.new(YAML.load_file('rights.yml'))
|
18
18
|
#
|
19
|
-
# auth.
|
20
|
-
# auth.
|
21
|
-
# auth.
|
22
|
-
# auth.
|
23
|
-
# auth.
|
24
|
-
# auth.
|
25
|
-
# auth.
|
26
|
-
# auth.
|
27
|
-
# auth.
|
28
|
-
# auth.
|
29
|
-
# auth.
|
30
|
-
# auth.
|
19
|
+
# auth.authenticate! 'guest', 'projects' #=> raises IQ::ACL::AccessDeniedError
|
20
|
+
# auth.authenticate! 'jonny', 'projects' #=> 'rw'
|
21
|
+
# auth.authenticate! 'billy', 'projects' #=> raises IQ::ACL::AccessDeniedError
|
22
|
+
# auth.authenticate! 'terry', 'projects' #=> 'r'
|
23
|
+
# auth.authenticate! 'guest', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
|
24
|
+
# auth.authenticate! 'jonny', 'projects/private' #=> 'rw'
|
25
|
+
# auth.authenticate! 'billy', 'projects/private' #=> 'rw'
|
26
|
+
# auth.authenticate! 'terry', 'projects/private' #=> raises IQ::ACL::AccessDeniedError
|
27
|
+
# auth.authenticate! 'guest', 'projects/public' #=> 'r'
|
28
|
+
# auth.authenticate! 'jonny', 'projects/public' #=> 'r'
|
29
|
+
# auth.authenticate! 'billy', 'projects/public' #=> 'r'
|
30
|
+
# auth.authenticate! 'terry', 'projects/public' #=> 'rw
|
31
31
|
#
|
32
|
-
# # A block may be given to
|
32
|
+
# # A block may be given to authenticate! that should return true if the yielded
|
33
33
|
# # rights are adequate for the user, for example the following will raise an
|
34
34
|
# # IQ::ACL::AccessDeniedError as 'terry' does not have write access to the
|
35
35
|
# # 'projects' path. If 'terry' had write access to the 'projects' path, the
|
36
36
|
# # exception would not be thrown.
|
37
37
|
#
|
38
|
-
# auth.
|
38
|
+
# auth.authenticate! 'terry', 'projects' do |rights|
|
39
39
|
# rights.include?('w')
|
40
40
|
# end
|
41
|
+
#
|
42
|
+
# # In the previous examples, strings are used to identify the user, however
|
43
|
+
# # user may be any object. This becomes quite powerful as you could use the
|
44
|
+
# # objects returned from an ORM such as ActiveRecord. Also the rights in the
|
45
|
+
# # previous examples were strings, however these may be of any type also,
|
46
|
+
# # again allowing powerful solutions to be built e.g.
|
47
|
+
#
|
48
|
+
# user = User.find_by_email('jamie@example.com')
|
49
|
+
# auth = IQ::ACL::Basic.new('projects/*' => { user => user.roles })
|
50
|
+
# auth.authenticate!(user, 'projects/some-project') do |roles|
|
51
|
+
# roles.find_by_name('project_editor')
|
52
|
+
# end
|
41
53
|
#
|
42
54
|
class IQ::ACL::Basic
|
43
55
|
|
44
56
|
# Returns a new instance to be authenticated against.
|
45
57
|
#
|
46
|
-
# @param [Hash]
|
58
|
+
# @param [Hash] permissions
|
47
59
|
def initialize(permissions)
|
48
60
|
raise ArgumentError, 'Must supply permissions as a hash' unless permissions.is_a?(Hash)
|
49
61
|
@permissions = permissions
|
50
62
|
end
|
51
|
-
|
63
|
+
|
52
64
|
# Returns the rights that a user has for a given path. When the user has no
|
53
|
-
# access to the given path,
|
54
|
-
#
|
55
|
-
# block is
|
65
|
+
# access to the given path, nil is returned.
|
66
|
+
#
|
67
|
+
# When a block is supplied the user rights are yielded as the block parameter
|
68
|
+
# and the block is expected to return true when the rights are sufficient.
|
56
69
|
#
|
57
|
-
# @param [
|
70
|
+
# @param [Object] user
|
58
71
|
# @param [String] path
|
59
72
|
#
|
60
|
-
# @return [
|
61
|
-
def
|
73
|
+
# @return [nil, Object] the rights that the given user has to the path.
|
74
|
+
def authenticate(user, path)
|
62
75
|
raise ArgumentError, 'Path must be a string' unless path.is_a?(String)
|
63
76
|
|
64
77
|
segments = path.split('/')
|
65
78
|
rights = until segments.empty?
|
66
79
|
if rights = permissions[segments.join('/')]
|
67
80
|
access = rights[user] || rights['*']
|
68
|
-
|
81
|
+
return nil if (rights.has_key?(user) || rights.has_key?('*')) && access.nil?
|
69
82
|
break access if access
|
70
83
|
end
|
71
84
|
segments.pop
|
72
|
-
end || (global = permissions['*']) && (global[user] || global['*']) ||
|
85
|
+
end || (global = permissions['*']) && (global[user] || global['*']) || nil
|
73
86
|
|
74
|
-
|
87
|
+
return nil if block_given? && (yield(rights) != true)
|
75
88
|
rights
|
76
89
|
end
|
90
|
+
|
91
|
+
# Returns the rights that a user has for a given path. When the user has no
|
92
|
+
# access to the given path, an IQ::ACL::AccessDeniedError is raised.
|
93
|
+
# When a block is supplied the user rights are yielded as the block parameter
|
94
|
+
# and the block is expected to return true when the rights are sufficient.
|
95
|
+
#
|
96
|
+
# @param [Object] user
|
97
|
+
# @param [String] path
|
98
|
+
#
|
99
|
+
# @raise [IQ::ACL::AccessDeniedError] when result of block is not true.
|
100
|
+
# @return [Object] the rights that the given user has to the path.
|
101
|
+
def authenticate!(user, path, &block)
|
102
|
+
authenticate(user, path, &block) || raise(IQ::ACL::AccessDeniedError, 'User does not have access to path')
|
103
|
+
end
|
77
104
|
|
78
105
|
private
|
79
106
|
|
80
107
|
attr_reader :permissions
|
81
|
-
|
82
|
-
def access_denied!
|
83
|
-
raise IQ::ACL::AccessDeniedError, 'User does not have access to path'
|
84
|
-
end
|
108
|
+
|
85
109
|
end
|
data/test/iq/acl_test.rb
CHANGED
@@ -13,99 +13,231 @@ class IQ::ACLTest < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
context "
|
16
|
+
context "authenticate" do
|
17
17
|
should "respond" do
|
18
|
-
assert_respond_to IQ::ACL::Basic.new({}), :
|
18
|
+
assert_respond_to IQ::ACL::Basic.new({}), :authenticate
|
19
19
|
end
|
20
20
|
|
21
21
|
should "accept username as first argument" do
|
22
22
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => true })
|
23
|
-
assert_nothing_raised(ArgumentError) { instance.
|
23
|
+
assert_nothing_raised(ArgumentError) { instance.authenticate('the user', 'the/path') }
|
24
24
|
end
|
25
25
|
|
26
26
|
should "accept path as second argument" do
|
27
27
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => true })
|
28
|
-
assert_nothing_raised(ArgumentError) { instance.
|
28
|
+
assert_nothing_raised(ArgumentError) { instance.authenticate('the user', 'the/path') }
|
29
29
|
end
|
30
30
|
|
31
31
|
should "raise when path is not a string" do
|
32
|
-
assert_raise(ArgumentError) { IQ::ACL::Basic.new({}).
|
32
|
+
assert_raise(ArgumentError) { IQ::ACL::Basic.new({}).authenticate('the user', :not_a_string) }
|
33
|
+
end
|
34
|
+
|
35
|
+
should "raise return nil when no match" do
|
36
|
+
assert_nil IQ::ACL::Basic.new({}).authenticate('the user', 'will/not/match')
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return nil when user access explicitly set to nil for given path even when a parent privilege set" do
|
40
|
+
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
41
|
+
assert_nil instance.authenticate('the user', 'the/path')
|
42
|
+
end
|
43
|
+
|
44
|
+
should "return nil when user access explicitly set to nil for given path even when root global set" do
|
45
|
+
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
46
|
+
assert_nil instance.authenticate('the user', 'the/path')
|
47
|
+
end
|
48
|
+
|
49
|
+
should "return nil when user access not known but global set to nil for given path even when parent set" do
|
50
|
+
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
51
|
+
assert_nil instance.authenticate('the user', 'the/path')
|
52
|
+
end
|
53
|
+
|
54
|
+
should "return nil when user access not known but global set to nil for given path even when root global set" do
|
55
|
+
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'ok' }, 'the/path' => { '*' => nil })
|
56
|
+
assert_nil instance.authenticate('the user', 'the/path')
|
57
|
+
end
|
58
|
+
|
59
|
+
should "return result of direct match in permissions hash with path and user when available" do
|
60
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
61
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
62
|
+
end
|
63
|
+
|
64
|
+
should "return result of direct match in permissions hash with path and user when available special case" do
|
65
|
+
instance = IQ::ACL::Basic.new('projects/rails-site.com' => { 'rails_site' => 'rw' })
|
66
|
+
assert_equal 'rw', instance.authenticate('rails_site', 'projects/rails-site.com')
|
67
|
+
end
|
68
|
+
|
69
|
+
should "return result of direct match in permissions hash with path and star user when user not found" do
|
70
|
+
instance = IQ::ACL::Basic.new('the/path' => { '*' => 'the access' })
|
71
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
72
|
+
end
|
73
|
+
|
74
|
+
should "return result of parent match in permissions hash with path and user over global user when no match" do
|
75
|
+
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'the access', '*' => 'global access' })
|
76
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return result of parent match in permissions hash with path and star user when user not found" do
|
80
|
+
instance = IQ::ACL::Basic.new('the' => { '*' => 'the access' })
|
81
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
82
|
+
end
|
83
|
+
|
84
|
+
should "continue down permissions tree until a match with path and user is found over global access" do
|
85
|
+
instance = IQ::ACL::Basic.new('the/long' => { 'the user' => 'the access', '*' => 'global access' })
|
86
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/long/big/nested/path')
|
87
|
+
end
|
88
|
+
|
89
|
+
should "continue down permissions tree until a match with path and star user when user not found" do
|
90
|
+
instance = IQ::ACL::Basic.new('the/long' => { '*' => 'the access' })
|
91
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/long/big/nested/path')
|
92
|
+
end
|
93
|
+
|
94
|
+
should "return result of user in star entry of permissions hash over star user when no other matches" do
|
95
|
+
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'the access', '*' => 'global access' }, 'other/path' => {})
|
96
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
97
|
+
end
|
98
|
+
|
99
|
+
should "return result of star user in star entry of permissions hash when no user match" do
|
100
|
+
instance = IQ::ACL::Basic.new('*' => { '*' => 'the access' }, 'other/path' => {})
|
101
|
+
assert_equal 'the access', instance.authenticate('the user', 'the/path')
|
102
|
+
end
|
103
|
+
|
104
|
+
context "using a block" do
|
105
|
+
should "yield the user rights when block given" do
|
106
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
107
|
+
the_rights = nil
|
108
|
+
instance.authenticate('the user', 'the/path') do |rights|
|
109
|
+
the_rights = rights
|
110
|
+
true
|
111
|
+
end
|
112
|
+
assert_equal 'the access', the_rights
|
113
|
+
end
|
114
|
+
|
115
|
+
should "return nil if block evaluates to false" do
|
116
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
117
|
+
|
118
|
+
assert_nil(
|
119
|
+
instance.authenticate('the user', 'the/path') do |rights|
|
120
|
+
false
|
121
|
+
end
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "return nil if block evaluates to anything other than true" do
|
126
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
127
|
+
|
128
|
+
assert_nil(
|
129
|
+
instance.authenticate('the user', 'the/path') do |rights|
|
130
|
+
'not true'
|
131
|
+
end
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "return rights when block evaluates to true" do
|
136
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
137
|
+
|
138
|
+
assert_equal(
|
139
|
+
'the access',
|
140
|
+
instance.authenticate('the user', 'the/path') do |rights|
|
141
|
+
true
|
142
|
+
end
|
143
|
+
)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "authenticate!" do
|
149
|
+
should "respond" do
|
150
|
+
assert_respond_to IQ::ACL::Basic.new({}), :authenticate!
|
151
|
+
end
|
152
|
+
|
153
|
+
should "accept username as first argument" do
|
154
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => true })
|
155
|
+
assert_nothing_raised(ArgumentError) { instance.authenticate!('the user', 'the/path') }
|
156
|
+
end
|
157
|
+
|
158
|
+
should "accept path as second argument" do
|
159
|
+
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => true })
|
160
|
+
assert_nothing_raised(ArgumentError) { instance.authenticate!('the user', 'the/path') }
|
161
|
+
end
|
162
|
+
|
163
|
+
should "raise when path is not a string" do
|
164
|
+
assert_raise(ArgumentError) { IQ::ACL::Basic.new({}).authenticate!('the user', :not_a_string) }
|
33
165
|
end
|
34
166
|
|
35
167
|
should "raise access denied error when no match" do
|
36
|
-
assert_raise(IQ::ACL::AccessDeniedError) { IQ::ACL::Basic.new({}).
|
168
|
+
assert_raise(IQ::ACL::AccessDeniedError) { IQ::ACL::Basic.new({}).authenticate!('the user', 'will/not/match') }
|
37
169
|
end
|
38
170
|
|
39
171
|
should "raise when user access explicitly set to nil for given path even when a parent privilege set" do
|
40
172
|
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
41
|
-
assert_raise(IQ::ACL::AccessDeniedError) { instance.
|
173
|
+
assert_raise(IQ::ACL::AccessDeniedError) { instance.authenticate!('the user', 'the/path') }
|
42
174
|
end
|
43
175
|
|
44
176
|
should "raise when user access explicitly set to nil for given path even when root global set" do
|
45
177
|
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
46
|
-
assert_raise(IQ::ACL::AccessDeniedError) { instance.
|
178
|
+
assert_raise(IQ::ACL::AccessDeniedError) { instance.authenticate!('the user', 'the/path') }
|
47
179
|
end
|
48
180
|
|
49
181
|
should "raise when user access not known but global set to nil for given path even when parent privilege set" do
|
50
182
|
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'ok' }, 'the/path' => { 'the user' => nil })
|
51
|
-
assert_raise(IQ::ACL::AccessDeniedError) { instance.
|
183
|
+
assert_raise(IQ::ACL::AccessDeniedError) { instance.authenticate!('the user', 'the/path') }
|
52
184
|
end
|
53
185
|
|
54
186
|
should "raise when user access not known but global set to nil for given path even when root global set" do
|
55
187
|
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'ok' }, 'the/path' => { '*' => nil })
|
56
|
-
assert_raise(IQ::ACL::AccessDeniedError) { instance.
|
188
|
+
assert_raise(IQ::ACL::AccessDeniedError) { instance.authenticate!('the user', 'the/path') }
|
57
189
|
end
|
58
190
|
|
59
191
|
should "return result of direct match in permissions hash with path and user when available" do
|
60
192
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
61
|
-
assert_equal 'the access', instance.
|
193
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
62
194
|
end
|
63
195
|
|
64
196
|
should "return result of direct match in permissions hash with path and user when available special case" do
|
65
197
|
instance = IQ::ACL::Basic.new('projects/rails-site.com' => { 'rails_site' => 'rw' })
|
66
|
-
assert_equal 'rw', instance.
|
198
|
+
assert_equal 'rw', instance.authenticate!('rails_site', 'projects/rails-site.com')
|
67
199
|
end
|
68
200
|
|
69
201
|
should "return result of direct match in permissions hash with path and star user when user not found" do
|
70
202
|
instance = IQ::ACL::Basic.new('the/path' => { '*' => 'the access' })
|
71
|
-
assert_equal 'the access', instance.
|
203
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
72
204
|
end
|
73
205
|
|
74
206
|
should "return result of parent match in permissions hash with path and user over global user when no match" do
|
75
207
|
instance = IQ::ACL::Basic.new('the' => { 'the user' => 'the access', '*' => 'global access' })
|
76
|
-
assert_equal 'the access', instance.
|
208
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
77
209
|
end
|
78
210
|
|
79
211
|
should "return result of parent match in permissions hash with path and star user when user not found" do
|
80
212
|
instance = IQ::ACL::Basic.new('the' => { '*' => 'the access' })
|
81
|
-
assert_equal 'the access', instance.
|
213
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
82
214
|
end
|
83
215
|
|
84
216
|
should "continue down permissions tree until a match with path and user is found over global access" do
|
85
217
|
instance = IQ::ACL::Basic.new('the/long' => { 'the user' => 'the access', '*' => 'global access' })
|
86
|
-
assert_equal 'the access', instance.
|
218
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/long/big/nested/path')
|
87
219
|
end
|
88
220
|
|
89
221
|
should "continue down permissions tree until a match with path and star user when user not found" do
|
90
222
|
instance = IQ::ACL::Basic.new('the/long' => { '*' => 'the access' })
|
91
|
-
assert_equal 'the access', instance.
|
223
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/long/big/nested/path')
|
92
224
|
end
|
93
225
|
|
94
226
|
should "return result of user in star entry of permissions hash over star user when no other matches" do
|
95
227
|
instance = IQ::ACL::Basic.new('*' => { 'the user' => 'the access', '*' => 'global access' }, 'other/path' => {})
|
96
|
-
assert_equal 'the access', instance.
|
228
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
97
229
|
end
|
98
230
|
|
99
231
|
should "return result of star user in star entry of permissions hash when no user match" do
|
100
232
|
instance = IQ::ACL::Basic.new('*' => { '*' => 'the access' }, 'other/path' => {})
|
101
|
-
assert_equal 'the access', instance.
|
233
|
+
assert_equal 'the access', instance.authenticate!('the user', 'the/path')
|
102
234
|
end
|
103
235
|
|
104
236
|
context "using a block" do
|
105
237
|
should "yield the user rights when block given" do
|
106
238
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
107
239
|
the_rights = nil
|
108
|
-
instance.
|
240
|
+
instance.authenticate!('the user', 'the/path') do |rights|
|
109
241
|
the_rights = rights
|
110
242
|
true
|
111
243
|
end
|
@@ -116,7 +248,7 @@ class IQ::ACLTest < Test::Unit::TestCase
|
|
116
248
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
117
249
|
|
118
250
|
assert_raise(IQ::ACL::AccessDeniedError) do
|
119
|
-
instance.
|
251
|
+
instance.authenticate!('the user', 'the/path') do |rights|
|
120
252
|
false
|
121
253
|
end
|
122
254
|
end
|
@@ -126,7 +258,7 @@ class IQ::ACLTest < Test::Unit::TestCase
|
|
126
258
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
127
259
|
|
128
260
|
assert_raise(IQ::ACL::AccessDeniedError) do
|
129
|
-
instance.
|
261
|
+
instance.authenticate!('the user', 'the/path') do |rights|
|
130
262
|
'not true'
|
131
263
|
end
|
132
264
|
end
|
@@ -136,7 +268,7 @@ class IQ::ACLTest < Test::Unit::TestCase
|
|
136
268
|
instance = IQ::ACL::Basic.new('the/path' => { 'the user' => 'the access' })
|
137
269
|
|
138
270
|
assert_nothing_raised(IQ::ACL::AccessDeniedError) do
|
139
|
-
instance.
|
271
|
+
instance.authenticate!('the user', 'the/path') do |rights|
|
140
272
|
true
|
141
273
|
end
|
142
274
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 1.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jamie Hill, SonicIQ Ltd.
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-06-02 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|