role_model 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -8
- data/Rakefile +3 -0
- data/VERSION +1 -1
- data/lib/role_model/class_methods.rb +32 -0
- data/lib/role_model/implementation.rb +21 -0
- data/lib/role_model/roles.rb +1 -1
- data/lib/role_model.rb +5 -43
- data/role_model.gemspec +8 -4
- data/spec/custom_matchers.rb +2 -1
- data/spec/custom_matchers_spec.rb +62 -0
- data/spec/role_model_spec.rb +1 -1
- metadata +15 -4
data/README.rdoc
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
= RoleModel
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
RoleModel is the framework agnostic, efficient and declarative way to do
|
4
|
+
(user) roles. Assigned roles will be efficiently stored as a bitmask
|
5
|
+
directly into your model within an configurable attribute.
|
5
6
|
|
6
|
-
|
7
|
-
(default: <tt>roles_mask</tt>). Here's how to get started:
|
7
|
+
It works like this:
|
8
8
|
|
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
|
-
attr_accessor :roles_mask # in real life this would be an persisted attribute
|
14
|
+
attr_accessor :roles_mask # in real life this would be an persisted attribute
|
15
15
|
|
16
16
|
include RoleModel
|
17
17
|
|
@@ -39,7 +39,7 @@ Assigned roles will be stored as a bitmask in an configurable attribute
|
|
39
39
|
>> u.roles << :manager
|
40
40
|
=> [:admin, :manager]
|
41
41
|
|
42
|
-
#
|
42
|
+
# querying roles...
|
43
43
|
|
44
44
|
# ... retrieve all assigned roles
|
45
45
|
>> u.roles # aliased to role_symbols for DeclarativeAuthorization
|
@@ -48,8 +48,6 @@ Assigned roles will be stored as a bitmask in an configurable attribute
|
|
48
48
|
# ... check for individual roles
|
49
49
|
>> u.has_role? :author
|
50
50
|
=> false
|
51
|
-
>> u.is_a? :admin # has_role? is aliased as is_a?
|
52
|
-
=> true
|
53
51
|
|
54
52
|
# see the internal bitmask representation (3 = 0b0011)
|
55
53
|
>> u.roles_mask
|
data/Rakefile
CHANGED
@@ -28,6 +28,9 @@ Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
28
28
|
spec.libs << 'lib' << 'spec'
|
29
29
|
spec.pattern = 'spec/**/*_spec.rb'
|
30
30
|
spec.rcov = true
|
31
|
+
spec.rcov_opts.concat ['--exclude', 'rcov.rb']
|
32
|
+
spec.rcov_opts.concat ['--exclude', '.*_spec.rb']
|
33
|
+
spec.rcov_opts.concat ['--exclude', 'spec_helper.rb']
|
31
34
|
end
|
32
35
|
|
33
36
|
task :spec => :check_dependencies
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RoleModel
|
2
|
+
module ClassMethods
|
3
|
+
def inherited(subclass) # :nodoc:
|
4
|
+
::RoleModel::INHERITABLE_CLASS_ATTRIBUTES.each do |attribute|
|
5
|
+
instance_var = "@#{attribute}"
|
6
|
+
subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
|
7
|
+
end
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
# set the bitmask attribute role assignments will be stored in
|
12
|
+
def roles_attribute(name)
|
13
|
+
self.roles_attribute = name
|
14
|
+
end
|
15
|
+
|
16
|
+
# alternative method signature: set the bitmask attribute role assignments will be stored in
|
17
|
+
def roles_attribute=(name)
|
18
|
+
self.roles_attribute_name = name.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
# :call-seq:
|
22
|
+
# roles(:role_1, ..., :role_n)
|
23
|
+
# roles('role_1', ..., 'role_n')
|
24
|
+
# roles([:role_1, ..., :role_n])
|
25
|
+
# roles(['role_1', ..., 'role_n'])
|
26
|
+
#
|
27
|
+
# declare valid roles
|
28
|
+
def roles(*roles)
|
29
|
+
self.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RoleModel
|
2
|
+
module Implementation
|
3
|
+
|
4
|
+
# assign roles
|
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 })
|
7
|
+
end
|
8
|
+
|
9
|
+
# query assigned roles
|
10
|
+
def roles
|
11
|
+
Roles.new(self, self.class.valid_roles.reject { |r| ((self.send(self.class.roles_attribute_name) || 0) & 2**self.class.valid_roles.index(r)).zero? })
|
12
|
+
end
|
13
|
+
alias role_symbols roles
|
14
|
+
|
15
|
+
# check if a given role has been assigned
|
16
|
+
def has_role?(role)
|
17
|
+
roles.include?(role.to_sym)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/role_model/roles.rb
CHANGED
data/lib/role_model.rb
CHANGED
@@ -1,58 +1,20 @@
|
|
1
|
+
require 'role_model/implementation'
|
2
|
+
require 'role_model/class_methods'
|
1
3
|
require 'role_model/roles'
|
2
4
|
|
3
5
|
module RoleModel
|
4
6
|
|
5
7
|
INHERITABLE_CLASS_ATTRIBUTES = [:roles_attribute_name, :valid_roles]
|
6
8
|
|
9
|
+
include Implementation
|
10
|
+
|
7
11
|
def self.included(base) # :nodoc:
|
8
12
|
base.extend ClassMethods
|
9
13
|
base.class_eval do
|
10
14
|
class << self
|
11
15
|
attr_accessor(*::RoleModel::INHERITABLE_CLASS_ATTRIBUTES)
|
12
16
|
end
|
13
|
-
roles_attribute :roles_mask
|
14
|
-
end
|
15
|
-
|
16
|
-
# assign roles
|
17
|
-
def roles=(*roles)
|
18
|
-
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 })
|
19
|
-
end
|
20
|
-
|
21
|
-
# query assigned roles
|
22
|
-
def roles
|
23
|
-
Roles.new(self, self.class.valid_roles.reject { |r| ((self.send(self.class.roles_attribute_name) || 0) & 2**self.class.valid_roles.index(r)).zero? })
|
24
|
-
end
|
25
|
-
alias role_symbols roles
|
26
|
-
|
27
|
-
# check if a given role has been assigned
|
28
|
-
def has_role?(role)
|
29
|
-
roles.include?(role.to_sym)
|
30
|
-
end
|
31
|
-
alias is_a? has_role?
|
32
|
-
end
|
33
|
-
|
34
|
-
module ClassMethods
|
35
|
-
def inherited(subclass) # :nodoc:
|
36
|
-
::RoleModel::INHERITABLE_CLASS_ATTRIBUTES.each do |attribute|
|
37
|
-
instance_var = "@#{attribute}"
|
38
|
-
subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
|
39
|
-
end
|
40
|
-
super
|
41
|
-
end
|
42
|
-
|
43
|
-
# set the bitmask attribute role assignment will be stored in
|
44
|
-
def roles_attribute(name)
|
45
|
-
self.roles_attribute = name
|
46
|
-
end
|
47
|
-
|
48
|
-
# alternative method signature: set the bitmask attribute role assignment will be stored in
|
49
|
-
def roles_attribute=(name)
|
50
|
-
self.roles_attribute_name = name.to_sym
|
51
|
-
end
|
52
|
-
|
53
|
-
# declare valid roles
|
54
|
-
def roles(*roles)
|
55
|
-
self.valid_roles = Array[*roles].flatten.map { |r| r.to_sym }
|
17
|
+
roles_attribute :roles_mask # set default bitmask attribute
|
56
18
|
end
|
57
19
|
end
|
58
20
|
|
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.3.
|
8
|
+
s.version = "0.3.2"
|
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-08-04}
|
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 = [
|
@@ -24,9 +24,12 @@ Gem::Specification.new do |s|
|
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"lib/role_model.rb",
|
27
|
+
"lib/role_model/class_methods.rb",
|
28
|
+
"lib/role_model/implementation.rb",
|
27
29
|
"lib/role_model/roles.rb",
|
28
30
|
"role_model.gemspec",
|
29
31
|
"spec/custom_matchers.rb",
|
32
|
+
"spec/custom_matchers_spec.rb",
|
30
33
|
"spec/role_model_spec.rb",
|
31
34
|
"spec/roles_spec.rb",
|
32
35
|
"spec/spec.opts",
|
@@ -35,10 +38,11 @@ Gem::Specification.new do |s|
|
|
35
38
|
s.homepage = %q{http://github.com/martinrehfeld/role_model}
|
36
39
|
s.rdoc_options = ["--charset=UTF-8"]
|
37
40
|
s.require_paths = ["lib"]
|
38
|
-
s.rubygems_version = %q{1.3.
|
41
|
+
s.rubygems_version = %q{1.3.7}
|
39
42
|
s.summary = %q{Declare, assign and query roles with ease}
|
40
43
|
s.test_files = [
|
41
44
|
"spec/custom_matchers.rb",
|
45
|
+
"spec/custom_matchers_spec.rb",
|
42
46
|
"spec/role_model_spec.rb",
|
43
47
|
"spec/roles_spec.rb",
|
44
48
|
"spec/spec_helper.rb"
|
@@ -48,7 +52,7 @@ Gem::Specification.new do |s|
|
|
48
52
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
53
|
s.specification_version = 3
|
50
54
|
|
51
|
-
if Gem::Version.new(Gem::
|
55
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
56
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
53
57
|
else
|
54
58
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
data/spec/custom_matchers.rb
CHANGED
@@ -5,8 +5,9 @@ module CustomMatchers
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def ==(actual)
|
8
|
+
return false if actual.size < @expected.size
|
8
9
|
@expected.each do | value |
|
9
|
-
return false unless actual.
|
10
|
+
return false unless actual.any? { |actual_value| value == actual_value }
|
10
11
|
end
|
11
12
|
true
|
12
13
|
rescue NoMethodError => ex
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module CustomMatchers
|
4
|
+
describe ArrayIncludingMatcher do
|
5
|
+
|
6
|
+
it "should describe itself properly" do
|
7
|
+
ArrayIncludingMatcher.new(:a, :b).description.should == "array_including(:a, :b)"
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "passing" do
|
11
|
+
it "should match the same array" do
|
12
|
+
array_including(:a).should == [:a]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should match a array with extra stuff" do
|
16
|
+
array_including(:a).should == [:a, :b]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should match a array regardless of element position" do
|
20
|
+
array_including(:a, :b).should == [:b, :a]
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when matching against other matchers" do
|
24
|
+
it "should match a symbol against anything()" do
|
25
|
+
array_including(anything, :b).should == [:a, :b]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should match an int against anything()" do
|
29
|
+
array_including(anything, :b).should == [1, :b]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should match a string against anything()" do
|
33
|
+
array_including(anything, :b).should == ["1", :b]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should match an arbitrary object against anything()" do
|
37
|
+
array_including(anything, :b).should == [Class.new.new, :b]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "failing" do
|
43
|
+
it "should not match a non-array" do
|
44
|
+
array_including(:a).should_not == :a
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not match a array with a missing element" do
|
48
|
+
array_including(:a).should_not == [:b]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not match an empty array with a given key" do
|
52
|
+
array_including(:a).should_not == []
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when matching against other matchers" do
|
56
|
+
it "should not match without additional elements" do
|
57
|
+
array_including(anything, 1).should_not == [1]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/role_model_spec.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: role_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
9
|
+
- 2
|
10
|
+
version: 0.3.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Martin Rehfeld
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-08-04 00:00:00 +02:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: rspec
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 2
|
@@ -48,9 +51,12 @@ files:
|
|
48
51
|
- Rakefile
|
49
52
|
- VERSION
|
50
53
|
- lib/role_model.rb
|
54
|
+
- lib/role_model/class_methods.rb
|
55
|
+
- lib/role_model/implementation.rb
|
51
56
|
- lib/role_model/roles.rb
|
52
57
|
- role_model.gemspec
|
53
58
|
- spec/custom_matchers.rb
|
59
|
+
- spec/custom_matchers_spec.rb
|
54
60
|
- spec/role_model_spec.rb
|
55
61
|
- spec/roles_spec.rb
|
56
62
|
- spec/spec.opts
|
@@ -65,28 +71,33 @@ rdoc_options:
|
|
65
71
|
require_paths:
|
66
72
|
- lib
|
67
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
68
75
|
requirements:
|
69
76
|
- - ">="
|
70
77
|
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
71
79
|
segments:
|
72
80
|
- 0
|
73
81
|
version: "0"
|
74
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
75
84
|
requirements:
|
76
85
|
- - ">="
|
77
86
|
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
78
88
|
segments:
|
79
89
|
- 0
|
80
90
|
version: "0"
|
81
91
|
requirements: []
|
82
92
|
|
83
93
|
rubyforge_project:
|
84
|
-
rubygems_version: 1.3.
|
94
|
+
rubygems_version: 1.3.7
|
85
95
|
signing_key:
|
86
96
|
specification_version: 3
|
87
97
|
summary: Declare, assign and query roles with ease
|
88
98
|
test_files:
|
89
99
|
- spec/custom_matchers.rb
|
100
|
+
- spec/custom_matchers_spec.rb
|
90
101
|
- spec/role_model_spec.rb
|
91
102
|
- spec/roles_spec.rb
|
92
103
|
- spec/spec_helper.rb
|