Explorar o código

Continue working on api.

Cixo Develop hai 7 meses
pai
achega
f7f7cf9a11

+ 91 - 59
assets/application_secret.py

@@ -1,5 +1,3 @@
-import typing
-
 from .user import user
 from .user import user_builder
 from .user_loader import user_loader
@@ -11,59 +9,8 @@ from .application_part import application_part
 from .apikey import bad_apikey_exception
 from .validators import name_validator
 from .validators import domain_validator
-
-class secret_response:
-    def __init__(self, target: secret | secret_builder) -> None:
-        if isinstance(target, secret):
-            self.__target = target
-            return
-
-        self.__target = target.result
-
-    @property
-    def response(self) -> dict:
-        return {
-            "name": self.target.name,
-            "domain": self.target.domain,
-            "coded" : self.target.coded
-        }
-
-    @property
-    def target(self) -> secret:
-        return self.__target
-
-    @property
-    def builder(self) -> secret_builder:
-        return secret_builder(self.__target)
-
-class secret_collection_response:
-    def __init__(self, target: typing.Iterable[secret] | None = None) -> None:
-        self.__collection = []
-
-        if target is None:
-            return
-
-        if type(target) is list:
-            self.__collection = target.copy()
-            return
-
-        for count in target:
-            self.__collection.append(count)
-
-    @property
-    def response(self) -> dict:
-        return [ count.response for count in self.collection ]
-
-    @property
-    def collection(self) -> list:
-        return self.__collection.copy()
-
-    def append(self, target: secret | secret_builder) -> object:
-        if isinstance(target, secret_builder):
-            target = target.result
-
-        self.__collection.append(target)
-        return self
+from .application_secret_response import secret_response
+from .application_secret_response import secret_collection_response
 
 class application_secret(application_part):
     def get(self, apikey: str, name: str) -> dict:
@@ -86,7 +33,7 @@ class application_secret(application_part):
             return validation
 
         if not secret_coder.validate(coded):
-            return self._fail_response(cause = "Invalid coded secret")
+            return self._fail_response(cause = "Invalid coded secret.")
 
         with self.__secret_database(apikey) as loader:
             builder = secret_builder()
@@ -95,11 +42,96 @@ class application_secret(application_part):
             builder.coded = coded
             builder.owner = loader.owner
 
-            loader.append(builder.result)     
+            if loader.append(builder.result):   
+                return self._success_response()
 
-            return self._success_response()
+            return self._fail_response(cause = "Name already in use.")
+
+    def drop(self, apikey: str, name: str) -> dict:
+        with self.__secret_database(apikey) as loader:
+            target = loader.load_by_name(name) 
+
+            if target is None:
+                return self.__not_found_response()
+
+            if loader.drop(target):
+                return self._success_response()
+
+            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)
+            )
+
+        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)
+
+            if target is None:
+                return self.__not_found_response()
+
+            builder = secret_builder(target)
+
+            if new_name is not None:
+                builder.name = new_name
+
+            if domain is not None:
+                builder.domain = domain
+
+            if coded is not None:
+                builder.coded = 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:
+        validation = self._validation("name", name_validator(name))
+
+        if validation is not None:
+            return validation
+
+        with self.__secret_database(apikey) as loader:
+            result = loader.name_in_use(name)
+
+            return self._success_response(in_use = result, name = name)
+
+    def domain_search(self, apikey: str, domain: str) -> dict:
+        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:
+        with self.__secret_database(apikey) as loader:
+            results = loader.search_for_name(name) 
+
+            return secret_collection_response(results).response
 
-    @property
     def __not_found_response(self) -> dict:
         return self._fail_response(cause = "Secret not found.")
 

+ 59 - 0
assets/application_secret_response.py

@@ -0,0 +1,59 @@
+import typing
+
+from .secret import secret
+from .secret import secret_builder
+
+class secret_response:
+    def __init__(self, target: secret | secret_builder) -> None:
+        if isinstance(target, secret):
+            self.__target = target
+            return
+
+        self.__target = target.result
+
+    @property
+    def response(self) -> dict:
+        return {
+            "name": self.target.name,
+            "domain": self.target.domain,
+            "coded" : self.target.coded
+        }
+
+    @property
+    def target(self) -> secret:
+        return self.__target
+
+    @property
+    def builder(self) -> secret_builder:
+        return secret_builder(self.__target)
+
+class secret_collection_response:
+    def __init__(self, target: typing.Iterable[secret] | None = None) -> None:
+        self.__collection = []
+
+        if target is None:
+            return
+
+        if type(target) is list:
+            self.__collection = target.copy()
+            return
+
+        for count in target:
+            self.__collection.append(count)
+
+    @property
+    def response(self) -> dict:
+        return [
+            secret_response(count).response for count in self.collection 
+        ]
+
+    @property
+    def collection(self) -> list:
+        return self.__collection.copy()
+
+    def append(self, target: secret | secret_builder) -> object:
+        if isinstance(target, secret_builder):
+            target = target.result
+
+        self.__collection.append(target)
+        return self

+ 37 - 7
tests/008-application_secret.py

@@ -20,29 +20,59 @@ def drop_db() -> None:
 drop_db()
 
 connection = sqlmodel.create_engine("sqlite:///008-application_secret.db")
+
 user_app = assets.application_user(connection)
 secret_app = assets.application_secret(connection)
+crypter_app = assets.application_crypter(connection)
 
 sqlmodel.SQLModel.metadata.create_all(connection)
 
 user_app.register("test", "password")
-apikey = user_app.login("test", "password")["apikey"]
 
-print("Create test user, apikey: " + apikey)
+apikey = user_app.login("test", "password")["apikey"]
+print("Created test user, apikey: " + apikey)
 
-code_key = user_app.get(apikey)["code_key"]
-coder = assets.code_key_manager("password", code_key).coder
-coded = coder.encrypt("sample")
+coded = crypter_app.encrypt(apikey, "password", "SAMPLE")["crypted"]
+print("Encrypted content: " + coded)
 
 secret_app.create(apikey, "sample", "https://xyz.com", coded)
 
 print()
 print("Created secret.")
 print("Result:")
-print(secret_app.get(apikey, "sample"))
+coded_result = secret_app.get(apikey, "sample")["coded"]
+print(coded_result)
 
 print()
 print("Decoding:")
-print(coder.decrypt(secret_app.get(apikey, "sample")["coded"]))
+print(crypter_app.decrypt(apikey, "password", coded_result))
+
+print()
+print("Search by domain:")
+print(secret_app.domain_search(apikey, "xyz.com"))
+
+print()
+print("Search by name:")
+print(secret_app.name_search(apikey, "sam"))
+
+print()
+print("Name in use: ")
+print(secret_app.name_in_use(apikey, "sample"))
+
+print()
+print("Name not in use:")
+print(secret_app.name_in_use(apikey, "not_name"))
+
+print()
+print("Updating...")
+print(secret_app.update(apikey, "sample", "new_sample", "https:abc.pl"))
+print("After update:")
+print(secret_app.get(apikey, "new_sample"))
+
+print()
+print("Deleting...")
+print(secret_app.drop(apikey, "new_sample"))
+print("After delete:")
+print(secret_app.get(apikey, "new_sample"))
 
 drop_db()

+ 2 - 1
tests/009-application_crypter.py

@@ -55,4 +55,5 @@ print()
 print("Testing with bad apikey:")
 print(crypter_app.decrypt("NOT_EXISTS", "bad_psk", outside_sample_crypted))
 
-drop_db()
+drop_db()
+