yus 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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