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 +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +2 -8
- data/app/controllers/admin/roles_controller.rb +8 -3
- data/app/helpers/effective_roles_helper.rb +106 -2
- data/app/models/concerns/acts_as_role_restricted.rb +15 -14
- data/app/views/effective/roles/_summary_table.html.haml +2 -1
- data/config/effective_roles.rb +6 -29
- data/lib/effective_roles.rb +68 -151
- data/lib/effective_roles/engine.rb +2 -14
- data/lib/effective_roles/version.rb +1 -1
- metadata +20 -8
- data/app/models/effective/access_denied.rb +0 -17
- data/lib/effective_roles/set_current_user.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f392991013eeab38fcc7b6092c1014078fc2a356833bd5033b9a268987dc512
|
4
|
+
data.tar.gz: 38bb573be4e391b9cfd6141713bd89d29914e46148705588f1859642a5269bed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef6d332b9c6d93d8e28b61e856c93ec20e8c731b2fd02678fd1dcd8e52c2bcd12e1f5b68c891d82a265054065fe5694cc2bd59baa72ddaf2bb4553af28a93739
|
7
|
+
data.tar.gz: e7f10cde194b45115445a09bd99d0da254c81dd611c97cb9f1c25e8cd33181941449aaa20eb45b5b24d4bea0af8397720cf1156865ef0bf217b1798bf103225a
|
data/MIT-LICENSE
CHANGED
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
|
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
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_roles) }
|
4
5
|
|
5
|
-
|
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
|
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,
|
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
|
-
=
|
16
|
+
- level = effective_roles_authorization_level(controller, role, klass)
|
17
|
+
= effective_roles_authorization_badge(level)
|
data/config/effective_roles.rb
CHANGED
@@ -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 => []
|
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
|
-
#
|
96
|
-
config.layout = 'application'
|
73
|
+
# config.layout = 'admin'
|
97
74
|
end
|
data/lib/effective_roles.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
+
def self.config(namespace = nil)
|
12
|
+
@config ||= ActiveSupport::OrderedOptions.new
|
13
|
+
namespace ||= Tenant.current if defined?(Tenant)
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
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.
|
34
|
-
|
22
|
+
def self.setup(namespace = nil, &block)
|
23
|
+
yield(config(namespace))
|
35
24
|
end
|
36
25
|
|
37
|
-
|
38
|
-
|
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
|
-
|
38
|
+
Array(config.roles.find { |role| role == obj })
|
55
39
|
elsif obj.kind_of?(String)
|
56
|
-
|
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**
|
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
|
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
|
-
|
105
|
-
|
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
|
-
|
115
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
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
|
143
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
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
|
-
|
101
|
+
if assignable[:new_record] && resource.new_record?
|
102
|
+
assigned += Array(assignable[:new_record])
|
164
103
|
end
|
165
|
-
end
|
166
104
|
|
167
|
-
|
168
|
-
|
169
|
-
|
105
|
+
if assignable[:persisted] && resource.persisted?
|
106
|
+
assigned += Array(assignable[:persisted])
|
107
|
+
end
|
170
108
|
|
171
|
-
|
172
|
-
|
109
|
+
assigned
|
110
|
+
elsif config.assignable_roles.kind_of?(Array)
|
111
|
+
config.assignable_roles
|
112
|
+
end.uniq
|
173
113
|
|
174
|
-
|
114
|
+
# Check boxes
|
115
|
+
multiple = resource.acts_as_role_restricted_options[:multiple] if multiple.nil?
|
116
|
+
return assigned_roles if multiple
|
175
117
|
|
176
|
-
|
177
|
-
|
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.
|
182
|
-
|
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
|
-
|
216
|
-
|
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
|
-
|
219
|
-
|
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
|
-
|
222
|
-
return :index if (controller.instance_exec(controller, :index, resource, &auth_method) rescue false)
|
137
|
+
private
|
223
138
|
|
224
|
-
|
225
|
-
|
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
|
-
|
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::
|
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", :
|
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
|
|
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
|
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:
|
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.
|
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
|
-
|