Browse Source

Continue work on secrets.

Cixo Develop 7 months ago
parent
commit
2750e35cf1
4 changed files with 99 additions and 8 deletions
  1. BIN
      002-test.db
  2. 3 1
      assets/__init__.py
  3. 80 7
      assets/secret.py
  4. 16 0
      tests/003-password_crypto.py

BIN
002-test.db


+ 3 - 1
assets/__init__.py

@@ -4,4 +4,6 @@ from .user import user_builder
 from .user_loader import user_loader
 from .database import database
 from .apikey import apikey
-from .secret_crypto import secret_crypto
+from .secret import secret
+from .secret import secret_builder
+from .secret_crypto import secret_crypto

+ 80 - 7
assets/secret.py

@@ -2,32 +2,70 @@ import sqlmodel
 import hashlib
 import Crypto
 
+from .user import user
+from .secret_crypto import secret_crypto
+
 class secret(sqlmodel.SQLModel, table = True):
+    """
+    This class represents secret in the database.
+    """
+
     id: int | None = sqlmodel.Field(default = None, primary_key = True)
-    name: str = sqlmodel.Field(default = None, index = True)
-    domain: str = sqlmodel.Field(default = None, index = True)
-    crypted: bytes = sqlmodel.Field(default = None)
-    nonce: bytes = sqlmodel.Field(default = None)
+    name: str | None = sqlmodel.Field(default = None, index = True)
+    domain: str | None = sqlmodel.Field(default = None, index = True)
+    crypted: bytes | None = sqlmodel.Field(default = None)
+    nonce: bytes | None = sqlmodel.Field(default = None)
+    owner: int | None = sqlmodel.Field(default = None, foreign_key = "user.id") 
 
 class secret_builder:
-    def __init__(self):
+    """
+    This class is responsible for creating new secrets for the user.
+    """
+
+    def __init__(self) -> None:
+        """
+        This function create new clean builder.
+        """
+
         self.clean()
 
     def clean(self) -> None:
+        """
+        This function clean builder, and prepare it to build new secret.
+        """
+
         self.__target = secret()
 
     @property
     def ready(self) -> bool:
+        """ True when secret is ready, false when not. """
+
         if self.__target.name is None or self.__target.domain is None:
             return False
 
         if self.__target.crypted is None or self.__target.nonce is None:
             return False
 
+        if self.__target.owner is None:
+            return False
+
         return True
 
+    @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. """
+
+        self.__target.owner = user.id
+
     @property
     def result(self) -> secret:
+        """ This return ready secret if it is ready, or raise Exception. """
+
         if not self.ready:
             raise TypeError("Secret is not ready to load.")
 
@@ -35,11 +73,46 @@ class secret_builder:
 
     @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
 
-    def crypt(self, key: str, target: str) -> bool:
-        pass
+    @name.setter
+    def name(self, target: str) -> None:
+        """ This set name of the secret. """
+
+        self.__target.name = target
+
+    @domain.setter
+    def domain(self, target: str) -> None:
+        """ This set domain of the secret. """
+
+        self.__target.domain = target
+
+    def crypt(self, key: str, target: str) -> None:
+        """
+        This function crypt secret. It require password which could decrypt
+        it laser, and target secret. It automatic set crypted and nonce secret
+        fields. If secret already has nonce, then it use it. When secret nonce
+        is empty, then it would provide new random nonce for secret.
+
+        Parameters:
+            key (str): Password to protect secret
+            targer (str): Secret to encrypt
+        """
+
+        crypter = secret_crypto(key)
+
+        if self.__target.nonce is not None:
+            crypter.set_iv(self.__target.nonce)
+
+        crypted, nonce = crypter.crypted(target)
+
+        self.__target.crypted = crypted
+        self.__target.nonce = nonce

+ 16 - 0
tests/003-password_crypto.py

@@ -0,0 +1,16 @@
+import pathlib
+
+current = pathlib.Path(__file__).parent
+root = current.parent
+
+import sys
+sys.path.append(str(root))
+
+import assets
+
+secret = "123456"
+sample1 = assets.secret_crypto(secret)
+sample1_crypted, sample1_iv = sample1.crypted("Sample")
+
+sample1 = assets.secret_crypto(secret, sample1_iv)
+print("\"Sample\" after decrypt: " + sample1.decrypt(sample1_crypted))