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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b99718f6d48907515dff8a39fd93995f044a4bb085ab7113efeea26e0273ad3
4
- data.tar.gz: 46c90e5bf82f050e4772018508e594d1ebaa8e04b33268b332c4c0ded334583d
3
+ metadata.gz: d65b84894faeb3238628a9b7171979e7b6e472aaac77c0a6012e03393560a38b
4
+ data.tar.gz: 610df250cf0731176e364771e64e0fbc5e0c661e143d26060a7b580472811fd8
5
5
  SHA512:
6
- metadata.gz: 4e19a473a79d8f349c304f820ee6678180d805cf3c565f6dc71fd779613e6d200563ba8192a17f8a1eac8e676df6346266f8937900f162183485dfe39b96e4ec
7
- data.tar.gz: 0c039d6dd0f6397f43a2661a38c2646a2e807105f8f85cd221c611b54c16bb5a739ddc4d2e1c706b25d8c3dc899dd5ae0453b1024328fea39f110602f02417cb
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
- # @resource = @resource_class.new(resource_params)
119
+ @resource ||= @resource_class.new
129
120
 
130
- # This 2nd @resource initiation is so we run run whitelisting attribs on the object.
131
- # Class whitelisting is far more broad than object attrib whitelisting.
132
- # Necessary if class permissions have a permissions-block.
133
- @resource ||= @resource_class.new(resource_params(@resource))
134
-
135
- # 2nd auth on the object itself
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 @resource.save
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
- authorize! :update, @resource
156
-
157
- second_authorize = false
158
- ActiveRecord::Base.transaction do
159
- @resource.assign_attributes(resource_params(@resource))
160
- second_authorize = can?(action_name.to_sym, @resource)
161
- unless second_authorize
162
- # NOTE: Does not halt the controller process, just rolls back the DB
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
@@ -0,0 +1,10 @@
1
+ module CanCanCan
2
+ module AbstractResourceController
3
+ class Configuration
4
+ # attr_accessor :silence_raised_errors, :use_smart_nested_authorizations
5
+
6
+ def initialize
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module CanCanCan
2
+ module AbstractResourceController
3
+ VERSION = '1.0.2'
4
+ end
5
+ end
@@ -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: 0.0.2
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: