1from six.moves import urllib_parse as urlparse 2 3import jsonpointer 4 5from flex.exceptions import ( 6 ValidationError, 7) 8from flex.datastructures import ( 9 ValidationDict, 10) 11from flex.error_messages import MESSAGES 12from flex.constants import ( 13 OBJECT, 14 STRING, 15) 16from flex.decorators import ( 17 skip_if_not_of_type, 18) 19from flex.validation.common import ( 20 generate_object_validator, 21) 22 23reference_object_schema = { 24 'type': OBJECT, 25 'additionalProperties': False, 26 'required': [ 27 '$ref', 28 ], 29 'properties': { 30 '$ref': { 31 'type': STRING, 32 }, 33 }, 34} 35 36 37@skip_if_not_of_type(STRING) 38def validate_reference_pointer(reference, context, **kwargs): 39 parts = urlparse.urlparse(reference) 40 if any((parts.scheme, parts.netloc, parts.path, parts.params, parts.query)): 41 raise ValidationError( 42 MESSAGES['reference']['unsupported'].format(reference), 43 ) 44 45 try: 46 jsonpointer.resolve_pointer(context, parts.fragment) 47 except jsonpointer.JsonPointerException: 48 raise ValidationError( 49 MESSAGES['reference']['undefined'].format(reference), 50 ) 51 52 53non_field_validators = ValidationDict() 54non_field_validators.add_property_validator('$ref', validate_reference_pointer) 55 56reference_object_validator = generate_object_validator( 57 schema=reference_object_schema, 58 non_field_validators=non_field_validators, 59) 60