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