role_model 0.5.0 → 0.6.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.
- data/README.rdoc +15 -11
- data/VERSION +1 -1
- data/lib/role_model/class_methods.rb +12 -0
- data/lib/role_model/implementation.rb +1 -1
- data/lib/role_model/roles.rb +12 -4
- data/role_model.gemspec +2 -2
- data/spec/role_model_spec.rb +98 -37
- data/spec/roles_spec.rb +33 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -9,12 +9,12 @@ It works like this:
|
|
9
9
|
# given a User class with a roles_mask attribute
|
10
10
|
require 'rubygems'
|
11
11
|
require 'role_model'
|
12
|
-
|
12
|
+
|
13
13
|
class User
|
14
14
|
attr_accessor :roles_mask # in real life this would be an persisted attribute
|
15
15
|
|
16
16
|
include RoleModel
|
17
|
-
|
17
|
+
|
18
18
|
# optionally set the integer attribute to store the roles in,
|
19
19
|
# :roles_mask is the default
|
20
20
|
roles_attribute :roles_mask
|
@@ -27,20 +27,20 @@ It works like this:
|
|
27
27
|
#
|
28
28
|
# Test drive (check the RDoc or source for additional finesse)
|
29
29
|
#
|
30
|
-
|
30
|
+
|
31
31
|
>> u = User.new
|
32
32
|
=> #<User ...>
|
33
|
-
|
33
|
+
|
34
34
|
# role assignment
|
35
35
|
>> u.roles = [:admin] # ['admin'] works as well
|
36
36
|
=> [:admin]
|
37
|
-
|
38
|
-
# adding roles
|
37
|
+
|
38
|
+
# adding roles (remove via delete or re-assign)
|
39
39
|
>> u.roles << :manager
|
40
40
|
=> [:admin, :manager]
|
41
41
|
|
42
42
|
# querying roles...
|
43
|
-
|
43
|
+
|
44
44
|
# get all valid roles that have been declared
|
45
45
|
>> User.valid_roles
|
46
46
|
=> [:admin, :manager, :author]
|
@@ -48,21 +48,25 @@ It works like this:
|
|
48
48
|
# ... retrieve all assigned roles
|
49
49
|
>> u.roles # aliased to role_symbols for DeclarativeAuthorization
|
50
50
|
=> [:admin, :manager]
|
51
|
-
|
51
|
+
|
52
52
|
# ... check for individual roles
|
53
53
|
>> u.has_role? :author # has_role? is also aliased to is?
|
54
54
|
=> false
|
55
|
-
|
55
|
+
|
56
56
|
# ... check for multiple roles
|
57
57
|
>> u.has_any_role? :author, :manager # has_any_role? is also aliased to is_any_of?
|
58
58
|
=> true
|
59
|
-
|
59
|
+
|
60
60
|
>> u.has_all_roles? :author, :manager # has_all_roles? is also aliased to is?
|
61
61
|
=> false
|
62
|
-
|
62
|
+
|
63
63
|
# see the internal bitmask representation (3 = 0b0011)
|
64
64
|
>> u.roles_mask
|
65
65
|
=> 3
|
66
|
+
|
67
|
+
# see the role mask for a certain role(s)
|
68
|
+
>> User.mask_for :admin, :author
|
69
|
+
=> 5
|
66
70
|
|
67
71
|
Once you have included RoleModel, your model is perfectly fit to be used
|
68
72
|
together with a role-based authorization solution, such as
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -28,5 +28,17 @@ module RoleModel
|
|
28
28
|
def roles(*roles)
|
29
29
|
self.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
|
30
30
|
end
|
31
|
+
|
32
|
+
def mask_for(*roles)
|
33
|
+
(Array[*roles].map {|r|
|
34
|
+
r.respond_to?(:each) ? r.to_a : r
|
35
|
+
}.flatten.map { |r|
|
36
|
+
r.to_sym
|
37
|
+
} & valid_roles).map { |r|
|
38
|
+
2**valid_roles.index(r)
|
39
|
+
}.inject { |sum, bitvalue|
|
40
|
+
sum + bitvalue
|
41
|
+
} || 0
|
42
|
+
end
|
31
43
|
end
|
32
44
|
end
|
@@ -3,7 +3,7 @@ module RoleModel
|
|
3
3
|
|
4
4
|
# assign roles
|
5
5
|
def roles=(*roles)
|
6
|
-
self.send("#{self.class.roles_attribute_name}=",
|
6
|
+
self.send("#{self.class.roles_attribute_name}=", self.class.mask_for(*roles))
|
7
7
|
end
|
8
8
|
|
9
9
|
# query assigned roles
|
data/lib/role_model/roles.rb
CHANGED
@@ -4,14 +4,22 @@ module RoleModel
|
|
4
4
|
class Roles < ::Set # :nodoc:
|
5
5
|
attr_reader :model_instance
|
6
6
|
|
7
|
-
def initialize(sender,
|
8
|
-
super(
|
7
|
+
def initialize(sender, roles)
|
8
|
+
super(roles)
|
9
9
|
@model_instance = sender
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def add(role)
|
13
|
+
roles = super
|
14
|
+
model_instance.roles = roles if model_instance
|
14
15
|
self
|
15
16
|
end
|
17
|
+
alias_method :<<, :add
|
18
|
+
|
19
|
+
def delete(role)
|
20
|
+
model_instance.roles = super(role.to_sym)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
16
24
|
end
|
17
25
|
end
|
data/role_model.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{role_model}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Martin Rehfeld"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-10}
|
13
13
|
s.description = %q{Ever needed to assign roles to a model, say a User, and build conditional behaviour on top of that? Enter RoleModel -- roles have never been easier! Just declare your roles and you are done. Assigned roles will be stored as a bitmask.}
|
14
14
|
s.email = %q{martin.rehfeld@glnetworks.de}
|
15
15
|
s.extra_rdoc_files = [
|
data/spec/role_model_spec.rb
CHANGED
@@ -126,6 +126,13 @@ describe RoleModel do
|
|
126
126
|
subject.roles.should include(:bar)
|
127
127
|
subject.should have(1).roles
|
128
128
|
end
|
129
|
+
|
130
|
+
it "should allow reassigning the #roles value aka Roles object" do
|
131
|
+
subject.roles << :bar
|
132
|
+
subject.roles = subject.roles
|
133
|
+
subject.roles.should include(:foo, :bar)
|
134
|
+
subject.should have(2).roles
|
135
|
+
end
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
@@ -180,6 +187,47 @@ describe RoleModel do
|
|
180
187
|
end
|
181
188
|
end
|
182
189
|
|
190
|
+
describe "#delete" do
|
191
|
+
subject { model_class.new }
|
192
|
+
|
193
|
+
context "with roles :foo and :bar already assigned" do
|
194
|
+
before(:each) do
|
195
|
+
subject.roles = [:foo, :bar]
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should delete a existing role given as a symbol" do
|
199
|
+
subject.roles.delete(:foo)
|
200
|
+
subject.roles.should_not include(:foo)
|
201
|
+
subject.should have(1).roles
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should delete a existing role given as a string" do
|
205
|
+
subject.roles.delete('foo')
|
206
|
+
subject.roles.should_not include(:foo)
|
207
|
+
subject.should have(1).roles
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should not change anything if a non existing role is given" do
|
211
|
+
subject.roles.delete(:third)
|
212
|
+
subject.roles.should include(:foo, :bar)
|
213
|
+
subject.should have(2).roles
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "without roles assigned" do
|
218
|
+
it "should have 0 roles if a role is given as a symbol" do
|
219
|
+
subject.roles.delete(:foo)
|
220
|
+
subject.should have(0).roles
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should have 0 roles if a role is given as a string" do
|
224
|
+
subject.roles.delete('foo')
|
225
|
+
subject.should have(0).roles
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
183
231
|
context "query for an individual role" do
|
184
232
|
[:has_any_role?, :is_any_of?, :has_role?, :has_all_roles?, :is?, :has_roles?].each do |check_role_assignment_method|
|
185
233
|
describe "##{check_role_assignment_method}" do
|
@@ -212,28 +260,14 @@ describe RoleModel do
|
|
212
260
|
describe "##{check_role_assignment_method}" do
|
213
261
|
subject { model_class.new }
|
214
262
|
|
215
|
-
it "should return true when the given role was assigned" do
|
216
|
-
subject.roles = :foo
|
217
|
-
subject.send(check_role_assignment_method, :foo).should be_true
|
218
|
-
end
|
219
|
-
|
220
263
|
it "should return true when any of the given roles was assigned" do
|
221
|
-
subject.roles = :foo
|
264
|
+
subject.roles = [:foo, :baz]
|
222
265
|
subject.send(check_role_assignment_method, :foo, :bar).should be_true
|
223
266
|
end
|
224
267
|
|
225
|
-
it "should return false when the given
|
226
|
-
subject.roles = :bar
|
227
|
-
subject.send(check_role_assignment_method, :
|
228
|
-
end
|
229
|
-
|
230
|
-
it "should return false when no role was assigned" do
|
231
|
-
subject.send(check_role_assignment_method, :foo).should be_false
|
232
|
-
subject.send(check_role_assignment_method, :bar).should be_false
|
233
|
-
end
|
234
|
-
|
235
|
-
it "should return false when asked for an undefined role" do
|
236
|
-
subject.send(check_role_assignment_method, :baz).should be_false
|
268
|
+
it "should return false when none of the given roles were assigned" do
|
269
|
+
subject.roles = [:foo, :bar]
|
270
|
+
subject.send(check_role_assignment_method, :baz, :quux).should be_false
|
237
271
|
end
|
238
272
|
end
|
239
273
|
end
|
@@ -242,33 +276,19 @@ describe RoleModel do
|
|
242
276
|
describe "##{check_role_assignment_method}" do
|
243
277
|
subject { model_class.new }
|
244
278
|
|
245
|
-
it "should return true when the given
|
246
|
-
subject.roles = :foo
|
247
|
-
subject.send(check_role_assignment_method, :foo).should be_true
|
248
|
-
end
|
249
|
-
|
250
|
-
it "should return true when all of the given roles was assigned" do
|
279
|
+
it "should return true when all of the given roles were assigned" do
|
251
280
|
subject.roles = [:foo, :bar]
|
252
281
|
subject.send(check_role_assignment_method, :foo, :bar).should be_true
|
253
282
|
end
|
254
283
|
|
255
|
-
it "should return false when
|
284
|
+
it "should return false when only some of the given roles were assigned" do
|
256
285
|
subject.roles = [:foo, :bar]
|
257
286
|
subject.send(check_role_assignment_method, :bar, :baz).should be_false
|
258
287
|
end
|
259
288
|
|
260
|
-
it "should return false when the given
|
261
|
-
subject.roles = :bar
|
262
|
-
subject.send(check_role_assignment_method, :
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should return false when no role was assigned" do
|
266
|
-
subject.send(check_role_assignment_method, :foo).should be_false
|
267
|
-
subject.send(check_role_assignment_method, :bar).should be_false
|
268
|
-
end
|
269
|
-
|
270
|
-
it "should return false when asked for an undefined role" do
|
271
|
-
subject.send(check_role_assignment_method, :baz).should be_false
|
289
|
+
it "should return false when none of the given roles were assigned" do
|
290
|
+
subject.roles = [:foo, :bar]
|
291
|
+
subject.send(check_role_assignment_method, :baz, :quux).should be_false
|
272
292
|
end
|
273
293
|
end
|
274
294
|
end
|
@@ -346,4 +366,45 @@ describe RoleModel do
|
|
346
366
|
end
|
347
367
|
end
|
348
368
|
|
369
|
+
describe ".mask_for" do
|
370
|
+
subject { model_class.new }
|
371
|
+
|
372
|
+
before(:each) do
|
373
|
+
model_class.instance_eval do
|
374
|
+
attr_accessor :roles_mask
|
375
|
+
attr_accessor :custom_roles_mask
|
376
|
+
include RoleModel
|
377
|
+
roles :foo, :bar, :third
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context "passing" do
|
382
|
+
it "should return the role mask of a role" do
|
383
|
+
subject.class.mask_for(:foo).should == 1
|
384
|
+
subject.class.mask_for(:bar).should == 2
|
385
|
+
subject.class.mask_for(:third).should == 4
|
386
|
+
end
|
387
|
+
|
388
|
+
it "should return the role mask of an array of roles" do
|
389
|
+
subject.class.mask_for(:foo, :bar).should == 3
|
390
|
+
subject.class.mask_for(:foo, :third).should == 5
|
391
|
+
subject.class.mask_for(:foo, :bar, :third).should == 7
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should return the role mask of a string array of roles" do
|
395
|
+
subject.class.mask_for("foo").should == 1
|
396
|
+
subject.class.mask_for("foo", "bar").should == 3
|
397
|
+
subject.class.mask_for("foo", "third").should == 5
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should return the role mask of the existing roles" do
|
401
|
+
subject.class.mask_for(:foo, :quux).should == 1
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should return 0 when a role that does not exist is passed" do
|
405
|
+
subject.class.mask_for(:quux).should == 0
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
349
410
|
end
|
data/spec/roles_spec.rb
CHANGED
@@ -5,6 +5,9 @@ describe RoleModel::Roles do
|
|
5
5
|
let(:model_instance) { Class.new.new }
|
6
6
|
let(:array) { [:foo, :bar] }
|
7
7
|
subject { RoleModel::Roles.new(model_instance, array) }
|
8
|
+
before(:each) do
|
9
|
+
model_instance.stub(:roles=)
|
10
|
+
end
|
8
11
|
|
9
12
|
its(:model_instance) { should equal(model_instance) }
|
10
13
|
it { should include(:foo, :bar) }
|
@@ -16,4 +19,34 @@ describe RoleModel::Roles do
|
|
16
19
|
subject << :baz
|
17
20
|
end
|
18
21
|
end
|
22
|
+
|
23
|
+
describe "#add" do
|
24
|
+
it "should add the given element to the model_instance.roles by re-assigning all roles" do
|
25
|
+
model_instance.should_receive(:roles=).with(array_including(:foo, :bar, :baz))
|
26
|
+
subject.add(:baz)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#merge" do
|
31
|
+
it "should add the given enum to the model_instance.roles by re-assigning all roles" do
|
32
|
+
model_instance.should_receive(:roles=).with(array_including(:foo, :bar, :baz, :quux))
|
33
|
+
subject.merge([:baz, :quux])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#delete" do
|
38
|
+
it "should delete the given element to the model_instance.roles by re-assigning all roles" do
|
39
|
+
model_instance.should_receive(:roles=).with(subject)
|
40
|
+
subject.delete :foo
|
41
|
+
subject.should_not include(:foo)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#subtract" do
|
46
|
+
it "should remove the given enum to the model_instance.roles by re-assigning all roles" do
|
47
|
+
model_instance.should_receive(:roles=).with(subject)
|
48
|
+
subject.subtract([:foo, :bar])
|
49
|
+
subject.should have(0).roles
|
50
|
+
end
|
51
|
+
end
|
19
52
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: role_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Martin Rehfeld
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-10 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|