|
@@ -0,0 +1,286 @@
|
|
|
|
|
+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
|
|
|
|
|
+
|