"""JSON Draft3 Schema Validator Wrapper. A wrapper module for a JSON Draft3 Schema validator. JSON Draft3 Schema: https://tools.ietf.org/html/draft-zyp-json-schema-03. This wrapper module allows: - fail_fast=False: do not exit on first validation error. - validating any data dict against any JSON Draft 3 validation schema. - error response returns with body containing: | errors: { field_name1: error_message, field_name2: error_message } """ from oto import response from backend.constants import error from backend.constants import validation def raml_header_to_json_schema(raml_headers): """Take RAML specs for headers for an endpoint. Converts to JSON Draft 3 schema to use with our validator. NOTE: we have to filter out props with None as the value. Args: raml_headers (collections.OrderedDict): the headers part of a RAML endpoint descriptor. Returns: dict: the dict representing JSON validation schema snippet. """ properties = {} for item in raml_headers: _props = raml_headers[item] props = {} for prop in _props.__dict__: if _props.__dict__[prop] is not None: props[prop] = _props.__dict__[prop] properties[item] = props schema = { '$schema': 'http://json-schema.org/draft-03/schema', 'type': 'object', 'required': True, 'properties': properties } return schema def validate(data, validator): """Generic JSON Draft3 Schema Validation. Args: data (dict): the JSON to be validated. validator (Draft3Validator): the JSON Draft3 Schema to validate against Returns: Response: the response of the create operation. """ errors = {} sorted_errors = sorted(validator.iter_errors(data), key=str) for e in sorted_errors: if e.relative_path: errors[e.relative_path.pop()] = _get_error_message(e) elif e.absolute_schema_path: errors[e.absolute_schema_path.pop()] = _get_error_message(e) if len(errors) > 0: return response.create_error_response( code=error.VALIDATION_ERROR_CODE, message=errors, status=400) return response.Response(message={'status': 'ok'}, status=200) def _get_error_message(validation_error): """Get custom error message if exits. Custom error message store in request json in dict `errors` of each object's field. Dict store custom errors as validator(key) : custom error message(value) Args: validation_error: error from validator Returns: str: custom or default error message """ if validation.ERRORS in validation_error.schema.keys(): custom_error_message = validation_error.schema[validation.ERRORS] if validation_error.validator in custom_error_message.keys(): return custom_error_message[validation_error.validator] return validation_error.message