# import copy # import re # import json # import socket # import os # import sys # import typing # import collections # from types import MethodType # # os.chdir("/www/server/panel") # if 'class/' not in sys.path: # sys.path.insert(0, 'class/') # import public # # re_key_match = re.compile(r'^[\w\s\[\]\-.]+$') # re_key_match2 = re.compile(r'^\.?__[\w\s[\]\-]+__\.?$') # key_filter_list = ['get', 'set', 'get_items', 'exists', '__contains__', '__setitem__', '__getitem__', '__delitem__', # '__delattr__', '__setattr__', '__getattr__', '__class__', 'get_file'] # # 匹配IP地址 # match_ipv4 = re.compile(r'^(?:(?:25[0-5]|(?:2[0-4]|1?\d)?\d)\.){3}(?:25[0-5]|(?:2[0-4]|1?\d)?\d)$') # match_ipv6 = re.compile(r'^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})|(?:(?:[0-9a-fA-F]{1,4}:){1,7}:)|(?:(?:[0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4})|(?:(?:[0-9a-fA-F]{1,4}:){5}(?::[0-9a-fA-F]{1,4}){1,2})|(?:(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,3})|(?:(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,4})|(?:(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,5})|(?:(?:[0-9a-fA-F]{1,4}:){1}(?::[0-9a-fA-F]{1,4}){1,6})|(?::(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))') # # 安全文件路径 # match_safe_path = re.compile(r'^[\w\s./\-]*$') # # HOST基本格式 # match_based_host = re.compile(r'^[\w.:\-]+$') # # 匹配类私有属性名称 # match_class_private_property = re.compile(r'^(?:_\w+)?__\w+') # # 通用版本号格式验证 major.minor[.patch]/主版本.子版本[.修订号] # match_general_version_format = re.compile(r'^\d+(?:\.\d+){1,2}$') # # md5格式验证 # match_md5_format = re.compile(r'^[a-fA-F0-9]{32}$') # # aap_t_simple_result = collections.namedtuple('aap_t_simple_result', ['success', 'msg']) # # class HintException(Exception): # pass # # # class Param: # __VALIDATE_OPTS = [ # '>', # '<', # '>=', # '<=', # '=', # 'in', # 'not in', # ] # # def __init__(self, name: str): # self.name: str = name # self.__validate_rules: typing.List[_ValidateRule] = [] # self.__filters: typing.List[callable] = [] # # # 验证器 Begin -----> # # def Require(self): # """ # 必选参数 # @return: self # """ # self.__validate_rules.append(_RequireValidation(self.name)) # return self # # def Date(self): # """ # 日期字符串 # @return: self # """ # self.__validate_rules.append(_DateValidation(self.name)) # return self # # def Timestamp(self): # """ # Unix时间戳 # @return: self # """ # self.__validate_rules.append(_TimestampValidation(self.name)) # return self # # def Url(self): # """ # URL # @return: self # """ # self.__validate_rules.append(_UrlValidation(self.name)) # return self # # def Ip(self): # """ # IP地址 # @return: self # """ # self.__validate_rules.append(_IpValidation(self.name)) # return self # # def Ipv4(self): # """ # IPv4地址 # @return: self # """ # self.__validate_rules.append(_Ipv4Validation(self.name)) # return self # # def Ipv6(self): # """ # IPv6地址 # @return: self # """ # self.__validate_rules.append(_Ipv6Validation(self.name)) # return self # # def Host(self): # """ # 主机地址(可以包含端口号) # @return: self # """ # self.__validate_rules.append(_HostValidation(self.name)) # return self # # def Port(self): # """ # 端口号 # @return: self # """ # return self.Integer('between', [1, 65535]) # # def Json(self): # """ # JSON字符串 # @return: self # """ # self.__validate_rules.append(_JsonValidation(self.name)) # return self # # def Array(self): # """ # JSON-Array字符串 # @return: self # """ # self.__validate_rules.append(_ArrayValidation(self.name)) # return self # # def Object(self): # """ # JSON-Object字符串 # @return: self # """ # self.__validate_rules.append(_ObjectValidation(self.name)) # return self # # def List(self): # """ # 限制参数数据类型:list # @return: self # """ # self.__validate_rules.append(_ListValidation(self.name)) # return self # # def Tuple(self): # """ # 限制参数数据类型:tuple # @return: self # """ # self.__validate_rules.append(_TupleValidation(self.name)) # return self # # def Dict(self): # """ # 限制参数数据类型:dict # @return: self # """ # self.__validate_rules.append(_DictValidation(self.name)) # return self # # def Bool(self): # """ # 布尔值或boolean字符串 true/false # @return: self # """ # self.__validate_rules.append(_BoolValidation(self.name)) # return self # # def String(self, opt: typing.Optional[str] = None, length_or_list: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # """ # 字符串 # @param opt: str 运算符 # @param length_or_list: int|list[int|str]|None 字符串长度或字符串集合 # @return: self # """ # self.__validate_rules.append(_StringValidation(self.name, opt, length_or_list)) # return self # # def Number(self, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[int, float, typing.List[typing.Union[int, float]]]] = None): # """ # 数值 # @param opt: str 运算符 # @param num: int 数值大小 # @return: self # """ # self.__validate_rules.append(_NumberValidation(self.name, opt, num)) # return self # # def Integer(self, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[typing.Union[int, typing.List[int]]]] = None): # """ # 整数 # @param opt: str 运算符 # @param num: int 数值大小 # @return: self # """ # self.__validate_rules.append(_IntegerValidation(self.name, opt, num)) # return self # # def Float(self, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[int, float, typing.List[typing.Union[int, float]]]] = None): # """ # 浮点数 # @param opt: str 运算符 # @param num: int 数值大小 # @return: self # """ # self.__validate_rules.append(_FloatValidation(self.name, opt, num)) # return self # # def Alpha(self, opt: typing.Optional[str] = None, length_or_list: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # """ # 纯字母 # @param opt: str 运算符 # @param length_or_list: int|list[int|str]|None 字符串长度或字符串集合 # @return: self # """ # self.__validate_rules.append(_AlphaValidation(self.name, opt, length_or_list)) # return self # # def Alphanum(self, opt: typing.Optional[str] = None, length_or_list: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # """ # 字母+数字 # @param opt: str 运算符 # @param length_or_list: int|list[int|str]|None 字符串长度或字符串集合 # @return: self # """ # self.__validate_rules.append(_AlphanumValidation(self.name, opt, length_or_list)) # return self # # def Mobile(self): # """ # (中国)手机号码 # @return: self # """ # self.__validate_rules.append(_MobileValidation(self.name)) # return self # # def Email(self): # """ # 邮箱地址 # @return: self # """ # self.__validate_rules.append(_EmailValidation(self.name)) # return self # # def Regexp(self, exp: str): # """ # 正则表达式 # @param exp: str 正则表达式 # @return: self # """ # self.__validate_rules.append(_RegexpValidation(self.name, exp)) # return self # # def File(self): # """ # 文件上传 # @return: self # """ # self.__validate_rules.append(_FileValidation(self.name)) # return self # # def Size(self, opt: typing.Optional[str] = None, size: typing.Optional[typing.Union[int, typing.List[int]]] = None): # """ # 上传文件大小 # @param opt: str 运算符 # @param size: int 上传文件大小bytes # @return: self # """ # self.__validate_rules.append(_SizeValidation(self.name, opt, size)) # return self # # def Mime(self, opt: typing.Optional[str] = None, mime_type: typing.Optional[typing.Union[str, typing.List[str]]] = None): # """ # 上传文件Mimetype # @param opt: str 运算符 # @param mime_type: str 上传文件Mimetype # @return: self # """ # self.__validate_rules.append(_MimeValidation(self.name, opt, mime_type)) # return self # # def Ext(self, opt: typing.Optional[str] = None, ext: typing.Optional[typing.Union[str, typing.List[str]]] = None): # """ # 上传文件后缀名 # @param opt: str 运算符 # @param ext: str 上传文件后缀名 # @return: self # """ # self.__validate_rules.append(_ExtValidation(self.name, opt, ext)) # return self # # def SafePath(self): # """ # 文件路径 # @return: self # """ # self.__validate_rules.append(_SafePathValidation(self.name)) # return self # # # <------- 验证器 End # # # 过滤器 Begin ------> # # def Trim(self): # """ # 去除字符串两端空白字符 # @return: self # """ # self.__filters.append(lambda x: str(x).strip()) # return self # # def Xss(self): # """ # XSS过滤 # @return: self # """ # self.__filters.append(_xssencode) # return self # # def Filter(self, f: callable): # """ # 自定义参数过滤器 # @param f: callable func(x: any) -> any # @return: self # """ # self.__filters.append(f) # return self # # # <------- 过滤器 End # # def do_validate(self, args: dict): # """ # 执行验证器 # @param args: dict 请求参数列表 # @return: self # """ # for v in self.__validate_rules: # v.validate(args) # # return self # # def do_filter(self, val, extra_filters: typing.Union[typing.List[callable], typing.Tuple[callable]] = ()) -> any: # """ # 执行参数过滤器 # @param val: any # @param extra_filters: list[callable]|tuple[callable] # @return: any # """ # from functools import reduce # return reduce(lambda x, y: y(x), list(extra_filters) + self.__filters, val) # # # class _ValidateRule: # def validate(self, args: dict): # raise NotImplementedError('method validate() not implemented.') # # # class _RequireValidation(_ValidateRule): # """ # 必选参数验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} is required' # # def validate(self, args: dict): # if self.name in args: # return # # if 'FILES' in args and self.name in args['FILES']: # return # # raise HintException(self.errmsg.format(self.name)) # # # class _DateValidation(_ValidateRule): # """ # 日期字符串验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid datetime' # # def validate(self, args: dict): # if self.name not in args: # return # # if re.match(r'^(?:\d{2}-\d{2}-\d{2}|\d{2}/\d{2}/\d{2})(?: \d{2}:\d{2}(?::\d{2})?)?$', # str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _TimestampValidation(_ValidateRule): # """ # Unix时间戳验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid timestamp' # # def validate(self, args: dict): # if self.name not in args: # return # # if re.match(r'^\d{10}$', str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _UrlValidation(_ValidateRule): # """ # URL地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid URL' # # def validate(self, args: dict): # if self.name not in args: # return # # regex_obj = re.compile( # r'^(?:http|ftp)s?://' # r'(?:(?:[A-Z0-9_](?:[A-Z0-9-_]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-_]{2,}\.?)|' # r'localhost|' # r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # r'(?::\d+)?' # r'(?:/?|[/?]\S+)$', re.IGNORECASE) # # if regex_obj.match(str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _IpValidation(_ValidateRule): # """ # IP地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid IP' # # def validate(self, args: dict): # if self.name not in args: # return # # ipstr = str(args[self.name]).strip() # # if _is_ipv4(ipstr) or _is_ipv6(ipstr): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _Ipv4Validation(_ValidateRule): # """ # IPv4地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid IPv4' # # def validate(self, args: dict): # if self.name not in args: # return # # if _is_ipv4(str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _Ipv6Validation(_ValidateRule): # """ # IPv6地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid IPv4' # # def validate(self, args: dict): # if self.name not in args: # return # # if _is_ipv6(str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _HostValidation(_ValidateRule): # """ # 主机地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid HOST' # # def validate(self, args: dict): # if self.name not in args: # return # # if match_based_host.match(str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _JsonValidation(_ValidateRule): # """ # JSON字符串验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid JSON' # # def validate(self, args: dict): # if self.name not in args: # return # # try: # json.loads(str(args[self.name]).strip()) # return # except: # pass # # raise HintException(self.errmsg.format(self.name)) # # # class _ArrayValidation(_ValidateRule): # """ # JSON-Array字符串验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid JSON Array' # # def validate(self, args: dict): # if self.name not in args: # return # # try: # obj = json.loads(str(args[self.name]).strip()) # # if isinstance(obj, list): # return # except: # pass # # raise HintException(self.errmsg.format(self.name)) # # # class _ObjectValidation(_ValidateRule): # """ # JSON-Object字符串验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid JSON Object' # # def validate(self, args: dict): # if self.name not in args: # return # # try: # obj = json.loads(str(args[self.name]).strip()) # # if isinstance(obj, dict): # return # except: # pass # # raise HintException(self.errmsg.format(self.name)) # # # class _BoolValidation(_ValidateRule): # """ # bool字符串验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} must be bool' # # def validate(self, args: dict): # if self.name not in args: # return # # val = args[self.name] # # if isinstance(val, bool) or re.match(r'^true|false$', str(args[self.name]).strip(), re.IGNORECASE): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _ListValidation(_ValidateRule): # """ # list数据类型验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} must be list' # # def validate(self, args: dict): # if self.name not in args: # return # # if isinstance(args[self.name], list): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _TupleValidation(_ValidateRule): # """ # tuple数据类型验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} must be tuple' # # def validate(self, args: dict): # if self.name not in args: # return # # if isinstance(args[self.name], tuple): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _DictValidation(_ValidateRule): # """ # dict数据类型验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} must be dict' # # def validate(self, args: dict): # if self.name not in args: # return # # if isinstance(args[self.name], dict): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _OperationHelper: # """ # 运算辅助类 # """ # # def __init__(self, name: str, opt: typing.Optional[str], operand: typing.Optional[typing.Union[str, int, float, typing.List[typing.Union[str, int, float]]]], data_type): # self.name: str = name # self.opt = opt # self.operand = operand # self.data_type = data_type # self._opt_check() # self._data_type_check() # # def do(self, val: typing.Union[str, int, float], data_type=None): # val = str(val).strip() # # if data_type is not None: # self.data_type = data_type # self._data_type_check() # # if self.opt is None: # return # # if self.operand is None: # return # # if self.opt == '=': # self._eq(self._calc_num(val)) # elif self.opt == '>': # self._gt(self._calc_num(val)) # elif self.opt == '>=': # self._gte(self._calc_num(val)) # elif self.opt == '<': # self._lt(self._calc_num(val)) # elif self.opt == '<=': # self._lte(self._calc_num(val)) # elif self.opt == 'between': # self._between(self._calc_num(val)) # elif self.opt == 'in': # self._in(self.data_type(val)) # elif self.opt == 'not in': # self._not_in(self.data_type(val)) # # def _calc_num(self, val: str) -> typing.Union[int, float]: # if self.data_type is str: # return len(val) # # return self.data_type(val) # # def _opt_check(self): # if self.opt is None: # return # # self.opt = self.opt.lower() # # if self.operand is None: # return # # if self.opt in ['=', '>', '<', '>=', '<='] and not isinstance(self.operand, int): # raise HintException('当运算符opt是 \'{}\' 时,运算数只能是int类型或float类型,当前类型 {}'.format(self.opt, type(self.operand))) # # if self.opt in ['in', 'not in', 'between'] and not isinstance(self.operand, list): # raise HintException('当运算符opt是 \'{}\' 时,运算数只能是list类型,当前类型 {}'.format(self.opt, type(self.operand))) # # def _data_type_check(self): # if self.data_type is str: # return # # if self.data_type is int: # return # # if self.data_type is float: # return # # raise HintException('data_type只能是str、int、float 当前 {}'.format(self.data_type)) # # def _eq(self, num: typing.Union[int, float]): # if num == self.operand: # return # # raise HintException( # '{}{} must equal {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', self.operand)) # # def _gt(self, num: typing.Union[int, float]): # if num > self.operand: # return # # raise HintException( # '{}{} must greater than {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', # self.operand)) # # def _gte(self, num: typing.Union[int, float]): # if num >= self.operand: # return # # raise HintException( # '{}{} must greater than or equal {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', # self.operand)) # # def _lt(self, num: typing.Union[int, float]): # if num < self.operand: # return # # raise HintException( # '{}{} must less than {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', # self.operand)) # # def _lte(self, num: typing.Union[int, float]): # if num <= self.operand: # return # # raise HintException( # '{}{} must less than or equal {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', # self.operand)) # # def _between(self, num: typing.Union[int, float]): # if len(self.operand) != 2: # raise HintException('当运算符opt是 \'between\' 时,运算数只能是list类型,并且list的长度只能是2,当前list长度 {}'.format(len(self.operand))) # # if num >= self.operand[0] and num <= self.operand[1]: # return # # raise HintException( # '{}{} must between {} and {}'.format(self.name, ' length' if isinstance(self.data_type, str) else '', # self.operand[0], self.operand[1])) # # def _in(self, item: typing.Union[int, float, str]): # if len(self.operand) < 1: # raise HintException('当运算符opt是 \'{}\' 时,运算数只能是list类型,并且list的长度必须大于0,当前list长度 0'.format(self.opt)) # # if item in self.operand: # return # # raise HintException('{} must in {}'.format(self.name, self.operand)) # # def _not_in(self, item: typing.Union[int, float, str]): # if len(self.operand) < 1: # raise HintException('当运算符opt是 \'{}\' 时,运算数只能是list类型,并且list的长度必须大于0,当前list长度 0'.format(self.opt)) # # if item in self.operand: # raise HintException('{} must not in {}'.format(self.name, self.operand)) # # # class _StringValidation(_ValidateRule): # """ # 字符串验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, v: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # self.name: str = name # self.errmsg: str = '{} must be string' # self.op = _OperationHelper(name, opt, v, str) # # def validate(self, args: dict): # if self.name not in args: # return # # s = args[self.name] # # if isinstance(s, str): # self.op.do(s) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _NumberValidation(_ValidateRule): # """ # 数字验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[int, float, typing.List[typing.Union[int, float]]]] = None): # self.name: str = name # self.errmsg: str = '{} must be number' # self.op = _OperationHelper(name, opt, num, float) # # def validate(self, args: dict): # if self.name not in args: # return # # num = args[self.name] # # if _is_number(num): # self.op.do(num, _get_number_data_type(num)) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _IntegerValidation(_ValidateRule): # """ # 整数验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[int, typing.List[int]]] = None): # self.name: str = name # self.errmsg: str = '{} must be integer' # self.op = _OperationHelper(name, opt, num, int) # # def validate(self, args: dict): # if self.name not in args: # return # # num = args[self.name] # # if _is_int(num): # self.op.do(num) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _FloatValidation(_ValidateRule): # """ # 浮点数验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, num: typing.Optional[typing.Union[float, typing.List[float]]] = None): # self.name: str = name # self.errmsg: str = '{} must be float' # self.op = _OperationHelper(name, opt, num, float) # # def validate(self, args: dict): # if self.name not in args: # return # # num = args[self.name] # # if _is_float(num): # self.op.do(num) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _AlphaValidation(_ValidateRule): # """ # 纯字母验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, v: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # self.name: str = name # self.errmsg: str = '{} must be alpha' # self.op = _OperationHelper(name, opt, v, str) # # def validate(self, args: dict): # if self.name not in args: # return # # s = str(args[self.name]).strip() # # if re.match(r'^[a-zA-Z]+$', s): # self.op.do(s) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _AlphanumValidation(_ValidateRule): # """ # 字母数字验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, v: typing.Optional[typing.Union[int, typing.List[typing.Union[int, str]]]] = None): # self.name: str = name # self.errmsg: str = '{} must be alphanum' # self.op = _OperationHelper(name, opt, v, str) # # def validate(self, args: dict): # if self.name not in args: # return # # s = str(args[self.name]).strip() # # if re.match(r'^[a-zA-Z0-9]+$', s): # self.op.do(s) # return # # raise HintException(self.errmsg.format(self.name)) # # # class _MobileValidation(_ValidateRule): # """ # (中国)手机号码验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid mobile' # # def validate(self, args: dict): # if self.name not in args: # return # # s = str(args[self.name]).strip() # # if re.match(r'^1[3-9]\d{9}$', s): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _EmailValidation(_ValidateRule): # """ # 邮箱地址验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid email' # # def validate(self, args: dict): # if self.name not in args: # return # # s = str(args[self.name]).strip() # # if re.match(r'^.+@(\[?)[a-zA-Z0-9\-.]+\.(?:[a-zA-Z]{2,}|\d{1,3})\1$', s): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _RegexpValidation(_ValidateRule): # """ # 正则表达式验证类 # """ # # def __init__(self, name: str, regexp: str): # self.name: str = name # self.errmsg: str = '{} not success verified by regexp' # self.regexp: str = regexp # # def validate(self, args: dict): # if self.name not in args: # return # # s = str(args[self.name]).strip() # # if re.match(self.regexp, s): # return # # raise HintException(self.errmsg.format(self.name)) # # # class _FileValidation(_ValidateRule): # """ # 文件上传验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg: str = '{} not valid file' # # def validate(self, args: dict): # if 'FILES' in args and self.name in args['FILES']: # return # # raise HintException(self.errmsg.format(self.name)) # # # class _SizeValidation(_ValidateRule): # """ # 文件大小验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, size: typing.Optional[typing.Union[int, typing.List[int]]] = None): # self.name: str = name # self.op = _OperationHelper(name, opt, size, int) # # def validate(self, args: dict): # if 'FILES' not in args or self.name not in args['FILES']: # return # # self.op.do(args['FILES'][self.name].content_length) # # # class _MimeValidation(_ValidateRule): # """ # 文件mimetype验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, mime_type: typing.Optional[typing.Union[str, typing.List[str]]] = None): # self.name: str = name # self.op = _OperationHelper(name, opt, mime_type, str) # # def validate(self, args: dict): # if 'FILES' not in args or self.name not in args['FILES']: # return # # self.op.do(args['FILES'][self.name].mimetype) # # # class _ExtValidation(_ValidateRule): # """ # 文件后缀名验证类 # """ # # def __init__(self, name: str, opt: typing.Optional[str] = None, ext: typing.Optional[typing.Union[str, typing.List[str]]] = None): # self.name: str = name # self.op = _OperationHelper(name, opt, ext, str) # # def validate(self, args: dict): # if 'FILES' not in args or self.name not in args['FILES']: # return # # f = args['FILES'][self.name] # # self.op.do(os.path.splitext(f.filename)[-1]) # # # class _SafePathValidation(_ValidateRule): # """ # 文件路径名验证类 # """ # # def __init__(self, name: str): # self.name: str = name # self.errmsg = '{} not safe path' # # def validate(self, args: dict): # if self.name not in args: # return # # if _is_safe_path(str(args[self.name]).strip()): # return # # raise HintException(self.errmsg.format(self.name)) # # # def trim_filter() -> callable: # """ # 获取Trim参数过滤器 # @return: callable # """ # return lambda x: str(x).strip() # # # def xss_filter() -> callable: # """ # 获取XSS参数过滤器 # @return: callable # """ # return _xssencode # # # def _is_ipv4(ip: str) -> bool: # ''' # @name 是否是IPV4地址 # @author hwliang # @param ip IP地址 # @return True/False # ''' # # 验证基本格式 # if not match_ipv4.match(ip): # return False # # # 验证每个段是否在合理范围 # try: # socket.inet_pton(socket.AF_INET, ip) # except AttributeError: # try: # socket.inet_aton(ip) # except socket.error: # return False # except socket.error: # return False # return True # # # def _is_ipv6(ip: str) -> bool: # ''' # @name 是否为IPv6地址 # @author hwliang # @param ip 地址 # @return True/False # ''' # # 验证基本格式 # if not match_ipv6.match(ip): # return False # # # 验证IPv6地址 # try: # socket.inet_pton(socket.AF_INET6, ip) # except socket.error: # return False # return True # # # def _xssencode(text: str) -> str: # """ # XSS过滤 # @param text: str # @return bool # """ # try: # from cgi import html # list = ['`', '~', '&', '#', '/', '*', '$', '@', '<', '>', '\"', '\'', ';', '%', ',', '.', '\\u'] # ret = [] # for i in text: # if i in list: # i = '' # ret.append(i) # str_convert = ''.join(ret) # text2 = html.escape(str_convert, quote=True) # return text2 # except: # return text.replace('&', '&').replace('"', '"').replace('<', '<').replace('>', '>') # # # def _is_safe_path(path: str, force: bool = True) -> bool: # """ # 文件路径过滤 # @param path: str # @param force: bool # @return: bool # """ # if len(path) > 256: # return False # # checks = ['..', './', '\\', '%', '$', '^', '&', '*', '~', '"', "'", ';', '|', '{', '}', '`'] # # for c in checks: # if path.find(c) > -1: # return False # # if force: # if not match_safe_path.match(path): # return False # # return True # # # def _is_number(s) -> bool: # """ # @name 判断输入参数是否一个数字 # @author Zhj<2022-07-18> # @param s 输入参数 # @return bool # """ # try: # float(s) # return True # except ValueError: # pass # # try: # import unicodedata # unicodedata.numeric(s) # return True # except (TypeError, ValueError): # pass # # return False # # # def _is_int(s) -> bool: # """ # 判断输入是否是整数 # @param s: any # @return bool # """ # try: # int(s) # return True # except ValueError: # pass # # return False # # # def _is_float(s) -> bool: # """ # 判断输入是否是浮点数 # @param s: any # @return bool # """ # try: # float(s) # return True # except ValueError: # pass # # return False # # # def _get_number_data_type(s): # """ # 获取数字的数据类型 # @param s 输入参数 # @return int|float # """ # try: # int(s) # return int # except ValueError: # pass # # return float # # # # 参数验证器 # class Validator: # def __init__(self, rules: typing.Union[typing.Tuple[Param], typing.List[Param]], raise_exc: bool = True): # self.__RULES = list(rules) # self.__RAISE_EXC = raise_exc # # # 参数格式校验 # def check(self, args: dict) -> aap_t_simple_result: # try: # for v in self.__RULES: # v.do_validate(args) # except Exception as e: # if self.__RAISE_EXC: # raise # # return aap_t_simple_result(False, str(e)) # # return aap_t_simple_result(True, 'ok') # # # 参数列表过滤 # def filter(self, args: dict) -> typing.Dict: # new_args = {} # # for v in self.__RULES: # if v.name not in args: # continue # # new_args = v.do_filter(args[v.name]) # # return new_args # # # class wpbase(object): # __validated = set() # __store = {} # def __init__(self, get=None): # # self.__validated = set() # # self.__store = {} # if get: # self.__store = vars(get) # # for key, value in vars(get).items(): # # self.set(key, value) # # print(self.__store) # # # def __setattr__(self, key, value): # if match_class_private_property.match(key): # object.__setattr__(self, key, value) # return # # self.__store[key] = value # # # def set(self, key, value): # # # if not isinstance(value, str) or not isinstance(key, str): return False # # if key in key_filter_list: # # raise ValueError("wrong field name") # # if not re_key_match.match(key) or re_key_match2.match(key): # # raise ValueError("wrong field name") # # return setattr(self, key, value) # # def get_items(self): # return self.__store # # def validate(self, validate_rules: typing.List[Param], filters: typing.List[callable] = (trim_filter(),), args=None) -> None: # """ # @name 验证请求参数 # @param validate_rules: list[validate.Param] 参数验证规则 # @param filters: list[callable] 参数过滤器 # @raise Error # """ # filters = list(filters) # if args: # if not isinstance(args, dict): # self.__store = vars(args) # else: # self.__store = args # for v in validate_rules: # v.do_validate(self.__store) # # if v.name in self.__store: # self.__store[v.name] = v.do_filter(self.__store[v.name], filters) # # self.__validated.add(v.name) class wpbase(object): def __init__(self, get=None): pass