|
|
@@ -3,6 +3,8 @@ 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
|
|
|
|
|
|
class user(sqlmodel.SQLModel, table = True):
|
|
|
"""
|
|
|
@@ -11,10 +13,29 @@ class user(sqlmodel.SQLModel, table = True):
|
|
|
used to access database via API.
|
|
|
"""
|
|
|
|
|
|
- id: int | None = sqlmodel.Field(default = None, primary_key = True)
|
|
|
+ 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:
|
|
|
@@ -35,6 +56,9 @@ class user(sqlmodel.SQLModel, table = True):
|
|
|
if self.apikey is None:
|
|
|
return False
|
|
|
|
|
|
+ if self.code_key is None:
|
|
|
+ return False
|
|
|
+
|
|
|
return True
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
@@ -56,6 +80,7 @@ class user(sqlmodel.SQLModel, table = True):
|
|
|
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
|
|
|
|
|
|
@@ -100,10 +125,65 @@ class user_builder(builder, target_type = user):
|
|
|
|
|
|
self._target.nick = target.upper()
|
|
|
|
|
|
- @password.setter
|
|
|
- def password(self, target: str) -> None:
|
|
|
+ def set_password(
|
|
|
+ self,
|
|
|
+ password: str,
|
|
|
+ old_password: str | None = None
|
|
|
+ ) -> None:
|
|
|
"""
|
|
|
- target: str - New password to hash and set
|
|
|
+ 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
|
|
|
"""
|
|
|
|
|
|
+ if old_password is None:
|
|
|
+ self.__init_password(password)
|
|
|
+ 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) -> None:
|
|
|
+ """
|
|
|
+ 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
|
|
|
+ """
|
|
|
+
|
|
|
+ if old_password == new_password:
|
|
|
+ raise Exception("New password is same as old password.")
|
|
|
+
|
|
|
+ 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
|