rolify 2.2.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +11 -7
- data/CHANGELOG.rdoc +6 -0
- data/README.rdoc +36 -4
- data/UPGRADE.rdoc +22 -0
- data/lib/generators/rolify/role/role_generator.rb +5 -6
- data/lib/generators/rolify/role/templates/README-active_record +21 -0
- data/lib/generators/rolify/role/templates/README-mongoid +17 -0
- data/lib/generators/rolify/role/templates/initializer.rb +5 -6
- data/lib/generators/rolify/role/templates/{role.rb → role-active_record.rb} +0 -0
- data/lib/generators/rolify/role/templates/role-mongoid.rb +8 -0
- data/lib/rolify/adapters/active_record.rb +83 -0
- data/lib/rolify/adapters/base.rb +53 -0
- data/lib/rolify/adapters/mongoid.rb +87 -0
- data/lib/rolify/configure.rb +40 -0
- data/lib/rolify/dynamic.rb +21 -0
- data/lib/rolify/railtie.rb +20 -0
- data/lib/rolify/resource.rb +25 -0
- data/lib/rolify/role.rb +32 -110
- data/lib/rolify/version.rb +1 -1
- data/lib/rolify.rb +35 -0
- data/rolify.gemspec +3 -2
- data/spec/generators/rolify/role/role_generator_spec.rb +75 -16
- data/spec/rolify/config_spec.rb +189 -0
- data/spec/rolify/custom_spec.rb +15 -0
- data/spec/rolify/resource_spec.rb +317 -0
- data/spec/rolify/role_spec.rb +8 -495
- data/spec/rolify/shared_contexts.rb +74 -0
- data/spec/rolify/shared_examples/shared_examples_for_dynamic.rb +110 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_all_roles.rb +71 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_any_role.rb +71 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_no_role.rb +97 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_role_getter.rb +135 -0
- data/spec/rolify/shared_examples/shared_examples_for_has_role_setter.rb +92 -0
- data/spec/rolify/shared_examples/shared_examples_for_roles.rb +80 -0
- data/spec/spec_helper.rb +10 -5
- data/spec/support/{models.rb → adapters/active_record.rb} +11 -8
- data/spec/support/adapters/mongoid.rb +56 -0
- data/spec/support/data.rb +14 -5
- metadata +76 -20
- data/benchmarks/performance.rb +0 -51
data/.travis.yml
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
rvm:
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
- 1.8.7
|
3
|
+
- 1.9.3
|
4
|
+
- ruby-head
|
5
|
+
- rbx
|
6
|
+
- jruby
|
7
|
+
- ree
|
8
|
+
|
9
|
+
env:
|
10
|
+
- ADAPTER=active_record
|
11
|
+
- ADAPTER=mongoid
|
9
12
|
|
10
13
|
before_install:
|
11
14
|
- gem update --system
|
12
15
|
- gem --version
|
16
|
+
- ruby -v
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= 3.0 (unreleased)
|
2
|
+
* support for Mongoid
|
3
|
+
* roles search on resources on instance level (e.g. <tt>Forum.first.roles</tt>) and class level (e.g. <tt>Forum.with_role("admin", user)</tt>)
|
4
|
+
* heavy lifting and redesign of the library, code and specs refactoring
|
5
|
+
* enhanced drastically specs coverage: 1001 examples !
|
6
|
+
|
1
7
|
= 2.2.2 (Feb 17, 2012)
|
2
8
|
* fixed another bug occurring when dynamic shortcuts is enabled
|
3
9
|
* display now a README file after running the generator to show the next setup steps
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= rolify {<img src="https://secure.travis-ci.org/EppO/rolify.png?branch=
|
1
|
+
= rolify {<img src="https://secure.travis-ci.org/EppO/rolify.png?branch=master">}[http://travis-ci.org/EppO/rolify] {<img src="https://gemnasium.com/EppO/rolify.png">}[https://gemnasium.com/EppO/rolify]
|
2
2
|
|
3
3
|
Very simple Roles library without any authorization enforcement supporting scope on resource object.
|
4
4
|
|
@@ -12,7 +12,7 @@ This library was intended to be used with CanCan[https://github.com/ryanb/cancan
|
|
12
12
|
== Requirements
|
13
13
|
|
14
14
|
* >= Rails 3.1
|
15
|
-
* ActiveRecord ORM
|
15
|
+
* ActiveRecord ORM <b>or</b> Mongoid
|
16
16
|
* supports ruby 1.8/1.9, REE, JRuby and Rubinius
|
17
17
|
|
18
18
|
== Installation
|
@@ -36,7 +36,9 @@ First, create your Role model and migration file using this generator:
|
|
36
36
|
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.
|
37
37
|
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.
|
38
38
|
|
39
|
-
|
39
|
+
If you want to use Mongoid instead of ActiveRecord, follow these instructions[https://github.com/EppO/rolify/wiki/Configuration], and skip to step #3
|
40
|
+
|
41
|
+
=== 2. Run the migration (only required when using ActiveRecord)
|
40
42
|
|
41
43
|
Let's migrate !
|
42
44
|
|
@@ -99,7 +101,37 @@ A global role overrides resource role request:
|
|
99
101
|
user.has_role? "moderator", Forum.last
|
100
102
|
=> true
|
101
103
|
|
102
|
-
|
104
|
+
=== 5. Resource roles querying
|
105
|
+
|
106
|
+
Starting from rolify 3.0, you can search roles on instance level or class level resources.
|
107
|
+
|
108
|
+
==== Instance level
|
109
|
+
|
110
|
+
forum = Forum.first
|
111
|
+
forum.roles
|
112
|
+
# => [ list of roles that are only binded to forum instance ]
|
113
|
+
forum.applied_roles
|
114
|
+
# => [ list of roles binded to forum instance and to the Forum class ]
|
115
|
+
|
116
|
+
==== Class level
|
117
|
+
|
118
|
+
Forum.with_role("admin")
|
119
|
+
# => [ list of Forum instances that has role "admin" binded to it ]
|
120
|
+
Forum.with_role("admin", current_user)
|
121
|
+
# => [ list of Forum instances that has role "admin" binded to it and belongs to current_user roles ]
|
122
|
+
|
123
|
+
Forum.find_roles
|
124
|
+
# => [ list of roles that binded to any Forum instance or to the Forum class ]
|
125
|
+
Forum.find_roles("admin")
|
126
|
+
# => [ list of roles that binded to any Forum instance or to the Forum class with "admin" as a role name ]
|
127
|
+
Forum.find_roles("admin", current_user)
|
128
|
+
# => [ list of roles that binded to any Forum instance or to the Forum class with "admin" as a role name and belongs to current_user roles ]
|
129
|
+
|
130
|
+
== Resources
|
131
|
+
|
132
|
+
* {Wiki}[https://github.com/EppO/rolify/wiki]
|
133
|
+
* {Usage}[https://github.com/EppO/rolify/wiki/Usage]: all the available commands
|
134
|
+
* {Tutorial}[https://github.com/EppO/rolify/wiki/Tutorial]: how to use {rolify}[http://eppo.github.com/rolify] with {Devise}[https://github.com/plataformatec/devise] and {CanCan}[https://github.com/ryanb/cancan].
|
103
135
|
|
104
136
|
== Questions or Problems?
|
105
137
|
|
data/UPGRADE.rdoc
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
= Upgrade instructions for Rolify library
|
2
|
+
|
3
|
+
== From a previous rolify installation (1.x or 2.x)
|
4
|
+
|
5
|
+
The easiest way is to re-run the generator using <tt>rails g Rolify:Role</tt> command, and overwrite the initializer file. Both the migration file and the <tt>role.rb</tt> haven't changed.
|
6
|
+
In the <tt>config/initializers/rolify.rb</tt> file, here are the deprecated settings:
|
7
|
+
* <tt>role_cname</tt>
|
8
|
+
* <tt>user_cname</tt>
|
9
|
+
By default, these settings were commented out, so you can safely remove them.
|
10
|
+
If you changed them, you can remove them in the initializer file too. <tt>user_cname</tt> is no longer used in 3.x, you don't need it anymore.
|
11
|
+
Add your custom <tt>role_cname</tt> setting as argument of the rolify method you use in your User class.
|
12
|
+
For instance, if you use <tt>Privilege</tt> as <tt>Role</tt> class, you should add this to your whatever your <tt>User</tt> class is, let's say <tt>Client</tt> for the sake of example:
|
13
|
+
class Client < ActiveRecord::Base
|
14
|
+
rolify :role_cname => "Privilege"
|
15
|
+
end
|
16
|
+
If you use the default <tt>Role</tt> class name, you don't have to specify the <tt>:role_cname</tt> argument.
|
17
|
+
|
18
|
+
If you use <i>dynamic methods</i> (<tt>user.is_admin?</tt> like methods), you should turn it on using <tt>use_dynamic_shortcuts</tt> method starting from rolify 3.0:
|
19
|
+
Rolify.configure do |c|
|
20
|
+
c.use_dynamic_shortcuts
|
21
|
+
end
|
22
|
+
The old fashion way still works though, but won't work anymore if the setter method name is changed in a possible future. You've been warned :-)
|
@@ -8,22 +8,21 @@ module Rolify
|
|
8
8
|
source_root File.expand_path('../templates', __FILE__)
|
9
9
|
argument :role_cname, :type => :string, :default => "Role"
|
10
10
|
argument :user_cname, :type => :string, :default => "User"
|
11
|
+
argument :orm_adapter, :type => :string, :default => "active_record"
|
11
12
|
class_option :dynamic_shortcuts, :type => :boolean, :default => false
|
12
13
|
|
13
14
|
desc "Generates a model with the given NAME and a migration file."
|
14
15
|
|
15
16
|
def generate_role
|
16
|
-
template "role.rb", "app/models/#{role_cname.downcase}.rb"
|
17
|
+
template "role-#{orm_adapter}.rb", "app/models/#{role_cname.downcase}.rb"
|
17
18
|
inject_into_class(model_path, user_cname.camelize) do
|
18
|
-
"
|
19
|
-
" #{'# ' if !options[:dynamic_shortcuts]}extend Rolify::Dynamic\n" +
|
20
|
-
" has_and_belongs_to_many :roles#{", :class_name => \"" + role_cname.camelize + "\"" if role_cname != "Role"}, :join_table => :#{user_cname.tableize + "_" + role_cname.tableize}\n"
|
19
|
+
"\trolify\n"
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
def copy_role_file
|
25
24
|
template "initializer.rb", "config/initializers/rolify.rb"
|
26
|
-
migration_template "migration.rb", "db/migrate/rolify_create_#{role_cname.tableize}"
|
25
|
+
migration_template "migration.rb", "db/migrate/rolify_create_#{role_cname.tableize}" if orm_adapter == "active_record"
|
27
26
|
end
|
28
27
|
|
29
28
|
def model_path
|
@@ -35,7 +34,7 @@ module Rolify
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def show_readme
|
38
|
-
readme "README" if behavior == :invoke
|
37
|
+
readme "README-#{orm_adapter}" if behavior == :invoke
|
39
38
|
end
|
40
39
|
end
|
41
40
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
An initializer file has been created here: config/initializers/rolify.rb, you
|
4
|
+
can change rolify settings to match your needs.
|
5
|
+
Defaults values are commented out.
|
6
|
+
|
7
|
+
A Role class has been been created in app/models (with the name you gave as
|
8
|
+
argument otherwise the default is role.rb), you can add your own business logic
|
9
|
+
inside.
|
10
|
+
|
11
|
+
Inside your User class (or the name you gave as argument otherwise the default
|
12
|
+
is user.rb), rolify method has been inserted to provide rolify methods.
|
13
|
+
|
14
|
+
Now, if you just have to run the migration using rake command:
|
15
|
+
|
16
|
+
rake db:migrate
|
17
|
+
|
18
|
+
and you will be able to add the resourcify method inside all models you want
|
19
|
+
scoped by a role.
|
20
|
+
|
21
|
+
===============================================================================
|
@@ -0,0 +1,17 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
An initializer file has been created here: config/initializers/rolify.rb, you
|
4
|
+
can change rolify settings to match your needs.
|
5
|
+
Defaults values are commented out.
|
6
|
+
|
7
|
+
A Role class has been been created in app/models (with the name you gave as
|
8
|
+
argument otherwise the default is role.rb), you can add your own business logic
|
9
|
+
inside.
|
10
|
+
|
11
|
+
Inside your User class (or the name you gave as argument otherwise the default
|
12
|
+
is user.rb), rolify method has been inserted to provide rolify methods.
|
13
|
+
|
14
|
+
Now, if you are able to add the resourcify method inside all models you want
|
15
|
+
scoped by a role.
|
16
|
+
|
17
|
+
===============================================================================
|
@@ -1,8 +1,7 @@
|
|
1
1
|
Rolify.configure do |c|
|
2
|
-
#
|
3
|
-
<%= "# " if
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
<%= "# " if !options[:dynamic_shortcuts] %>c.dynamic_shortcuts = <%= options[:dynamic_shortcuts] == true ? true : false %> if defined?(Rails::Server) || defined?(Rails::Console)
|
2
|
+
# By default ORM adapter is ActiveRecord. uncomment to use mongoid
|
3
|
+
<%= "# " if orm_adapter == "active_record" %>c.use_mongoid
|
4
|
+
|
5
|
+
# Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false
|
6
|
+
<%= "# " if !options[:dynamic_shortcuts] %>c.use_dynamic_shortcuts
|
8
7
|
end
|
File without changes
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rolify/adapters/base'
|
2
|
+
|
3
|
+
module Rolify
|
4
|
+
module Adapter
|
5
|
+
class ActiveRecord < Adapter::Base
|
6
|
+
def find(relation, role_name, resource)
|
7
|
+
query, values = build_query(role_name, resource)
|
8
|
+
relation.where(query, *values)
|
9
|
+
end
|
10
|
+
|
11
|
+
def where(relation, args)
|
12
|
+
conditions, values = build_conditions(relation, args)
|
13
|
+
relation.where(conditions, *values)
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
|
17
|
+
role_class.find_or_create_by_name_and_resource_type_and_resource_id(role_name, resource_type, resource_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add(relation, role)
|
21
|
+
relation.role_ids |= [role.id]
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(relation, role_name, resource = nil)
|
25
|
+
role = relation.where(:name => role_name)
|
26
|
+
role = role.where(:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)) if resource
|
27
|
+
role = role.where(:resource_id => resource.id) if resource && !resource.is_a?(Class)
|
28
|
+
relation.delete(role) if role
|
29
|
+
end
|
30
|
+
|
31
|
+
def resources_find(roles_table, relation, role_name)
|
32
|
+
resources = relation.joins("INNER JOIN \"#{roles_table}\" ON \"#{roles_table}\".\"resource_type\" = '#{relation.to_s}'")
|
33
|
+
resources = resources.where("#{roles_table}.name = ? AND #{roles_table}.resource_type = ?", role_name, relation.to_s)
|
34
|
+
resources
|
35
|
+
end
|
36
|
+
|
37
|
+
def in(relation, roles)
|
38
|
+
relation.where("#{role_class.to_s.tableize}.id IN (?) AND ((resource_id = #{relation.table_name}.id) OR (resource_id IS NULL))", roles)
|
39
|
+
end
|
40
|
+
|
41
|
+
def exists?(relation, column)
|
42
|
+
relation.where("#{column} IS NOT NULL")
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def build_conditions(relation, args)
|
48
|
+
conditions = []
|
49
|
+
values = []
|
50
|
+
args.each do |arg|
|
51
|
+
if arg.is_a? Hash
|
52
|
+
a, v = build_query(arg[:name], arg[:resource])
|
53
|
+
elsif arg.is_a?(String) || arg.is_a?(Symbol)
|
54
|
+
a, v = build_query(arg.to_s)
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Invalid argument type: only hash or string or a symbol allowed"
|
57
|
+
end
|
58
|
+
conditions << a
|
59
|
+
values += v
|
60
|
+
end
|
61
|
+
conditions = conditions.join(' OR ')
|
62
|
+
[ conditions, values ]
|
63
|
+
end
|
64
|
+
|
65
|
+
def build_query(role, resource = nil)
|
66
|
+
return [ "name = ?", [ role ] ] if resource == :any
|
67
|
+
query = "((name = ?) AND (resource_type IS NULL) AND (resource_id IS NULL))"
|
68
|
+
values = [ role ]
|
69
|
+
if resource
|
70
|
+
query.insert(0, "(")
|
71
|
+
query += " OR ((name = ?) AND (resource_type = ?) AND (resource_id IS NULL))"
|
72
|
+
values << role << (resource.is_a?(Class) ? resource.to_s : resource.class.name)
|
73
|
+
if !resource.is_a? Class
|
74
|
+
query += " OR ((name = ?) AND (resource_type = ?) AND (resource_id = ?))"
|
75
|
+
values << role << resource.class.name << resource.id
|
76
|
+
end
|
77
|
+
query += ")"
|
78
|
+
end
|
79
|
+
[ query, values ]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Rolify
|
2
|
+
module Adapter
|
3
|
+
class Base
|
4
|
+
def initialize(role_cname)
|
5
|
+
@role_cname = role_cname
|
6
|
+
end
|
7
|
+
|
8
|
+
def role_class
|
9
|
+
@role_cname.constantize
|
10
|
+
end
|
11
|
+
|
12
|
+
def find(relation, role_name, resource)
|
13
|
+
raise NotImplementedError.new("You must implement find")
|
14
|
+
end
|
15
|
+
|
16
|
+
def where(relation, args)
|
17
|
+
raise NotImplementedError.new("You must implement where")
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
|
21
|
+
raise NotImplementedError.new("You must implement find_or_create_by")
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(relation, role_name, resource = nil)
|
25
|
+
raise NotImplementedError.new("You must implement add")
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove(relation, role_name, resource = nil)
|
29
|
+
raise NotImplementedError.new("You must implement delete")
|
30
|
+
end
|
31
|
+
|
32
|
+
def resources_find(roles_table, relation, role_name)
|
33
|
+
raise NotImplementedError.new("You must implement resources_find")
|
34
|
+
end
|
35
|
+
|
36
|
+
def in(resources, roles)
|
37
|
+
raise NotImplementedError.new("You must implement in")
|
38
|
+
end
|
39
|
+
|
40
|
+
def exists?(relation, column)
|
41
|
+
raise NotImplementedError.new("You must implement exists?")
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_conditions(relation, args)
|
45
|
+
raise NotImplementedError.new("You must implement build_conditions")
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_query(role, resource = nil)
|
49
|
+
raise NotImplementedError.new("You must implement build_query")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'rolify/adapters/base'
|
2
|
+
|
3
|
+
module Rolify
|
4
|
+
module Adapter
|
5
|
+
class Mongoid < Adapter::Base
|
6
|
+
def find(relation, role_name, resource)
|
7
|
+
query = build_query(role_name, resource)
|
8
|
+
query.each do |condition|
|
9
|
+
criteria = relation.where(condition)
|
10
|
+
return criteria.all if !criteria.empty?
|
11
|
+
end
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def where(relation, args)
|
16
|
+
conditions = build_conditions(relation, args)
|
17
|
+
relation.any_of(*conditions)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
|
21
|
+
self.role_class.find_or_create_by(:name => role_name,
|
22
|
+
:resource_type => resource_type,
|
23
|
+
:resource_id => resource_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(relation, role)
|
27
|
+
relation.roles << role
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove(relation, role_name, resource = nil)
|
31
|
+
role = { :name => role_name }
|
32
|
+
role.merge!({:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)}) if resource
|
33
|
+
role.merge!({ :resource_id => resource.id }) if resource && !resource.is_a?(Class)
|
34
|
+
relation.where(role).destroy_all
|
35
|
+
end
|
36
|
+
|
37
|
+
def resources_find(roles_table, relation, role_name)
|
38
|
+
roles = roles_table.classify.constantize.where(:name => role_name, :resource_type => relation.to_s)
|
39
|
+
resources = []
|
40
|
+
roles.each do |role|
|
41
|
+
return relation.all if role.resource_id.nil?
|
42
|
+
resources << role.resource
|
43
|
+
end
|
44
|
+
resources
|
45
|
+
end
|
46
|
+
|
47
|
+
def in(resources, roles)
|
48
|
+
return [] if resources.empty? || roles.empty?
|
49
|
+
resources.delete_if { |resource| (resource.applied_roles && roles).empty? }
|
50
|
+
resources
|
51
|
+
end
|
52
|
+
|
53
|
+
def exists?(relation, column)
|
54
|
+
relation.where(column.to_sym.ne => nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def build_conditions(relation, args)
|
60
|
+
conditions = []
|
61
|
+
args.each do |arg|
|
62
|
+
if arg.is_a? Hash
|
63
|
+
query = build_query(arg[:name], arg[:resource])
|
64
|
+
elsif arg.is_a?(String) || arg.is_a?(Symbol)
|
65
|
+
query = build_query(arg)
|
66
|
+
else
|
67
|
+
raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
|
68
|
+
end
|
69
|
+
conditions += query
|
70
|
+
end
|
71
|
+
conditions
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_query(role, resource = nil)
|
75
|
+
return [{ :name => role }] if resource == :any
|
76
|
+
query = [{ :name => role, :resource_type => nil, :resource_id => nil }]
|
77
|
+
if resource
|
78
|
+
query << { :name => role, :resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name), :resource_id => nil }
|
79
|
+
if !resource.is_a? Class
|
80
|
+
query << { :name => role, :resource_type => resource.class.name, :resource_id => resource.id }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
query
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Rolify
|
2
|
+
module Configure
|
3
|
+
@@dynamic_shortcuts = false
|
4
|
+
@@orm = "active_record"
|
5
|
+
|
6
|
+
def configure
|
7
|
+
yield self if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def dynamic_shortcuts
|
11
|
+
@@dynamic_shortcuts || false
|
12
|
+
end
|
13
|
+
|
14
|
+
def dynamic_shortcuts=(is_dynamic)
|
15
|
+
@@dynamic_shortcuts = is_dynamic
|
16
|
+
end
|
17
|
+
|
18
|
+
def orm
|
19
|
+
@@orm
|
20
|
+
end
|
21
|
+
|
22
|
+
def orm=(orm)
|
23
|
+
@@orm = orm
|
24
|
+
end
|
25
|
+
|
26
|
+
def use_mongoid
|
27
|
+
self.orm = "mongoid"
|
28
|
+
end
|
29
|
+
|
30
|
+
def use_dynamic_shortcuts
|
31
|
+
self.dynamic_shortcuts = true #if defined?(Rails::Server) || defined?(Rails::Console)
|
32
|
+
end
|
33
|
+
|
34
|
+
def use_defaults
|
35
|
+
@@dynamic_shortcuts = false
|
36
|
+
@@orm = "active_record"
|
37
|
+
@@adapter = Rolify::Adapter::ActiveRecord.new("Role")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rolify
|
2
|
+
module Dynamic
|
3
|
+
def load_dynamic_methods
|
4
|
+
self.role_class.all.each do |r|
|
5
|
+
define_dynamic_method(r.name, r.resource)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_dynamic_method(role_name, resource)
|
10
|
+
class_eval do
|
11
|
+
define_method("is_#{role_name}?".to_sym) do
|
12
|
+
has_role?("#{role_name}")
|
13
|
+
end if !method_defined?("is_#{role_name}?".to_sym)
|
14
|
+
|
15
|
+
define_method("is_#{role_name}_of?".to_sym) do |arg|
|
16
|
+
has_role?("#{role_name}", arg)
|
17
|
+
end if !method_defined?("is_#{role_name}_of?".to_sym) && !!resource
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rolify'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Rolify
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer 'rolify.initialize' do
|
7
|
+
ActiveSupport.on_load(:active_record) do
|
8
|
+
ActiveRecord::Base.send :extend, Rolify
|
9
|
+
end
|
10
|
+
|
11
|
+
config.after_initialize do
|
12
|
+
::Mongoid::Document.module_eval do
|
13
|
+
def self.included(base)
|
14
|
+
base.extend Rolify
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end if defined?(Mongoid)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rolify
|
2
|
+
module Resource
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def find_roles(role_name = nil, user = nil)
|
9
|
+
roles = user && (user != :any) ? user.roles : self.role_class
|
10
|
+
roles = roles.where(:resource_type => self.to_s)
|
11
|
+
roles = roles.where(:name => role_name) if role_name && (role_name != :any)
|
12
|
+
roles
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_role(role_name, user = nil)
|
16
|
+
resources = self.adapter.resources_find(self.role_class.to_s.tableize, self, role_name)
|
17
|
+
user ? self.adapter.in(resources, user.roles.where(:name => role_name)) : resources
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def applied_roles
|
22
|
+
self.roles + self.class.role_class.where(:resource_type => self.class.to_s, :resource_id => nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|