def linkFrom(validator, linkFrom, instance, schema): # avoid circular import from snovault import Item, TYPES, COLLECTIONS request = get_current_request() collections = request.registry[COLLECTIONS] linkType, linkProp = linkFrom.split('.') if validator.is_type(instance, "string"): base = collections[linkType] try: item = find_resource(base, instance.replace(':', '%3A')) if item is None: raise KeyError() except KeyError: error = "%r not found" % instance yield ValidationError(error) return if not isinstance(item, Item): error = "%r is not a linkable resource" % instance yield ValidationError(error) return if linkType not in set([item.type_info.name] + item.type_info.base_types): error = "%r is not of type %s" % (instance, repr(linkType)) yield ValidationError(error) return pass else: path = instance.get('@id') if validator._serialize: lv = len(validator._validated) if '@id' in instance: del instance['@id'] # treat the link property as not required # because it will be filled in when the child is created/updated subschema = request.registry[TYPES][linkType].schema subschema = copy.deepcopy(subschema) if linkProp in subschema['required']: subschema['required'].remove(linkProp) for error in validator.descend(instance, subschema): yield error if validator._serialize: validated_instance = validator._validated[lv] del validator._validated[lv:] if path is not None: item = find_resource(request.root, path.replace(':', '%3A')) validated_instance['uuid'] = str(item.uuid) elif 'uuid' in validated_instance: # where does this come from? del validated_instance['uuid'] validator._validated[-1] = validated_instance
def _get_user_info(user_data): """ get user info from user_data object :param user_data: user_data object from oauth service """ if not user_data: raise ValidationError('No user data provided') if not user_data.get('email') or not user_data.get('email').strip(): raise ValidationError('No e-mail provided') first_name, last_name = _get_first_and_last_names_from_name(user_data.get('name')) return { 'email': user_data['email'], 'first_name': user_data.get('given_name') or user_data.get('first_name') or first_name, 'last_name': user_data.get('family_name') or user_data.get('last_name') or last_name or user_data.get('email').split('@')[0], }
def additionalItems(validator, aI, instance, schema): if ( not validator.is_type(instance, "array") or validator.is_type(schema.get("items", {}), "object") ): return if validator._serialize: validated_instance = validator._validated[-1] if validator.is_type(aI, "object"): for index, item in enumerate(instance[len(schema.get("items", [])):]): if validator._serialize: lv = len(validator._validated) for error in validator.descend(item, aI, path=index): yield error if validator._serialize: validated_instance.append(validator._validated[lv]) del validator._validated[lv:] elif len(instance) > len(schema.get("items", [])): if not aI: error = "Additional items are not allowed (%s %s unexpected)" yield ValidationError( error % _utils.extras_msg(instance[len(schema.get("items", [])):]) ) elif validator._serialize: for item in instance[len(schema.get("items", [])):]: validated_instance.append(deepcopy(item))
def additionalProperties(validator, aP, instance, schema): if not validator.is_type(instance, "object"): return extras = list(_utils.find_additional_properties(instance, schema)) if not extras: return if validator._serialize: validated_instance = validator._validated[-1] if validator.is_type(aP, "object"): for extra in extras: if validator._serialize: lv = len(validator._validated) for error in validator.descend(instance[extra], aP, path=extra): yield error if validator._serialize: validated_instance[extra] = validator._validated[lv] del validator._validated[lv:] elif not aP: error = "Additional properties are not allowed (%s %s unexpected)" yield ValidationError(error % _utils.extras_msg(extras)) elif validator._serialize: for extra in extras: validated_instance[extra] = deepcopy(instance[extra])
def format(validator, format, instance, schema): if (validator.format_checker is not None and validator.is_type(instance, "string")): try: validator.format_checker.check(instance, format) except FormatError as error: yield ValidationError(error.message, cause=error.cause)
def signup(context, request): """ Create new user. :param request: Pyramid request object """ domain = 'encode.auth0.com' access_token = request.json.get('accessToken') if not access_token: raise HTTPBadRequest(explanation='Access token required') url = 'https://{domain}/userinfo?access_token={access_token}'.format(domain=domain, access_token=access_token) user_data_request = requests.get(url) if user_data_request.status_code != 200: raise HTTPBadRequest(explanation='Could not get user data') user_data = user_data_request.json() if user_data['email_verified'] is not True: raise HTTPBadRequest(explanation='Unverified email') user_info = _get_user_info(user_data) validate_request(context.type_info.schema, request, user_info) if request.errors: raise ValidationError(', '.join(request.errors)) result = collection_add(context, request, user_info) if not result or result['status'] != 'success': raise HTTPInternalServerError(explanation='attempt to create account was not successful') return HTTPCreated(explanation='User created')
def validators(validator, validators, instance, schema): if not validator.is_type(validators, "array"): raise Exception("Bad schema") # raise some sort of schema error for validator_name in validators: validate = VALIDATOR_REGISTRY.get(validator_name) if validate is None: raise Exception('Validator %s not found' % validator_name) error = validate(instance, schema) if error: yield ValidationError(error)
def oneOf_draft4(validator, oneOf, instance, schema): subschemas = enumerate(oneOf) all_errors = [] for index, subschema in subschemas: errs = list(validator.descend(instance, subschema, schema_path=index)) if not errs: first_valid = subschema break all_errors.extend(errs) else: yield ValidationError( "%r is not valid under any of the given schemas" % (instance, ), context=all_errors, ) more_valid = [s for i, s in subschemas if validator.is_valid(instance, s)] if more_valid: more_valid.append(first_valid) reprs = ", ".join(repr(schema) for schema in more_valid) yield ValidationError("%r is valid under each of %s" % (instance, reprs))
def anyOf_draft4(validator, anyOf, instance, schema): all_errors = [] for index, subschema in enumerate(anyOf): errs = list(validator.descend(instance, subschema, schema_path=index)) if not errs: break all_errors.extend(errs) else: yield ValidationError( "%r is not valid under any of the given schemas" % (instance, ), context=all_errors, )
def multipleOf(validator, dB, instance, schema): if not validator.is_type(instance, "number"): return if isinstance(dB, float): mod = instance % dB failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE else: failed = instance % dB if failed: yield ValidationError("%r is not a multiple of %r" % (instance, dB))
def properties_draft3(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return if validator._serialize: validated_instance = validator._validated[-1] for property, subschema in iteritems(properties): if property in instance: if validator._serialize: lv = len(validator._validated) for error in validator.descend( instance[property], subschema, path=property, schema_path=property, ): yield error if validator._serialize: validated_instance[property] = validator._validated[lv] del validator._validated[lv:] else: if validator._serialize: if "default" in subschema: validated_instance[property] = deepcopy(subschema["default"]) if "serverDefault" in subschema: default = validator.server_default(instance, subschema) if default is not NO_DEFAULT: validated_instance[property] = default if subschema.get("required", False): error = ValidationError("%r is a required property" % property) error._set( validator="required", validator_value=subschema["required"], instance=instance, schema=schema, ) error.path.appendleft(property) error.schema_path.extend([property, "required"]) yield error
def additionalProperties(validator, aP, instance, schema): if not validator.is_type(instance, "object"): return extras = set(_utils.find_additional_properties(instance, schema)) if validator.is_type(aP, "object"): for extra in extras: for error in validator.descend(instance[extra], aP, path=extra): yield error elif not aP and extras: error = "Additional properties are not allowed (%s %s unexpected)" yield ValidationError(error % _utils.extras_msg(extras))
def additionalItems(validator, aI, instance, schema): if (not validator.is_type(instance, "array") or validator.is_type(schema.get("items", {}), "object")): return if validator.is_type(aI, "object"): for index, item in enumerate(instance[len(schema.get("items", [])):]): for error in validator.descend(item, aI, path=index): yield error elif not aI and len(instance) > len(schema.get("items", [])): error = "Additional items are not allowed (%s %s unexpected)" yield ValidationError( error % _utils.extras_msg(instance[len(schema.get("items", [])):]))
def properties_draft3(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return for property, subschema in iteritems(properties): if property in instance: for error in validator.descend( instance[property], subschema, path=property, schema_path=property, ): yield error elif subschema.get("required", False): error = ValidationError("%r is a required property" % property) error._set( validator="required", validator_value=subschema["required"], instance=instance, schema=schema, ) error.path.appendleft(property) error.schema_path.extend([property, "required"]) yield error
def properties_draft3(validator, properties, instance, schema): if not validator.is_type(instance, "object"): return for property, subschema in iteritems(properties): if property in instance: for error in validator.descend( instance[property], subschema, path=property, schema_path=property, ): yield error elif subschema.get("required", False): error = ValidationError("%r is a required property" % property) error._set( validator="required", validator_value=subschema["required"], instance=instance, schema=schema, ) error.path.appendleft(property) error.schema_path.extend([property, "required"]) yield error
def maximum(validator, maximum, instance, schema): if not validator.is_type(instance, "number"): return instance = float(instance) if schema.get("exclusiveMaximum", False): failed = instance >= maximum cmp = "greater than or equal to" else: failed = instance > maximum cmp = "greater than" if failed: yield ValidationError("%r is %s the maximum of %r" % (instance, cmp, maximum))
def dependencies(validator, dependencies, instance, schema): if not validator.is_type(instance, "object"): return for property, dependency in iteritems(dependencies): if property not in instance: continue if validator.is_type(dependency, "object"): for error in validator.descend(instance, dependency, schema_path=property): yield error else: dependencies = _utils.ensure_list(dependency) for dependency in dependencies: if dependency not in instance: yield ValidationError("%r is a dependency of %r" % (dependency, property))
def type_draft3(validator, types, instance, schema): types = _utils.ensure_list(types) all_errors = [] for index, type in enumerate(types): if type == "any": return if validator.is_type(type, "object"): errors = list(validator.descend(instance, type, schema_path=index)) if not errors: return all_errors.extend(errors) elif validator.is_type(type, "string"): if validator.is_type(instance, type): return else: yield ValidationError( _utils.types_msg(instance, types), context=all_errors, )
def linkTo(validator, linkTo, instance, schema): # avoid circular import from snovault import Item, COLLECTIONS if not validator.is_type(instance, "string"): return request = get_current_request() collections = request.registry[COLLECTIONS] if validator.is_type(linkTo, "string"): base = collections.get(linkTo, request.root) linkTo = [linkTo] if linkTo else [] elif validator.is_type(linkTo, "array"): base = request.root else: raise Exception("Bad schema") # raise some sort of schema error try: item = find_resource(base, instance.replace(':', '%3A')) if item is None: raise KeyError() except KeyError: error = "%r not found" % instance yield ValidationError(error) return if not isinstance(item, Item): error = "%r is not a linkable resource" % instance yield ValidationError(error) return if linkTo and not set([item.type_info.name] + item.base_types).intersection(set(linkTo)): reprs = (repr(it) for it in linkTo) error = "%r is not of type %s" % (instance, ", ".join(reprs)) yield ValidationError(error) return linkEnum = schema.get('linkEnum') if linkEnum is not None: if not validator.is_type(linkEnum, "array"): raise Exception("Bad schema") if not any(UUID(enum_uuid) == item.uuid for enum_uuid in linkEnum): reprs = ', '.join(repr(it) for it in linkTo) error = "%r is not one of %s" % (instance, reprs) yield ValidationError(error) return if schema.get('linkSubmitsFor'): userid = None for principal in request.effective_principals: if principal.startswith('userid.'): userid = principal[len('userid.'):] break if userid is not None: user = request.root[userid] submits_for = user.upgrade_properties().get('submits_for') if (submits_for is not None and not any(UUID(uuid) == item.uuid for uuid in submits_for) and not request.has_permission('submit_for_any')): error = "%r is not in user submits_for" % instance yield ValidationError(error) return # And normalize the value to a uuid if validator._serialize: validator._validated[-1] = str(item.uuid)
def not_draft4(validator, not_schema, instance, schema): if validator.is_valid(instance, not_schema): yield ValidationError("%r is not allowed for %r" % (not_schema, instance))
def minItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) < mI: yield ValidationError("%r is too short" % (instance, ))
def maxItems(validator, mI, instance, schema): if validator.is_type(instance, "array") and len(instance) > mI: yield ValidationError("%r is too long" % (instance, ))
def maxProperties_draft4(validator, mP, instance, schema): if not validator.is_type(instance, "object"): return if validator.is_type(instance, "object") and len(instance) > mP: yield ValidationError("%r is too short" % (instance, ))
def required_draft4(validator, required, instance, schema): if not validator.is_type(instance, "object"): return for property in required: if property not in instance: yield ValidationError("%r is a required property" % property)
def pattern(validator, patrn, instance, schema): if (validator.is_type(instance, "string") and not re.search(patrn, instance)): yield ValidationError("%r does not match %r" % (instance, patrn))
def disallow_draft3(validator, disallow, instance, schema): for disallowed in _utils.ensure_list(disallow): if validator.is_valid(instance, {"type": [disallowed]}): yield ValidationError("%r is disallowed for %r" % (disallowed, instance))
def uniqueItems(validator, uI, instance, schema): if (uI and validator.is_type(instance, "array") and not _utils.uniq(instance)): yield ValidationError("%r has non-unique elements" % instance)
def enum(validator, enums, instance, schema): if instance not in enums: yield ValidationError("%r is not one of %r" % (instance, enums))
def type_draft4(validator, types, instance, schema): types = _utils.ensure_list(types) if not any(validator.is_type(instance, type) for type in types): yield ValidationError(_utils.types_msg(instance, types))
def maxLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) > mL: yield ValidationError("%r is too long" % (instance, ))
def minLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) < mL: yield ValidationError("%r is too short" % (instance, ))