rolify 0.4.0 → 0.5.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/CHANGELOG.rdoc +8 -0
- data/README.rdoc +1 -1
- data/lib/generators/rolify/role/role_generator.rb +4 -1
- data/lib/generators/rolify/role/templates/initializer.rb +1 -0
- data/lib/rolify/role.rb +85 -54
- data/lib/rolify/version.rb +1 -1
- data/spec/rolify/role_spec.rb +11 -0
- data/spec/support/models.rb +3 -2
- metadata +2 -1
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
= 0.5
|
2
|
+
* dynamic shortcuts support
|
3
|
+
* creates automatically new methods upon new role creation (or at startup for a Rails app)
|
4
|
+
* <tt>has_role "admin"</tt> will create a method called <tt>is_admin?</tt>
|
5
|
+
* <tt>has_role "moderator", Forum.first</tt> will create 2 methods:
|
6
|
+
* <tt>is_moderator_of?(resource)</tt>
|
7
|
+
* <tt>is_moderator?</tt>
|
8
|
+
|
1
9
|
= v0.4
|
2
10
|
* removing role support
|
3
11
|
* <tt>has_no_role</tt> removes a global role or a role scoped to a resource
|
data/README.rdoc
CHANGED
@@ -34,6 +34,7 @@ First, create your Role model and migration file using this generator:
|
|
34
34
|
|
35
35
|
Role and User classes are the default. You can specify any Role class name you want. This is completly a new file so any name can do the job.
|
36
36
|
For the User class name, you would probably use the one provided by your authentication solution. rolify just adds some class methods in an existing User class.
|
37
|
+
<b>**For now, please stick to Role and User class names, see {#5}[https://github.com/EppO/rolify/issues/5] for details**</b>
|
37
38
|
|
38
39
|
=== 2. Run the migration
|
39
40
|
|
@@ -92,5 +93,4 @@ If you have any issue or feature request with/for rolify, please add an {issue o
|
|
92
93
|
|
93
94
|
* put syntactic sugar:
|
94
95
|
* <tt>is_admin?</tt> and <tt>is_admin_of?(resource)</tt> like shortcuts
|
95
|
-
* multiple role names query at the same time
|
96
96
|
* write a tutorial showing how to use rolify with CanCan and devise
|
@@ -14,11 +14,14 @@ module Rolify
|
|
14
14
|
def generate_role
|
15
15
|
template "role.rb", "app/models/role.rb"
|
16
16
|
inject_into_class(model_path, user_cname.camelize) do
|
17
|
-
" include Rolify\n" +
|
17
|
+
" include Rolify::Roles\n" +
|
18
|
+
" extend Rolify::Reloaded\n" +
|
19
|
+
" has_and_belongs_to_many :roles, :class_name => \"#{role_cname.camelize}\"\n"
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
23
|
def copy_role_file
|
24
|
+
template "initializer.rb", "config/initializers/rolify.rb"
|
22
25
|
migration_template "migration.rb", "db/migrate/rolify_create_#{role_cname.tableize}"
|
23
26
|
end
|
24
27
|
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= user_cname.camelize %>.load_dynamic_methods
|
data/lib/rolify/role.rb
CHANGED
@@ -1,69 +1,100 @@
|
|
1
1
|
module Rolify
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
|
3
|
+
module Roles
|
4
|
+
|
5
|
+
def has_role(role_name, resource = nil)
|
6
|
+
role = Role.find_or_create_by_name_and_resource_type_and_resource_id( :name => role_name,
|
7
|
+
:resource_type => (resource.class.name if resource),
|
8
|
+
:resource_id => (resource.id if resource))
|
9
|
+
if !roles.include?(role)
|
10
|
+
self.class.define_dynamic_method role_name, resource
|
11
|
+
self.roles << role
|
12
|
+
end
|
13
|
+
end
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
def has_role?(role_name, resource = nil)
|
16
|
+
query, values = build_query(role_name, resource)
|
17
|
+
self.roles.where(*query, *values).size > 0
|
18
|
+
end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def has_all_roles?(*args)
|
21
|
+
conditions = []
|
22
|
+
values = []
|
23
|
+
args.each do |arg|
|
24
|
+
if arg.is_a? Hash
|
25
|
+
return false if !self.has_role?(arg[:name], arg[:resource])
|
26
|
+
elsif arg.is_a? String
|
27
|
+
return false if !self.has_role?(arg)
|
28
|
+
else
|
29
|
+
raise ArgumentError, "Invalid argument type: only hash or string allowed"
|
30
|
+
end
|
24
31
|
end
|
32
|
+
true
|
25
33
|
end
|
26
|
-
true
|
27
|
-
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def has_any_role?(*args)
|
36
|
+
conditions = []
|
37
|
+
values = []
|
38
|
+
args.each do |arg|
|
39
|
+
if arg.is_a? Hash
|
40
|
+
a, v = build_query(arg[:name], arg[:resource])
|
41
|
+
elsif arg.is_a? String
|
42
|
+
a, v = build_query(arg)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "Invalid argument type: only hash or string allowed"
|
45
|
+
end
|
46
|
+
conditions << a
|
47
|
+
values += v
|
39
48
|
end
|
40
|
-
conditions
|
41
|
-
values += v
|
49
|
+
self.roles.where([ conditions.join(' OR '), *values ]).size > 0
|
42
50
|
end
|
43
|
-
self.roles.where([ conditions.join(' OR '), *values ]).size > 0
|
44
|
-
end
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
def has_no_role(role_name, resource = nil)
|
53
|
+
role = Role.where( :name => role_name)
|
54
|
+
role = role.where( :resource_type => resource.class.name,
|
55
|
+
:resource_id => resource.id) if resource
|
56
|
+
self.roles.delete(role) if role
|
57
|
+
end
|
52
58
|
|
53
|
-
|
54
|
-
|
59
|
+
def roles_name
|
60
|
+
self.roles.select(:name).map { |r| r.name }
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def build_query(role, resource = nil)
|
66
|
+
query = "((name = ?) AND (resource_type IS NULL) AND (resource_id IS NULL))"
|
67
|
+
values = [ role ]
|
68
|
+
if resource
|
69
|
+
query.insert(0, "(")
|
70
|
+
query += " OR ((name = ?) AND (resource_type = ?) AND (resource_id = ?)))"
|
71
|
+
values << role << resource.class.name << resource.id
|
72
|
+
end
|
73
|
+
[ [ query ], values]
|
74
|
+
end
|
75
|
+
|
55
76
|
end
|
77
|
+
|
78
|
+
module Reloaded
|
79
|
+
|
80
|
+
def load_dynamic_methods
|
81
|
+
Role.all.each do |r|
|
82
|
+
define_dynamic_method(r.name, r.resource)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def define_dynamic_method(role_name, resource)
|
88
|
+
class_eval do
|
89
|
+
define_method("is_#{role_name}?".to_sym) do
|
90
|
+
has_role?("#{role_.name}")
|
91
|
+
end if !method_defined? "is_#{role_name}?".to_sym
|
56
92
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
values = [ role ]
|
62
|
-
if resource
|
63
|
-
query.insert(0, "(")
|
64
|
-
query += " OR ((name = ?) AND (resource_type = ?) AND (resource_id = ?)))"
|
65
|
-
values << role << resource.class.name << resource.id
|
93
|
+
define_method("is_#{role_name}_of?".to_sym) do |arg|
|
94
|
+
has_role?("#{role_name}", arg)
|
95
|
+
end if !method_defined?("is_#{role_name}_of?".to_sym) && resource
|
96
|
+
end
|
66
97
|
end
|
67
|
-
|
98
|
+
|
68
99
|
end
|
69
100
|
end
|
data/lib/rolify/version.rb
CHANGED
data/spec/rolify/role_spec.rb
CHANGED
@@ -4,6 +4,8 @@ describe Rolify do
|
|
4
4
|
context "in a Instance level" do
|
5
5
|
before(:all) do
|
6
6
|
@admin = User.first
|
7
|
+
@admin.has_role "admin"
|
8
|
+
@admin.has_role "moderator", Forum.first
|
7
9
|
end
|
8
10
|
|
9
11
|
it "should respond to has_role method" do
|
@@ -30,6 +32,15 @@ describe Rolify do
|
|
30
32
|
@admin.should respond_to(:has_no_role).with(1).arguments
|
31
33
|
@admin.should respond_to(:has_no_role).with(2).arguments
|
32
34
|
end
|
35
|
+
|
36
|
+
it "should respond to dynamic methods" do
|
37
|
+
@admin.should respond_to(:is_admin?).with(0).arguments
|
38
|
+
@admin.should respond_to(:is_moderator_of?).with(1).arguments
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not respond to any unknown methods" do
|
42
|
+
@admin.should_not respond_to(:is_god?)
|
43
|
+
end
|
33
44
|
end
|
34
45
|
|
35
46
|
context "with a global role" do
|
data/spec/support/models.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
2
|
has_and_belongs_to_many :roles, :join_table => :users_roles
|
3
|
-
include Rolify
|
3
|
+
include Rolify::Roles
|
4
|
+
extend Rolify::Reloaded
|
4
5
|
end
|
5
6
|
|
6
7
|
class Role < ActiveRecord::Base
|
@@ -9,4 +10,4 @@ class Role < ActiveRecord::Base
|
|
9
10
|
end
|
10
11
|
|
11
12
|
class Forum < ActiveRecord::Base
|
12
|
-
end
|
13
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rolify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.5.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Florent Monbillard
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- README.rdoc
|
52
52
|
- Rakefile
|
53
53
|
- lib/generators/rolify/role/role_generator.rb
|
54
|
+
- lib/generators/rolify/role/templates/initializer.rb
|
54
55
|
- lib/generators/rolify/role/templates/migration.rb
|
55
56
|
- lib/generators/rolify/role/templates/role.rb
|
56
57
|
- lib/rolify.rb
|