rolify 2.2.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.travis.yml +11 -7
  2. data/CHANGELOG.rdoc +6 -0
  3. data/README.rdoc +36 -4
  4. data/UPGRADE.rdoc +22 -0
  5. data/lib/generators/rolify/role/role_generator.rb +5 -6
  6. data/lib/generators/rolify/role/templates/README-active_record +21 -0
  7. data/lib/generators/rolify/role/templates/README-mongoid +17 -0
  8. data/lib/generators/rolify/role/templates/initializer.rb +5 -6
  9. data/lib/generators/rolify/role/templates/{role.rb → role-active_record.rb} +0 -0
  10. data/lib/generators/rolify/role/templates/role-mongoid.rb +8 -0
  11. data/lib/rolify/adapters/active_record.rb +83 -0
  12. data/lib/rolify/adapters/base.rb +53 -0
  13. data/lib/rolify/adapters/mongoid.rb +87 -0
  14. data/lib/rolify/configure.rb +40 -0
  15. data/lib/rolify/dynamic.rb +21 -0
  16. data/lib/rolify/railtie.rb +20 -0
  17. data/lib/rolify/resource.rb +25 -0
  18. data/lib/rolify/role.rb +32 -110
  19. data/lib/rolify/version.rb +1 -1
  20. data/lib/rolify.rb +35 -0
  21. data/rolify.gemspec +3 -2
  22. data/spec/generators/rolify/role/role_generator_spec.rb +75 -16
  23. data/spec/rolify/config_spec.rb +189 -0
  24. data/spec/rolify/custom_spec.rb +15 -0
  25. data/spec/rolify/resource_spec.rb +317 -0
  26. data/spec/rolify/role_spec.rb +8 -495
  27. data/spec/rolify/shared_contexts.rb +74 -0
  28. data/spec/rolify/shared_examples/shared_examples_for_dynamic.rb +110 -0
  29. data/spec/rolify/shared_examples/shared_examples_for_has_all_roles.rb +71 -0
  30. data/spec/rolify/shared_examples/shared_examples_for_has_any_role.rb +71 -0
  31. data/spec/rolify/shared_examples/shared_examples_for_has_no_role.rb +97 -0
  32. data/spec/rolify/shared_examples/shared_examples_for_has_role_getter.rb +135 -0
  33. data/spec/rolify/shared_examples/shared_examples_for_has_role_setter.rb +92 -0
  34. data/spec/rolify/shared_examples/shared_examples_for_roles.rb +80 -0
  35. data/spec/spec_helper.rb +10 -5
  36. data/spec/support/{models.rb → adapters/active_record.rb} +11 -8
  37. data/spec/support/adapters/mongoid.rb +56 -0
  38. data/spec/support/data.rb +14 -5
  39. metadata +76 -20
  40. data/benchmarks/performance.rb +0 -51
data/.travis.yml CHANGED
@@ -1,12 +1,16 @@
1
1
  rvm:
2
- - 1.8.7
3
- - 1.9.2
4
- - 1.9.3
5
- - ruby-head
6
- - rbx
7
- - jruby
8
- - ree
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=v3">}[http://travis-ci.org/EppO/rolify] {<img src="https://gemnasium.com/EppO/rolify.png">}[https://gemnasium.com/EppO/rolify]
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
- === 2. Run the migration
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
- Please see on {the wiki}[https://github.com/EppO/rolify/wiki/Usage] for all the available commands and the {Tutorial}[https://github.com/EppO/rolify/wiki/Tutorial] to understand how to use {rolify}[http://eppo.github.com/rolify] with {Devise}[https://github.com/plataformatec/devise] and {CanCan}[https://github.com/ryanb/cancan].
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
- " include Rolify::Roles\n" +
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
- # User class to put the roles association. Default is: "User"
3
- <%= "# " if user_cname == "User" %>c.user_cname = "<%= user_cname %>"
4
- # Role class provided by Rolify. Default is: "Role"
5
- <%= "# " if role_cname == "Role" %>c.role_cname = "<%= role_cname %>"
6
- # Dynamic shortcuts for Role class (user.is_admin? like methods). Default is: false
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
@@ -0,0 +1,8 @@
1
+ class <%= role_cname.camelize %>
2
+ include Mongoid::Document
3
+
4
+ has_and_belongs_to_many :<%= user_cname.tableize %>
5
+ belongs_to :resource, :polymorphic => true
6
+
7
+ field :name, :type => String
8
+ end
@@ -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