Jelajahi Sumber

Add documentation and full functions to api bind.

Cixo Develop 7 bulan lalu
induk
melakukan
562081d29b
3 mengubah file dengan 196 tambahan dan 39 penghapusan
  1. 175 38
      assets/application_secret.py
  2. 15 0
      assets/secret_loader.py
  3. 6 1
      tests/008-application_secret.py

+ 175 - 38
assets/application_secret.py

@@ -13,7 +13,23 @@ from .application_secret_response import secret_response
 from .application_secret_response import secret_collection_response
 
 class application_secret(application_part):
+    """ 
+    This class is responsible for managing secrets in the application. 
+    """
+
     def get(self, apikey: str, name: str) -> dict:
+        """
+        This load secret by name. It return full secret, with crypted content, 
+        or fail response when secret with given name not exists.
+
+        Parameters:
+            apikey (str): ApiKey of the secret owner
+            name (str): Name of the secret
+
+        Returns:
+            (dict): Result to convert into JSON
+        """
+
         with self.__secret_database(apikey) as loader:
             target = loader.load_by_name(name)
 
@@ -22,19 +38,69 @@ class application_secret(application_part):
 
             return secret_response(target).response
 
+    def __validator(self, **kwargs) -> dict | None:
+        """
+        This validate given parameters. It return None when all given items 
+        is valid, or dict with fail response dict.
+
+        Kwargs:
+            name (str): Name to valid
+            new_name (str): Name to valid
+            domain (str): Domain to valid
+            coded (str): Crypted content to valid
+
+        Returns:
+            (dict): Fail to return as JSON
+            (None): Validating parameters ara valid
+        """
+        
+        result = None
+
+        if "name" in kwargs:
+            name = kwargs["name"]
+            result = self._validation("name", name_validator(name))
+        
+        if "new_name" in kwargs:
+            name = kwargs["new_name"]
+            result = self._validation("name", name_validator(name))
+
+        if "domain" in kwargs and result is None:
+            domain = kwargs["domain"]
+            result = self._validation("domain", domain_validator(domain))
+
+        if not "coded" in kwargs:
+            return result
+            
+        coded = kwargs["coded"]
+
+        if not secret_coder.validate(coded):
+            return self._fail_response(cause = "Invalid coded secret.")
+
+        return result
+
     def create(self, apikey: str, name: str, domain: str, coded: str) -> dict:
