restful_json 3.4.2 → 4.0.0
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 +8 -8
- data/README.md +656 -453
- data/Rakefile +1 -1
- data/lib/restful_json.rb +0 -4
- data/lib/restful_json/config.rb +58 -14
- data/lib/restful_json/controller.rb +132 -67
- data/lib/restful_json/default_controller.rb +9 -1
- data/lib/restful_json/version.rb +1 -1
- metadata +2 -48
- data/lib/restful_json/base_controller.rb +0 -13
- data/lib/restful_json/railtie.rb +0 -19
- data/lib/twinturbo/application_permitter.rb +0 -93
- data/lib/twinturbo/controller.rb +0 -43
data/Rakefile
CHANGED
data/lib/restful_json.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
1
|
require 'restful_json/version'
|
2
2
|
require 'restful_json/config'
|
3
|
-
require 'twinturbo/application_permitter'
|
4
|
-
require 'twinturbo/controller'
|
5
|
-
require 'restful_json/base_controller'
|
6
3
|
require 'restful_json/controller'
|
7
4
|
require 'restful_json/default_controller'
|
8
|
-
require 'restful_json/railtie' if defined? ::Rails::Railtie
|
data/lib/restful_json/config.rb
CHANGED
@@ -9,6 +9,11 @@ module RestfulJson
|
|
9
9
|
:return_resource,
|
10
10
|
:render_enabled,
|
11
11
|
:use_permitters,
|
12
|
+
:action_to_permitter,
|
13
|
+
:allow_action_specific_params_methods,
|
14
|
+
:actions_that_authorize,
|
15
|
+
:actions_that_permit,
|
16
|
+
:actions_supporting_params_methods,
|
12
17
|
:avoid_respond_with,
|
13
18
|
:return_error_data,
|
14
19
|
:rescue_class,
|
@@ -23,37 +28,76 @@ module RestfulJson
|
|
23
28
|
end
|
24
29
|
|
25
30
|
RestfulJson.configure do
|
31
|
+
|
32
|
+
# default for :using in can_filter_by
|
26
33
|
self.can_filter_by_default_using = [:eq]
|
34
|
+
|
35
|
+
# to log debug info during request handling
|
27
36
|
self.debug = false
|
37
|
+
|
38
|
+
# delimiter for values in request parameter values
|
28
39
|
self.filter_split = ','.freeze
|
40
|
+
|
41
|
+
# equivalent to specifying respond_to :json, :html in the controller, and can be overriden in the controller. Note that by default responders gem sets respond_to :html in application_controller.rb.
|
29
42
|
self.formats = :json, :html
|
43
|
+
|
44
|
+
# default number of records to return if using the page request function
|
30
45
|
self.number_of_records_in_a_page = 15
|
46
|
+
|
47
|
+
# delimiter for ARel predicate in the request parameter name
|
31
48
|
self.predicate_prefix = '!'.freeze
|
49
|
+
|
50
|
+
# if true, will render resource and HTTP 201 for post/create or resource and HTTP 200 for put/update. ignored if render_enabled is false.
|
32
51
|
self.return_resource = false
|
52
|
+
|
53
|
+
# if false, controller actions will just set instance variable and return it instead of calling setting instance variable and then calling render/respond_with
|
33
54
|
self.render_enabled = true
|
55
|
+
|
56
|
+
# use Permitters
|
34
57
|
self.use_permitters = true
|
58
|
+
|
59
|
+
# instead of using Rails default respond_with, explicitly define render in respond_with block
|
35
60
|
self.avoid_respond_with = true
|
61
|
+
|
62
|
+
# use the permitter_class for create and update, if use_permitters = true
|
63
|
+
self.action_to_permitter = {create: nil, update: nil}
|
64
|
+
|
65
|
+
# the methods that call authorize! action_sym, @model_class
|
66
|
+
self.actions_that_authorize = [:create, :update]
|
67
|
+
|
68
|
+
# if not using permitters, will check respond_to?("(action)_(plural_or_singular_model_name)_params".to_sym) and if true will __send__(method)
|
69
|
+
self.allow_action_specific_params_methods = true
|
70
|
+
|
71
|
+
# if not using permitters, will check respond_to?("(singular_model_name)_params".to_sym) and if true will __send__(method)
|
72
|
+
self.actions_that_permit = [:create, :update]
|
73
|
+
|
74
|
+
# in error JSON, break out the exception info into fields for debugging
|
36
75
|
self.return_error_data = true
|
37
|
-
|
76
|
+
|
77
|
+
# the class that is rescued in each action method, but if nil will always reraise and not handle
|
38
78
|
self.rescue_class = StandardError
|
79
|
+
|
80
|
+
# will define order of errors handled and what status and/or i18n message key to use
|
39
81
|
self.rescue_handlers = []
|
40
|
-
|
41
|
-
#
|
82
|
+
|
83
|
+
# rescue_handlers are an ordered array of handlers to handle rescue of self.rescue_class or sub types.
|
84
|
+
# can use optional i18n_key for message, but will default to e.message if i18n_key not found.
|
85
|
+
|
86
|
+
# support 404 error for ActiveRecord::RecordNotFound if using ActiveRecord.
|
42
87
|
begin
|
43
88
|
require 'active_record/errors'
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
]
|
53
|
-
end
|
89
|
+
self.rescue_handlers << {exception_classes: [ActiveRecord::RecordNotFound], status: :not_found, i18n_key: 'api.not_found'.freeze}
|
90
|
+
rescue LoadError, NameError
|
91
|
+
end
|
92
|
+
|
93
|
+
# support 403 error for CanCan::AccessDenied if using CanCan
|
94
|
+
begin
|
95
|
+
require 'cancan/exceptions'
|
96
|
+
self.rescue_handlers << {exception_classes: [CanCan::AccessDenied], status: :forbidden, i18n_key: 'api.not_found'.freeze}
|
54
97
|
rescue LoadError, NameError
|
55
98
|
end
|
56
99
|
|
57
|
-
#
|
100
|
+
# support 500 error for everything else that is a self.rescue_class (in action)
|
58
101
|
self.rescue_handlers << {status: :internal_server_error, i18n_key: 'api.internal_server_error'.freeze}
|
102
|
+
|
59
103
|
end
|
@@ -16,8 +16,8 @@ module RestfulJson
|
|
16
16
|
module Controller
|
17
17
|
extend ::ActiveSupport::Concern
|
18
18
|
|
19
|
-
NILS = ['NULL'.freeze,'null'.freeze,'nil'.freeze]
|
20
|
-
SINGLE_VALUE_ACTIONS = [
|
19
|
+
NILS = ['NULL'.freeze, 'null'.freeze, 'nil'.freeze]
|
20
|
+
SINGLE_VALUE_ACTIONS = [:create, :update, :destroy, :show, :new, :edit]
|
21
21
|
|
22
22
|
included do
|
23
23
|
# this can be overriden in the controller via defining respond_to
|
@@ -113,7 +113,7 @@ module RestfulJson
|
|
113
113
|
# TODO: support custom actions to be automaticaly defined
|
114
114
|
args.each do |an_action|
|
115
115
|
if options[:is]
|
116
|
-
self.action_to_query[an_action.
|
116
|
+
self.action_to_query[an_action.to_sym] = options[:is]
|
117
117
|
else
|
118
118
|
raise "#{self.class.name} must supply an :is option with query_for #{an_action.inspect}"
|
119
119
|
end
|
@@ -132,7 +132,7 @@ module RestfulJson
|
|
132
132
|
self.ordered_by = (Array.wrap(self.ordered_by) + Array.wrap(args)).flatten.compact.collect {|item|item.is_a?(Hash) ? item : {item.to_sym => :asc}}
|
133
133
|
end
|
134
134
|
|
135
|
-
# Associate a non-standard ActiveModel
|
135
|
+
# Associate a non-standard ActiveModel::Serializer for one or more actions, e.g.
|
136
136
|
# serialize_action :index, with: FoosSerializer
|
137
137
|
# or
|
138
138
|
# serialize_action :index, :some_custom_action, with: FooSerializer
|
@@ -143,13 +143,27 @@ module RestfulJson
|
|
143
143
|
options = args.extract_options!
|
144
144
|
args.each do |an_action|
|
145
145
|
if options[:with]
|
146
|
-
self.action_to_serializer[an_action.
|
147
|
-
self.action_to_serializer_for[an_action.
|
146
|
+
self.action_to_serializer[an_action.to_sym] = options[:with]
|
147
|
+
self.action_to_serializer_for[an_action.to_sym] = options[:for] if options[:for]
|
148
148
|
else
|
149
149
|
raise "#{self.class.name} must supply an :with option with serialize_action #{an_action.inspect}"
|
150
150
|
end
|
151
151
|
end
|
152
152
|
end
|
153
|
+
|
154
|
+
# Use default or custom ActionController::Permitter with one or more actions, e.g.
|
155
|
+
# permit_action :create, :update # this does nothing because it uses permitter_class, e.g. FooPermitter for FoosController
|
156
|
+
# or:
|
157
|
+
# permit_action :index, :some_custom_action, with: FoosQueryPermitter
|
158
|
+
def permit_action(*args)
|
159
|
+
options = args.extract_options!
|
160
|
+
args.each do |an_action|
|
161
|
+
if options[:with]
|
162
|
+
# if key set to nil, it will use the permitter_class method during the action
|
163
|
+
self.action_to_permitter[an_action.to_sym] = options[:with]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
153
167
|
end
|
154
168
|
|
155
169
|
# In initialize we:
|
@@ -173,10 +187,12 @@ module RestfulJson
|
|
173
187
|
@model_at_plural_name_sym = "@#{@model_plural_name}".to_sym
|
174
188
|
@model_at_singular_name_sym = "@#{@model_singular_name}".to_sym
|
175
189
|
|
176
|
-
#
|
190
|
+
# default methods for strong parameters
|
191
|
+
@model_plural_name_params_sym = "#{@model_plural_name}_params".to_sym
|
177
192
|
@model_singular_name_params_sym = "#{@model_singular_name}_params".to_sym
|
178
|
-
|
179
|
-
@
|
193
|
+
|
194
|
+
@action_to_singular_action_model_params_method = {}
|
195
|
+
@action_to_plural_action_model_params_method = {}
|
180
196
|
|
181
197
|
underscored_modules_and_underscored_plural_model_name = qualified_controller_name.gsub('::','_').underscore
|
182
198
|
|
@@ -228,6 +244,62 @@ module RestfulJson
|
|
228
244
|
render_error(e, handling_data) unless @performed_render
|
229
245
|
end
|
230
246
|
|
247
|
+
# Finds model using provided info in params, prior to any permittance,
|
248
|
+
# via where()...first.
|
249
|
+
#
|
250
|
+
# Supports composite_keys.
|
251
|
+
def find_model_instance
|
252
|
+
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854.
|
253
|
+
# primary_key array support for composite_primary_keys.
|
254
|
+
if @model_class.primary_key.is_a? Array
|
255
|
+
c = @model_class
|
256
|
+
c.primary_key.each {|pkey|c.where(pkey.to_sym => params[pkey].to_s)}
|
257
|
+
@value = c.first
|
258
|
+
else
|
259
|
+
@value = @model_class.where(@model_class.primary_key.to_sym => params[@model_class.primary_key].to_s).first
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Finds model using provided info in params, prior to any permittance,
|
264
|
+
# via where()...first! with exception raise if does not exist.
|
265
|
+
#
|
266
|
+
# Supports composite_keys.
|
267
|
+
def find_model_instance!
|
268
|
+
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854.
|
269
|
+
# primary_key array support for composite_primary_keys.
|
270
|
+
if @model_class.primary_key.is_a? Array
|
271
|
+
c = @model_class
|
272
|
+
c.primary_key.each {|pkey|c.where(pkey.to_sym => params[pkey].to_s)}
|
273
|
+
# raise exception if not found
|
274
|
+
@value = c.first!
|
275
|
+
else
|
276
|
+
@value = @model_class.where(@model_class.primary_key.to_sym => params[@model_class.primary_key].to_s).first! # raise exception if not found
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def allowed_params
|
281
|
+
action_sym = params[:action].to_sym
|
282
|
+
singular = single_value_response?
|
283
|
+
action_specific_params_method = singular ? (@action_to_singular_action_model_params_method[action_sym] ||= "#{action_sym}_#{@model_singular_name}_params".to_sym) : (@action_to_plural_action_model_params_method[action_sym] ||= "#{action_sym}_#{@model_plural_name}_params".to_sym)
|
284
|
+
model_name_params_method = singular ? @model_singular_name_params_sym : @model_plural_name_params_sym
|
285
|
+
|
286
|
+
if self.actions_that_authorize.include?(action_sym)
|
287
|
+
authorize! action_sym, @model_class
|
288
|
+
end
|
289
|
+
|
290
|
+
if self.actions_that_permit.include?(action_sym)
|
291
|
+
if self.use_permitters
|
292
|
+
return permitted_params_using(self.action_to_permitter[action_sym] || permitter_class)
|
293
|
+
elsif self.allow_action_specific_params_methods && respond_to?(action_specific_params_method)
|
294
|
+
return __send__(action_specific_params_method)
|
295
|
+
elsif self.actions_supporting_params_methods.include?(action_sym) && respond_to?(model_name_params_method)
|
296
|
+
return __send__(model_name_params_method)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
params
|
301
|
+
end
|
302
|
+
|
231
303
|
# Renders error using handling data options (where options are probably hash from self.rescue_handlers that was matched).
|
232
304
|
#
|
233
305
|
# If include_error_data? is true, it returns something like the following (with the appropriate HTTP status code via setting appropriate status in respond_do:
|
@@ -271,8 +343,8 @@ module RestfulJson
|
|
271
343
|
respond_with(@value) do |format|
|
272
344
|
format.json do
|
273
345
|
# define local variables in blocks, not outside of them, to be safe, even though would work in this case
|
274
|
-
custom_action_serializer = self.action_to_serializer[params[:action].
|
275
|
-
custom_action_serializer_for = self.action_to_serializer_for[params[:action].
|
346
|
+
custom_action_serializer = self.action_to_serializer[params[:action].to_sym]
|
347
|
+
custom_action_serializer_for = self.action_to_serializer_for[params[:action].to_sym]
|
276
348
|
serialization_key = single_value_response? ? (custom_action_serializer_for == :each ? :each_serializer : :serializer) : (custom_action_serializer_for == :array ? :serializer : :each_serializer)
|
277
349
|
if !@value.respond_to?(:errors) || @value.errors.empty?
|
278
350
|
render custom_action_serializer ? {json: @value, status: success_code, serialization_key => custom_action_serializer} : {json: @value, status: success_code}
|
@@ -283,10 +355,10 @@ module RestfulJson
|
|
283
355
|
end
|
284
356
|
else
|
285
357
|
# code duplicated from above because local vars don't always traverse well into block (based on wierd ruby-proc bug experienced)
|
286
|
-
custom_action_serializer = self.action_to_serializer[params[:action].
|
287
|
-
custom_action_serializer_for = self.action_to_serializer_for[params[:action].
|
358
|
+
custom_action_serializer = self.action_to_serializer[params[:action].to_sym]
|
359
|
+
custom_action_serializer_for = self.action_to_serializer_for[params[:action].to_sym]
|
288
360
|
serialization_key = single_value_response? ? (custom_action_serializer_for == :array ? :serializer : :each_serializer) : (custom_action_serializer_for == :each ? :each_serializer : :serializer)
|
289
|
-
respond_with @value, custom_action_serializer ? {(self.action_to_serializer_for[params[:action].
|
361
|
+
respond_with @value, custom_action_serializer ? {(self.action_to_serializer_for[params[:action].to_sym] == :each ? :each_serializer : :serializer) => custom_action_serializer} : {}
|
290
362
|
end
|
291
363
|
else
|
292
364
|
@value
|
@@ -294,7 +366,7 @@ module RestfulJson
|
|
294
366
|
end
|
295
367
|
|
296
368
|
def single_value_response?
|
297
|
-
SINGLE_VALUE_ACTIONS.include?(params[:action].
|
369
|
+
SINGLE_VALUE_ACTIONS.include?(params[:action].to_sym)
|
298
370
|
end
|
299
371
|
|
300
372
|
# The controller's index (list) method to list resources.
|
@@ -302,10 +374,11 @@ module RestfulJson
|
|
302
374
|
# Note: this method be alias_method'd by query_for, so it is more than just index.
|
303
375
|
def index
|
304
376
|
# could be index or another action if alias_method'd by query_for
|
305
|
-
logger.debug "#{params[:action]
|
377
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
378
|
+
p_params = allowed_params
|
306
379
|
t = @model_class.arel_table
|
307
380
|
value = @model_class.scoped # returns ActiveRecord::Relation equivalent to select with no where clause
|
308
|
-
custom_query = self.action_to_query[params[:action].
|
381
|
+
custom_query = self.action_to_query[params[:action].to_sym]
|
309
382
|
if custom_query
|
310
383
|
value = custom_query.call(t, value)
|
311
384
|
end
|
@@ -313,12 +386,12 @@ module RestfulJson
|
|
313
386
|
self.param_to_query.each do |param_name, param_query|
|
314
387
|
if params[param_name]
|
315
388
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
316
|
-
value = param_query.call(t, value,
|
389
|
+
value = param_query.call(t, value, p_params[param_name].to_s)
|
317
390
|
end
|
318
391
|
end
|
319
392
|
|
320
393
|
self.param_to_through.each do |param_name, through_array|
|
321
|
-
if
|
394
|
+
if p_params[param_name]
|
322
395
|
# build query
|
323
396
|
# e.g. SomeModel.scoped.joins({:assoc_name => {:sub_assoc => {:sub_sub_assoc => :sub_sub_sub_assoc}}).where(sub_sub_sub_assoc_model_table_name: {column_name: value})
|
324
397
|
last_model_class = @model_class
|
@@ -327,7 +400,7 @@ module RestfulJson
|
|
327
400
|
if association_or_attribute == through_array.last
|
328
401
|
# must convert param value to string before possibly using with ARel because of CVE-2013-1854, fixed in: 3.2.13 and 3.1.12
|
329
402
|
# https://groups.google.com/forum/?fromgroups=#!msg/rubyonrails-security/jgJ4cjjS8FE/BGbHRxnDRTIJ
|
330
|
-
value = value.joins(joins).where(last_model_class.table_name.to_sym => {association_or_attribute =>
|
403
|
+
value = value.joins(joins).where(last_model_class.table_name.to_sym => {association_or_attribute => p_params[param_name].to_s})
|
331
404
|
else
|
332
405
|
found_classes = last_model_class.reflections.collect {|association_name, reflection| reflection.class_name.constantize if association_name.to_sym == association_or_attribute}.compact
|
333
406
|
if found_classes.size > 0
|
@@ -350,7 +423,7 @@ module RestfulJson
|
|
350
423
|
self.param_to_attr_and_arel_predicate.keys.each do |param_name|
|
351
424
|
options = param_to_attr_and_arel_predicate[param_name][2]
|
352
425
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
353
|
-
param =
|
426
|
+
param = p_params[param_name].to_s || options[:with_default]
|
354
427
|
|
355
428
|
if param.present? && param_to_attr_and_arel_predicate[param_name]
|
356
429
|
attr_sym = param_to_attr_and_arel_predicate[param_name][0]
|
@@ -364,42 +437,42 @@ module RestfulJson
|
|
364
437
|
end
|
365
438
|
end
|
366
439
|
|
367
|
-
if
|
368
|
-
page =
|
440
|
+
if p_params[:page] && self.supported_functions.include?(:page)
|
441
|
+
page = p_params[:page].to_i
|
369
442
|
page = 1 if page < 1 # to avoid people using this as a way to get all records unpaged, as that probably isn't the intent?
|
370
443
|
#TODO: to_s is hack to avoid it becoming an Arel::SelectManager for some reason which not sure what to do with
|
371
444
|
value = value.skip((self.number_of_records_in_a_page * (page - 1)).to_s)
|
372
445
|
value = value.take((self.number_of_records_in_a_page).to_s)
|
373
446
|
end
|
374
447
|
|
375
|
-
if
|
448
|
+
if p_params[:skip] && self.supported_functions.include?(:skip)
|
376
449
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
377
|
-
value = value.skip(
|
450
|
+
value = value.skip(p_params[:skip].to_s)
|
378
451
|
end
|
379
452
|
|
380
|
-
if
|
453
|
+
if p_params[:take] && self.supported_functions.include?(:take)
|
381
454
|
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
382
|
-
value = value.take(
|
455
|
+
value = value.take(p_params[:take].to_s)
|
383
456
|
end
|
384
457
|
|
385
|
-
if
|
458
|
+
if p_params[:uniq] && self.supported_functions.include?(:uniq)
|
386
459
|
value = value.uniq
|
387
460
|
end
|
388
461
|
|
389
462
|
# these must happen at the end and are independent
|
390
|
-
if
|
463
|
+
if p_params[:count] && self.supported_functions.include?(:count)
|
391
464
|
value = value.count.to_i
|
392
|
-
elsif
|
465
|
+
elsif p_params[:page_count] && self.supported_functions.include?(:page_count)
|
393
466
|
count_value = value.count.to_i # this executes the query so nothing else can be done in AREL
|
394
467
|
value = (count_value / self.number_of_records_in_a_page) + (count_value % self.number_of_records_in_a_page ? 1 : 0)
|
395
468
|
else
|
469
|
+
#TODO: also declaratively specify order via order=attr1,attr2, etc. like can_filter_by w/queries, subattrs, and direction.
|
396
470
|
self.ordered_by.each do |attr_to_direction|
|
397
471
|
# this looks nasty, but makes no sense to iterate keys if only single of each
|
398
472
|
value = value.order(t[attr_to_direction.keys[0]].send(attr_to_direction.values[0]))
|
399
473
|
end
|
400
474
|
value = value.to_a
|
401
|
-
end
|
402
|
-
|
475
|
+
end
|
403
476
|
@value = value
|
404
477
|
instance_variable_set(@model_at_plural_name_sym, @value)
|
405
478
|
render_or_respond(true)
|
@@ -409,9 +482,11 @@ module RestfulJson
|
|
409
482
|
|
410
483
|
# The controller's show (get) method to return a resource.
|
411
484
|
def show
|
412
|
-
logger.debug "#{params[:action]
|
413
|
-
|
414
|
-
|
485
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
486
|
+
@value = find_model_instance!
|
487
|
+
# allowed_params used primarily for authorization. can't do this to get id param(s) because those are sent via route, not
|
488
|
+
# in wrapped params (if wrapped)
|
489
|
+
allowed_params
|
415
490
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
416
491
|
render_or_respond(true, @value.nil? ? :not_found : :ok)
|
417
492
|
rescue self.rescue_class => e
|
@@ -420,7 +495,10 @@ module RestfulJson
|
|
420
495
|
|
421
496
|
# The controller's new method (e.g. used for new record in html format).
|
422
497
|
def new
|
423
|
-
logger.debug "#{params[:action]
|
498
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
499
|
+
# allowed_params used primarily for authorization. can't do this to get id param(s) because those are sent via route, not
|
500
|
+
# in wrapped params (if wrapped)
|
501
|
+
allowed_params
|
424
502
|
@value = @model_class.new
|
425
503
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
426
504
|
render_or_respond(true)
|
@@ -430,9 +508,11 @@ module RestfulJson
|
|
430
508
|
|
431
509
|
# The controller's edit method (e.g. used for edit record in html format).
|
432
510
|
def edit
|
433
|
-
logger.debug "#{params[:action]
|
434
|
-
|
435
|
-
|
511
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
512
|
+
@value = find_model_instance!
|
513
|
+
# allowed_params used primarily for authorization. can't do this to get id param(s) because those are sent via route, not
|
514
|
+
# in wrapped params (if wrapped)
|
515
|
+
allowed_params
|
436
516
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
437
517
|
@value
|
438
518
|
rescue self.rescue_class => e
|
@@ -441,17 +521,7 @@ module RestfulJson
|
|
441
521
|
|
442
522
|
# The controller's create (post) method to create a resource.
|
443
523
|
def create
|
444
|
-
logger.debug "#{params[:action]
|
445
|
-
if self.use_permitters
|
446
|
-
authorize! :create, @model_class
|
447
|
-
allowed_params = permitted_params
|
448
|
-
elsif respond_to? @create_model_singular_name_params_sym
|
449
|
-
allowed_params = send(@create_model_singular_name_params_sym)
|
450
|
-
elsif respond_to? @model_singular_name_params_sym
|
451
|
-
allowed_params = send(@model_singular_name_params_sym)
|
452
|
-
else
|
453
|
-
allowed_params = params
|
454
|
-
end
|
524
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
455
525
|
@value = @model_class.new(allowed_params)
|
456
526
|
@value.save
|
457
527
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
@@ -462,20 +532,12 @@ module RestfulJson
|
|
462
532
|
|
463
533
|
# The controller's update (put) method to update a resource.
|
464
534
|
def update
|
465
|
-
logger.debug "#{params[:action]
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
elsif respond_to? @model_singular_name_params_sym
|
472
|
-
allowed_params = send(@model_singular_name_params_sym)
|
473
|
-
else
|
474
|
-
allowed_params = params
|
475
|
-
end
|
476
|
-
# to_s as safety measure for vulnerabilities similar to CVE-2013-1854
|
477
|
-
@value = @model_class.where(id: params[:id].to_s).first # don't raise exception
|
478
|
-
@value.update_attributes(allowed_params) unless @value.nil?
|
535
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
536
|
+
@value = find_model_instance!
|
537
|
+
# allowed_params used primarily for authorization. can't do this to get id param(s) because those are sent via route, not
|
538
|
+
# in wrapped params (if wrapped)
|
539
|
+
p_params = allowed_params
|
540
|
+
@value.update_attributes(p_params) unless @value.nil?
|
479
541
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
480
542
|
render_or_respond(true, @value.nil? ? :not_found : :ok)
|
481
543
|
rescue self.rescue_class => e
|
@@ -484,9 +546,12 @@ module RestfulJson
|
|
484
546
|
|
485
547
|
# The controller's destroy (delete) method to destroy a resource.
|
486
548
|
def destroy
|
487
|
-
logger.debug "#{params[:action]
|
488
|
-
#
|
489
|
-
@value =
|
549
|
+
logger.debug "#{params[:action]} called in #{self.class}: model=#{@model_class}, request.format=#{request.format}, request.content_type=#{request.content_type}, params=#{params.inspect}" if self.debug
|
550
|
+
# don't raise error- DELETE should be idempotent per REST.
|
551
|
+
@value = find_model_instance
|
552
|
+
# allowed_params used primarily for authorization. can't do this to get id param(s) because those are sent via route, not
|
553
|
+
# in wrapped params (if wrapped)
|
554
|
+
p_params = allowed_params
|
490
555
|
@value.destroy if @value
|
491
556
|
instance_variable_set(@model_at_singular_name_sym, @value)
|
492
557
|
if !@value.respond_to?(:errors) || @value.errors.empty? || (request.format != 'text/html' && request.content_type != 'text/html')
|