import os import functools from .apikey import apikey from .apikey_validator import apikey_validator from .apikey_exceptions import apikey_syntax_error class apikey_factory: def __init__(self, prefix: str = "key") -> None: self.__size = 256 self.__prefix = prefix def set_size(self, size: int) -> object: self.__size = size return self def set_prefix(self, prefix: str) -> object: self.__prefix = prefix return self @property def prefix_separator(self) -> str: return "_" @property def prefix(self) -> str: return self.__prefix @property def size(self) -> int: return self.__size @functools.lru_cache def __get_random_token_size(self, token_size: int) -> int: random_size = token_size / 2 + token_size % 2 random_size = int(random_size) return random_size @functools.lru_cache def __get_token_size(self, full_size: int, prefix_size: int) -> int: return full_size - prefix_size - len(self.prefix_separator) def __get_random(self) -> str: token_size = self.__get_token_size(self.size, len(self.prefix)) random_size = self.__get_random_token_size(token_size) return os.urandom(random_size).hex()[0:token_size] def __get_new_token(self) -> str: return self.prefix + self.prefix_separator + self.__get_random() def generate(self) -> apikey: return apikey( self.__get_new_token(), self.size, self.prefix, self.prefix_separator ) def load(self, token: str) -> apikey: if not self.get_validator().validate(token): raise apikey_syntax_error() return apikey( token, self.size, self.prefix, self.prefix_separator ) def get_validator(self) -> apikey_validator: return self.__get_validator_cache( self.size, self.prefix, self.prefix_separator ) @functools.lru_cache def __get_validator_cache( self, size: int, prefix: str, prefix_separator: str ) -> apikey_validator: return apikey_validator( size, prefix, prefix_separator )