-        validation = self._validation("name", name_validator(name))
-        validation = validation or self._validation(
-            "domain", 
-            domain_validator(domain)
+        """
+        This register new secret.
+
+        Parameters:
+            apikey (str): ApiKey of the owner
+            name (str): Name of the secret
+            domain (str): Domain to the secret
+            coded (str): Crypted content of the secret
+
+        Returns:
+            (dict): Result of the action to convert into JSON
+        """
+
+        validation = self.__validator(
+            name = name,
+            domain = domain,
+            coded = coded
         )
 
         if validation is not None:
             return validation
 
-        if not secret_coder.validate(coded):
-            return self._fail_response(cause = "Invalid coded secret.")
-
         with self.__secret_database(apikey) as loader:
             builder = secret_builder()
             builder.name = name
@@ -48,6 +114,17 @@ class application_secret(application_part):
             return self._fail_response(cause = "Name already in use.")
 
     def drop(self, apikey: str, name: str) -> dict:
+        """
+        This remove secret from database.
+
+        Parameters:
+            apikey (str): Owner of the secret
+            name (str): Name of the secret
+
+        Returns:
+            (dict): Result to return as JSON
+        """
+
         with self.__secret_database(apikey) as loader:
             target = loader.load_by_name(name) 
 
@@ -59,34 +136,25 @@ class application_secret(application_part):
 
             return self._fail_response(cause = "Internal database error.")
 
-    def update(
-        self, 
-        apikey: str, 
-        name: str, 
-        new_name: str | None = None,
-        domain: str | None = None,
-        coded: str | None = None
-    ) -> dict:
-        validation = None
-        
-        if new_name is not None:
-            validation = validation or self._validation(
-                "name", 
-                name_validator(new_name)
-            )
-        
-        if domain is not None:
-            validation = validation or self._validation(
-                "domain", 
-                domain_validator(domain)
-            )
+    def update(self, apikey: str, name: str, **kwargs) -> dict:
+        """
+        This update secret data in the database.
+
+        Parameters: 
+            apikey (str): ApiKey of the secret owner
+            name (str): Old name of the secret
+
+        Kwargs:
+            new_name (str): New name of the secret
+            domain (str): Domain of the secret
+            coded (str): Coded content of the secret 
+        """
+
+        validation = self.__validator(**kwargs)
 
         if validation is not None:
             return validation
 
-        if coded is not None and not secret_coder.validate(coded):
-            return self._fail_response(cause = "Invalid coded secret.")
-
         with self.__secret_database(apikey) as loader:
             target = loader.load_by_name(name)
 
@@ -95,21 +163,32 @@ class application_secret(application_part):
 
             builder = secret_builder(target)
 
-            if new_name is not None:
-                builder.name = new_name
+            if "new_name" in kwargs:
+                builder.name = kwargs["new_name"]
 
-            if domain is not None:
-                builder.domain = domain
+            if "domain" in kwargs:
+                builder.domain = kwargs["domain"]
 
-            if coded is not None:
-                builder.coded = coded
+            if "coded" in kwargs:
+                builder.coded = kwargs["coded"]
 
             if loader.update(builder.result):                
                 return self._success_response()
 
             return self._fail_response(cause = "Name already in use.")
 
-    def name_in_use(self, apikey: str, name: str) -> bool:
+    def name_in_use(self, apikey: str, name: str) -> dict:
+        """
+        This check that name is used by any sectet.
+
+        Parameters:
+            apikey (str): ApiKey of the owner
+            name (str): Name to check
+
+        Returns:
+            (dict): Result of the operation to return as JSON
+        """
+
         validation = self._validation("name", name_validator(name))
 
         if validation is not None:
@@ -121,25 +200,83 @@ class application_secret(application_part):
             return self._success_response(in_use = result, name = name)
 
     def domain_search(self, apikey: str, domain: str) -> dict:
+        """
+        This search in database by domain name.
+
+        Parameters:
+            apikey (str): ApiKey of the secrets owner
+            domain (str): Domain name to search
+
+        Returns:
+            (dict): Result to return as JSON
+        """
+
         with self.__secret_database(apikey) as loader:
             results = loader.search_for_domain(domain)
 
             return secret_collection_response(results).response
 
     def name_search(self, apikey: str, name: str) -> dict:
+        """
+        This search in database by domain name.
+
+        Parameters:
+            apikey (str): ApiKey of the secrets owner
+            name (str): Name to search
+
+        Returns:
+            (dict): Result to return as JSON
+        """
+
         with self.__secret_database(apikey) as loader:
             results = loader.search_for_name(name) 
 
             return secret_collection_response(results).response
 
+    def get_all(self, apikey: str) -> dict:
+        """
+        This return all secrets own by user.
+
+        Parameters:
+            apikey (str): ApiKey of the user
+
+        Returns:
+            (dict): Collection of the user secrets
+        """
+        
+        with self.__secret_database(apikey) as loader:
+            results = loader.get_all()
+
+            return search_collection_response(results).response
+
     def __not_found_response(self) -> dict:
+        """ 
+        It create response with not found error.
+
+        Returns:
+            (dict): Result to return as JSON
+        """
+
         return self._fail_response(cause = "Secret not found.")
 
     @property
     def __user_database(self) -> user_loader:
+        """ It return user database. """
+        
         return user_loader(self._connector)
 
     def __secret_database(self, apikey: str) -> secret_loader:
+        """
+        It return new secret database for user with given apikey. When
+        user is not exists, then raise bad_apikey_exception.
+
+        Parameters:
+            apikey (str): ApiKey of the owner
+
+        Returns:
+            (secret_loader): Secret loader for the owner
+        """
+
         with self.__user_database as loader:
             target = loader.get_by_apikey(apikey)
 

+ 15 - 0
assets/secret_loader.py

@@ -118,6 +118,21 @@ class secret_loader(sqlmodel.Session):
         for item in result:
             yield item
 
+    def get_all(self) -> typing.Iterable[secret]:
+        """
+        This return all secrets of the user.
+
+        Returns:
+            (Iterable[secret]): All secrets of the owner
+        """
+
+        query = self.__select
+        result = self.exec(query)
+
+        for item in result:
+            yield item
+
+
     def name_in_use(self, target: str) -> bool:
         """
         This check that name is already in use.

+ 6 - 1
tests/008-application_secret.py

@@ -65,7 +65,12 @@ print(secret_app.name_in_use(apikey, "not_name"))
 
 print()
 print("Updating...")
-print(secret_app.update(apikey, "sample", "new_sample", "https:abc.pl"))
+print(secret_app.update(
+    apikey, 
+    "sample", 
+    new_name = "new_sample", 
+    domain = "https:abc.pl"
+))
 print("After update:")
 print(secret_app.get(apikey, "new_sample"))