import re import enum class validator_result(enum.IntEnum): """ This is class, which provide validator_results. Validator results is presents as int, and this class define which int represent which error. """ """ Valid result. """ valid = 0 """ Given string is too long. """ too_long = 1 """ Given string is too short. """ too_short = 2 """ Given string not contain one of required chars. """ add_required_char = 3 """ Given string contain one of blocked chars. """ contain_invalid_char = 4 def name(code: int) -> str | None: """ This function convert given error code to readable string. When given code means, that string is valid, return None. Parameters: code (int): Error code number Returns: (str | None): Error as string, None when code is valid """ if code == validator_result.valid: return None if code == validator_result.too_long: return "Given string is too long." if code == validator_result.too_short: return "Given string is too short." if code == validator_result.add_required_char: return "Given string not contain one of required chars." if code == validator_result.contain_invalid_char: return "Given string contain char, which is blocker." return "Not known error number." class validator: """ This is validator class. It is responsible for checking, that given string meets the organisation policy. For example, password is not too short, or contain required string. """ def __init__(self, content: str | None = None) -> None: """ This is class initialiser, it get string to check. It also could get None, then information validator is builded. Information validator is validator, which not validate anything, but provide information about validation, like max_lenght. Parameters: content (str | None): Target string to check, or None """ self.__content = content @property def content(self) -> str: """ String to check, provided in the constructor. When content is None, it raise TypeError. Returns: (str): Content of the validator """ if self.__content is None: error = "This is only validator, which provide informations. " error = error + "It has not any content." raise TypeError(error) return self.__content @property def is_valid(self) -> bool: """ This check that provided string is valid. Returns: (bool): True when provided string is valid, False if not """ return self.result == validator_result.valid @property def result(self) -> int: """ This return result of the check, as number from validator_result. Returns: (int): Result of the validation. """ lenght = len(self.content) invalid_regex = False contain_regex = False if len(self.must_contain) > 0: contain_regex = "[" + "".join(self.must_contain) + "]" if len(self.invalid_chars) > 0: invalid_regex = "[" + "".join(self.invalid_chars) + "]" if lenght > self.max_lenght: return validator_result.too_long if lenght < self.min_lenght: return validator_result.too_short if invalid_regex and len(re.findall(invalid_regex, self.content)) > 0: return validator_result.contain_invalid_char if contain_regex and len(re.findall(contain_regex, self.content)) == 0: return validator_result.add_required_char return self._end_final(self.content) def _end_final(self, content: str) -> int: """ This function is end check. It could be overwriten to make custom validation. For example check for additional reguls. Parameters: content (str): Content of the string, which must be validate Returns: (int): Number from validator_results enum """ return validator_result.valid @property def info(self) -> str | None: """ This return additional info about validator, for frontend. """ return None @property def min_lenght(self) -> int: """ This return minimum lenght of the string. """ raise TypeError("Property min_lenght must be overwrite.") @property def max_lenght(self) -> int: """ This return maximum lenght of the string. """ raise TypeError("Property max_lenght must be overwrite.") @property def must_contain(self) -> list: """ This return list of chars, one of them must being in content """ raise TypeError("Property must_contain must be overwrite.") @property def invalid_chars(self) -> list: """ This return chars, which can not being in the content. """ raise TypeError("Property invalid_chars must be overwrite.") class validator_dumper: """ This class is responsible for validators info dumps, required for example on application frontend, to presents information. """ def __init__(self, target: type) -> None: """ This set target validator. Parameters: target (type): This is validator to setup, as class """ self.__target = target() @property def target(self) -> validator: """ Target validator. """ return self.__target @property def route(self) -> dict: """ This is dump of all informations as dictionary. * max-lenght (int) -> validator.max_lenght * min-lenght (int) -> validator.min_lenght * invalid-chars (list) -> validator.invalid_chars * required-chars (list) -> validator.must_contain * readable-info (str) -> validator.info or "" Returns: (dict): Info as described up """ return { "max-lenght": self.target.max_lenght, "min-lenght": self.target.min_lenght, "invalid-chars": self.target.invalid_chars, "required-chars": self.target.must_contain, "readable-info": self.target.info or "" } class password_validator(validator): """ This is validator for main app password. """ @property def max_lenght(self) -> int: return 256 @property def must_contain(self) -> list: return [] @property def invalid_chars(self) -> list: return ["\"", "'", " ", "\t", "\n", "`"] @property def info(self) -> str: return "Password can not have white chars and quotation marks." @property def min_lenght(self) -> int: return 8 class nick_validator(validator): """ This is validator for nick in app. """ @property def max_lenght(self) -> int: return 256 @property def must_contain(self) -> list: return [] @property def invalid_chars(self) -> list: return [] @property def min_lenght(self) -> int: return 4 @property def info(self) -> str | None: return "Nick can contain only letters, digits, and \"-, _\" chars." def _end_final(self, content: str) -> int: for letter in content: if letter.isalpha(): continue if letter.isdigit(): continue if letter == "_" or letter == "-": continue return validator_result.contain_invalid_char return validator_result.valid