cancancan_resource_controller 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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