import sqlmodel import hashlib import Crypto from .user import user from .builder import builder from .secret_coder import secret_coder class secret(sqlmodel.SQLModel, table = True): """ This class represents secret in the database. """ id: int = sqlmodel.Field(default = None, primary_key = True) name: str = sqlmodel.Field(default = None, index = True) domain: str = sqlmodel.Field(default = None, index = True) coded: str = sqlmodel.Field(default = None, index = False) owner: int = sqlmodel.Field( default = None, foreign_key = "user.id", index = True ) @property def in_database(self) -> bool: """ True when secret exists in database. """ return self.id is not None @property def ready(self) -> bool: """ True when all fields are filled. """ if self.name is None or self.domain is None: return False if self.coded is None or self.owner is None: return False return True def __str__(self) -> str: """ This cast user to string, very usefull for debug. Returns: (str): User dump as string """ result = "" result = result + "Secret " if self.id is not None: result = result + "(" + str(self.id) + ")" result = result + "\n" result = result + "Name: " + self.name + "\n" result = result + "Domain: " + self.domain + "\n" result = result + "Owner ID: " + str(self.owner) + "\n" result = result + "Coded: " + self.coded + "\n" return result class secret_builder(builder, target_type = secret): """ This class is responsible for creating new secrets for the user. """ @property def owner(self) -> int | None: """ This return ID of the secret owner, or None if not set. """ return self._target.owner @owner.setter def owner(self, target: user): """ This set new owner of the secret. """ if not target.in_database: raise TypeError("Target user for secret is not registered.") self._target.owner = target.id @property def name(self) -> str | None: """ This return name of the secret or None if not set. """ return self._target.name @property def domain(self) -> str | None: """ This return domain of the secret or None if not set. """ return self._target.domain @name.setter def name(self, target: str) -> None: """ This set name of the secret. """ self._target.name = target.upper() @domain.setter def domain(self, target: str) -> None: """ This set domain of the secret. """ self._target.domain = target @property def coded(self) -> str | None: """ This return coded secret or None. """ return self._target.coded @coded.setter def coded(self, target: str) -> None: """ This set new coded secret. It also check it format, and when detect that format is not correct, raise TypeError. Parameters: target (str): Target secret to set """ if not secret_coder.validate(target): raise TypeError("Coded secret is not in correct format.") self._target.coded = target