module JSONAPI::Exceptions::UserDefinedExceptions
Checking for User Defined Exceptions
Allows a user of the gem to define extra requirements they want the middlewar to check for.
Public Class Methods
Performs compliance checks on the document to see if it complies
to the user defined requirements
@param document [Hash] The hash representation of the json body @param config_manager [JSONAPI::ConfigManager] The config_manager option to retreive user
requirements from
@return [NilClass | String] Nil or the String Error Message
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 43 def check_user_document_requirements(document, config_manager, opts) return if config_manager.nil? config = get_config(config_manager, opts[:http_method], opts[:path]) err = check_for_client_generated_id(document, config.allow_client_ids, opts[:http_method]) return if config.default? && config_manager.size.positive? if err.nil? err = check_for_required_document_members(document, config.required_document_members) end # To add more user requirement features, add more methods here JSONAPI::Exceptions::UserDefinedExceptions::InvalidDocument.new(err) unless err.nil? end
Performs compliance checks on the headers to see if it complies
to the user defined requirements
@param headers [Hash | JSONAPI::HeaderCollection] The collection of provided headers. Keys should be upper case strings
with underscores instead of dashes.
@param config (see check_user_document_requirements)
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 64 def check_user_header_requirements(headers, config_manager, opts) return if config_manager.nil? config = get_config(config_manager, opts[:http_method], opts[:path]) return if config.default? && config_manager.size.positive? err = check_for_required_headers(headers, config.required_headers) # To add more user requirement features, add more methods here JSONAPI::Exceptions::UserDefinedExceptions::InvalidHeader.new(err) unless err.nil? end
Performs compliance checks on the query params to see if it complies
to the user defined requirements
@param rack_req_params [Hash] The hash of the query parameters given by Rack::Request @param config (see check_user_document_requirements)
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 81 def check_user_query_param_requirements(rack_req_params, config_manager, opts) return if config_manager.nil? config = get_config(config_manager, opts[:http_method], opts[:path]) return if config.default? && config_manager.size.positive? err = check_for_required_params(rack_req_params, config.required_query_params) # To add more user requirement features, add more methods here JSONAPI::Exceptions::UserDefinedExceptions::InvalidQueryParam.new(err) unless err.nil? end
Private Class Methods
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 157 def both_are_hashes(first, second) first.is_a?(Hash) && second.is_a?(Hash) end
Checks if a resource id was included in the primary resource sent in a POST request @param document (see# check_required_document_members) @param allow_client_ids [TrueClass | FalseClass] Does the user allow client generated
ids
@param http_method [String] Does the document belong to a POST request
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 178 def check_for_client_generated_id(document, allow_client_ids, http_method) return unless http_method == 'POST' && !allow_client_ids return unless JSONAPI::Utility.all_hash_path?(document, %i[data id]) msg = 'Document MUST return 403 Forbidden in response to an unsupported request ' \ 'to create a resource with a client-generated ID.' [msg, 403] end
Checks to see whether the document conatians all the require members
See spec file for more examples. Ex: { data: [ { type: nil, attributes: { a1: nil, a2: nil } } ], meta: { m1: nil } }
@param document (see check_user_document_requirements) @param req_mems The hash representation of the user-defined required json members.
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 118 def check_for_required_document_members(document, req_mems) if reached_value_to_check?(document, req_mems) return check_values(document, req_mems) end err = check_structure(document, req_mems) return err unless err.nil? case req_mems when Hash req_mems.each do |k, v| err = check_for_required_document_members(document[k], v) return err unless err.nil? end when Array document.each do |m| err = check_for_required_document_members(m, req_mems.first) return err unless err.nil? end end nil end
Checks to makes sure the headers conatin the user defined required headers @param headers [Hash] The provided headers @param req_headers [Hash] The required headers
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 194 def check_for_required_headers(headers, req_headers) return if req_headers.nil? req_headers.each do |hdr| h_name = hdr.to_s.upcase.gsub(/-/, '_') unless headers[h_name] return ["Headers missing one of the user-defined required headers: #{h_name}"] end end nil end
Checks to make sure the query params contain the user defined required params
Rack Request Params Ex: { 'fields' => { 'articles' => 'title,body,author', 'people' => 'name' }, 'include' => 'author,comments-likers,comments.users', 'josh_ua' => 'demoss,simpson', 'page' => { 'offset' => '5', 'limit' => '20' }, 'filter' => { 'comments' => '(author/age > 21)', 'users' => '(age < 15)' }, 'sort' => 'age,title' } Required Params Hash Ex: { fields: { articles: nil }, include: nil page: nil }
@param rack_req_params [Hash] The Rack::Request.params hash @param required_params [Hash] The user defined required query params
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 228 def check_for_required_params(rack_req_params, required_params) return if required_params.nil? case required_params when Hash required_params.each do |k, v| return ["Query Params missing one of the user-defined required query params: #{k}"] unless rack_req_params[k.to_s] err = check_for_required_params(rack_req_params[k.to_s], v) return err unless err.nil? end when nil return else return ['The user-defined required query params hash must contain keys with values either hash or nil'] end nil end
Check if same class or if req_mems nil. If not it indicates the user has specified set
of required values for a given key. Check whether the current valueis within the set.
@param (see check_required_document_members) @return [NilClass | String] An error message if one found.
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 145 def check_structure(document, req_mems) if both_are_hashes(document, req_mems) doc_keys = document.keys req_keys = req_mems.keys return if doc_keys & req_keys == req_keys ["Document is missing user-defined required keys: #{req_keys - doc_keys}"] else return if document.instance_of?(req_mems.class) || req_mems.nil? ["User-defined required members hash does not mimic structure of json document: #{document}"] end end
Checks whether a value given is within the permitted values @param value_given [Any]
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 168 def check_values(value_given, permitted_values) return if permitted_values.nil? || (permitted_values.is_a?(Proc) && permitted_values.call(value_given)) ["The user-defined Proc found at #{permitted_values.source_location}, evaluated the given value, #{value_given}, to be non compliant."] end
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 246 def get_config(config_manager, http_method, path) if http_method res_type = JSONAPI::Utility.path_to_res_type(path) config_manager[res_type] || config_manager.global else config_manager.global end end
@return [TrueClass | FalseClass]
# File lib/easy/jsonapi/exceptions/user_defined_exceptions.rb, line 162 def reached_value_to_check?(document, req_mems) (req_mems.is_a?(Proc) || req_mems.nil?) && !document.is_a?(Hash) && !document.is_a?(Array) end