def _validate_scalar_timestamp(self, timestamp_value, path): def _check_int_timestamp_boundaries(timestamp): if timestamp < 1: # Timestamp integers can't be negative self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Integer value of timestamp can't be below 0", path=path, value=timestamp, timestamp=str(timestamp), )) if timestamp > 2147483647: # Timestamp integers can't be above the upper limit of # 32 bit integers self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Integer value of timestamp can't be above 2147483647", path=path, value=timestamp, timestamp=str(timestamp), )) if isinstance(timestamp_value, int) or isinstance(timestamp_value, float): _check_int_timestamp_boundaries(timestamp_value) elif isinstance(timestamp_value, datetime): # Datetime objects currently have nothing to validate. # In the future, more options will be added to datetime validation pass elif isinstance(timestamp_value, basestring): v = timestamp_value.strip() # parse("") will give a valid date but it should not be # considered a valid timestamp if v == "": self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Timestamp value is empty. Path: '{path}'", path=path, value=nativestr(timestamp_value), timestamp=nativestr(timestamp_value))) else: # A string can contain a valid unit timestamp integer. Check if it is valid and validate it try: int_v = int(v) _check_int_timestamp_boundaries(int_v) except ValueError: # Just continue to parse it as a timestamp try: parse(timestamp_value) # If it can be parsed then it is valid except Exception: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Timestamp: '{timestamp}'' is invalid. Path: '{path}'", path=path, value=nativestr(timestamp_value), timestamp=nativestr(timestamp_value))) else: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Not a valid timestamp", path=path, value=timestamp_value, timestamp=timestamp_value, ))
def _validate_range(self, max_, min_, max_ex, min_ex, value, path, prefix): """ Validate that value is within range values. """ if not isinstance(value, int) and not isinstance(value, float): raise CoreError("Value must be a integer type") log.debug( u"Validate range : %s : %s : %s : %s : %s : %s", max_, min_, max_ex, min_ex, value, path, ) if max_ is not None: if max_ < value: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', greater than max limit '{max_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_=max_)) if min_ is not None: if min_ > value: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', less than min limit '{min_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_=min_)) if max_ex is not None: if max_ex <= value: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', greater than or equals to max limit(exclusive) '{max_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_ex=max_ex)) if min_ex is not None: if min_ex >= value: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', less than or equals to min limit(exclusive) '{min_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_ex=min_ex))
def _validate_range(self, max_, min_, max_ex, min_ex, errors, value, path, prefix): """ Validate that value is within range values. """ log.debug(u"Validate range : {} : {} : {} : {} : {} : {}".format( max_, min_, max_ex, min_ex, value, path, )) if max_ is not None: if max_ < value: errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', greater than max limit '{max_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_=max_)) if min_ is not None: if min_ > value: errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', less than min limit '{min_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_=min_)) if max_ex is not None: if max_ex <= value: errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', greater than or equals to max limit(exclusive) '{max_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_ex=max_ex)) if min_ex is not None: if min_ex >= value: errors.append( SchemaError.SchemaErrorEntry( msg= u"Type '{prefix}' has size of '{value}', less than or equals to min limit(exclusive) '{min_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_ex=min_ex))
def _validate_range(self, max_, min_, max_ex, min_ex, value, path, prefix): """ Validate that value is within range values. """ if not isinstance(value, int) and not isinstance(value, float): raise CoreError("Value must be a integer type") log.debug( u"Validate range : %s : %s : %s : %s : %s : %s", max_, min_, max_ex, min_ex, value, path, ) if max_ is not None: if max_ < value: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', greater than max limit '{max_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_=max_)) if min_ is not None: if min_ > value: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', less than min limit '{min_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_=min_)) if max_ex is not None: if max_ex <= value: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', greater than or equals to max limit(exclusive) '{max_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_ex=max_ex)) if min_ex is not None: if min_ex >= value: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', less than or equals to min limit(exclusive) '{min_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_ex=min_ex))
def _validate_range(self, max_, min_, max_ex, min_ex, errors, value, path, prefix): """ Validate that value is within range values. """ log.debug( u"Validate range : {} : {} : {} : {} : {} : {}".format( max_, min_, max_ex, min_ex, value, path, ) ) if max_ is not None: if max_ < value: errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', greater than max limit '{max_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_=max_)) if min_ is not None: if min_ > value: errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', less than min limit '{min_}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_=min_)) if max_ex is not None: if max_ex <= value: errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', greater than or equals to max limit(exclusive) '{max_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, max_ex=max_ex)) if min_ex is not None: if min_ex >= value: errors.append(SchemaError.SchemaErrorEntry( msg=u"Type '{prefix}' has size of '{value}', less than or equals to min limit(exclusive) '{min_ex}'. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, prefix=prefix, min_ex=min_ex))
def _validate_scalar_timestamp(self, timestamp_value, path): """ """ def _check_int_timestamp_boundaries(timestamp): """ """ if timestamp < 1: # Timestamp integers can't be negative self.errors.append( SchemaError.SchemaErrorEntry( msg=u"Integer value of timestamp can't be below 0", path=path, value=timestamp, timestamp=str(timestamp), )) if timestamp > 2147483647: # Timestamp integers can't be above the upper limit of # 32 bit integers self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Integer value of timestamp can't be above 2147483647", path=path, value=timestamp, timestamp=str(timestamp), )) if isinstance(timestamp_value, (int, float)): _check_int_timestamp_boundaries(timestamp_value) elif isinstance(timestamp_value, datetime.datetime): # Datetime objects currently have nothing to validate. # In the future, more options will be added to datetime validation pass elif isinstance(timestamp_value, basestring): v = timestamp_value.strip() # parse("") will give a valid date but it should not be # considered a valid timestamp if v == "": self.errors.append( SchemaError.SchemaErrorEntry( msg=u"Timestamp value is empty. Path: '{path}'", path=path, value=nativestr(timestamp_value), timestamp=nativestr(timestamp_value))) else: # A string can contain a valid unit timestamp integer. Check if it is valid and validate it try: int_v = int(v) _check_int_timestamp_boundaries(int_v) except ValueError: # Just continue to parse it as a timestamp try: parse(timestamp_value) # If it can be parsed then it is valid except Exception: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Timestamp: '{timestamp}'' is invalid. Path: '{path}'", path=path, value=nativestr(timestamp_value), timestamp=nativestr(timestamp_value))) else: self.errors.append( SchemaError.SchemaErrorEntry( msg=u"Not a valid timestamp", path=path, value=timestamp_value, timestamp=timestamp_value, ))
def _validate_scalar(self, value, rule, path, done=None): """ """ log.debug(u"Validate scalar") log.debug(u" Scalar : Value : %s", value) log.debug(u" Scalar : Rule : %s", rule) log.debug(u" Scalar : RuleType : %s", rule.type) log.debug(u" Scalar : Path %s", path) # Handle 'func' argument on this scalar self._handle_func(value, rule, path, done) if rule.assertion is not None: self._validate_assert(rule, value, path) if value is None: return True if rule.enum is not None and value not in rule.enum: self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Enum '{value}' does not exist. Path: '{path}' Enum: {enum_values}", path=path, value=nativestr(value) if tt['str'](value) else value, enum_values=rule.enum, )) # Set default value if rule.default and value is None: value = rule.default if not self._validate_scalar_type(value, rule.type, path): return if value is None: return if rule.pattern is not None: # # Try to trim away the surrounding slashes around ruby style /<regex>/ if they are defined. # This is a quirk from ruby that they define regex patterns with surrounding slashes. # Docs on how ruby regex works can be found here: https://ruby-doc.org/core-2.4.0/Regexp.html # The original ruby implementation uses this code to validate patterns # unless value.to_s =~ rule.regexp # Becuase python do not work with surrounding slashes we have to trim them away in order to make the regex work # if rule.pattern.startswith('/') and rule.pattern.endswith( '/') and self.fix_ruby_style_regex: rule.pattern = rule.pattern[1:-1] log.debug( "Trimming slashes around ruby style regex. New pattern value: '{0}'" .format(rule.pattern)) try: log.debug("Matching pattern '{0}' to regex '{1}".format( rule.pattern, value)) res = re.match(rule.pattern, value, re.UNICODE) except TypeError: res = None if res is None: # Not matching self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Value '{value}' does not match pattern '{pattern}'. Path: '{path}'", path=path, value=nativestr(str(value)), pattern=rule._pattern)) else: log.debug("Pattern matched...") if rule.range is not None: if not is_scalar(value): raise CoreError(u"value is not a valid scalar") r = rule.range try: v = len(value) value = v except Exception: pass self._validate_range( r.get("max"), r.get("min"), r.get("max-ex"), r.get("min-ex"), value, path, "scalar", ) if rule.length is not None: self._validate_length( rule.length, value, path, 'scalar', ) # Validate timestamp if rule.type == "timestamp": self._validate_scalar_timestamp(value, path) if rule.type == "date": if not is_scalar(value): raise CoreError(u'value is not a valid scalar') date_format = rule.format self._validate_scalar_date(value, date_format, path)
def _validate_scalar(self, value, rule, path, done=None): log.debug(u"Validate scalar") log.debug(u" # %s", value) log.debug(u" # %s", rule) log.debug(u" # %s", rule.type) log.debug(u" # %s", path) # Handle 'func' argument on this scalar self._handle_func(value, rule, path, done) if rule.enum is not None: if value not in rule.enum: self.errors.append( SchemaError.SchemaErrorEntry( msg=u"Enum '{value}' does not exist. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, )) # Set default value if rule.default and value is None: value = rule.default self._validate_scalar_type(value, rule.type, path) if value is None: return if rule.pattern is not None: res = re.match(rule.pattern, str(value)) if res is None: # Not matching self.errors.append( SchemaError.SchemaErrorEntry( msg= u"Value '{value}' does not match pattern '{pattern}'. Path: '{path}'", path=path, value=nativestr(str(value)), pattern=rule._pattern)) if rule.range is not None: if not is_scalar(value): raise CoreError(u"value is not a valid scalar") r = rule.range try: v = len(value) value = v except Exception: pass self._validate_range( r.get("max", None), r.get("min", None), r.get("max-ex", None), r.get("min-ex", None), value, path, "scalar", ) # Validate timestamp if rule.type == "timestamp": self._validate_scalar_timestamp(value, path)
def _validate_scalar(self, value, rule, path, done=None): log.debug(u"Validate scalar") log.debug(u" # %s", value) log.debug(u" # %s", rule) log.debug(u" # %s", rule.type) log.debug(u" # %s", path) # Handle 'func' argument on this scalar self._handle_func(value, rule, path, done) if rule.enum is not None: if value not in rule.enum: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Enum '{value}' does not exist. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, )) # Set default value if rule.default and value is None: value = rule.default self._validate_scalar_type(value, rule.type, path) if value is None: return if rule.pattern is not None: res = re.match(rule.pattern, value, re.UNICODE) if res is None: # Not matching self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Value '{value}' does not match pattern '{pattern}'. Path: '{path}'", path=path, value=nativestr(str(value)), pattern=rule._pattern)) if rule.range is not None: if not is_scalar(value): raise CoreError(u"value is not a valid scalar") r = rule.range try: v = len(value) value = v except Exception: pass self._validate_range( r.get("max", None), r.get("min", None), r.get("max-ex", None), r.get("min-ex", None), value, path, "scalar", ) # Validate timestamp if rule.type == "timestamp": self._validate_scalar_timestamp(value, path)
def _validate_scalar(self, value, rule, path, errors, done=None): log.debug(u"Validate scalar") log.debug(u" # {}".format(value)) log.debug(u" # {}".format(rule)) log.debug(u" # {}".format(rule._type)) log.debug(u" # {}".format(path)) # Handle 'func' argument on this scalar self._handle_func(value, rule, path, errors, done) if rule._enum is not None: if value not in rule._enum: errors.append(SchemaError.SchemaErrorEntry( msg=u"Enum '{value}' does not exist. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, )) # Set default value if rule._default and value is None: value = rule._default self._validate_scalar_type(value, rule._type, errors, path) if value is None: return if rule._pattern is not None: res = re.match(rule._pattern, str(value)) if res is None: # Not matching errors.append(SchemaError.SchemaErrorEntry( msg=u"Value '{value}' does not match pattern '{pattern}'. Path: '{path}'", path=path, value=nativestr(value), pattern=rule._pattern)) if rule._range is not None: if not is_scalar(value): raise CoreError(u"value is not a valid scalar") r = rule._range try: v = len(value) value = v except Exception: pass self._validate_range( r.get("max", None), r.get("min", None), r.get("max-ex", None), r.get("min-ex", None), errors, value, path, "scalar", ) # Validate timestamp if rule._type == "timestamp": v = value.strip() # parse("") will give a valid date but it should not be # considered a valid timestamp if v == "": errors.append(SchemaError.SchemaErrorEntry( msg=u"Timestamp value is empty. Path: '{path}'", path=path, value=nativestr(value), timestamp=nativestr(value))) else: try: parse(value) # If it can be parsed then it is valid except Exception: errors.append(SchemaError.SchemaErrorEntry( msg=u"Timestamp: '{timestamp}'' is invalid. Path: '{path}'", path=path, value=nativestr(value), timestamp=nativestr(value)))
def _validate_scalar(self, value, rule, path, errors, done=None): log.debug(u"Validate scalar") log.debug(u" # {}".format(value)) log.debug(u" # {}".format(rule)) log.debug(u" # {}".format(rule._type)) log.debug(u" # {}".format(path)) # Handle 'func' argument on this scalar self._handle_func(value, rule, path, errors, done) if rule._enum is not None: if value not in rule._enum: errors.append( SchemaError.SchemaErrorEntry( msg=u"Enum '{value}' does not exist. Path: '{path}'", path=path, value=nativestr(value) if tt['str'](value) else value, )) # Set default value if rule._default and value is None: value = rule._default self._validate_scalar_type(value, rule._type, errors, path) if value is None: return if rule._pattern is not None: res = re.match(rule._pattern, str(value)) if res is None: # Not matching errors.append( SchemaError.SchemaErrorEntry( msg= u"Value '{value}' does not match pattern '{pattern}'. Path: '{path}'", path=path, value=nativestr(value), pattern=rule._pattern)) if rule._range is not None: if not is_scalar(value): raise CoreError(u"value is not a valid scalar") r = rule._range try: v = len(value) value = v except Exception: pass self._validate_range( r.get("max", None), r.get("min", None), r.get("max-ex", None), r.get("min-ex", None), errors, value, path, "scalar", ) # Validate timestamp if rule._type == "timestamp": v = value.strip() # parse("") will give a valid date but it should not be # considered a valid timestamp if v == "": errors.append( SchemaError.SchemaErrorEntry( msg=u"Timestamp value is empty. Path: '{path}'", path=path, value=nativestr(value), timestamp=nativestr(value))) else: try: parse(value) # If it can be parsed then it is valid except Exception: errors.append( SchemaError.SchemaErrorEntry( msg= u"Timestamp: '{timestamp}'' is invalid. Path: '{path}'", path=path, value=nativestr(value), timestamp=nativestr(value)))