cancancan_resource_controller 0.0.1 → 1.0.1

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: a38bfb98462e336b34961d82c4d130022bf466971f55c11699e707b7e6ce4fff
4
- data.tar.gz: aa0be9ebb6885fc7b15156d0517f1df7c236c3da081a8cf01f6e5b3bf1b456ba
3
+ metadata.gz: eee99830d75b2311be4016ca35dce550688103ea8256a919b2c3f6230a3d8a22
4
+ data.tar.gz: c55c835c8ffd5350d45e246063fc3722e00a604138e9369ea93398c010de6819
5
5
  SHA512:
6
- metadata.gz: 565013e091449c0a17c33413b7c2c7be15bb660ec644cda55db34df9310cdb7a3b94a3639b256df1745390b1cebc976d121eae3efe39bfe85954f75ef6a4af55
7
- data.tar.gz: d7b727d66c11e8cf171e2eb6ba0f5175740b8be186ef0e463782e0a619951ccffca6f83fa4a50576d6ebf406629b77a840f74a5ad57b1344ea20fdce8eb3ddd9
6
+ metadata.gz: e4eecffac11d43c86bf6c1a65e45476c60b5927fd201940c0863b5aa1e489e7de2377b23f57f511d42fffda88f2f577dffc53c18e3ec9720f072b5603bab667d
7
+ data.tar.gz: c784109abe07fc8039d96d4eb023b96d72e74fec52af54e2161a127aed238f805a8523bf97dda293823b0d202541330267e6bde522b42651c4c3dbc5750272f2
@@ -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
@@ -189,7 +168,6 @@ module CanCanCan
189
168
  @resource ||= @resource_class.find(params[:id])
190
169
  authorize! :destroy, @resource
191
170
  # retuning the resource in a pre-destroyed state as a destroy response
192
- results = @resource
193
171
  if @resource.destroy
194
172
  respond_after_destroy
195
173
  else
@@ -237,7 +215,7 @@ module CanCanCan
237
215
  def respond_after_destroy
238
216
  respond_to do |format|
239
217
  format.html { redirect_to url_for(controller: controller_name, action: 'index') }
240
- format.json { render json: results, status: :no_content }
218
+ format.json { render json: @resource, status: :no_content }
241
219
  end
242
220
  end
243
221
 
@@ -246,36 +224,6 @@ module CanCanCan
246
224
  return resource_query
247
225
  end
248
226
 
249
- # can pass in custom method to supplant 'param.permit', like if you wanted to whitelist a hash instead of params.
250
- # ex: CanCanCanResourceController#deactivate_helper, permits on fake params: ActionController::Parameters.new(deactive_params)
251
- def resource_params resource_object = nil, opts = {}, &block
252
- local_action_name = opts[:custom_action_name] || action_name
253
- allowlist_permitted = get_nested_attributes_for_class(@resource_class, local_action_name.to_sym, resource_object)
254
-
255
- # # Rails kludge, issue with allowing parameters with empty arrays
256
- # # Needs to be nested, recursive
257
- # # Updating params in-place
258
- # params.each do |key, value|
259
- # if key.to_s =~ /(.*)_ids/ && (value == "remove" || value == ["remove"])
260
- # params[key] = []
261
- # end
262
- # end
263
-
264
- if block_given?
265
- params_with_only_allowed_parameters = yield(allowlist_permitted)
266
- else
267
- params_with_only_allowed_parameters = param_permit(allowlist_permitted)
268
- end
269
-
270
- # sanitize all input.
271
- sanitized_params_with_only_allowed_parameters = clean_parameter_data(params_with_only_allowed_parameters)
272
-
273
- # recast type (and have to re-permit)
274
- sanitized_params_with_only_allowed_parameters = ActionController::Parameters.new(sanitized_params_with_only_allowed_parameters).permit(allowlist_permitted)
275
-
276
- return sanitized_params_with_only_allowed_parameters
277
- end
278
-
279
227
  # recursive
280
228
  # src: https://apidock.com/rails/v5.2.3/ActionView/Helpers/SanitizeHelper/sanitize
281
229
  def clean_parameter_data param_value
@@ -312,86 +260,6 @@ module CanCanCan
312
260
  end
313
261
  end
314
262
 
