cancancan_resource_controller 0.0.2 → 1.0.2
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 +4 -4
- data/lib/cancancan/abstract_resource_controller.rb +18 -149
- data/lib/cancancan/configuration.rb +10 -0
- data/lib/cancancan/version.rb +5 -0
- data/lib/cancancan_resource_controller.rb +24 -1
- metadata +17 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d65b84894faeb3238628a9b7171979e7b6e472aaac77c0a6012e03393560a38b
|
4
|
+
data.tar.gz: 610df250cf0731176e364771e64e0fbc5e0c661e143d26060a7b580472811fd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2be5a3c7cbcdf9589435a6b2b57da0c5fde6454768441528da2a2e1ddaa80526aaf668a68ceee8b3c5f311dec7da16bf6c2445e831bad7fab4165faa2a93a656
|
7
|
+
data.tar.gz: 80caf64d6786139549aca8617c2fb4e8f194589877b477d5f67ecc947c40e47ff6768afce7cd3722af8b063432cb4e71478502fa32a1c2fb60bfd1df4b5da47a
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cancancan_nested_assignment_and_authorization'
|
1
2
|
# How to utilize CanCan Permissions to work with this controller:
|
2
3
|
module CanCanCan
|
3
4
|
module AbstractResourceController
|
@@ -11,14 +12,6 @@ module CanCanCan
|
|
11
12
|
MAX_ASSOCIATIVE_NESTED_DEPTH = 60
|
12
13
|
REGEX_FOR_HTML_TAG_DETECTION = /.*\<\/?[^_\W]+\>.*/
|
13
14
|
|
14
|
-
# to handle adding/removing associations by "_ids" suffix
|
15
|
-
IDS_ATTIB_PERMISSION_KEY_GEN = Proc.new { |assoc_key| "#{assoc_key.to_s.singularize}_ids".to_sym }
|
16
|
-
IDS_ACTION_PERMISSION_KEY_GEN = Proc.new { |assoc_key| "_can_add_or_remove_association_#{assoc_key.to_s}".to_sym }
|
17
|
-
|
18
|
-
# to handle updating nested attributes
|
19
|
-
NESTED_ATTIB_PERMISSION_KEY_GEN = Proc.new { |assoc_key| "#{assoc_key.to_s}_attributes".to_sym }
|
20
|
-
NESTED_ACTION_PERMISSION_KEY_GEN = Proc.new { |assoc_key| "_can_update_association_#{assoc_key.to_s}".to_sym }
|
21
|
-
|
22
15
|
# For Read-Only fields
|
23
16
|
# - define this on your class model
|
24
17
|
# optional allowlist for incoming parameters for the implemented resource
|
@@ -95,15 +88,13 @@ module CanCanCan
|
|
95
88
|
# Allow @resource to be set from subclass controller
|
96
89
|
@resource ||= @resource_class.find(params[:id])
|
97
90
|
authorize! :show, @resource
|
98
|
-
|
91
|
+
|
99
92
|
respond_with_resource
|
100
93
|
end
|
101
94
|
|
102
95
|
def new
|
103
96
|
authorize! :create, @resource_class
|
104
97
|
@resource ||= @resource_class.new(resource_params)
|
105
|
-
# 2nd auth on the object itself
|
106
|
-
# Not authing on the nested resources, that could have come in as nested attributes.
|
107
98
|
authorize! :create, @resource
|
108
99
|
|
109
100
|
respond_with_resource
|
@@ -125,17 +116,16 @@ module CanCanCan
|
|
125
116
|
|
126
117
|
def create
|
127
118
|
authorize! :create, @resource_class
|
128
|
-
|
119
|
+
@resource ||= @resource_class.new
|
129
120
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
authorize! :create, @resource
|
121
|
+
service = CanCanCan::AssignmentAndAuthorization.new(
|
122
|
+
current_ability,
|
123
|
+
action_name,
|
124
|
+
@resource,
|
125
|
+
clean_parameter_data(params)
|
126
|
+
)
|
137
127
|
|
138
|
-
if
|
128
|
+
if service.call
|
139
129
|
respond_with_resource
|
140
130
|
else
|
141
131
|
begin
|
@@ -152,25 +142,14 @@ module CanCanCan
|
|
152
142
|
def update
|
153
143
|
authorize! :update, @resource_class
|
154
144
|
@resource ||= @resource_class.find(params[:id])
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
raise ActiveRecord::Rollback
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
unless second_authorize
|
168
|
-
raise CanCan::AccessDenied.new("Not authorized!", action_name.to_sym, @resource)
|
169
|
-
end
|
170
|
-
|
171
|
-
# 2nd auth, on the updates of the object, without saving, so we can rollback without auth.
|
172
|
-
# authorize! :update, @resource
|
173
|
-
if @resource.save
|
145
|
+
service = CanCanCan::AssignmentAndAuthorization.new(
|
146
|
+
current_ability,
|
147
|
+
action_name,
|
148
|
+
@resource,
|
149
|
+
clean_parameter_data(params)
|
150
|
+
)
|
151
|
+
|
152
|
+
if service.call
|
174
153
|
respond_with_resource
|
175
154
|
else
|
176
155
|
begin
|
@@ -245,36 +224,6 @@ module CanCanCan
|
|
245
224
|
return resource_query
|
246
225
|
end
|
247
226
|
|
248
|
-
# can pass in custom method to supplant 'param.permit', like if you wanted to whitelist a hash instead of params.
|
249
|
-
# ex: CanCanCanResourceController#deactivate_helper, permits on fake params: ActionController::Parameters.new(deactive_params)
|
250
|
-
def resource_params resource_object = nil, opts = {}, &block
|
251
|
-
local_action_name = opts[:custom_action_name] || action_name
|
252
|
-
allowlist_permitted = get_nested_attributes_for_class(@resource_class, local_action_name.to_sym, resource_object)
|
253
|
-
|
254
|
-
# # Rails kludge, issue with allowing parameters with empty arrays
|
255
|
-
# # Needs to be nested, recursive
|
256
|
-
# # Updating params in-place
|
257
|
-
# params.each do |key, value|
|
258
|
-
# if key.to_s =~ /(.*)_ids/ && (value == "remove" || value == ["remove"])
|
259
|
-
# params[key] = []
|
260
|
-
# end
|
261
|
-
# end
|
262
|
-
|
263
|
-
if block_given?
|
264
|
-
params_with_only_allowed_parameters = yield(allowlist_permitted)
|
265
|
-
else
|
266
|
-
params_with_only_allowed_parameters = param_permit(allowlist_permitted)
|
267
|
-
end
|
268
|
-
|
269
|
-
# sanitize all input.
|
270
|
-
sanitized_params_with_only_allowed_parameters = clean_parameter_data(params_with_only_allowed_parameters)
|
271
|
-
|
272
|
-
# recast type (and have to re-permit)
|
273
|
-
sanitized_params_with_only_allowed_parameters = ActionController::Parameters.new(sanitized_params_with_only_allowed_parameters).permit(allowlist_permitted)
|
274
|
-
|
275
|
-
return sanitized_params_with_only_allowed_parameters
|
276
|
-
end
|
277
|
-
|
278
227
|
# recursive
|
279
228
|
# src: https://apidock.com/rails/v5.2.3/ActionView/Helpers/SanitizeHelper/sanitize
|
280
229
|
def clean_parameter_data param_value
|
@@ -311,86 +260,6 @@ module CanCanCan
|
|
311
260
|
end
|
312
261
|
end
|
313
262
|
|
314
|
-
# Not checking instances of classes. What if they are object-state dependent?
|
315
|
-
# Need to run them again, after object instantiation, but in a different method.
|
316
|
-
def get_nested_attributes_for_class resource_class, action_name, root_level_object, depth = 0
|
317
|
-
raise "invalid action class: #{action_name.class}" if !action_name.is_a?(Symbol)
|
318
|
-
association_parameters = []
|
319
|
-
if depth > MAX_ASSOCIATIVE_NESTED_DEPTH
|
320
|
-
return association_parameters
|
321
|
-
end
|
322
|
-
|
323
|
-
# Handle resource_class attribs
|
324
|
-
# issue here is the 'action_name' on the root 'resource_class' may not be the action that the user has for the 'assoc_class'
|
325
|
-
# i.e:
|
326
|
-
# We may want the user to update Account, and create attachments on it, but not 'update' attachments.
|
327
|
-
if depth == 0
|
328
|
-
association_parameters = current_ability.permitted_attributes(action_name, (root_level_object || resource_class))
|
329
|
-
else
|
330
|
-
association_parameters = current_ability.permitted_attributes(action_name, resource_class)
|
331
|
-
end
|
332
|
-
|
333
|
-
if resource_class.const_defined?('RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST') && !resource_class::RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST.nil?
|
334
|
-
association_parameters &= resource_class::RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST
|
335
|
-
end
|
336
|
-
|
337
|
-
# remove customized, non-params, assoc' attrib data by only allowing class columns
|
338
|
-
association_parameters &= resource_class.column_names.collect(&:to_sym)
|
339
|
-
|
340
|
-
resource_class.reflect_on_all_associations(:has_many).each do |assoc_class|
|
341
|
-
resource_key = assoc_class.name
|
342
|
-
# attrib_permission_key = (resource_key.to_s.singularize + '_ids').to_sym
|
343
|
-
attrib_permission_key = IDS_ATTIB_PERMISSION_KEY_GEN.call(resource_key)
|
344
|
-
# action_permission_key = ('_can_add_or_remove_association_' + resource_key.to_s).to_sym
|
345
|
-
action_permission_key = IDS_ACTION_PERMISSION_KEY_GEN.call(resource_key)
|
346
|
-
# i.e. can?(:can_participation_ids, Account)
|
347
|
-
# Check to see if we manually gave the user a custom permission
|
348
|
-
# # (i.e.: can [:update, :can_account_sector_ids], Account)
|
349
|
-
# OR
|
350
|
-
# see if it has the attribute on the class's allowed params
|
351
|
-
if can?(action_permission_key, resource_class) || can?(action_name, resource_class, attrib_permission_key)
|
352
|
-
association_parameters << {
|
353
|
-
attrib_permission_key => []
|
354
|
-
}
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
resource_class.nested_attributes_options.each do |resource_key, options|
|
359
|
-
reflection_class = resource_class.reflect_on_association(resource_key).class
|
360
|
-
reflection_type = reflection_class.name
|
361
|
-
assoc_class = resource_class.reflect_on_association(resource_key).klass
|
362
|
-
|
363
|
-
if [
|
364
|
-
"ActiveRecord::Reflection::BelongsToReflection",
|
365
|
-
"ActiveRecord::Reflection::HasOneReflection",
|
366
|
-
"ActiveRecord::Reflection::HasManyReflection"
|
367
|
-
].include?(reflection_type)
|
368
|
-
parameter_key = NESTED_ATTIB_PERMISSION_KEY_GEN.call(resource_key)
|
369
|
-
permission_key = NESTED_ACTION_PERMISSION_KEY_GEN.call(resource_key)
|
370
|
-
|
371
|
-
# Can check if permission to update assoc is defined as an action OR as an attrib on the parent resource_class
|
372
|
-
if can?(permission_key, resource_class) || can?(action_name, resource_class, parameter_key)
|
373
|
-
# Handle recursion
|
374
|
-
assoc_parameters = get_nested_attributes_for_class(assoc_class, action_name, root_level_object, depth + 1)
|
375
|
-
|
376
|
-
if options[:allow_destroy] && can?(:destroy, resource_class)
|
377
|
-
assoc_parameters << :_destroy
|
378
|
-
end
|
379
|
-
|
380
|
-
association_parameters << {
|
381
|
-
parameter_key => assoc_parameters
|
382
|
-
}
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
return association_parameters
|
388
|
-
end
|
389
|
-
|
390
|
-
def param_permit base_parameters
|
391
|
-
params.permit(base_parameters)
|
392
|
-
end
|
393
|
-
|
394
263
|
def initialize_resource_class
|
395
264
|
# First priority is the namespaced model, e.g. User::Group
|
396
265
|
@resource_class ||= begin
|
@@ -1,4 +1,27 @@
|
|
1
|
+
require_relative 'cancancan/configuration'
|
1
2
|
require_relative 'cancancan/abstract_resource_controller'
|
3
|
+
require_relative 'cancancan/version'
|
2
4
|
|
3
5
|
# include the extension
|
4
|
-
# ActiveRecord::Base.send(:include, Serializer::Concern)
|
6
|
+
# ActiveRecord::Base.send(:include, Serializer::Concern)
|
7
|
+
|
8
|
+
module CanCanCan
|
9
|
+
module AbstractResourceController
|
10
|
+
# config src: http://lizabinante.com/blog/creating-a-configurable-ruby-gem/
|
11
|
+
class << self
|
12
|
+
attr_accessor :configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configuration
|
16
|
+
@configuration ||= Configuration.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.reset
|
20
|
+
@configuration = Configuration.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.configure
|
24
|
+
yield(configuration)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cancancan_resource_controller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- benjamin.dana.software.dev@gmail.com
|
@@ -30,6 +30,20 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 3.5.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cancancan_nested_auth
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: rails
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,6 +135,8 @@ extensions: []
|
|
121
135
|
extra_rdoc_files: []
|
122
136
|
files:
|
123
137
|
- lib/cancancan/abstract_resource_controller.rb
|
138
|
+
- lib/cancancan/configuration.rb
|
139
|
+
- lib/cancancan/version.rb
|
124
140
|
- lib/cancancan_resource_controller.rb
|
125
141
|
homepage: https://github.com/danabr75/cancancan_resource_controller
|
126
142
|
licenses:
|