diff --git a/docs/source/Resources/Secrets/Secrets_Type.rst b/docs/source/Resources/Secrets/Secrets_Type.rst new file mode 100644 index 0000000..af8d4ce --- /dev/null +++ b/docs/source/Resources/Secrets/Secrets_Type.rst @@ -0,0 +1,87 @@ +**Secrets Type** +=============== + + +.. _SecretsInfo: + +SecretsInfo +----------- + + **Attributes:** + + | id: :ref:`GenericID` + | Unique identifier for the secret. + + | key: str + | Key name of the secret. + + | tags: Optional[List[:ref:`TagsObj`]] + | List of tags associated with the secret. + + | value_length: int + | Length of the secret value. + + | created_at: datetime + | Date and time when the secret was created. + + | updated_at: datetime + | Date and time when the secret was last updated. + + +.. _SecretsCreate: + +SecretsCreate +------------- + + **Attributes:** + + | key: str + | Key name for the new secret. + + | value: str + | Value of the secret. + + | tags: Optional[List[:ref:`TagsObj`]] + | List of tags to associate with the secret. + + +.. _SecretsEdit: + +SecretsEdit +---------- + + **Attributes:** + + | value: Optional[str] + | New value for the secret. + + | tags: Optional[List[:ref:`TagsObj`]] + | Updated list of tags for the secret. + + +.. _SecretsFilter: + +SecretsFilter +------------ + + **Attributes:** + + | key: str + | Key name to filter secrets by. + + | tags: Optional[List[:ref:`TagsObj`]] + | Tags to filter secrets by. + + +.. _SecretsQuery: + +SecretsQuery(:ref:`Query`) +------------ + + **Attributes:** + + | fields: Optional[List[Literal["id", "key", "tags", "created_at", "updated_at"]]] + | List of fields to include in the query results. + + | filter: Optional[:ref:`SecretsFilter`] + | Filter criteria for the query. diff --git a/docs/source/Resources/Secrets/index.rst b/docs/source/Resources/Secrets/index.rst new file mode 100644 index 0000000..6851a7b --- /dev/null +++ b/docs/source/Resources/Secrets/index.rst @@ -0,0 +1,162 @@ +**Secrets** +========== + +Manage secrets in your application. + +======= +list +======= + +Retrieves a paginated list of all secrets stored in the profile with filtering and sorting options. + +See: `Secrets `_ + + **Parameters:** + + | *Optional* **queryObj**: :ref:`SecretsQuery` + | Query parameters to filter the results. + + .. code-block:: + :caption: **Default queryObj:** + + queryObj = { + "page": 1, + "fields": ["id", "key"], + "filter": {}, + "amount": 20, + "orderBy": ["key", "asc"] + } + + **Returns:** + + | list[:ref:`SecretsInfo`] + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Secrets" / "Access" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.secrets.list({ + "page": 1, + "fields": ["id", "key"], + "amount": 20 + }) + print(result) # [ { 'id': 'secret-id-123', 'key': 'API_KEY' } ] + + +======= +info +======= + +Retrieves detailed information about a specific secret using its ID. + +See: `Secrets `_ + + **Parameters:** + + | **secretID**: str + | Secret ID + + **Returns:** + + | :ref:`SecretsInfo` + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Secrets" / "Access" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + secret_info = resources.secrets.info("secret-id-123") + print(secret_info) # { 'id': 'secret-id-123', 'key': 'API_KEY' } + + +======= +create +======= + +Creates a new secret in the profile with the specified key and value. + +See: `Creating a Secret `_ + + **Parameters:** + + | **secretObj**: :ref:`SecretsCreate` + | Secret information + + **Returns:** + + | dict[str, :ref:`GenericID`] + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Secrets" / "Create" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.secrets.create({ + "key": "API_KEY", + "value": "my-secret-value" + }) + print(result) # { 'id': 'secret-id-132' } + + +======= +edit +======= + +Modifies the properties of an existing secret. + +See: `Secrets `_ + + **Parameters:** + + | **secretID**: str + | Secret ID + + | **secretObj**: :ref:`SecretsEdit` + | Secret information to update + + **Returns:** + + | string + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Secrets" / "Edit" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.secrets.edit("secret-id-123", { + "value": "new-secret-value", + "tags": [{"key": "type", "value": "user"}] + }) + print(result) # Successfully Updated + + +======= +delete +======= + +Permanently removes a secret from the profile. + +See: `Secrets `_ + + **Parameters:** + + | **secretID**: str + | Secret ID + + **Returns:** + + | string + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Secrets" / "delete" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.secrets.delete("secret-id-123") + print(result) # Successfully Removed diff --git a/docs/source/Resources/ServiceAuthorization/Service_Authorization_Types.rst b/docs/source/Resources/ServiceAuthorization/Service_Authorization_Types.rst new file mode 100644 index 0000000..8279ba7 --- /dev/null +++ b/docs/source/Resources/ServiceAuthorization/Service_Authorization_Types.rst @@ -0,0 +1,59 @@ +**Service Authorization Types** +=============================== + + +.. _GenericTokenAuthorization: + +GenericToken +----------- + + | **GenericToken**: str + | Token used on TagoIO, string with 34 characters + + +.. _TokenCreateResponseAuthorization: + +TokenCreateResponse +----------------- + + **Attributes:** + + | token: :ref:`GenericTokenAuthorization` + | The authorization token. + + | name: str + | Name of the token. + + | profile: :ref:`GenericID` + | Profile ID associated with the token. + + | additional_parameters: Optional[str] + | [Optional] Verification code to validate middleware requests. + + +.. _ServiceAuthorizationFilter: + +ServiceAuthorizationFilter +------------------------ + + **Attributes:** + + | name: str + | Name to filter service authorizations by. + + | token: :ref:`GenericToken` + | Token to filter service authorizations by. + + +.. _ServiceAuthorizationQuery: + +ServiceAuthorizationQuery(:ref:`Query`) +------------------- + + **Attributes:** + + | fields: Optional[List["name" or "token" or "verification_code" or "created_at"]] + | List of fields to include in the query results. + + | filter: Optional[:ref:`ServiceAuthorizationFilter`] + | Filter criteria for the query. diff --git a/docs/source/Resources/ServiceAuthorization/index.rst b/docs/source/Resources/ServiceAuthorization/index.rst new file mode 100644 index 0000000..55afa8b --- /dev/null +++ b/docs/source/Resources/ServiceAuthorization/index.rst @@ -0,0 +1,132 @@ +**Service Authorization** +======================= + +Manage service authorization tokens. + +=========== +tokenList +=========== + +Retrieves a paginated list of all service authorization tokens with filtering and sorting options. + +See: `Authorization `_ + + **Parameters:** + + | *Optional* **query**: :ref:`ServiceAuthorizationQuery` + | Query parameters to filter the results. + + .. code-block:: + :caption: **Default query:** + + query = { + "page": 1, + "fields": ["name", "token"], + "filter": {}, + "amount": 20, + "orderBy": ["created_at", "desc"] + } + + **Returns:** + + | list[:ref:`TokenDataList`] + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Service Authorization" / "Access" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.serviceAuthorization.tokenList({ + "page": 1, + "fields": ["name", "token", "verification_code"], + "amount": 20 + }) + print(result) # [ { 'name': 'API Service Token', 'token': 'token-xyz-123' } ] + + +============ +tokenCreate +============ + +Generates and retrieves a new service authorization token with specified permissions. + +See: `Authorization `_ + + **Parameters:** + + | **tokenParams**: :ref:`TokenData` + | Parameters for the new token + + **Returns:** + + | :ref:`TokenCreateResponseAuthorization` + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Service Authorization" / "Create" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.serviceAuthorization.tokenCreate({ + "name": "Service Token", + "verification_code": "additional parameter" + }) + print(result) # { 'token': 'token-xyz-123', 'name': 'Service Token', ... } + + +============ +tokenDelete +============ + +Permanently removes a service authorization token. + +See: `Authorization `_ + + **Parameters:** + + | **token**: :ref:`GenericTokenAuthorization` + | Token to be deleted + + **Returns:** + + | str + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Service Authorization" / "Delete" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.serviceAuthorization.tokenDelete("token-xyz-123") + print(result) # Token Successfully Removed + + +=========== +tokenEdit +=========== + +Updates a service authorization token with an optional verification code. + +See: `Authorization `_ + + **Parameters:** + + | **token**: :ref:`GenericTokenAuthorization` + | Token to be updated + + | *Optional* **verificationCode**: str + | New verification code for the token + + **Returns:** + + | str + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy "Service Authorization" / "Edit" in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.serviceAuthorization.tokenEdit("token-xyz-123", "verification-code") + print(result) # Authorization Code Successfully Updated diff --git a/docs/source/Resources/index.rst b/docs/source/Resources/index.rst index 44c02c0..1a758ff 100644 --- a/docs/source/Resources/index.rst +++ b/docs/source/Resources/index.rst @@ -40,3 +40,5 @@ Instance IntegrationConnector/index Profile/index Run/index + Secrets/index + ServiceAuthorization/index diff --git a/src/tagoio_sdk/modules/Resources/AccountDeprecated.py b/src/tagoio_sdk/modules/Resources/AccountDeprecated.py index 67d3188..ac243a5 100644 --- a/src/tagoio_sdk/modules/Resources/AccountDeprecated.py +++ b/src/tagoio_sdk/modules/Resources/AccountDeprecated.py @@ -14,6 +14,8 @@ from .Integration import Integration from .Profile import Profile from .Run import Run +from .Secrets import Secrets +from .Service_Authorization import ServiceAuthorization class AccountDeprecated(Account): @@ -51,3 +53,7 @@ def __init__(self, params: GenericModuleParams): """@deprecated moved to Resources().run""" self.profiles = Profile(params) """@deprecated moved to Resources().profiles""" + self.secrets = Secrets(params) + """@deprecated moved to Resources().secrets""" + self.serviceAuthorization = ServiceAuthorization(params) + """@deprecated moved to Resources().secrets""" diff --git a/src/tagoio_sdk/modules/Resources/Resources.py b/src/tagoio_sdk/modules/Resources/Resources.py index d7c3a33..3037a62 100644 --- a/src/tagoio_sdk/modules/Resources/Resources.py +++ b/src/tagoio_sdk/modules/Resources/Resources.py @@ -14,6 +14,8 @@ from .Notifications import Notifications from .Profile import Profile from .Run import Run +from .Secrets import Secrets +from .Service_Authorization import ServiceAuthorization from .Integration import Integration from .Account import Account @@ -35,5 +37,7 @@ def __init__(self, params: Optional[GenericModuleParams] = None): self.notifications = Notifications(params) self.profile = Profile(params) self.run = Run(params) + self.secrets = Secrets(params) + self.serviceAuthorization = ServiceAuthorization(params) self.integration = Integration(params) self.account = Account(params) diff --git a/src/tagoio_sdk/modules/Resources/Secrets.py b/src/tagoio_sdk/modules/Resources/Secrets.py new file mode 100644 index 0000000..a692c5d --- /dev/null +++ b/src/tagoio_sdk/modules/Resources/Secrets.py @@ -0,0 +1,160 @@ +from typing import Dict, List, Optional + +from tagoio_sdk.common.Common_Type import GenericID +from tagoio_sdk.common.tagoio_module import TagoIOModule +from tagoio_sdk.modules.Utils.dateParser import dateParser +from tagoio_sdk.modules.Resources.Secrets_Type import SecretsCreate, SecretsEdit, SecretsInfo, SecretsQuery + + +class Secrets(TagoIOModule): + def list(self, queryObj: Optional[SecretsQuery] = None) -> List[SecretsInfo]: + """ + @description: + Retrieves a paginated list of all secrets stored in the profile with filtering and sorting options. + + @see: + https://help.tago.io/portal/en/kb/articles/secrets Secrets + + @example: + If receive an error "Authorization Denied", check policy **Secrets** / **Access** in Access Management. + ```python + resources = Resources() + result = resources.secrets.list({ + "page": 1, + "fields": ["id", "key"], + "amount": 20 + }) + print(result) # [ { 'id': 'secret-id-123', 'key': 'API_KEY' } ] + ``` + """ + queryObj = queryObj or {} + + orderBy = "key,asc" + if "orderBy" in queryObj: + orderBy = f"{queryObj['orderBy'][0]},{queryObj['orderBy'][1]}" + + result = self.doRequest( + { + "path": "/secrets", + "method": "GET", + "params": { + "page": queryObj.get("page", 1), + "fields": queryObj.get("fields", ["id", "key"]), + "filter": queryObj.get("filter", {}), + "amount": queryObj.get("amount", 20), + "orderBy": orderBy, + }, + } + ) + + return result + + def info(self, secretID: GenericID) -> SecretsInfo: + """ + @description: + Retrieves detailed information about a specific secret using its ID. + + @see: + https://help.tago.io/portal/en/kb/articles/secrets Secrets + + @example: + If receive an error "Authorization Denied", check policy **Secrets** / **Access** in Access Management. + ```python + resources = Resources() + secret_info = resources.secrets.info("secret-id-123") + print(secret_info) # { 'id': 'secret-id-123', 'key': 'API_KEY' } + ``` + """ + result = self.doRequest( + { + "path": f"/secrets/{secretID}", + "method": "GET", + } + ) + + result = dateParser(result, ["created_at", "updated_at"]) + + return result + + def create(self, secretObj: SecretsCreate) -> Dict[str, GenericID]: + """ + @description: + Creates a new secret in the profile with the specified key and value. + + @see: + https://help.tago.io/portal/en/kb/articles/secrets#Creating_a_Secret Creating a Secret + + @example: + If receive an error "Authorization Denied", check policy **Secrets** / **Create** in Access Management. + ```python + resources = Resources() + result = resources.secrets.create({ + "key": "API_KEY", + "value": "my-secret-value" + }) + print(result) # { 'id': 'secret-id-132' } + ``` + """ + result = self.doRequest( + { + "path": "/secrets", + "method": "POST", + "body": {**secretObj}, + } + ) + + return result + + def edit(self, secretID: GenericID, secretObj: SecretsEdit) -> str: + """ + @description: + Modifies the properties of an existing secret. + + @see: + https://help.tago.io/portal/en/kb/articles/secrets Secrets + + @example: + If receive an error "Authorization Denied", check policy **Secrets** / **Edit** in Access Management. + ```python + resources = Resources() + result = resources.secrets.edit("secret-id-123", { + "value": "new-secret-value", + "tags": [{"key": "type", "value": "user"}] + }) + print(result) # Successfully Updated + ``` + """ + result = self.doRequest( + { + "path": f"/secrets/{secretID}", + "method": "PUT", + "body": {**secretObj}, + } + ) + + return result + + def delete(self, secretID: GenericID) -> str: + """ + @description: + Permanently removes a secret from the profile. + + @see: + https://help.tago.io/portal/en/kb/articles/secrets Secrets + + @example: + If receive an error "Authorization Denied", check policy **Secrets** / **delete** in Access Management. + ```python + resources = Resources() + result = resources.secrets.delete("secret-id-123") + print(result) # Successfully Removed + ``` + """ + result = self.doRequest( + { + "path": f"/secrets/{secretID}", + "method": "DELETE", + } + ) + + return result diff --git a/src/tagoio_sdk/modules/Resources/Secrets_Type.py b/src/tagoio_sdk/modules/Resources/Secrets_Type.py new file mode 100644 index 0000000..e5c13cd --- /dev/null +++ b/src/tagoio_sdk/modules/Resources/Secrets_Type.py @@ -0,0 +1,34 @@ +from datetime import datetime +from typing import List, Optional, TypedDict, Literal + +from tagoio_sdk.common.Common_Type import GenericID, TagsObj, Query + + +class SecretsInfo(TypedDict): + id: GenericID + key: str + tags: Optional[List[TagsObj]] + value_length: int + created_at: datetime + updated_at: datetime + + +class SecretsCreate(TypedDict): + key: str + value: str + tags: Optional[List[TagsObj]] + + +class SecretsEdit(TypedDict, total=False): + value: str + tags: Optional[List[TagsObj]] + + +class SecretsFilter(TypedDict): + key: str + tags: Optional[List[TagsObj]] + + +class SecretsQuery(Query): + fields: Optional[List[Literal["id", "key", "tags", "created_at", "updated_at"]]] + filter: Optional[SecretsFilter] diff --git a/src/tagoio_sdk/modules/Resources/Service_Authorization.py b/src/tagoio_sdk/modules/Resources/Service_Authorization.py new file mode 100644 index 0000000..abe1168 --- /dev/null +++ b/src/tagoio_sdk/modules/Resources/Service_Authorization.py @@ -0,0 +1,138 @@ +from typing import List, Optional + +from tagoio_sdk.common.Common_Type import TokenDataList, TokenData +from tagoio_sdk.common.tagoio_module import TagoIOModule +from tagoio_sdk.modules.Resources.Service_Authorization_Types import ( + TokenCreateResponse, + GenericToken, + ServiceAuthorizationQuery, +) +from tagoio_sdk.modules.Utils.dateParser import dateParserList + + +class ServiceAuthorization(TagoIOModule): + def tokenList(self, query: Optional[ServiceAuthorizationQuery] = None) -> List[TokenDataList]: + """ + @description: + Retrieves a paginated list of all service authorization tokens with filtering and sorting options. + + @see: + https://help.tago.io/portal/en/kb/articles/218-authorization Authorization + + @example: + If receive an error "Authorization Denied", check policy **Service Authorization** / **Access** in Access Management. + ```python + resources = Resources() + result = resources.serviceAuthorization.tokenList({ + "page": 1, + "fields": ["name", "token", "verification_code"], + "amount": 20 + }) + print(result) # [ { 'name': 'API Service Token', 'token': 'token-xyz-123' } ] + ``` + """ + query = query or {} + + orderBy = "created_at,desc" + if "orderBy" in query: + orderBy = f"{query['orderBy'][0]},{query['orderBy'][1]}" + + result = self.doRequest( + { + "path": "/serviceauth", + "method": "GET", + "params": { + "page": query.get("page", 1), + "fields": query.get("fields", ["name", "token"]), + "filter": query.get("filter", {}), + "amount": query.get("amount", 20), + "orderBy": orderBy, + }, + } + ) + + result = dateParserList(result, ["created_at", "last_authorization", "expire_time"]) + + return result + + def tokenCreate(self, tokenParams: TokenData) -> TokenCreateResponse: + """ + @description: + Generates and retrieves a new service authorization token with specified permissions. + + @see: + https://help.tago.io/portal/en/kb/articles/218-authorization Authorization + + @example: + If receive an error "Authorization Denied", check policy **Service Authorization** / **Create** in Access Management. + ```python + resources = Resources() + result = resources.serviceAuthorization.tokenCreate({ + "name": "Service Token", + "verification_code": "additional parameter" + }) + print(result) # { 'token': 'token-xyz-123', 'name': 'Service Token', ... } + ``` + """ + result = self.doRequest( + { + "path": "/serviceauth", + "method": "POST", + "body": tokenParams, + } + ) + + return result + + def tokenDelete(self, token: GenericToken) -> str: + """ + @description: + Permanently removes a service authorization token. + + @see: + https://help.tago.io/portal/en/kb/articles/218-authorization Authorization + + @example: + If receive an error "Authorization Denied", check policy **Service Authorization** / **Delete** in Access Management. + ```python + resources = Resources() + result = resources.serviceAuthorization.tokenDelete("token-xyz-123") + print(result) # Token Successfully Removed + ``` + """ + result = self.doRequest( + { + "path": f"/serviceauth/{token}", + "method": "DELETE", + } + ) + + return result + + def tokenEdit(self, token: GenericToken, verificationCode: Optional[str] = None) -> str: + """ + @description: + Updates a service authorization token with an optional verification code. + + @see: + https://help.tago.io/portal/en/kb/articles/218-authorization Authorization + + @example: + If receive an error "Authorization Denied", check policy **Service Authorization** / **Edit** in Access Management. + ```python + resources = Resources() + result = resources.serviceAuthorization.tokenEdit("token-xyz-123", "verification-code") + print(result) # Authorization Code Successfully Updated + ``` + """ + result = self.doRequest( + { + "path": f"/serviceauth/{token}", + "method": "PUT", + "body": { + "verification_code": verificationCode, + }, + } + ) + + return result diff --git a/src/tagoio_sdk/modules/Resources/Service_Authorization_Types.py b/src/tagoio_sdk/modules/Resources/Service_Authorization_Types.py new file mode 100644 index 0000000..e7b8b82 --- /dev/null +++ b/src/tagoio_sdk/modules/Resources/Service_Authorization_Types.py @@ -0,0 +1,24 @@ +from typing import List, Literal, Optional, TypedDict + +from tagoio_sdk.common.Common_Type import GenericID, Query + +GenericToken = str +"""Token used on TagoIO, string with 34 characters""" + + +class TokenCreateResponse(TypedDict): + token: GenericToken + name: str + profile: GenericID + verification_code: Optional[str] + """[Optional] Verification code to validate middleware requests.""" + + +class ServiceAuthorizationFilter(TypedDict): + name: str + token: GenericToken + + +class ServiceAuthorizationQuery(Query): + fields: Optional[List[Literal["name", "token", "verification_code", "created_at"]]] + filter: Optional[ServiceAuthorizationFilter] diff --git a/tests/Resources/test_secrets.py b/tests/Resources/test_secrets.py new file mode 100644 index 0000000..d633a21 --- /dev/null +++ b/tests/Resources/test_secrets.py @@ -0,0 +1,157 @@ +import os +from requests_mock.mocker import Mocker + +from tagoio_sdk.modules.Resources.Resources import Resources +from tagoio_sdk.modules.Resources.Secrets_Type import SecretsInfo + +os.environ["T_ANALYSIS_TOKEN"] = "your_token_value" + + +def mockSecretsList() -> list[SecretsInfo]: + return { + "status": True, + "result": [ + { + "id": "secret_id_1", + "key": "API_KEY", + "value_length": 32, + "tags": [{"key": "type", "value": "api"}], + "created_at": "2023-02-21T15:17:35.759Z", + "updated_at": "2023-02-21T15:17:35.759Z", + }, + { + "id": "secret_id_2", + "key": "DB_PASSWORD", + "value_length": 16, + "tags": [{"key": "type", "value": "database"}], + "created_at": "2023-02-22T10:30:45.123Z", + "updated_at": "2023-02-22T10:30:45.123Z", + }, + ], + } + + +def mockSecretInfo() -> SecretsInfo: + return { + "status": True, + "result": { + "id": "secret_id_1", + "key": "API_KEY", + "value_length": 32, + "tags": [{"key": "type", "value": "api"}], + "created_at": "2023-02-21T15:17:35.759Z", + "updated_at": "2023-02-21T15:17:35.759Z", + }, + } + + +def mockCreateSecret() -> dict: + return { + "status": True, + "result": {"id": "new_secret_id"}, + } + + +def testSecretsMethodList(requests_mock: Mocker) -> None: + """Test list method of Secrets class.""" + mock_response = mockSecretsList() + requests_mock.get("https://api.tago.io/secrets", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + query = { + "page": 1, + "fields": ["id", "key", "tags"], + "amount": 20, + "orderBy": ["key", "asc"], + } + + result = resources.secrets.list(query) + + # Check if the result is a list + assert isinstance(result, list) + # Check if the result has the expected items + assert len(result) == 2 + # Check if items have expected properties + assert result[0]["id"] == "secret_id_1" + assert result[0]["key"] == "API_KEY" + assert result[1]["id"] == "secret_id_2" + assert result[1]["key"] == "DB_PASSWORD" + assert result[0]["tags"][0]["key"] == "type" + assert result[0]["tags"][0]["value"] == "api" + + +def testSecretsMethodCreate(requests_mock: Mocker) -> None: + """Test create method of Secrets class.""" + mock_response = mockCreateSecret() + requests_mock.post("https://api.tago.io/secrets", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + secret_data = { + "key": "NEW_API_KEY", + "value": "secret_value_123", + "tags": [{"key": "type", "value": "api"}], + } + + result = resources.secrets.create(secret_data) + + # Check if result has expected structure + assert result["id"] == "new_secret_id" + + +def testSecretsMethodInfo(requests_mock: Mocker) -> None: + """Test info method of Secrets class.""" + mock_response = mockSecretInfo() + requests_mock.get("https://api.tago.io/secrets/secret_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + result = resources.secrets.info("secret_id_1") + + # Check if result has expected properties + assert result["id"] == "secret_id_1" + assert result["key"] == "API_KEY" + assert result["value_length"] == 32 + assert len(result["tags"]) == 1 + assert result["tags"][0]["key"] == "type" + assert result["tags"][0]["value"] == "api" + + +def testSecretsMethodEdit(requests_mock: Mocker) -> None: + """Test edit method of Secrets class.""" + mock_response = { + "status": True, + "result": "Successfully Updated", + } + + requests_mock.put("https://api.tago.io/secrets/secret_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + secret_data = { + "value": "new_secret_value", + "tags": [{"key": "environment", "value": "production"}], + } + + result = resources.secrets.edit("secret_id_1", secret_data) + + # Check if result has expected message + assert result == "Successfully Updated" + + +def testSecretsMethodDelete(requests_mock: Mocker) -> None: + """Test delete method of Secrets class.""" + mock_response = { + "status": True, + "result": "Successfully Removed", + } + + requests_mock.delete("https://api.tago.io/secrets/secret_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + result = resources.secrets.delete("secret_id_1") + + # Check if result has expected message + assert result == "Successfully Removed" diff --git a/tests/Resources/test_service_authorization.py b/tests/Resources/test_service_authorization.py new file mode 100644 index 0000000..e91b589 --- /dev/null +++ b/tests/Resources/test_service_authorization.py @@ -0,0 +1,120 @@ +import os +from requests_mock.mocker import Mocker + +from tagoio_sdk.modules.Resources.Resources import Resources +from tagoio_sdk.common.Common_Type import TokenDataList, TokenData +from tagoio_sdk.modules.Resources.Service_Authorization_Types import TokenCreateResponse + +os.environ["T_ANALYSIS_TOKEN"] = "your_token_value" + + +def mockTokenList() -> list[TokenDataList]: + return { + "status": True, + "result": [ + { + "token": "token_id_1", + "name": "Service Token 1", + "permission": "full", + "verification_code": "abc123", + "created_at": "2023-02-21T15:17:35.759Z", + "last_authorization": "2023-02-22T10:30:45.123Z", + "expire_time": "never", + }, + { + "token": "token_id_2", + "name": "Service Token 2", + "permission": "read", + "verification_code": "def456", + "created_at": "2023-03-15T08:22:17.432Z", + "last_authorization": "2023-03-16T14:05:22.789Z", + "expire_time": "2024-03-15T08:22:17.432Z", + }, + ], + } + + +def mockTokenCreate() -> dict: + return { + "status": True, + "result": { + "token": "new_token_id", + "name": "New Service Token", + "profile": "profile_id_123", + "additional_parameters": "verification_code_789", + }, + } + + +def testServiceAuthorizationMethodTokenList(requests_mock: Mocker) -> None: + """Test tokenList method of ServiceAuthorization class.""" + mock_response = mockTokenList() + requests_mock.get("https://api.tago.io/serviceauth", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + query = { + "page": 1, + "fields": ["name", "token", "permission"], + "amount": 20, + "orderBy": ["name", "asc"], + } + + result = resources.serviceAuthorization.tokenList(query) + + # Check if the result is a list + assert isinstance(result, list) + # Check if the result has the expected items + assert len(result) == 2 + # Check if items have expected properties + assert result[0]["token"] == "token_id_1" + assert result[0]["name"] == "Service Token 1" + assert result[0]["permission"] == "full" + assert result[1]["token"] == "token_id_2" + assert result[1]["name"] == "Service Token 2" + + +def testServiceAuthorizationMethodTokenCreate(requests_mock: Mocker) -> None: + """Test tokenCreate method of ServiceAuthorization class.""" + mock_response = mockTokenCreate() + requests_mock.post("https://api.tago.io/serviceauth", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + + token_data = { + "name": "New Service Token", + "verification_code": "verification_code_789", + "permission": "full", + } + + result = resources.serviceAuthorization.tokenCreate(token_data) + + # Check if result has expected structure + assert result["token"] == "new_token_id" + assert result["name"] == "New Service Token" + assert result["profile"] == "profile_id_123" + assert result["additional_parameters"] == "verification_code_789" + + +def testServiceAuthorizationMethodTokenDelete(requests_mock: Mocker) -> None: + """Test tokenDelete method of ServiceAuthorization class.""" + mock_response = {"status": True, "result": "Token Successfully Removed"} + requests_mock.delete("https://api.tago.io/serviceauth/token_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.serviceAuthorization.tokenDelete("token_id_1") + + # Check if result has expected message + assert result == "Token Successfully Removed" + + +def testServiceAuthorizationMethodTokenEdit(requests_mock: Mocker) -> None: + """Test tokenEdit method of ServiceAuthorization class.""" + mock_response = {"status": True, "result": "Authorization Code Successfully Updated"} + requests_mock.put("https://api.tago.io/serviceauth/token_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.serviceAuthorization.tokenEdit("token_id_1", "new_verification_code") + + # Check if result has expected message + assert result == "Authorization Code Successfully Updated"