| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | 
							- import sqlmodel
 
- from .apikey import apikey
 
- from .password import password
 
- from .builder import builder
 
- from .code_key import code_key
 
- from .code_key import code_key_manager
 
- from .secret_coder import bad_password
 
- class user(sqlmodel.SQLModel, table = True):
 
-     """
 
-     This represents user in database. All users has own unique nick and api
 
-     key. Nick and password is used to login, api key is long, random and
 
-     used to access database via API.
 
-     """
 
-     id: int = sqlmodel.Field(default = None, primary_key = True)
 
-     nick: str = sqlmodel.Field(index = True, unique = True)
 
-     password: str = sqlmodel.Field(index = False)
 
-     apikey: str = sqlmodel.Field(index = True, unique = True)
 
-     code_key: str = sqlmodel.Field(index = False)
 
-     def key(self, password: str) -> code_key_manager | None:
 
-         """
 
-         This return crypto key wrapper, to manage, recrypt, encrypt, decrypt
 
-         and other with key. It require password, and when code key is not 
 
-         set, return None.
 
-         Parameters:
 
-             password (str): Password used to decrypt crypto key
 
-         Returns:
 
-             (code_key_manager): Crypto key wrapper
 
-         """
 
-         if self.code_key is None:
 
-             return None
 
-         return code_key(password = password, crypted_key = self.code_key)
 
-     @property
 
-     def in_database(self) -> bool:
 
-         """ True when user exists in database. """
 
-         return self.id is not None
 
-     @property
 
-     def ready(self) -> bool:
 
-         """ True when all fields are filled. """
 
-         if self.nick is None:
 
-             return False
 
-         if self.password is None:
 
-             return False
 
-         if self.apikey is None:
 
-             return False
 
-         if self.code_key is None:
 
-             return False
 
-         return True
 
-     def __str__(self) -> str:
 
-         """
 
-         This function dump user to string, very usefull for debug.
 
-         Returns:
 
-             (str): User as string
 
-         """
 
-         result = ""
 
-         result = result + "User "
 
-         if self.id is not None:
 
-             result = result + "(" + str(self.id) + ")"
 
-         result = result + "\n"
 
-         
 
-         result = result + "Nick: " + self.nick + "\n"
 
-         result = result + "Password: " + self.password + "\n"
 
-         result = result + "API key: " + self.apikey + "\n"
 
-         result = result + "Code KEY: " + self.code_key + "\n"
 
-         return result
 
- class user_builder(builder, target_type = user):
 
-     """
 
-     This class is responsible for building new user.
 
-     """
 
-     def __init__(self, target: user | None = None) -> None:
 
-         """ 
 
-         This create new user builder. It can be initialized by already
 
-         created user. When None create empty user.
 
-         Parameters:
 
-             target(user | None): Target to initialize builder with
 
-         """
 
-         super().__init__(target)
 
-         if target is None:
 
-             self.refresh_apikey()
 
-     def refresh_apikey(self) -> None:
 
-         """
 
-         This function refresh apikey of the user. It could be useable to
 
-         logout all of the devices which use user account.
 
-         """
 
-         self._target.apikey = apikey()
 
-     @property
 
-     def nick(self) -> str | None:
 
-         """
 
-         return: str | None - Current nick of the user in builder
 
-         """
 
-         return self._target.nick
 
-     @property
 
-     def password(self) -> bool:
 
-         """
 
-         return: bool - True when password is set, false if not
 
-         """
 
-         return self._target.password is not None
 
-     @nick.setter
 
-     def nick(self, target: str) -> None:
 
-         """
 
-         target: str - New nick for the user
 
-         """
 
-         self._target.nick = target.upper()
 
-     def check_password(self, target: str) -> bool:
 
-         """
 
-         This function check that given password is correct with current user
 
-         password. It is usefull when trying to have second factor, password + 
 
-         ApiKey.
 
-         Parameters:
 
-             target (str): Password to check
 
-         Returns:
 
-             (bool): True when given password is correct, False when not
 
-         """
 
-         return password(target).validate(self._target.password)
 
-     def set_password(
 
-         self, 
 
-         password: str, 
 
-         old_password: str | None = None
 
-     ) -> bool:
 
-         """
 
-         This function set password to user. When only password is given, then 
 
-         it try to init user, which not have password and crypto key yet. User
 
-         which already set password, and crypto key, must being updated with
 
-         also old password.
 
-         Parameters:
 
-             password (str): New password to set
 
-             old_password (str | None) = None: Old password, require to recrypt
 
-         
 
-         Returns:
 
-             (bool): True when changed success, False when old password is bad
 
-         """
 
-         if old_password is None:
 
-             self.__init_password(password)
 
-             return True
 
-         return self.__change_password(old_password, password)
 
-     def __init_password(self, target: str) -> None:
 
-         """
 
-         This function initialize user with new password. User can not already 
 
-         have both password, and crypto key. When user already have crypto key
 
-         or password, then Exception is raised, to protect crypto key to not
 
-         being overwrited.
 
-         Parameters:
 
-             target (str): New password to set
 
-         """
 
-         if self._target.password is not None:
 
-             raise Exception("Password and code key is already set.")
 
-         if self._target.code_key is not None:
 
-             raise Exception("Password and code key is already set.")
 
-         self._target.password = password(target).result
 
-         self._target.code_key = code_key(password = target)
 
-     def __change_password(self, old_password: str, new_password: str) -> bool:
 
-         """
 
-         This change password, when user already have password and code key. It
 
-         recrypt crypto key, to could use new password for secret decrypting.
 
-         Parameters:
 
-             old_password (str): Old password
 
-             new_password (str): New password to set
 
-         
 
-         Returns:
 
-             (bool): True when changed success, False when old password is bad
 
-         """
 
-         if old_password == new_password:
 
-             return True
 
-         try:
 
-             key = self._target.key(old_password)
 
-             if key is None or self._target.password is None:
 
-                 raise Exception("User crypto key is not initialized yet.")
 
-             self._target.code_key = key.recrypt(new_password).encrypted
 
-             self._target.password = password(new_password).result
 
-             return True
 
-         except bad_password:
 
-             return False
 
 
  |