Editorial

This commit is contained in:
Roland Hedberg
2013-04-15 11:05:15 +02:00
parent e66e2cffdd
commit 68ab79f49d

View File

@@ -10,15 +10,19 @@ XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'
XSI_NIL = '{%s}nil' % XSI_NAMESPACE XSI_NIL = '{%s}nil' % XSI_NAMESPACE
# --------------------------------------------------------- # ---------------------------------------------------------
class NotValid(Exception): class NotValid(Exception):
pass pass
class OutsideCardinality(Exception): class OutsideCardinality(Exception):
pass pass
class MustValueError(ValueError): class MustValueError(ValueError):
pass pass
class ShouldValueError(ValueError): class ShouldValueError(ValueError):
pass pass
@@ -27,6 +31,7 @@ class ShouldValueError(ValueError):
NCNAME = re.compile("(?P<NCName>[a-zA-Z_](\w|[_.-])*)") NCNAME = re.compile("(?P<NCName>[a-zA-Z_](\w|[_.-])*)")
def valid_ncname(name): def valid_ncname(name):
match = NCNAME.match(name) match = NCNAME.match(name)
if not match: if not match:
@@ -83,6 +88,7 @@ def validate_on_or_after(not_on_or_after, slack):
else: else:
return False return False
def validate_before(not_before, slack): def validate_before(not_before, slack):
if not_before: if not_before:
now = time_util.utc_now() now = time_util.utc_now()
@@ -92,11 +98,13 @@ def validate_before(not_before, slack):
return True return True
def valid_address(address): def valid_address(address):
if not (valid_ipv4(address) or valid_ipv6(address)): if not (valid_ipv4(address) or valid_ipv6(address)):
raise NotValid("address") raise NotValid("address")
return True return True
def valid_ipv4(address): def valid_ipv4(address):
parts = address.split(".") parts = address.split(".")
if len(parts) != 4: if len(parts) != 4:
@@ -137,10 +145,12 @@ IPV6_PATTERN = re.compile(r"""
$ $
""", re.VERBOSE | re.IGNORECASE | re.DOTALL) """, re.VERBOSE | re.IGNORECASE | re.DOTALL)
def valid_ipv6(address): def valid_ipv6(address):
"""Validates IPv6 addresses. """ """Validates IPv6 addresses. """
return IPV6_PATTERN.match(address) is not None return IPV6_PATTERN.match(address) is not None
def valid_boolean(val): def valid_boolean(val):
vall = val.lower() vall = val.lower()
if vall in ["true", "false", "0", "1"]: if vall in ["true", "false", "0", "1"]:
@@ -148,6 +158,7 @@ def valid_boolean(val):
else: else:
raise NotValid("boolean") raise NotValid("boolean")
def valid_duration(val): def valid_duration(val):
try: try:
time_util.parse_duration(val) time_util.parse_duration(val)
@@ -155,6 +166,7 @@ def valid_duration(val):
raise NotValid("duration") raise NotValid("duration")
return True return True
def valid_string(val): def valid_string(val):
""" Expects unicode """ Expects unicode
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
@@ -167,16 +179,17 @@ def valid_string(val):
raise NotValid("string") raise NotValid("string")
if char == 0x09 or char == 0x0A or char == 0x0D: if char == 0x09 or char == 0x0A or char == 0x0D:
continue continue
elif char >= 0x20 and char <= 0xD7FF: elif 0x20 <= char <= 0xD7FF:
continue continue
elif char >= 0xE000 and char <= 0xFFFD: elif 0xE000 <= char <= 0xFFFD:
continue continue
elif char >= 0x10000 and char <= 0x10FFFF: elif 0x10000 <= char <= 0x10FFFF:
continue continue
else: else:
raise NotValid("string") raise NotValid("string")
return True return True
def valid_unsigned_short(val): def valid_unsigned_short(val):
try: try:
struct.pack("H", int(val)) struct.pack("H", int(val))
@@ -187,6 +200,7 @@ def valid_unsigned_short(val):
return True return True
def valid_non_negative_integer(val): def valid_non_negative_integer(val):
try: try:
integer = int(val) integer = int(val)
@@ -197,6 +211,7 @@ def valid_non_negative_integer(val):
raise NotValid("non negative integer") raise NotValid("non negative integer")
return True return True
def valid_integer(val): def valid_integer(val):
try: try:
int(val) int(val)
@@ -204,6 +219,7 @@ def valid_integer(val):
raise NotValid("integer") raise NotValid("integer")
return True return True
def valid_base64(val): def valid_base64(val):
try: try:
base64.b64decode(val) base64.b64decode(val)
@@ -211,6 +227,7 @@ def valid_base64(val):
raise NotValid("base64") raise NotValid("base64")
return True return True
def valid_qname(val): def valid_qname(val):
""" A qname is either """ A qname is either
NCName or NCName or
@@ -223,6 +240,7 @@ def valid_qname(val):
except ValueError: except ValueError:
return valid_ncname(val) return valid_ncname(val)
def valid_anytype(val): def valid_anytype(val):
""" Goes through all known type validators """ Goes through all known type validators
@@ -261,9 +279,11 @@ VALIDATOR = {
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
def validate_value_type(value, spec): def validate_value_type(value, spec):
""" """
c_value_type = {'base': 'string', 'enumeration': ['Permit', 'Deny', 'Indeterminate']} c_value_type = {'base': 'string', 'enumeration': ['Permit', 'Deny',
'Indeterminate']}
{'member': 'anyURI', 'base': 'list'} {'member': 'anyURI', 'base': 'list'}
{'base': 'anyURI'} {'base': 'anyURI'}
{'base': 'NCName'} {'base': 'NCName'}
@@ -278,7 +298,7 @@ def validate_value_type(value, spec):
raise NotValid("value not in enumeration") raise NotValid("value not in enumeration")
else: else:
return valid_string(value) return valid_string(value)
elif spec["base"] == "list": #comma separated list of values elif spec["base"] == "list": # comma separated list of values
for val in [v.strip() for v in value.split(",")]: for val in [v.strip() for v in value.split(",")]:
valid(spec["member"], val) valid(spec["member"], val)
else: else:
@@ -286,6 +306,7 @@ def validate_value_type(value, spec):
return True return True
def valid(typ, value): def valid(typ, value):
try: try:
return VALIDATOR[typ](value) return VALIDATOR[typ](value)
@@ -297,28 +318,29 @@ def valid(typ, value):
typ = "string" typ = "string"
return VALIDATOR[typ](value) return VALIDATOR[typ](value)
def _valid_instance(instance, val): def _valid_instance(instance, val):
try: try:
val.verify() val.verify()
except NotValid, exc: except NotValid, exc:
raise NotValid("Class '%s' instance: %s" % \ raise NotValid("Class '%s' instance: %s" % (
(instance.__class__.__name__, instance.__class__.__name__, exc.args[0]))
exc.args[0]))
except OutsideCardinality, exc: except OutsideCardinality, exc:
raise NotValid( raise NotValid(
"Class '%s' instance cardinality error: %s" % \ "Class '%s' instance cardinality error: %s" % (
(instance.__class__.__name__, exc.args[0])) instance.__class__.__name__, exc.args[0]))
ERROR_TEXT = "Wrong type of value '%s' on attribute '%s' expected it to be %s" ERROR_TEXT = "Wrong type of value '%s' on attribute '%s' expected it to be %s"
def valid_instance(instance): def valid_instance(instance):
instclass = instance.__class__ instclass = instance.__class__
class_name = instclass.__name__ class_name = instclass.__name__
if instance.text: # if instance.text:
_has_val = True # _has_val = True
else: # else:
_has_val = False # _has_val = False
if instclass.c_value_type and instance.text: if instclass.c_value_type and instance.text:
try: try:
@@ -340,15 +362,14 @@ def valid_instance(instance):
if typ.c_value_type: if typ.c_value_type:
spec = typ.c_value_type spec = typ.c_value_type
else: else:
spec = {"base": "string"} # doI need a default spec = {"base": "string"} # do I need a default
validate_value_type(value, spec) validate_value_type(value, spec)
else: else:
valid(typ, value) valid(typ, value)
except (NotValid, ValueError), exc: except (NotValid, ValueError), exc:
txt = ERROR_TEXT % (value, name, exc.args[0]) txt = ERROR_TEXT % (value, name, exc.args[0])
raise NotValid( raise NotValid("Class '%s' instance: %s" % (class_name, txt))
"Class '%s' instance: %s" % (class_name, txt))
for (name, _spec) in instclass.c_children.values(): for (name, _spec) in instclass.c_children.values():
value = getattr(instance, name, '') value = getattr(instance, name, '')
@@ -367,7 +388,7 @@ def valid_instance(instance):
_cmin = _cmax = _card = None _cmin = _cmax = _card = None
if value: if value:
_has_val = True #_has_val = True
if isinstance(value, list): if isinstance(value, list):
_list = True _list = True
vlen = len(value) vlen = len(value)
@@ -378,13 +399,13 @@ def valid_instance(instance):
if _card: if _card:
if _cmin is not None and _cmin > vlen: if _cmin is not None and _cmin > vlen:
raise NotValid( raise NotValid(
"Class '%s' instance cardinality error: %s" % \ "Class '%s' instance cardinality error: %s" % (
(class_name, "less then min (%s<%s)" % (vlen, class_name, "less then min (%s<%s)" % (vlen,
_cmin))) _cmin)))
if _cmax is not None and vlen > _cmax: if _cmax is not None and vlen > _cmax:
raise NotValid( raise NotValid(
"Class '%s' instance cardinality error: %s" % \ "Class '%s' instance cardinality error: %s" % (
(class_name, "more then max (%s>%s)" % (vlen, class_name, "more then max (%s>%s)" % (vlen,
_cmax))) _cmax)))
if _list: if _list:
@@ -396,8 +417,8 @@ def valid_instance(instance):
else: else:
if _cmin: if _cmin:
raise NotValid( raise NotValid(
"Class '%s' instance cardinality error: %s" % \ "Class '%s' instance cardinality error: %s" % (
(class_name, "too few values on %s" % name)) class_name, "too few values on %s" % name))
# if not _has_val: # if not _has_val:
# if class_name != "RequestedAttribute": # if class_name != "RequestedAttribute":
@@ -407,9 +428,10 @@ def valid_instance(instance):
return True return True
def valid_domain_name(dns_name): def valid_domain_name(dns_name):
m = re.match( m = re.match(
"^[a-z0-9]+([-.]{1}[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$", "^[a-z0-9]+([-.]{ 1 }[a-z0-9]+).[a-z]{2,5}(:[0-9]{1,5})?(\/.)?$",
dns_name, "ix") dns_name, "ix")
if not m: if not m:
raise ValueError("Not a proper domain name") raise ValueError("Not a proper domain name")