yus 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,335 @@
1
+ #!/usr/bin/env ruby
2
+ # Session -- yus -- 02.06.2006 -- hwyss@ywesee.com
3
+
4
+ require 'drb'
5
+ require 'thread'
6
+ require 'yus/entity'
7
+ begin
8
+ require 'encoding/character/utf-8'
9
+ rescue LoadError
10
+ end
11
+
12
+
13
+ module Yus
14
+ class Session
15
+ include DRb::DRbUndumped
16
+ def initialize(needle)
17
+ @needle = needle
18
+ @timeout = needle.config.session_timeout
19
+ @mutex = Mutex.new
20
+ touch!
21
+ end
22
+ def affiliate(name, groupname)
23
+ info("affiliate(name=#{name}, group=#{groupname})")
24
+ @mutex.synchronize {
25
+ allow_or_fail('edit', 'yus.entities')
26
+ user = find_or_fail(name)
27
+ group = find_or_fail(groupname)
28
+ user.join(group)
29
+ save(user, group)
30
+ }
31
+ touch!
32
+ end
33
+ def create_entity(name, valid_until=nil, valid_from=Time.now)
34
+ info("create_entity(name=#{name}, valid_until=#{valid_until}, valid_from=#{valid_from})")
35
+ entity = nil
36
+ @mutex.synchronize {
37
+ allow_or_fail('edit', 'yus.entities')
38
+ if(@needle.persistence.find_entity(name))
39
+ debug("create_entity: Duplicate Name: '#{name}'")
40
+ raise DuplicateNameError, "Duplicate name: #{name}"
41
+ end
42
+ entity = Entity.new(name, valid_until, valid_from)
43
+ entity.grant('set_password', name)
44
+ @needle.persistence.add_entity(entity)
45
+ }
46
+ touch!
47
+ entity
48
+ end
49
+ def delete_entity(name)
50
+ info("delete_entity(name=#{name})")
51
+ allow_or_fail 'edit', 'yus.entities'
52
+ entity = find_or_fail name
53
+ @needle.persistence.delete_entity name
54
+ touch!
55
+ end
56
+ def destroy!
57
+ @needle = @user = nil
58
+ @timeout = -1
59
+ end
60
+ def disaffiliate(name, groupname)
61
+ info("disaffiliate(name=#{name}, group=#{groupname})")
62
+ @mutex.synchronize {
63
+ allow_or_fail('edit', 'yus.entities')
64
+ user = find_or_fail(name)
65
+ group = find_or_fail(groupname)
66
+ puts group.inspect
67
+ puts user.leave(group).inspect
68
+ puts user.inspect
69
+ save(user, group)
70
+ }
71
+ touch!
72
+ end
73
+ def expired?
74
+ Time.now > (@last_access + @timeout)
75
+ end
76
+ def entities
77
+ allow_or_fail('edit', 'yus.entities')
78
+ touch!
79
+ @needle.persistence.entities
80
+ end
81
+ def find_entity(name)
82
+ allow_or_fail('edit', 'yus.entities')
83
+ touch!
84
+ @needle.persistence.find_entity(name)
85
+ end
86
+ def grant(name, action, item=nil, expires=nil)
87
+ info("grant(name=#{name}, action=#{action}, item=#{item}, expires=#{expires})")
88
+ @mutex.synchronize {
89
+ allow_or_fail('grant', action)
90
+ user = find_or_fail(name)
91
+ user.grant(action, item || :everything, expires || :never)
92
+ save(user)
93
+ }
94
+ touch!
95
+ end
96
+ def last_login(name, domain=@domain)
97
+ if(user = find_entity(name))
98
+ user.last_login(domain)
99
+ end
100
+ end
101
+ def remove_token(token)
102
+ @user.remove_token token
103
+ save @user
104
+ nil
105
+ end
106
+ def rename(oldname, newname)
107
+ info("rename(#{oldname}, #{newname})")
108
+ @mutex.synchronize {
109
+ allow_or_fail('edit', 'yus.entities')
110
+ user = find_or_fail(oldname)
111
+ if((other = @needle.persistence.find_entity(newname)) && other != user)
112
+ raise DuplicateNameError, "Duplicate name: #{newname}"
113
+ end
114
+ user.revoke('set_password', oldname)
115
+ user.rename(newname)
116
+ user.grant('set_password', newname)
117
+ save(user)
118
+ }
119
+ end
120
+ def revoke(name, action, item=nil, time=nil)
121
+ info("revoke(name=#{name}, action=#{action}, item=#{item}, time=#{time})")
122
+ @mutex.synchronize {
123
+ allow_or_fail('grant', action)
124
+ user = find_or_fail(name)
125
+ user.revoke(action, item || :everything, time)
126
+ save(user)
127
+ }
128
+ touch!
129
+ end
130
+ def set_password(name, pass)
131
+ @mutex.synchronize {
132
+ allow_or_fail('set_password', name)
133
+ user = find_or_fail(name)
134
+ user.passhash = @needle.config.digest.hexdigest(pass)
135
+ save(user)
136
+ }
137
+ touch!
138
+ end
139
+ def set_entity_preference(name, key, value, domain=@domain)
140
+ debug("set_entity_preference(name=#{name}, key=#{key}, value=#{value}, domain=#{domain})")
141
+ @mutex.synchronize {
142
+ allow_or_fail('edit', 'yus.entities')
143
+ user = find_or_fail(name)
144
+ user.set_preference(key, value, domain)
145
+ save(user)
146
+ }
147
+ touch!
148
+ end
149
+ private
150
+ def allow_or_fail(action, item)
151
+ unless(allowed?(action, item))
152
+ raise NotPrivilegedError, "You are not privileged to #{action} #{item}"
153
+ end
154
+ end
155
+ def debug(message)
156
+ @needle.logger.debug(self.class) { message }
157
+ end
158
+ def find_or_fail(name)
159
+ @needle.persistence.find_entity(name) \
160
+ or raise UnknownEntityError, "Unknown Entity '#{name}'"
161
+ end
162
+ def info(message)
163
+ @needle.logger.info(self.class) { message }
164
+ end
165
+ def save(*args)
166
+ args.each { |entity|
167
+ @needle.persistence.save_entity(entity)
168
+ }
169
+ end
170
+ def touch!
171
+ @last_access = Time.now
172
+ end
173
+ end
174
+ class AutoSession < Session
175
+ def initialize(needle, domain)
176
+ @domain = domain
177
+ super(needle)
178
+ end
179
+ def allowed?(*args)
180
+ false
181
+ end
182
+ def create_entity(name, pass=nil, valid_until=nil, valid_from=Time.now)
183
+ info("create_entity(name=#{name}, valid_until=#{valid_until}, valid_from=#{valid_from})")
184
+ entity = nil
185
+ @mutex.synchronize {
186
+ if(@needle.persistence.find_entity(name))
187
+ debug("create_entity: Duplicate Name: '#{name}'")
188
+ raise DuplicateNameError, "Duplicate name: #{name}"
189
+ end
190
+ entity = Entity.new(name, valid_until, valid_from)
191
+ entity.grant('set_password', name)
192
+ if(pass)
193
+ entity.passhash = @needle.config.digest.hexdigest(pass)
194
+ end
195
+ @needle.persistence.add_entity(entity)
196
+ }
197
+ touch!
198
+ end
199
+ def entity_allowed?(name, *args)
200
+ find_or_fail(name).allowed?(*args)
201
+ end
202
+ def get_entity_preference(name, key, domain=@domain)
203
+ debug("get_entity_preference(name=#{name}, key=#{key}, domain=#{domain})")
204
+ @mutex.synchronize {
205
+ user = find_or_fail(name)
206
+ user.get_preference(key, domain)
207
+ }
208
+ end
209
+ def get_entity_preferences(name, keys, domain=@domain)
210
+ debug("get_entity_preferences(name=#{name}, keys=#{keys}, domain=#{domain})")
211
+ @mutex.synchronize {
212
+ user = find_or_fail(name)
213
+ keys.inject({}) { |memo, key|
214
+ memo.store(key, user.get_preference(key, domain))
215
+ memo
216
+ }
217
+ }
218
+ end
219
+ def rename(oldname, newname)
220
+ info("rename(#{oldname}, #{newname})")
221
+ @mutex.synchronize {
222
+ user = find_or_fail(oldname)
223
+ if((other = @needle.persistence.find_entity(newname)) && other != user)
224
+ raise DuplicateNameError, "Duplicate name: #{newname}"
225
+ end
226
+ user.revoke('set_password', oldname)
227
+ user.rename(newname)
228
+ user.grant('set_password', newname)
229
+ save(user)
230
+ }
231
+ end
232
+ def reset_entity_password(name, token, password)
233
+ info("reset_entity_password(name=#{name}, token=#{token})")
234
+ @mutex.synchronize {
235
+ user = find_or_fail(name)
236
+ unless(user.allowed?('reset_password', token))
237
+ raise NotPrivilegedError, "You are not privileged to reset #{name}'s password"
238
+ end
239
+ user.passhash = @needle.config.digest.hexdigest(password)
240
+ user.revoke('reset_password', token)
241
+ save(user)
242
+ }
243
+ touch!
244
+ end
245
+ def set_entity_preference(name, key, value, domain=@domain)
246
+ debug("set_entity_preference(name=#{name}, key=#{key}, value=#{value}, domain=#{domain})")
247
+ @mutex.synchronize {
248
+ user = find_or_fail(name)
249
+ unless(user.get_preference(key, domain))
250
+ user.set_preference(key, value, domain)
251
+ save(user)
252
+ end
253
+ }
254
+ touch!
255
+ end
256
+ def grant(name, action, item=nil, expires=nil)
257
+ info("grant(name=#{name}, action=#{action}, item=#{item}, expires=#{expires})")
258
+ @mutex.synchronize {
259
+ user = find_or_fail(name)
260
+ user.grant(action, item || :everything, expires || :never)
261
+ save(user)
262
+ }
263
+ touch!
264
+ end
265
+ end
266
+ class EntitySession < Session
267
+ def initialize(needle, user, domain)
268
+ @user = user
269
+ @domain = domain
270
+ super(needle)
271
+ end
272
+ def allowed?(*args)
273
+ debug("allowed?(#{args.join(', ')})")
274
+ @user.allowed?(*args)
275
+ end
276
+ def name
277
+ @user.name
278
+ end
279
+ def generate_token
280
+ token = @needle.config.digest.hexdigest(rand(2**128).to_s)
281
+ expires = Time.now + @needle.config.token_lifetime.to_i * 24*60*60
282
+ @user.set_token token, expires
283
+ save @user
284
+ token
285
+ end
286
+ def get_preference(key)
287
+ @user.get_preference(key, @domain)
288
+ end
289
+ def ping
290
+ true
291
+ end
292
+ def set_preference(key, value)
293
+ debug("set_preference(#{key}, #{value})")
294
+ @user.set_preference(key, value, @domain)
295
+ save(@user)
296
+ touch!
297
+ end
298
+ def set_preferences(hash)
299
+ debug("set_preferences(#{hash.inspect}")
300
+ hash.each { |key, value|
301
+ @user.set_preference(key, value, @domain)
302
+ }
303
+ save(@user)
304
+ touch!
305
+ end
306
+ def valid?
307
+ @user.valid?
308
+ end
309
+ end
310
+ class TokenSession < EntitySession
311
+ def allowed?(*args)
312
+ key, arg, = args
313
+ if key == 'set_password' || ( key == 'edit' && arg == 'yus.entities' )
314
+ false
315
+ else
316
+ super
317
+ end
318
+ end
319
+ end
320
+ class RootSession < Session
321
+ def allowed?(*args)
322
+ true
323
+ end
324
+ def name
325
+ @needle.config.root_name
326
+ end
327
+ def show(name, recursive=false)
328
+ require 'pp'
329
+ find_or_fail(name).info(recursive).pretty_inspect
330
+ end
331
+ def valid?
332
+ true
333
+ end
334
+ end
335
+ end
data/sha256.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'digest/sha2'
2
+ print "password: ", ARGV[0], "\n"
3
+ print "SHA256 encoding: ",Digest::SHA256.hexdigest(ARGV[0]),"\n"
data/test/suite.rb ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # TestSuite -- yus -- 02.06.2006 -- rwaltert@ywesee.com
3
+
4
+ $: << File.dirname(File.expand_path(__FILE__))
5
+
6
+ Dir.foreach(File.dirname(__FILE__)) { |file|
7
+ require file if /^test_.*\.rb$/o.match(file)
8
+ }
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env ruby
2
+ # TestEntity -- yus -- 29.05.2006 -- hwyss@ywesee.com
3
+
4
+
5
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
6
+
7
+ require 'test/unit'
8
+ require 'yus/entity'
9
+
10
+ module Yus
11
+ class TestEntity < Test::Unit::TestCase
12
+ def setup
13
+ @user = Entity.new('user')
14
+ end
15
+ def test_authenticate
16
+ assert_equal(false, @user.authenticate(nil))
17
+ @user.passhash = '12345abcde'
18
+ assert_equal(false, @user.authenticate('abcde12345'))
19
+ assert_equal(true, @user.authenticate('12345abcde'))
20
+ end
21
+ def test_authenticate_token
22
+ assert_equal(false, @user.authenticate_token(nil))
23
+ token = '123456'
24
+ @user.set_token token, Time.now + 60
25
+ other = '654321'
26
+ @user.set_token other, Time.now + 60
27
+ assert_equal(true, @user.authenticate_token(token))
28
+ assert_equal(true, @user.authenticate_token(other))
29
+ assert_equal(false, @user.authenticate_token(token))
30
+ @user.set_token token, Time.now - 60
31
+ assert_equal(false, @user.authenticate_token(token))
32
+
33
+ # Be paranoid
34
+ token = '123456'
35
+ @user.set_token token, Time.now + 60
36
+ other = '654321'
37
+ @user.set_token other, Time.now + 60
38
+ assert_equal(false, @user.authenticate_token('hacker'))
39
+ assert_equal(false, @user.authenticate_token(token))
40
+ assert_equal(false, @user.authenticate_token(other))
41
+ end
42
+ def test_join
43
+ group1 = Entity.new('A Group')
44
+ group2 = Entity.new('Another Group')
45
+ assert_equal([], @user.affiliations)
46
+ @user.join(group1)
47
+ assert_equal([group1], @user.affiliations)
48
+ @user.join(group1)
49
+ assert_equal([group1], @user.affiliations)
50
+ @user.join(group2)
51
+ assert_equal([group1, group2], @user.affiliations)
52
+ @user.join(group1)
53
+ assert_equal([group1, group2], @user.affiliations)
54
+ @user.join(group2)
55
+ assert_equal([group1, group2], @user.affiliations)
56
+ end
57
+ def test_join__circular
58
+ group1 = Entity.new('A Group')
59
+ group2 = Entity.new('Another Group')
60
+ assert_equal([], @user.affiliations)
61
+ assert_nothing_raised {
62
+ @user.join(group1)
63
+ }
64
+ assert_raises(CircularAffiliationError) {
65
+ group1.join(@user)
66
+ }
67
+ assert_nothing_raised {
68
+ group1.join(group2)
69
+ }
70
+ assert_raises(CircularAffiliationError) {
71
+ group2.join(@user)
72
+ }
73
+ end
74
+ def test_leave
75
+ group1 = Entity.new('A Group')
76
+ group2 = Entity.new('Another Group')
77
+ group3 = Entity.new('A third Group')
78
+ @user.affiliations.push(group1, group2, group3)
79
+ assert_equal([group1, group2, group3], @user.affiliations)
80
+ @user.leave(group2)
81
+ assert_equal([group1, group3], @user.affiliations)
82
+ @user.leave(group2)
83
+ assert_equal([group1, group3], @user.affiliations)
84
+ end
85
+ def test_grant__action
86
+ assert_equal(false, @user.allowed?('write'))
87
+ @user.grant('write')
88
+ assert_equal(true, @user.allowed?('write'))
89
+ assert_equal(true, @user.allowed?('write', 'Article'))
90
+ end
91
+ def test_grant__action_class
92
+ assert_equal(false, @user.allowed?('write'))
93
+ @user.grant('write', 'Article')
94
+ assert_equal(false, @user.allowed?('write'))
95
+ assert_equal(true, @user.allowed?('write', 'Article'))
96
+ end
97
+ def test_allowed
98
+ assert_equal(false, @user.allowed?('write', 'Article'))
99
+ assert_equal(false, @user.allowed?('read', 'Article'))
100
+ @user.grant('read', 'Article')
101
+ assert_equal(false, @user.allowed?('write', 'Article'))
102
+ assert_equal(true, @user.allowed?('read', 'Article'))
103
+ assert_equal(false, @user.allowed?('write'))
104
+ assert_equal(false, @user.allowed?('read'))
105
+ end
106
+ def test_allowed__delegated
107
+ group1 = Entity.new('group1')
108
+ assert_equal(false, @user.allowed?('write', 'Article'))
109
+ group1.grant('read', 'Article')
110
+ @user.join(group1)
111
+ assert_equal(false, @user.allowed?('write', 'Article'))
112
+ assert_equal(true, @user.allowed?('read', 'Article'))
113
+ assert_equal(false, @user.allowed?('write'))
114
+ assert_equal(false, @user.allowed?('read'))
115
+ end
116
+ def test_allowed__delegated__once_removed
117
+ group1 = Entity.new('group1')
118
+ group2 = Entity.new('group1')
119
+ assert_equal(false, @user.allowed?('write', 'Article'))
120
+ group1.grant('read', 'Article')
121
+ group2.join(group1)
122
+ @user.join(group2)
123
+ assert_equal(false, @user.allowed?('write', 'Article'))
124
+ assert_equal(true, @user.allowed?('read', 'Article'))
125
+ assert_equal(false, @user.allowed?('write'))
126
+ assert_equal(false, @user.allowed?('read'))
127
+ end
128
+ def test_privileged
129
+ assert_equal(false, @user.privileged?('write', 'Article'))
130
+ @user.grant('read', 'Article')
131
+ assert_equal(false, @user.privileged?('write', 'Article'))
132
+ assert_equal(true, @user.privileged?('read', 'Article'))
133
+ assert_equal(false, @user.privileged?('write'))
134
+ assert_equal(false, @user.privileged?('read'))
135
+ end
136
+ def test_privileged__delegated
137
+ group1 = Entity.new('group1')
138
+ assert_equal(false, @user.privileged?('write', 'Article'))
139
+ group1.grant('read', 'Article')
140
+ @user.join(group1)
141
+ assert_equal(false, @user.privileged?('write', 'Article'))
142
+ assert_equal(false, @user.privileged?('read', 'Article'))
143
+ assert_equal(false, @user.privileged?('write'))
144
+ assert_equal(false, @user.privileged?('read'))
145
+ end
146
+ def test_privileged_until
147
+ assert_raises(NotPrivilegedError) {
148
+ @user.privileged_until('read', 'Article')
149
+ }
150
+ assert_raises(NotPrivilegedError) {
151
+ @user.privileged_until('write', 'Article')
152
+ }
153
+ @user.grant('read', 'Article')
154
+ assert_nil(@user.privileged_until('read', 'Article'))
155
+ assert_raises(NotPrivilegedError) {
156
+ @user.privileged_until('read')
157
+ }
158
+ assert_raises(NotPrivilegedError) {
159
+ @user.privileged_until('write', 'Article')
160
+ }
161
+ @user.grant('read', 'Article', Time.local(3000))
162
+ assert_raises(NotPrivilegedError) {
163
+ @user.privileged_until('read')
164
+ }
165
+ assert_equal(Time.local(3000),
166
+ @user.privileged_until('read', 'Article'))
167
+ assert_raises(NotPrivilegedError) {
168
+ @user.privileged_until('write', 'Article')
169
+ }
170
+ @user.grant('read', :everything, Time.local(4000))
171
+ assert_equal(Time.local(4000),
172
+ @user.privileged_until('read', 'Article'))
173
+ @user.grant('read', 'Article', Time.local(5000))
174
+ assert_equal(Time.local(5000),
175
+ @user.privileged_until('read', 'Article'))
176
+ end
177
+ def test_valid
178
+ assert_equal(true, @user.valid?)
179
+ @user.valid_from = Time.now + 100
180
+ assert_equal(false, @user.valid?)
181
+ @user.valid_until = Time.now - 100
182
+ assert_equal(false, @user.valid?)
183
+ @user.valid_from = Time.now - 200
184
+ assert_equal(false, @user.valid?)
185
+ @user.valid_until = Time.now + 100
186
+ assert_equal(true, @user.valid?)
187
+ @user.valid_until = nil
188
+ assert_equal(true, @user.valid?)
189
+ end
190
+ def test_domain_based_preference
191
+ assert_nil(@user.get_preference('other'))
192
+ assert_nil(@user.get_preference('pref'))
193
+ assert_nil(@user.get_preference('pref', 'domain'))
194
+ assert_nil(@user.get_preference('pref', 'other'))
195
+ @user.set_preference('pref', 'value', 'domain')
196
+ assert_nil(@user.get_preference('other'))
197
+ assert_nil(@user.get_preference('pref'))
198
+ assert_equal('value', @user.get_preference('pref', 'domain'))
199
+ assert_nil(@user.get_preference('pref', 'other'))
200
+ @user.set_preference('pref', 'global')
201
+ assert_nil(@user.get_preference('other'))
202
+ assert_equal('global', @user.get_preference('pref'))
203
+ assert_equal('value', @user.get_preference('pref', 'domain'))
204
+ assert_equal('global', @user.get_preference('pref', 'other'))
205
+ end
206
+ def test_rename
207
+ assert_equal('user', @user.name)
208
+ @user.rename('renamed')
209
+ assert_equal('renamed', @user.name)
210
+ end
211
+ def test_revoke__action
212
+ assert_equal(false, @user.allowed?('write'))
213
+ @user.grant('write')
214
+ assert_equal(true, @user.allowed?('write'))
215
+ @user.revoke('write')
216
+ assert_equal(false, @user.allowed?('write'))
217
+ end
218
+ def test_to_s
219
+ assert_equal('user', @user.to_s)
220
+ end
221
+ def test_info
222
+ assert_equal ['user'], @user.info
223
+ @user.grant('write')
224
+ assert_equal ['user', ['write', [['everything']]]], @user.info
225
+ @user.grant('write', 'Article')
226
+ assert_equal ['user', ['write', [['Article'], ['everything']]]], @user.info
227
+ group1 = Entity.new('group1')
228
+ group1.grant('read', 'Article')
229
+ @user.join(group1)
230
+ assert_equal ['user', ['write', [['Article'], ['everything']]], ['group1']], @user.info
231
+ group2 = Entity.new('group2')
232
+ group2.grant('read', 'Journal')
233
+ @user.join(group2)
234
+ assert_equal ['user', ['write', [['Article'], ['everything']]], ['group1', 'group2']], @user.info
235
+ assert_equal ['user', ['write', [['Article'], ['everything']]],
236
+ ['group1', ['read', [['Article']]]],
237
+ ['group2', ['read', [['Journal']]]]],
238
+ @user.info(true)
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ # TestPrivilege -- yus -- 31.05.2006 -- hwyss@ywesee.com
3
+
4
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
5
+
6
+ require 'test/unit'
7
+ require 'yus/privilege'
8
+
9
+ module Yus
10
+ class TestPrivilege < Test::Unit::TestCase
11
+ def setup
12
+ @privilege = Privilege.new
13
+ end
14
+ def test_grant
15
+ assert_equal(false, @privilege.granted?('Article'))
16
+ @privilege.grant('Article')
17
+ assert_equal(false, @privilege.granted?('Book'))
18
+ assert_equal(true, @privilege.granted?('Article'))
19
+ end
20
+ def test_grant__timed
21
+ assert_equal(false, @privilege.granted?('Article'))
22
+ @privilege.grant('Article', Time.now)
23
+ assert_equal(false, @privilege.granted?('Article'))
24
+ @privilege.grant('Article', Time.now + 0.5)
25
+ assert_equal(true, @privilege.granted?('Article'))
26
+ sleep(1)
27
+ assert_equal(false, @privilege.granted?('Article'))
28
+ end
29
+ def test_grant__everything
30
+ assert_equal(false, @privilege.granted?('Article'))
31
+ @privilege.grant(:everything)
32
+ assert_equal(true, @privilege.granted?('Article'))
33
+ end
34
+ def test_grant__wildcard
35
+ assert_equal(false, @privilege.granted?('org.oddb.company'))
36
+ @privilege.grant('org.oddb.*')
37
+ assert_equal(true, @privilege.granted?('org.oddb.company'))
38
+ assert_equal(false, @privilege.granted?('org.oddb'))
39
+ assert_equal(false, @privilege.granted?('org.foo.company'))
40
+ end
41
+ def test_revoke
42
+ @privilege.grant('Article')
43
+ assert_equal(true, @privilege.granted?('Article'))
44
+ @privilege.revoke('Article')
45
+ assert_equal(false, @privilege.granted?('Article'))
46
+ end
47
+ def test_revoke__timed
48
+ @privilege.grant('Article')
49
+ assert_equal(true, @privilege.granted?('Article'))
50
+ @privilege.revoke('Article', Time.now + 0.5)
51
+ assert_equal(true, @privilege.granted?('Article'))
52
+ sleep(1)
53
+ assert_equal(false, @privilege.granted?('Article'))
54
+ end
55
+ end
56
+ end