def __convert_json(schema, param_in, message_prefix): if isinstance(param_in, string_types): try: param_in = json.loads(param_in) except (ValueError, TypeError): raise InvalidParameter( '{0} A JSON object was expected. ' 'Instead got "{1}" of type {2}.'.format( message_prefix, param_in, type(param_in).__name__)) if not isinstance(param_in, dict): raise InvalidParameter( '{0} A JSON object was expected. ' 'Instead got "{1}" of type {2}.'.format( message_prefix, param_in, type(param_in).__name__)) if 'properties' not in schema: return param_in ret = {} for param_name, param_value in param_in.items(): if param_name in schema['properties']: ret[param_name] = convert_json(schema['properties'][param_name], param_value, message_prefix) else: raise InvalidParameter('{0} Input has unknown parameter {1}'.format(message_prefix, param_name)) return ret
def validate_device_fields(device_fields_api, device_fields, device_type, app, validate_required=True): message_prefix = 'Device type {0} for app {1}'.format(device_type, app) for field_api in device_fields_api: if field_api['name'] not in device_fields and 'default' in field_api: device_fields[field_api['name']] = field_api['default'] required_in_api = {field['name'] for field in device_fields_api if 'required' in field and field['required']} field_names = set(device_fields) if validate_required and (required_in_api - field_names): message = '{0} requires {1} field but only got {2}'.format(message_prefix, list(required_in_api), list(field_names)) logger.error(message) raise InvalidParameter(message) device_fields_api_dict = {field['name']: field for field in device_fields_api} for field, value in device_fields.items(): if field in device_fields_api_dict: validate_device_field(device_fields_api_dict[field], value, message_prefix) else: message = '{0} was passed field {1} which is not defined in its API'.format(message_prefix, field['name']) logger.warning(message) raise InvalidParameter(message) return device_fields
def validate_primitive_parameter(value, param, parameter_type, message_prefix, hide_input=False): try: converted_value = convert_primitive_type(value, parameter_type) except (ValueError, TypeError): message = '{0} has invalid input. ' \ 'Input {1} could not be converted to type {2}'.format(message_prefix, value, parameter_type) logger.error(message) raise InvalidParameter(message) else: param = deepcopy(param) if param['type'] in ('user', 'role'): handle_user_roles_validation(param) if 'required' in param: param.pop('required') try: Draft4Validator( param, format_checker=draft4_format_checker).validate(converted_value) except ValidationError as exception: if not hide_input: message = '{0} has invalid input. ' \ 'Input {1} with type {2} does not conform to ' \ 'validators: {3}'.format(message_prefix, value, parameter_type, format_exception_message(exception)) else: message = '{0} has invalid input. {1} does not conform to ' \ 'validators: {2}'.format(message_prefix, parameter_type, format_exception_message(exception)) logger.error(message) raise InvalidParameter(message) return converted_value
def validate_parameters(api, parameters, message_prefix, accumulator=None): api_dict = {} for param in api: api_dict[param['name']] = param converted = {} seen_params = set() arg_names = [argument.name for argument in parameters] if parameters else [] arguments_set = set(arg_names) errors = [] for param_name, param_api in api_dict.items(): try: argument = get_argument_by_name(parameters, param_name) if argument: arg_val = argument.get_value(accumulator) if accumulator or not argument.is_ref: converted[param_name] = validate_parameter(arg_val, param_api, message_prefix) elif 'default' in param_api: try: default_param = validate_parameter(param_api['default'], param_api, message_prefix) except InvalidParameter as e: default_param = param_api['default'] logger.warning( 'For {0}: Default input {1} (value {2}) does not conform to schema. (Error: {3})' 'Using anyways'.format(message_prefix, param_name, param_api['default'], format_exception_message(e))) converted[param_name] = default_param arguments_set.add(param_name) elif 'required' in param_api: message = 'For {0}: Parameter {1} is not specified and has no default'.format(message_prefix, param_name) logger.error(message) raise InvalidParameter(message) else: converted[param_name] = None arguments_set.add(param_name) seen_params.add(param_name) except InvalidParameter as e: errors.append(e.message) if seen_params != arguments_set: message = 'For {0}: Too many arguments. Extra arguments: {1}'.format(message_prefix, arguments_set - seen_params) logger.error(message) errors.append(message) if errors: raise InvalidParameter('Invalid arguments', errors=errors) return converted
def validate_parameter(value, param, message_prefix): param = deepcopy(param) primitive_type = 'primitive' if 'type' in param else 'object' converted_value = None if value is not None: if primitive_type == 'primitive': primitive_type = param['type'] if primitive_type in TYPE_MAP: converted_value = validate_primitive_parameter(value, param, primitive_type, message_prefix) elif primitive_type == 'array': try: converted_value = convert_array(param, value, message_prefix) if 'items' in param and param['items']['type'] in ('user', 'role'): handle_user_roles_validation(param['items']) Draft4Validator( param, format_checker=draft4_format_checker).validate(converted_value) except ValidationError as exception: message = '{0} has invalid input. Input {1} does not conform to ' \ 'validators: {2}'.format(message_prefix, value, format_exception_message(exception)) logger.error(message) raise InvalidParameter(message) else: raise InvalidParameter('In {0}: Unknown parameter type {1}'.format(message_prefix, primitive_type)) else: try: converted_value = convert_json(param, value, message_prefix) Draft4Validator( param['schema'], format_checker=draft4_format_checker).validate(converted_value) except ValidationError as exception: message = '{0} has invalid input. Input {1} does not conform to ' \ 'validators: {2}'.format(message_prefix, value, format_exception_message(exception)) logger.error(message) raise InvalidParameter(message) elif param.get('required'): message = "In {0}: Missing {1} parameter '{2}'".format(message_prefix, primitive_type, param['name']) logger.error(message) raise InvalidParameter(message) return converted_value
def convert_array(schema, param_in, message_prefix): if 'items' not in schema: return param_in item_type = schema['items']['type'] if item_type in TYPE_MAP: try: return convert_primitive_array(param_in, item_type) except ValueError: items = str(param_in) items = items if len(items) < 30 else '{0}...]'.format(items[:30]) message = '{0} has invalid input. Input {1} could not be converted to array ' \ 'with type "object"'.format(message_prefix, items) logger.error(message) raise InvalidParameter(message) else: return [convert_json(schema['items'], param, message_prefix) for param in param_in]
def convert_json(spec, param_in, message_prefix): if 'type' in spec: parameter_type = spec['type'] if parameter_type in TYPE_MAP: try: return convert_primitive_type(param_in, parameter_type) except ValueError: message = ( '{0} has invalid input. ' 'Input {1} could not be converted to type {2}'.format(message_prefix, param_in, parameter_type)) logger.error(message) raise InvalidParameter(message) elif parameter_type == 'array': return convert_array(spec, param_in, message_prefix) elif parameter_type == 'object': return __convert_json(spec, param_in, message_prefix) else: raise InvalidApi('{0} has invalid api'.format(message_prefix)) elif 'schema' in spec: return convert_json(spec['schema'], param_in, message_prefix) else: raise InvalidApi('{0} has invalid api'.format(message_prefix))