class Superintendent::Request::Validator
Constants
- DEFAULT_OPTIONS
- FORM_METHOD_ACTIONS
- JSON_API_CONTENT_TYPE
Public Class Methods
new(app, opts={})
click to toggle source
# File lib/superintendent/request/validator.rb, line 20 def initialize(app, opts={}) @app, @options = app, DEFAULT_OPTIONS.merge(opts) end
Public Instance Methods
call(env)
click to toggle source
# File lib/superintendent/request/validator.rb, line 24 def call(env) request = ActionDispatch::Request.new(env) # Only manage requests for the selected Mime Types and # FORM_METHOD_ACTIONS. if @options[:monitored_content_types].include?(request.content_type) && FORM_METHOD_ACTIONS.has_key?(request.request_method) request_data = request.request_parameters resource = requested_resource(request.path_info) begin forms = "#{resource}Form".constantize form = form_for_method(forms, request.request_method) rescue NameError => e return respond_404 # Return a 404 if no form was found. end errors = JSON::Validator.fully_validate( form, request_data, { errors_as_objects: true }) if ! errors.empty? return respond_400(serialize_errors(request.headers[Id::X_REQUEST_ID], errors)) end drop_extra_params!(form, request_data) unless request_data.blank? end @app.call(env) end
Private Instance Methods
adjust_errors(form_errors)
click to toggle source
Adjust the errors returned from the schema validator so they can be reused in the serialized error response.
# File lib/superintendent/request/validator.rb, line 70 def adjust_errors(form_errors) form_errors.each do |e| case e[:failed_attribute] when 'Required' e[:message].gsub!("The property '#/'", 'The request') end e[:message].gsub!("The property '#/", "The property '") e[:message] = e[:message][/.+?(?= in schema)/] end end
drop_extra_params!(form, data)
click to toggle source
Parameters that are not in the form are removed from the request so they never reach the controller.
# File lib/superintendent/request/validator.rb, line 58 def drop_extra_params!(form, data) form_data = form['properties']['data']['properties'] allowed_params = form_data['attributes']['properties'].keys rescue nil allowed_params.nil? ? nil : data['data']['attributes'].slice!(*allowed_params) end
form_for_method(forms, request_method)
click to toggle source
# File lib/superintendent/request/validator.rb, line 64 def form_for_method(forms, request_method) forms.send(FORM_METHOD_ACTIONS[request_method]).with_indifferent_access end
requested_resource(request_path)
click to toggle source
Determine the requested resource based on the requested endpoint
# File lib/superintendent/request/validator.rb, line 98 def requested_resource(request_path) parts = request_path.split('/') # if the last part is an ID, return the part before it, the resource. if (parts[-1]=~/(\d+|[A-Z]{2}[a-zA-Z0-9]{32})/) resource = parts[-2] else resource = parts[-1] end resource.singularize.classify end
respond_400(errors)
click to toggle source
# File lib/superintendent/request/validator.rb, line 109 def respond_400(errors) [400, {'Content-Type' => JSON_API_CONTENT_TYPE}, [errors]] end
respond_404()
click to toggle source
# File lib/superintendent/request/validator.rb, line 113 def respond_404 [404, {'Content-Type' => JSON_API_CONTENT_TYPE}, ['']] end
serialize_errors(request_id, form_errors)
click to toggle source
# File lib/superintendent/request/validator.rb, line 81 def serialize_errors(request_id, form_errors) form_errors = adjust_errors(form_errors) errors = [] form_errors.each do |e| error = { id: request_id, status: 400, code: e[:failed_attribute].underscore.dasherize, title: e[:failed_attribute], detail: e[:message] } errors << { attributes: error, type: 'errors' } end JSON.pretty_generate({errors: errors}) end