112 lines
2.5 KiB
Python
112 lines
2.5 KiB
Python
from . import exceptions
|
|
from . import util
|
|
|
|
class Sanitizer(util.ChildAware):
|
|
|
|
"""
|
|
Sanitizer base class.
|
|
"""
|
|
|
|
# whether this sanitizer matches multiple URL parts.
|
|
# this is a hhint for Router objects, any multipart
|
|
# variable in an URL route will match the remainder
|
|
# of the request path - at least when using the
|
|
# default Router implementation
|
|
multipart = False
|
|
|
|
def sanitize(self, value):
|
|
raise NotImplementedError("You can't use Sanitizer directly. Please subclass it.")
|
|
|
|
class String(Sanitizer):
|
|
|
|
def sanitize(self, value):
|
|
|
|
if isinstance(value, str):
|
|
return value
|
|
|
|
if isinstance(value, bytes):
|
|
return value.decode('UTF-8')
|
|
|
|
try:
|
|
return str(value)
|
|
except Exception:
|
|
raise exceptions.SanitationException(f"Not a valid string: {value}")
|
|
|
|
class Path(String):
|
|
|
|
multipart = True
|
|
|
|
def sanitize(self, value):
|
|
|
|
valid_string = super().sanitize(value)
|
|
|
|
if '..' in valid_string:
|
|
raise exception.SanitationException(f"Path MUST NOT contain '..', but '{valid_string}' does.")
|
|
|
|
return valid_string
|
|
|
|
class Integer(Sanitizer):
|
|
|
|
def sanitize(self, value):
|
|
|
|
if isinstance(value, int):
|
|
return value
|
|
|
|
try:
|
|
return int(value)
|
|
except Exception:
|
|
raise exceptions.SanitationException(f"Not a valid int: {value}")
|
|
|
|
class Float(Sanitizer):
|
|
|
|
def sanitize(self, value):
|
|
|
|
if isinstance(value, float):
|
|
return value
|
|
|
|
try:
|
|
return float(value)
|
|
except Exception:
|
|
raise exceptions.SanitationException(f"Not a valid float: {value}")
|
|
|
|
class Number(Sanitizer):
|
|
|
|
def sanitize(self, value):
|
|
|
|
if isinstance(value, int) or isinstance(value, float):
|
|
return value
|
|
|
|
try:
|
|
return int(value)
|
|
except Exception:
|
|
try:
|
|
return float(value)
|
|
except Exception:
|
|
raise exceptions.SanitationException(f"Not a valid Number: {value}")
|
|
|
|
class Bool(Sanitizer):
|
|
|
|
input_map = {
|
|
'true': True,
|
|
'false': False,
|
|
'yes': True,
|
|
'no': False,
|
|
'1': True,
|
|
'0': False,
|
|
}
|
|
|
|
def sanitize(self, value):
|
|
|
|
vl = str(value).lower()
|
|
if vl in self.input_map:
|
|
return self.input_map[vl]
|
|
|
|
raise exceptions.SanitationException(f"Not a valid bool: {value}")
|
|
|
|
STRING = String()
|
|
PATH = Path()
|
|
INTEGER = Integer()
|
|
FLOAT = Float()
|
|
NUMBER = Number()
|
|
BOOL = Bool()
|