effective_roles 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06f6a3d9bee34bb09cb46dca52cf1d7837ed636c9a1888e244aff16c1f8b772c
4
- data.tar.gz: 708a5daa2f874de24e5fe8b80f1cd1e4731d9fc30630f18ab16c666d47749e34
3
+ metadata.gz: 7f392991013eeab38fcc7b6092c1014078fc2a356833bd5033b9a268987dc512
4
+ data.tar.gz: 38bb573be4e391b9cfd6141713bd89d29914e46148705588f1859642a5269bed
5
5
  SHA512:
6
- metadata.gz: a960a0fc29fbfec810675e507628dcf4c6aa2327685866c02e51d267a163869e3ed19c9f6cb92b3ceb7f21315c4d6c42f1f7e19efa374f944970778cf62ad3c7
7
- data.tar.gz: 5d51969cfd0d88df911f5c79c550ce5085422ba82670250bb93781f5d95c298578d8c5b5c74bc3dfe4744f04b216ea2aaa00bccfefd097cf24491a5548d1f4a6
6
+ metadata.gz: ef6d332b9c6d93d8e28b61e856c93ec20e8c731b2fd02678fd1dcd8e52c2bcd12e1f5b68c891d82a265054065fe5694cc2bd59baa72ddaf2bb4553af28a93739
7
+ data.tar.gz: e7f10cde194b45115445a09bd99d0da254c81dd611c97cb9f1c25e8cd33181941449aaa20eb45b5b24d4bea0af8397720cf1156865ef0bf217b1798bf103225a
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2019 Code and Effect Inc.
1
+ Copyright 2021 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -8,10 +8,6 @@ Includes a mixin for adding authentication for any model.
8
8
 
9
9
  SQL Finders for returning an ActiveRecord::Relation with all permitted records.
10
10
 
11
- Handy formtastic and simple_form helpers for assigning roles.
12
-
13
- Rails 3.2.x and Rails 4
14
-
15
11
 
16
12
  ## Getting Started
17
13
 
@@ -158,8 +154,8 @@ When using assignable roles, you must assign the acts_as_role_restricted resourc
158
154
 
159
155
  You can do this in one of three ways:
160
156
 
161
- 1. Setting resource.current_user = current_user in your controller directly.
162
- 2. Add `before_action :set_effective_roles_current_user` to your ApplicationController
157
+ 1. Setting resource.current_user = current_user in your controller update action directly.
158
+ 2. Add `before_action -> { @thing.current_user = current_user }` to your ApplicationController
163
159
  3. Using `Effective::CrudController` to do this automatically.
164
160
 
165
161
  This restriction is only applied when running within the rails server. Not on rails console or db:seeds.
@@ -319,5 +315,3 @@ This model implements the https://github.com/ryanb/cancan/wiki/Role-Based-Author
319
315
  4. Push to the branch (`git push origin my-new-feature`)
320
316
  5. Bonus points for test coverage
321
317
  6. Create new Pull Request
322
-
323
-
@@ -1,12 +1,17 @@
1
1
  module Admin
2
2
  class RolesController < ApplicationController
3
- before_action :authenticate_user!
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_roles) }
4
5
 
5
- layout (EffectiveRoles.layout.kind_of?(Hash) ? EffectiveRoles.layout[:admin_roles] : EffectiveRoles.layout)
6
+ include Effective::CrudController
7
+
8
+ if (config = EffectiveRoles.config.layout)
9
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
10
+ end
6
11
 
7
12
  def index
8
13
  @page_title = 'Roles'
9
- EffectiveRoles.authorize!(self, :admin, :effective_roles)
10
14
  end
15
+
11
16
  end
12
17
  end
@@ -2,7 +2,7 @@ module EffectiveRolesHelper
2
2
  def effective_roles_summary(obj, options = {}) # User or a Post, any acts_as_roleable
3
3
  raise 'expected an acts_as_roleable object' unless obj.respond_to?(:roles)
4
4
 
