secret.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import sqlmodel
  2. import hashlib
  3. import Crypto
  4. from .user import user
  5. from .builder import builder
  6. from .secret_crypto import secret_crypto
  7. class secret(sqlmodel.SQLModel, table = True):
  8. """
  9. This class represents secret in the database.
  10. """
  11. id: int | None = sqlmodel.Field(default = None, primary_key = True)
  12. name: str | None = sqlmodel.Field(default = None, index = True)
  13. domain: str | None = sqlmodel.Field(default = None, index = True)
  14. crypted: bytes | None = sqlmodel.Field(default = None)
  15. nonce: bytes | None = sqlmodel.Field(default = None)
  16. owner: int | None = sqlmodel.Field(default = None, foreign_key = "user.id")
  17. @property
  18. def in_database(self) -> bool:
  19. """ True when secret exists in database. """
  20. return self.id is not None
  21. @property
  22. def ready(self) -> bool:
  23. """ True when all fields are filled. """
  24. if self.name is None or self.domain is None:
  25. return False
  26. if self.crypted is None or self.nonce is None:
  27. return False
  28. if self.owner is None:
  29. return False
  30. return True
  31. def __str__(self) -> str:
  32. """
  33. This cast user to string, very usefull for debug.
  34. Returns:
  35. (str): User dump as string
  36. """
  37. result = ""
  38. result = result + "Secret "
  39. if self.id is not None:
  40. result = result + "(" + str(self.id) + ")"
  41. result = result + "\n"
  42. result = result + "Name: " + self.name + "\n"
  43. result = result + "Domain: " + self.domain + "\n"
  44. result = result + "Owner ID: " + str(self.owner) + "\n"
  45. result = result + "Crypted: " + self.crypted.hex() + "\n"
  46. result = result + "Nonce: " + self.nonce.hex() + "\n"
  47. return result
  48. class secret_builder(builder, target_type = secret):
  49. """
  50. This class is responsible for creating new secrets for the user.
  51. """
  52. @property
  53. def owner(self) -> int | None:
  54. """ This return ID of the secret owner, or None if not set. """
  55. return self._target.owner
  56. @owner.setter
  57. def owner(self, target: user):
  58. """ This set new owner of the secret. """
  59. self._target.owner = user.id
  60. @property
  61. def name(self) -> str | None:
  62. """ This return name of the secret or None if not set. """
  63. return self._target.name
  64. @property
  65. def domain(self) -> str | None:
  66. """ This return domain of the secret or None if not set. """
  67. return self._target.domain
  68. @name.setter
  69. def name(self, target: str) -> None:
  70. """ This set name of the secret. """
  71. self._target.name = target.upper()
  72. @domain.setter
  73. def domain(self, target: str) -> None:
  74. """ This set domain of the secret. """
  75. self._target.domain = target
  76. def crypt(self, key: str, target: str) -> None:
  77. """
  78. This function crypt secret. It require password which could decrypt
  79. it laser, and target secret. It automatic set crypted and nonce secret
  80. fields. If secret already has nonce, then it use it. When secret nonce
  81. is empty, then it would provide new random nonce for secret.
  82. Parameters:
  83. key (str): Password to protect secret
  84. targer (str): Secret to encrypt
  85. """
  86. crypter = secret_crypto(key)
  87. if self._target.nonce is not None:
  88. crypter.set_iv(self.__target.nonce)
  89. crypted, nonce = crypter.crypted(target)
  90. self._target.crypted = crypted
  91. self._target.nonce = nonce