315
- # Not checking instances of classes. What if they are object-state dependent?
316
- # Need to run them again, after object instantiation, but in a different method.
317
- def get_nested_attributes_for_class resource_class, action_name, root_level_object, depth = 0
318
- raise "invalid action class: #{action_name.class}" if !action_name.is_a?(Symbol)
319
- association_parameters = []
320
- if depth > MAX_ASSOCIATIVE_NESTED_DEPTH
321
- return association_parameters
322
- end
323
-
324
- # Handle resource_class attribs
325
- # issue here is the 'action_name' on the root 'resource_class' may not be the action that the user has for the 'assoc_class'
326
- # i.e:
327
- # We may want the user to update Account, and create attachments on it, but not 'update' attachments.
328
- if depth == 0
329
- association_parameters = current_ability.permitted_attributes(action_name, (root_level_object || resource_class))
330
- else
331
- association_parameters = current_ability.permitted_attributes(action_name, resource_class)
332
- end
333
-
334
- if resource_class.const_defined?('RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST') && !resource_class::RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST.nil?
335
- association_parameters &= resource_class::RESOURCE_CONTROLLER_ATTRIB_ALLOWLIST
336
- end
337
-
338
- # remove customized, non-params, assoc' attrib data by only allowing class columns
339
- association_parameters &= resource_class.column_names.collect(&:to_sym)
340
-
341
- resource_class.reflect_on_all_associations(:has_many).each do |assoc_class|
342
- resource_key = assoc_class.name
343
- # attrib_permission_key = (resource_key.to_s.singularize + '_ids').to_sym
344
- attrib_permission_key = IDS_ATTIB_PERMISSION_KEY_GEN.call(resource_key)
345
- # action_permission_key = ('_can_add_or_remove_association_' + resource_key.to_s).to_sym
346
- action_permission_key = IDS_ACTION_PERMISSION_KEY_GEN.call(resource_key)
347
- # i.e. can?(:can_participation_ids, Account)
348
- # Check to see if we manually gave the user a custom permission
349
- # # (i.e.: can [:update, :can_account_sector_ids], Account)
350
- # OR
351
- # see if it has the attribute on the class's allowed params
352
- if can?(action_permission_key, resource_class) || can?(action_name, resource_class, attrib_permission_key)
353
- association_parameters << {
354
- attrib_permission_key => []
355
- }
356
- end
357
- end
358
-
359
- resource_class.nested_attributes_options.each do |resource_key, options|
360
- reflection_class = resource_class.reflect_on_association(resource_key).class
361
- reflection_type = reflection_class.name
362
- assoc_class = resource_class.reflect_on_association(resource_key).klass
363
-
364
- if [
365
- "ActiveRecord::Reflection::BelongsToReflection",
366
- "ActiveRecord::Reflection::HasOneReflection",
367
- "ActiveRecord::Reflection::HasManyReflection"
368
- ].include?(reflection_type)
369
- parameter_key = NESTED_ATTIB_PERMISSION_KEY_GEN.call(resource_key)
370
- permission_key = NESTED_ACTION_PERMISSION_KEY_GEN.call(resource_key)
371
-
372
- # Can check if permission to update assoc is defined as an action OR as an attrib on the parent resource_class
373
- if can?(permission_key, resource_class) || can?(action_name, resource_class, parameter_key)
374
- # Handle recursion
375
- assoc_parameters = get_nested_attributes_for_class(assoc_class, action_name, root_level_object, depth + 1)
376
-
377
- if options[:allow_destroy] && can?(:destroy, resource_class)
378
- assoc_parameters << :_destroy
379
- end
380
-
381
- association_parameters << {
382
- parameter_key => assoc_parameters
383
- }
384
- end
385
- end
386
- end
387
-
388
- return association_parameters
389
- end
390
-
391
- def param_permit base_parameters
392
- params.permit(base_parameters)
393
- end
394
-
395
263
  def initialize_resource_class
396
264
  # First priority is the namespaced model, e.g. User::Group
397
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.1'
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.1
4
+ version: 1.0.1
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:
@@ -141,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
157
  - !ruby/object:Gem::Version
142
158
  version: '0'
143
159
  requirements: []
144
- rubygems_version: 3.3.7
160
+ rubygems_version: 3.4.15
145
161
  signing_key:
146
162
  specification_version: 4
147
163
  summary: A Rails Controller Module that uses CanCan's permitted attribs instead of