5
- descriptions = EffectiveRoles.role_descriptions[obj.class.name] || EffectiveRoles.role_descriptions || {}
5
+ descriptions = EffectiveRoles.config.role_descriptions[obj.class.name] || EffectiveRoles.config.role_descriptions || {}
6
6
  opts = { obj: obj, roles: obj.roles, descriptions: descriptions }.merge(options)
7
7
 
8
8
  render partial: 'effective/roles/summary', locals: opts
@@ -17,7 +17,7 @@ module EffectiveRolesHelper
17
17
  raise 'Expected argument to be a Hash' unless opts.kind_of?(Hash)
18
18
 
19
19
  roles = Array(opts[:roles]).presence
20
- roles ||= [:public, :signed_in] + EffectiveRoles.roles
20
+ roles ||= [:public, :signed_in] + EffectiveRoles.config.roles
21
21
 
22
22
  if opts[:only].present?
23
23
  klasses = Array(opts[:only])
@@ -101,4 +101,108 @@ module EffectiveRolesHelper
101
101
  klass.respond_to?(:name) ? klass.name : klass.to_s
102
102
  end
103
103
 
104
+ # This is used by the effective_roles_summary_table helper method
105
+ def effective_roles_authorization_level(controller, role, resource)
106
+ authorization_method = EffectiveRoles.config.authorization_method
107
+
108
+ raise('expected an authorization method') unless (authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol))
109
+ return :unknown unless (controller.current_user rescue nil).respond_to?(:roles=)
110
+
111
+ # Store the current ability (cancan support) and roles
112
+ current_ability = controller.instance_variable_get(:@current_ability)
113
+ current_user = controller.instance_variable_get(:@current_user)
114
+ current_user_roles = controller.current_user.roles
115
+
116
+ # Set up the user, so the check is done with the desired permission level
117
+ controller.instance_variable_set(:@current_ability, nil)
118
+
119
+ level = nil
120
+
121
+ case role
122
+ when :signed_in
123
+ controller.current_user.roles = []
124
+ when :public
125
+ controller.instance_variable_set(:@current_user, nil)
126
+
127
+ if defined?(EffectiveLogging)
128
+ EffectiveLogging.supressed { (controller.request.env['warden'].set_user(false) rescue nil) }
129
+ else
130
+ (controller.request.env['warden'].set_user(false) rescue nil)
131
+ end
132
+ else
133
+ controller.current_user.roles = [role]
134
+ end
135
+
136
+ # Find the actual authorization level
137
+ level = effective_roles_item_authorization_level(controller, role, resource, authorization_method)
138
+
139
+ # Restore the existing current_user stuff
140
+ if role == :public
141
+ ActiveRecord::Base.transaction do
142
+ if defined?(EffectiveLogging)
143
+ EffectiveLogging.supressed { (controller.request.env['warden'].set_user(current_user) rescue nil) }
144
+ else
145
+ (controller.request.env['warden'].set_user(current_user) rescue nil)
146
+ end
147
+
148
+ raise ActiveRecord::Rollback
149
+ end
150
+ end
151
+
152
+ controller.instance_variable_set(:@current_ability, current_ability)
153
+ controller.instance_variable_set(:@current_user, current_user)
154
+ controller.current_user.roles = current_user_roles
155
+
156
+ level
157
+ end
158
+
159
+ def effective_roles_item_authorization_level(controller, role, resource, auth_method)
160
+ resource = (resource.new() rescue resource) if resource.kind_of?(ActiveRecord::Base)
161
+
162
+ # Custom actions
163
+ if resource.kind_of?(Hash)
164
+ resource.each do |key, value|
165
+ return (controller.instance_exec(controller, key, value, &auth_method) rescue false) ? :yes : :no
166
+ end
167
+ end
168
+
169
+ # Check for Manage
170
+ return :manage if (
171
+ (controller.instance_exec(controller, :create, resource, &auth_method) rescue false) &&
172
+ (controller.instance_exec(controller, :update, resource, &auth_method) rescue false) &&
173
+ (controller.instance_exec(controller, :show, resource, &auth_method) rescue false) &&
174
+ (controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
175
+ )
176
+
177
+ # Check for Update
178
+ return :update if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
179
+
180
+ # Check for Update Own
181
+ if resource.respond_to?('user=')
182
+ resource.user = controller.current_user
183
+ return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
184
+ resource.user = nil
185
+ elsif resource.respond_to?('user_id=')
186
+ resource.user_id = controller.current_user.id
187
+ return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
188
+ resource.user_id = nil
189
+ elsif resource.class.name.end_with?('User')
190
+ return :update_own if (controller.instance_exec(controller, :update, controller.current_user, &auth_method) rescue false)
191
+ end
192
+
193
+ # Check for Create
194
+ return :create if (controller.instance_exec(controller, :create, resource, &auth_method) rescue false)
195
+
196
+ # Check for Show
197
+ return :show if (controller.instance_exec(controller, :show, resource, &auth_method) rescue false)
198
+
199
+ # Check for Index
200
+ return :index if (controller.instance_exec(controller, :index, resource, &auth_method) rescue false)
201
+
202
+ # Check for Destroy
203
+ return :destroy if (controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
204
+
205
+ :none
206
+ end
207
+
104
208
  end
@@ -14,7 +14,7 @@
14
14
  module ActsAsRoleRestricted
15
15
  extend ActiveSupport::Concern
16
16
 
17
- module ActiveRecord
17
+ module Base
18
18
  def acts_as_role_restricted(multiple: false)
19
19
  @acts_as_role_restricted_opts = { multiple: multiple }
20
20
  include ::ActsAsRoleRestricted
@@ -29,22 +29,24 @@ module ActsAsRoleRestricted
29
29
 
30
30
  validates :roles_mask, numericality: true, allow_nil: true
31
31
 
32
- validate(if: -> { changes.include?(:roles_mask) }) do
33
- user = current_user || EffectiveRoles.current_user || (EffectiveLogging.current_user if defined?(EffectiveLogging))
34
-
35
- if user.blank? && EffectiveRoles.assignable_roles.present? && defined?(Rails::Server)
36
- self.errors.add(:roles, 'current_user must be present when assigning roles')
37
- end
38
-
32
+ validate(if: -> { changes.include?(:roles_mask) && EffectiveRoles.assignable_roles_present?(self) }) do
39
33
  roles_was = EffectiveRoles.roles_for(changes[:roles_mask].first)
40
34
  changed = (roles + roles_was) - (roles & roles_was) # XOR
41
35
 
42
- assignable = EffectiveRoles.assignable_roles_collection(self, user) # Returns all roles when user is blank
36
+ assignable = EffectiveRoles.assignable_roles_collection(self, current_user) # Returns all roles when user is blank
43
37
  unauthorized = changed - assignable
44
38
 
45
39
  authorized = roles.dup
46
40
  unauthorized.each { |role| authorized.include?(role) ? authorized.delete(role) : authorized.push(role) }
47
41
 
42
+ if unauthorized.present?
43
+ Rails.logger.info "\e[31m unassignable roles: #{unauthorized.map { |role| ":#{role}" }.to_sentence}"
44
+ end
45
+
46
+ if unauthorized.present? && current_user.blank? && defined?(Rails::Server)
47
+ self.errors.add(:roles, 'current_user must be present when assigning roles')
48
+ end
49
+
48
50
  self.roles_mask = EffectiveRoles.roles_mask_for(authorized)
49
51
  end
50
52
 
@@ -69,18 +71,18 @@ module ActsAsRoleRestricted
69
71
  def with_role_sql(*roles)
70
72
  roles = roles.flatten.compact
71
73
  roles = roles.first.roles if roles.length == 1 && roles.first.respond_to?(:roles)
72
- roles = (roles.map { |role| role.to_sym } & EffectiveRoles.roles)
74
+ roles = (roles.map { |role| role.to_sym } & EffectiveRoles.config.roles)
73
75
 
74
- roles.map { |role| "(#{self.table_name}.roles_mask & %d > 0)" % 2**EffectiveRoles.roles.index(role) }.join(' OR ')
76
+ roles.map { |role| "(#{self.table_name}.roles_mask & %d > 0)" % 2**EffectiveRoles.config.roles.index(role) }.join(' OR ')
75
77
  end
76
78
 
77
79
  def without_role(*roles)
78
80
  roles = roles.flatten.compact
79
81
  roles = roles.first.roles if roles.length == 1 && roles.first.respond_to?(:roles)
80
- roles = (roles.map { |role| role.to_sym } & EffectiveRoles.roles)
82
+ roles = (roles.map { |role| role.to_sym } & EffectiveRoles.config.roles)
81
83
 
82
84
  where(
83
- roles.map { |role| "NOT(#{self.table_name}.roles_mask & %d > 0)" % 2**EffectiveRoles.roles.index(role) }.join(' AND ')
85
+ roles.map { |role| "NOT(#{self.table_name}.roles_mask & %d > 0)" % 2**EffectiveRoles.config.roles.index(role) }.join(' AND ')
84
86
  ).or(where(roles_mask: nil))
85
87
  end
86
88
  end
@@ -127,4 +129,3 @@ module ActsAsRoleRestricted
127
129
  end
128
130
 
129
131
  end
130
-
@@ -13,4 +13,5 @@
13
13
  %td= effective_roles_authorization_label(klass)
14
14
  - roles.each do |role|
15
15
  %td.text-center
16
- = effective_roles_authorization_badge(EffectiveRoles.authorization_level(controller, role, klass))
16
+ - level = effective_roles_authorization_level(controller, role, klass)
17
+ = effective_roles_authorization_badge(level)
@@ -53,6 +53,8 @@ EffectiveRoles.setup do |config|
53
53
  # :superadmin => [:superadmin, :admin, :member], # Superadmins may create Pages for any role
54
54
  # :admin => [:admin, :member], # Admins may create Pages for admin and members
55
55
  # :member => [:member] # Members may create Pages for members
56
+ # },
57
+ # 'Post' => false # Don't enforce assignable roles validation
56
58
  # }
57
59
  #
58
60
  # Or just keep it simple, and use this Hash syntax of permissions for every resource
@@ -60,38 +62,13 @@ EffectiveRoles.setup do |config|
60
62
  # config.assignable_roles = {
61
63
  # :superadmin => [:superadmin, :admin, :member], # Superadmins may assign any resource any role
62
64
  # :admin => [:admin, :member], # Admins may only assign the :admin or :member role
63
- # :member => [] # Members may not assign any roles
65
+ # :member => [], # Members may not assign any roles
66
+ # :new_record => [:member] # Member may be assigned to a new_record without a current_user
64
67
  # }
65
68
 
66
69
  # Authorization Method
67
- #
68
- # This doesn't have anything to do with the roles themselves.
69
- # It's only used in two places:
70
- # - For the effective_roles_summary_table() helper method
71
- # - The /admin/roles page check
72
- #
73
- # It should match the authorization check used by your application
74
- #
75
- # This method is called by all controller actions with the appropriate action and resource
76
- # If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
77
- #
78
- # Use via Proc (and with CanCan):
79
- # config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
80
- #
81
- # Use via custom method:
82
- # config.authorization_method = :my_authorization_method
83
- #
84
- # And then in your application_controller.rb:
85
- #
86
- # def my_authorization_method(action, resource)
87
- # current_user.is?(:admin)
88
- # end
89
- #
90
- # Or disable the check completely:
91
- # config.authorization_method = false
92
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) } # CanCanCan
70
+ # This gem serves an /admin/roles endpoint that calls EffectiveResources.authorize!
93
71
 
94
72
  # Layout Settings
95
- # Configure the Layout per controller, or all at once
96
- config.layout = 'application'
73
+ # config.layout = 'admin'
97
74
  end
@@ -1,46 +1,30 @@
1
+ require 'effective_resources'
1
2
  require 'effective_roles/engine'
2
3
  require 'effective_roles/version'
3
4
 
4
5
  module EffectiveRoles
5
- mattr_accessor :roles
6
- mattr_accessor :role_descriptions
7
- mattr_accessor :assignable_roles
6
+ # mattr_accessor :roles
7
+ # mattr_accessor :role_descriptions
8
+ # mattr_accessor :assignable_roles
9
+ # mattr_accessor :layout
8
10
 
9
- mattr_accessor :layout
10
- mattr_accessor :authorization_method
11
+ def self.config(namespace = nil)
12
+ @config ||= ActiveSupport::OrderedOptions.new
13
+ namespace ||= Tenant.current if defined?(Tenant)
11
14
 
12
- def self.setup
13
- yield self
14
- end
15
-
16
- def self.permitted_params
17
- { roles: [] }
18
- end
19
-
20
- def self.authorized?(controller, action, resource)
21
- @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
22
-
23
- return !!authorization_method unless authorization_method.respond_to?(:call)
24
- controller = controller.controller if controller.respond_to?(:controller)
25
-
26
- begin
27
- !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
28
- rescue *@_exceptions
29
- false
15
+ if namespace
16
+ @config[namespace] ||= ActiveSupport::OrderedOptions.new
17
+ else
18
+ @config
30
19
  end
31
20
  end
32
21
 
33
- def self.authorize!(controller, action, resource)
34
- raise Effective::AccessDenied unless authorized?(controller, action, resource)
22
+ def self.setup(namespace = nil, &block)
23
+ yield(config(namespace))
35
24
  end
36
25
 
37
- # This is set by the "set_effective_roles_current_user" before_filter.
38
- def self.current_user=(user)
39
- @effective_roles_current_user = user
40
- end
41
-
42
- def self.current_user
43
- @effective_roles_current_user
26
+ def self.permitted_params
27
+ { roles: [] }
44
28
  end
45
29
 
46
30
  # This method converts whatever is given into its roles
@@ -49,11 +33,11 @@ module EffectiveRoles
49
33
  if obj.respond_to?(:is_role_restricted?)
50
34
  obj.roles
51
35
  elsif obj.kind_of?(Integer)
52
- roles.reject { |r| (obj & 2**roles.index(r)).zero? }
36
+ config.roles.reject { |r| (obj & 2 ** config.roles.index(r)).zero? }
53
37
  elsif obj.kind_of?(Symbol)
54
- [roles.find { |role| role == obj }].compact
38
+ Array(config.roles.find { |role| role == obj })
55
39
  elsif obj.kind_of?(String)
56
- [roles.find { |role| role == obj.to_sym }].compact
40
+ Array(config.roles.find { |role| role == obj.to_sym })
57
41
  elsif obj.kind_of?(Array)
58
42
  obj.map { |obj| roles_for(obj) }.flatten.compact
59
43
  elsif obj.nil?
@@ -65,11 +49,11 @@ module EffectiveRoles
65
49
 
66
50
  # EffectiveRoles.roles_mask_for(:admin, :member)
67
51
  def self.roles_mask_for(*roles)
68
- roles_for(roles).map { |r| 2**EffectiveRoles.roles.index(r) }.sum
52
+ roles_for(roles).map { |r| 2 ** config.roles.index(r) }.sum
69
53
  end
70
54
 
71
55
  def self.roles_collection(resource, current_user = nil, only: nil, except: nil, multiple: nil)
72
- if assignable_roles.present?
56
+ if config.assignable_roles.present?
73
57
  raise('expected object to respond to is_role_restricted?') unless resource.respond_to?(:is_role_restricted?)
74
58
  raise('expected current_user to respond to is_role_restricted?') if current_user && !current_user.respond_to?(:is_role_restricted?)
75
59
  end
@@ -79,7 +63,7 @@ module EffectiveRoles
79
63
  multiple = resource.acts_as_role_restricted_options[:multiple] if multiple.nil?
80
64
  assignable = assignable_roles_collection(resource, current_user, multiple: multiple)
81
65
 
82
- roles.map do |role|
66
+ config.roles.map do |role|
83
67
  next if only.present? && !only.include?(role)
84
68
  next if except.present? && except.include?(role)
85
69
 
@@ -92,139 +76,72 @@ module EffectiveRoles
92
76
  end
93
77
 
94
78
  def self.assignable_roles_collection(resource, current_user = nil, multiple: nil)
95
- return roles if assignable_roles.nil?
96
-
97
- raise 'EffectiveRoles config.assignable_roles_for must be a Hash, Array or nil' unless [Hash, Array].include?(assignable_roles.class)
98
- raise('expected resource to respond to is_role_restricted?') unless resource.respond_to?(:is_role_restricted?)
99
- raise('expected current_user to respond to is_role_restricted?') if current_user && !current_user.respond_to?(:is_role_restricted?)
100
-
101
- multiple = resource.acts_as_role_restricted_options[:multiple] if multiple.nil?
102
- current_user ||= (EffectiveRoles.current_user || (EffectiveLogging.current_user if defined?(EffectiveLogging)))
79
+ return config.roles unless assignable_roles_present?(resource)
103
80
 
104
- assignable = if assignable_roles.kind_of?(Array)
105
- assignable_roles
106
- elsif current_user.present?
107
- current_roles = assignable_roles[resource.class.to_s] || assignable_roles || {}
108
- current_user.roles.map { |role| current_roles[role] }.flatten.compact.uniq
109
- else
110
- current_roles = assignable_roles[resource.class.to_s] || assignable_roles || {}
111
- current_roles.values.flatten.uniq
81
+ if current_user && !current_user.respond_to?(:is_role_restricted?)
82
+ raise('expected current_user to respond to is_role_restricted?')
112
83
  end
113
84
 
114
- # Check boxes
115
- return assignable if multiple
116
-
117
- # Radios
118
- (resource.roles - assignable).present? ? [] : assignable
119
- end
120
-
121
- # This is used by the effective_roles_summary_table helper method
122
- def self.authorization_level(controller, role, resource)
123
- return :unknown unless (authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol))
124
- return :unknown unless (controller.current_user rescue nil).respond_to?(:roles=)
125
-
126
- # Store the current ability (cancan support) and roles
127
- current_ability = controller.instance_variable_get(:@current_ability)
128
- current_user = controller.instance_variable_get(:@current_user)
129
- current_user_roles = controller.current_user.roles
130
-
131
- # Set up the user, so the check is done with the desired permission level
132
- controller.instance_variable_set(:@current_ability, nil)
133
-
134
- level = nil
85
+ if !resource.respond_to?(:is_role_restricted?)
86
+ raise('expected current_user to respond to is_role_restricted?')
87
+ end
135
88
 
136
- case role
137
- when :signed_in
138
- controller.current_user.roles = []
139
- when :public
140
- controller.instance_variable_set(:@current_user, nil)
89
+ assigned_roles = if config.assignable_roles.kind_of?(Hash)
90
+ assignable = (config.assignable_roles[resource.class.to_s] || config.assignable_roles || {})
91
+ assigned = [] # our return value
141
92
 
142
- if defined?(EffectiveLogging)
143
- EffectiveLogging.supressed { (controller.request.env['warden'].set_user(false) rescue nil) }
144
- else
145
- (controller.request.env['warden'].set_user(false) rescue nil)
93
+ if current_user.blank?
94
+ assigned = assignable.values.flatten
146
95
  end
147
- else
148
- controller.current_user.roles = [role]
149
- end
150
-
151
- # Find the actual authorization level
152
- level = _authorization_level(controller, role, resource, authorization_method)
153
96
 
154
- # Restore the existing current_user stuff
155
- if role == :public
156
- ActiveRecord::Base.transaction do
157
- if defined?(EffectiveLogging)
158
- EffectiveLogging.supressed { (controller.request.env['warden'].set_user(current_user) rescue nil) }
159
- else
160
- (controller.request.env['warden'].set_user(current_user) rescue nil)
161
- end
97
+ if current_user.present?
98
+ assigned = current_user.roles.map { |role| assignable[role] }.flatten.compact
99
+ end
162
100
 
163
- raise ActiveRecord::Rollback
101
+ if assignable[:new_record] && resource.new_record?
102
+ assigned += Array(assignable[:new_record])
164
103
  end
165
- end
166
104
 
167
- controller.instance_variable_set(:@current_ability, current_ability)
168
- controller.instance_variable_set(:@current_user, current_user)
169
- controller.current_user.roles = current_user_roles
105
+ if assignable[:persisted] && resource.persisted?
106
+ assigned += Array(assignable[:persisted])
107
+ end
170
108
 
171
- level
172
- end
109
+ assigned
110
+ elsif config.assignable_roles.kind_of?(Array)
111
+ config.assignable_roles
112
+ end.uniq
173
113
 
174
- private
114
+ # Check boxes
115
+ multiple = resource.acts_as_role_restricted_options[:multiple] if multiple.nil?
116
+ return assigned_roles if multiple
175
117
 
176
- def self.role_description(role, obj = nil)
177
- raise 'EffectiveRoles config.role_descriptions must be a Hash' unless role_descriptions.kind_of?(Hash)
178
- (role_descriptions[obj.try(:class).to_s] || {})[role] || role_descriptions[role] || ''
118
+ # Radios
119
+ (resource.roles - assigned_roles).present? ? [] : assigned_roles
179
120
  end
180
121
 
181
- def self._authorization_level(controller, role, resource, auth_method)
182
- resource = (resource.new() rescue resource) if resource.kind_of?(ActiveRecord::Base)
183
-
184
- # Custom actions
185
- if resource.kind_of?(Hash)
186
- resource.each do |key, value|
187
- return (controller.instance_exec(controller, key, value, &auth_method) rescue false) ? :yes : :no
188
- end
189
- end
190
-
191
- # Check for Manage
192
- return :manage if (
193
- (controller.instance_exec(controller, :create, resource, &auth_method) rescue false) &&
194
- (controller.instance_exec(controller, :update, resource, &auth_method) rescue false) &&
195
- (controller.instance_exec(controller, :show, resource, &auth_method) rescue false) &&
196
- (controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
197
- )
198
-
199
- # Check for Update
200
- return :update if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
201
-
202
- # Check for Update Own
203
- if resource.respond_to?('user=')
204
- resource.user = controller.current_user
205
- return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
206
- resource.user = nil
207
- elsif resource.respond_to?('user_id=')
208
- resource.user_id = controller.current_user.id
209
- return :update_own if (controller.instance_exec(controller, :update, resource, &auth_method) rescue false)
210
- resource.user_id = nil
211
- elsif resource.kind_of?(User)
212
- return :update_own if (controller.instance_exec(controller, :update, controller.current_user, &auth_method) rescue false)
213
- end
122
+ def self.assignable_roles_present?(resource)
123
+ return false unless config.assignable_roles.present?
214
124
 
215
- # Check for Create
216
- return :create if (controller.instance_exec(controller, :create, resource, &auth_method) rescue false)
125
+ raise 'EffectiveRoles config.assignable_roles_for must be a Hash or Array' unless [Hash, Array].include?(config.assignable_roles.class)
126
+ raise('expected resource to respond to is_role_restricted?') unless resource.respond_to?(:is_role_restricted?)
217
127
 
218
- # Check for Show
219
- return :show if (controller.instance_exec(controller, :show, resource, &auth_method) rescue false)
128
+ if config.assignable_roles.kind_of?(Array)
129
+ config.assignable_roles
130
+ elsif config.assignable_roles.key?(resource.class.to_s)
131
+ config.assignable_roles[resource.class.to_s]
132
+ else
133
+ config.assignable_roles
134
+ end.present?
135
+ end
220
136
 
221
- # Check for Index
222
- return :index if (controller.instance_exec(controller, :index, resource, &auth_method) rescue false)
137
+ private
223
138
 
224
- # Check for Destroy
225
- return :destroy if (controller.instance_exec(controller, :destroy, resource, &auth_method) rescue false)
139
+ def self.role_description(role, obj = nil)
140
+ raise 'EffectiveRoles config.role_descriptions must be a Hash' unless config.role_descriptions.kind_of?(Hash)
226
141
 
227
- :none
142
+ description = config.role_descriptions.dig(obj.class.to_s, role) if obj.present?
143
+ description ||= config.role_descriptions[role]
144
+ description || ''
228
145
  end
229
146
 
230
147
  end
@@ -2,27 +2,15 @@ module EffectiveRoles
2
2
  class Engine < ::Rails::Engine
3
3
  engine_name 'effective_roles'
4
4
 
5
- config.autoload_paths += Dir["#{config.root}/app/models/concerns", "#{config.root}/lib/"]
6
-
7
5
  # Include acts_as_addressable concern and allow any ActiveRecord object to call it
8
6
  initializer 'effective_roles.active_record' do |app|
9
7
  ActiveSupport.on_load :active_record do
10
- ActiveRecord::Base.extend(ActsAsRoleRestricted::ActiveRecord)
11
- end
12
- end
13
-
14
- # Register the log_page_views concern so that it can be called in ActionController or elsewhere
15
- initializer 'effective_logging.log_changes_action_controller' do |app|
16
- Rails.application.config.to_prepare do
17
- ActiveSupport.on_load :action_controller do
18
- require 'effective_roles/set_current_user'
19
- ActionController::Base.include(EffectiveRoles::SetCurrentUser::ActionController)
20
- end
8
+ ActiveRecord::Base.extend(ActsAsRoleRestricted::Base)
21
9
  end
22
10
  end
23
11
 
24
12
  # Set up our default configuration options.
25
- initializer "effective_roles.defaults", :before => :load_config_initializers do |app|
13
+ initializer "effective_roles.defaults", before: :load_config_initializers do |app|
26
14
  eval File.read("#{config.root}/config/effective_roles.rb")
27
15
  end
28
16
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveRoles
2
- VERSION = '2.0.1'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_roles
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-28 00:00:00.000000000 Z
11
+ date: 2021-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: effective_resources
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: Assign multiple roles to any User or other ActiveRecord object. Select
28
42
  only the appropriate objects based on intelligent, chainable ActiveRecord::Relation
29
43
  finder methods.
@@ -38,7 +52,6 @@ files:
38
52
  - app/controllers/admin/roles_controller.rb
39
53
  - app/helpers/effective_roles_helper.rb
40
54
  - app/models/concerns/acts_as_role_restricted.rb
41
- - app/models/effective/access_denied.rb
42
55
  - app/views/admin/roles/index.html.haml
43
56
  - app/views/effective/roles/_summary.html.haml
44
57
  - app/views/effective/roles/_summary_table.html.haml
@@ -46,14 +59,13 @@ files:
46
59
  - config/routes.rb
47
60
  - lib/effective_roles.rb
48
61
  - lib/effective_roles/engine.rb
49
- - lib/effective_roles/set_current_user.rb
50
62
  - lib/effective_roles/version.rb
51
63
  - lib/generators/effective_roles/install_generator.rb
52
64
  homepage: https://github.com/code-and-effect/effective_roles
53
65
  licenses:
54
66
  - MIT
55
67
  metadata: {}
56
- post_install_message:
68
+ post_install_message:
57
69
  rdoc_options: []
58
70
  require_paths:
59
71
  - lib
@@ -68,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
80
  - !ruby/object:Gem::Version
69
81
  version: '0'
70
82
  requirements: []
71
- rubygems_version: 3.0.3
72
- signing_key:
83
+ rubygems_version: 3.1.2
84
+ signing_key:
73
85
  specification_version: 4
74
86
  summary: Assign multiple roles to any User or other ActiveRecord object. Select only
75
87
  the appropriate objects based on intelligent, chainable ActiveRecord::Relation finder
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- module EffectiveRoles
2
- module SetCurrentUser
3
- module ActionController
4
-
5
- # Add me to your ApplicationController
6
- # before_action :set_effective_roles_current_user
7
-
8
- def set_effective_roles_current_user
9
- EffectiveRoles.current_user = current_user
10
- end
11
-
12
- end
13
- end
14
- end
15
-