effective_roles 2.0.1 → 2.1.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.
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
-