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 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.5.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}=", (Array[*roles].flatten.map { |r| r.to_sym } & self.class.valid_roles).map { |r| 2**self.class.valid_roles.index(r) }.inject { |sum, bitvalue| sum + bitvalue })
6
+ self.send("#{self.class.roles_attribute_name}=", self.class.mask_for(*roles))
7
7
  end
8
8
 
9
9
  # query assigned roles
@@ -4,14 +4,22 @@ module RoleModel
4
4
  class Roles < ::Set # :nodoc:
5
5
  attr_reader :model_instance
6
6
 
7
- def initialize(sender, *roles)
8
- super(*roles)
7
+ def initialize(sender, roles)
8
+ super(roles)
9
9
  @model_instance = sender
10
10
  end
11
11
 
12
- def <<(role)
13
- model_instance.roles = super.to_a
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.5.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-08-17}
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 = [
@@ -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 role was not assigned" do
226
- subject.roles = :bar
227
- subject.send(check_role_assignment_method, :foo).should be_false
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 role was assigned" do
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 not all of the given roles were assigned" do
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 role was not assigned" do
261
- subject.roles = :bar
262
- subject.send(check_role_assignment_method, :foo).should be_false
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: 11
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
8
+ - 6
9
9
  - 0
10
- version: 0.5.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-08-17 00:00:00 +02:00
18
+ date: 2010-10-10 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency