diff --git a/docs/source/Resources/Run/Run_Types.rst b/docs/source/Resources/Run/Run_Types.rst index 588da9b..0620063 100644 --- a/docs/source/Resources/Run/Run_Types.rst +++ b/docs/source/Resources/Run/Run_Types.rst @@ -319,6 +319,21 @@ LoginAsUserOptions | :default: "8 hours" +.. _EmailTestData: + +EmailTestData +------------- + +Type for the email test data. + + **Attributes:** + + | **subject**: str + | Subject of the test email. + + | **body**: str + | Body content of the test email. + .. _SAMLAttributeMappings: diff --git a/docs/source/Resources/Run/index.rst b/docs/source/Resources/Run/index.rst index 3a27538..ce60e23 100644 --- a/docs/source/Resources/Run/index.rst +++ b/docs/source/Resources/Run/index.rst @@ -1,320 +1,543 @@ - **Run** -======== +======= -Manage services in account. +Manage TagoRUN environment configuration and users. -======= +==== info -======= +==== -Get information about the TagoRUN service. +Retrieves information about the current Run environment configuration. - **Returns** +See: `TagoRun `_ | `Run Themes `_ - | **result**: :ref:`RunInfo` - | Information about the TagoRUN service. + **Returns:** + | :ref:`RunInfo` -======= + .. code-block:: python + + # If receive an error "Authorization Denied", check policy **Profile** / **Access TagoRun settings** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.info() + print(result) # {'name': 'My Run Environment', 'logo': 'https://example.com/logo.png', ...} + + +==== edit -======= +==== + +Updates the Run environment configuration settings. -Edit the TagoRUN service information. +See: `TagoRun `_ | `Run Themes `_ **Parameters:** - | **data**: :ref:`RunInfo` - | Updated information for the TagoRUN service. + | **data**: dict + | Run configuration data to update **Returns:** - | **result**: str - | Success message. + | str + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy **Profile** / **Edit TagoRun settings** in Access Management. + from tagoio_sdk import Resources + resources = Resources() + result = resources.run.edit({"name": "My Run Environment", "logo": "https://example.com/logo.png"}) + print(result) # TagoIO Run Successfully Updated -============ + +========= listUsers -============ +========= + +Retrieves a paginated list of Run users with customizable fields and filtering options. -List users in the TagoRUN service. +See: `TagoRun `_ **Parameters:** | **query**: :ref:`Query` - | Query parameters for filtering and sorting the user list. + | Query parameters for filtering and sorting - **Returns:** + .. code-block:: + :caption: **Default query:** - | **result**: list[:ref:`UserInfo`] - | List of user information. + query = { + "page": 1, + "fields": ["id", "name"], + "filter": {}, + "amount": 20, + "orderBy": ["name", "asc"] + } + **Returns:** -============ -userInfo -============ - -Get information about a specific user in the TagoRUN service. + | list[:ref:`UserInfo`] - **Parameters:** + .. code-block:: python - | **userID**: :ref:`GenericID` - | ID of the user. + # If receive an error "Authorization Denied", or return empty list check policy **Run User** / **Access** in Access Management. + from tagoio_sdk import Resources - **Returns:** + resources = Resources() + result = resources.run.listUsers({ + "page": 1, + "fields": ["id", "name", "email"], + "amount": 20 + }) + print(result) # [{'id': 'user-id-123', 'name': 'John Doe', 'email': 'example@email.com'}] - | **result**: :ref:`UserInfo` - | Information about the user. +======== +userInfo +======== -================ -userCreate -================ +Retrieves detailed information about a specific Run user. -Create a new user in the TagoRUN service. +See: `TagoRun `_ **Parameters:** - | **data**: :ref:`UserCreateInfo` - | Information for creating the user. + | **userID**: :ref:`GenericID` + | User identification **Returns:** - | **result**: str - | Success message. + | :ref:`UserInfo` + .. code-block:: python -================ + # If receive an error "Authorization Denied", check policy **Run User** / **Access** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.userInfo("user-id-123") + print(result) # {'id': 'user-id-123', 'name': 'John Doe', 'email': 'example@email.com', ...} + + +========== userCreate -================ +========== + +Creates a new user in the Run environment. -Create a new user in the TagoRUN service. +See: `TagoRun `_ **Parameters:** | **data**: :ref:`UserCreateInfo` - | Information for creating the user. + | User creation data **Returns:** - | **result**: str - | Success message. + | dict + .. code-block:: python -================ + # If receive an error "Authorization Denied", check policy **Run User** / **Create** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.userCreate({ + "name": "John Doe", + "email": "john@example.com", + "password": "secure123", + "timezone": "America/New_York" + }) + print(result) # {'user': 'user-id-123'} + + +======== userEdit -================ +======== -Edit information about a specific user in the TagoRUN service. +Updates information for an existing Run user. + +See: `TagoRun `_ **Parameters:** | **userID**: :ref:`GenericID` - | ID of the user. + | User identification - | **data**: :ref:`UserInfo` - | Updated information for the user. + | **data**: dict + | User data to update **Returns:** - | **result**: str - | Success message. + | str + .. code-block:: python -================== + # If receive an error "Authorization Denied", check policy **Run User** / **Edit** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.userEdit("user-id-123", {"name": "Updated Name"}) + print(result) # TagoIO Run User Successfully Updated + + +========== userDelete -================== +========== + +Permanently deletes a user from the Run environment. -Delete a specific user from the TagoRUN service. +See: `TagoRun `_ **Parameters:** | **userID**: :ref:`GenericID` - | ID of the user. + | User identification **Returns:** - | **result**: str - | Success message. + | str + .. code-block:: python -================== + # If receive an error "Authorization Denied", check policy **Run User** / **Delete** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.userDelete("user-id-123") + print(result) # Successfully Removed + + +=========== loginAsUser -================== +=========== -Log in as a specific user in the TagoRUN service. +Generates a login token to authenticate as a specific Run user. **Parameters:** | **userID**: :ref:`GenericID` - | ID of the user. + | User identification - | **options**: Optional[:ref:`LoginAsUserOptions`] - | Additional options for the login. + | *Optional* **options**: :ref:`LoginAsUserOptions` + | Login options (e.g., expire_time) **Returns:** - | **result**: :ref:`LoginResponseRunUser` - | Login response. + | :ref:`LoginResponse` + .. code-block:: python -================ + # If receive an error "Authorization Denied", check policy **Run User** / **Login as user** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.loginAsUser("user-id-123") + print(result["token"]) # eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ... + + +========= emailTest -================ +========= -Send a test email from the TagoRUN service. +Tests the email configuration by sending a test message. **Parameters:** - | **data**: :ref:`EmailBase` - | Email data including subject and body. + | **data**: :ref:`EmailTestData` + | Email test data with subject and body **Returns:** - | **result**: str - | Success message. + | str + .. code-block:: python -====================== + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.emailTest({"subject": "Test Email", "body": "This is a test message"}) + print(result) # E-mail sent to example@email.com + + +================ notificationList -====================== +================ + +Retrieves a list of notifications for a specific Run user. -List notifications for a specific user in the TagoRUN service. +See: `Notifications for Users `_ **Parameters:** | **userID**: :ref:`GenericID` - | ID of the user. + | User identification **Returns:** - | **result**: list[:ref:`NotificationInfo`] - | List of notification information. + | list[:ref:`NotificationInfo`] + .. code-block:: python -====================== + # If receive an error "Authorization Denied", check policy **Run User** / **Access notification** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.notificationList("user-id-123") + print(result) # [{'id': 'notification-id-123', 'title': 'System Update', 'message': 'Features', ...}] + + +================== notificationCreate -====================== +================== -Create a new notification for a specific user in the TagoRUN service. +Creates a new notification for a Run user. + +See: `Notifications for Users `_ **Parameters:** | **userID**: :ref:`GenericID` - | ID of the user. + | User identification | **data**: :ref:`NotificationCreate` - | Information for creating the notification. + | Notification data **Returns:** - | **result**: :ref:`NotificationCreateReturn` - | Information about the created notification. + | :ref:`NotificationCreateReturn` + .. code-block:: python -====================== + # If receive an error "Authorization Denied", check policy **Run User** / **Create notification** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.notificationCreate("user-id-123", { + "title": "Update", + "message": "New feature available" + }) + print(result) # {'id': 'notification-id-123'} + + +================ notificationEdit -====================== +================ + +Updates an existing notification in the Run environment. -Edit information about a specific notification in the TagoRUN service. +See: `Notifications for Users `_ **Parameters:** | **notificationID**: :ref:`GenericID` - | ID of the notification. + | Notification identification - | **data**: :ref:`NotificationCreate` - | Updated information for the notification. + | **data**: dict + | Notification data to update **Returns:** - | **result**: str - | Success message. + | str + .. code-block:: python -====================== + # If receive an error "Authorization Denied", check policy **Run User** / **Edit notification** in Access Management. + from tagoio_sdk import Resources + + resources = Resources() + result = resources.run.notificationEdit("notification-id-123", {"title": "Updated Title"}) + print(result) # TagoIO Notification User Successfully Updated + + +================== notificationDelete -====================== +================== -Delete a specific notification from the TagoRUN service. +Deletes a notification from the Run environment. + +See: `Notifications for Users `_ **Parameters:** | **notificationID**: :ref:`GenericID` - | ID of the notification. + | Notification identification **Returns:** - | **result**: str - | Success message. + | str + + .. code-block:: python + + # If receive an error "Authorization Denied", check policy **Run User** / **Delete notification** in Access Management. + from tagoio_sdk import Resources + resources = Resources() + result = resources.run.notificationDelete("notification-id-123") + print(result) # Successfully Removed -============ + +=========== ssoSAMLInfo -============ +=========== -Get the SAML Single Sign-On information for the account's RUN. +Retrieves the SAML Single Sign-On configuration information for the Run environment. +See: `Single Sign-On (SSO) `_ -============ + **Returns:** + + | :ref:`RunSAMLInfo` + + .. code-block:: python + + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.ssoSAMLInfo() + print(result) # {'sp': {'entity_id': 'https://example.com', ...}, ...} + + +=========== ssoSAMLEdit -============ +=========== + +Updates the SAML SSO configuration for the Run environment. -Edit the SAML Single Sign-On metadata and mappings for the account's RUN. +See: `Single Sign-On (SSO) `_ **Parameters:** | **data**: :ref:`RunSAMLEditInfo` - | Updated data for a RUN's SAML Single Sign-On configuration. + | SAML SSO configuration data + + **Returns:** + + | str + .. code-block:: python -=================== + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.ssoSAMLEdit({ + "active": True, + "idp_metadata": "..." + }) + print(result) # TagoIO Run SAML SSO Successfully Updated + + +================== createCustomDomain -=================== +================== -Create a TagoRUN custom domain for the profile. +Creates a custom domain configuration for the Run environment. + +See: `Custom Domain Configuration `_ **Parameters:** - | **profile_id**: str - | ID of the profile + | **profile_id**: str + | Profile identification -.. toctree:: + | **customDomainData**: :ref:`CustomDomainCreate` + | Custom domain configuration data - Run_Types + **Returns:** + | str -================ + .. code-block:: python + + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.createCustomDomain("profile-id-123", { + "domain": "app.mycompany.com" + }) + print(result) # Custom domain created successfully + + +=============== getCustomDomain -================ +=============== + +Retrieves the custom domain configuration for a Run profile. + +See: `Custom Domain Configuration `_ + + **Parameters:** -Set details of TagoRun custom domain for the profile. + | **profile_id**: str + | Profile identification - **Parameters** + **Returns:** + + | :ref:`CustomDomainInfo` + + .. code-block:: python - | **profile_id**: str - | ID of the profile + from tagoio_sdk import Resources + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.getCustomDomain("profile-id-123") + print(result) # {'domain': 'app.mycompany.com', 'verified': True, ...} -=================== + +================== deleteCustomDomain -=================== +================== + +Removes the custom domain configuration from a Run profile. -Delete a TagoRUN custom domain for the profile. +See: `Custom Domain Configuration `_ - **Parameters** + **Parameters:** - | **profile_id**: str - | ID of the profile + | **profile_id**: str + | Profile identification + + **Returns:** + | str -======================= + .. code-block:: python + + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.deleteCustomDomain("profile-id-123") + print(result) # Custom domain deleted successfully + + +====================== regenerateCustomDomain -======================= +====================== + +Regenerates the custom domain configuration for a Run profile. -Regenerate a TagoRUN custom domain for the profile. +See: `Custom Domain Configuration `_ - **Parameters** + **Parameters:** - | **profile_id**: str - | ID of the profile + | **profile_id**: str + | Profile identification + + **Returns:** + + | str + + .. code-block:: python + + from tagoio_sdk import Resources + + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.regenerateCustomDomain("profile-id-123") + print(result) # Custom domain regenerated successfully + + +.. toctree:: + + Run_Types diff --git a/src/tagoio_sdk/modules/Resources/Run.py b/src/tagoio_sdk/modules/Resources/Run.py index 63d7f8e..e7c4bf2 100644 --- a/src/tagoio_sdk/modules/Resources/Run.py +++ b/src/tagoio_sdk/modules/Resources/Run.py @@ -1,5 +1,5 @@ +from typing import Dict from typing import Optional -from typing import TypedDict from tagoio_sdk.common.Common_Type import GenericID from tagoio_sdk.common.Common_Type import Query @@ -9,6 +9,7 @@ from tagoio_sdk.modules.Resources.Notification_Type import NotificationInfo from tagoio_sdk.modules.Resources.Run_Type import CustomDomainCreate from tagoio_sdk.modules.Resources.Run_Type import CustomDomainInfo +from tagoio_sdk.modules.Resources.Run_Type import EmailTestData from tagoio_sdk.modules.Resources.Run_Type import LoginAsUserOptions from tagoio_sdk.modules.Resources.Run_Type import LoginResponse from tagoio_sdk.modules.Resources.Run_Type import RunInfo @@ -21,13 +22,23 @@ class Run(TagoIOModule): - """ - Manage services in account - Be sure to use an account token with “write” permissions when using - functions like create, edit and delete. - """ - def info(self) -> RunInfo: + """ + @description: + Retrieves information about the current Run environment configuration. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + https://help.tago.io/portal/en/kb/articles/run-themes Run Themes + + @example: + If receive an error "Authorization Denied", check policy **Profile** / **Access TagoRun settings** in Access Management. + ```python + resources = Resources() + result = resources.run.info() + print(result) # {'name': 'My Run Environment', 'logo': 'https://example.com/logo.png', ...} + ``` + """ result = self.doRequest( { "path": "/run", @@ -37,7 +48,23 @@ def info(self) -> RunInfo: return result - def edit(self, data: RunInfo) -> str: + def edit(self, data: Dict) -> str: + """ + @description: + Updates the Run environment configuration settings. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + https://help.tago.io/portal/en/kb/articles/run-themes Run Themes + + @example: + If receive an error "Authorization Denied", check policy **Profile** / **Edit TagoRun settings** in Access Management. + ```python + resources = Resources() + result = resources.run.edit({"name": "My Run Environment", "logo": "https://example.com/logo.png"}) + print(result) # TagoIO Run Successfully Updated + ``` + """ result = self.doRequest( { "path": "/run", @@ -48,7 +75,28 @@ def edit(self, data: RunInfo) -> str: return result - def listUsers(self, query: Query) -> list[UserInfo]: + def listUsers(self, query: Optional[Query] = None) -> list[UserInfo]: + """ + @description: + Retrieves a paginated list of Run users with customizable fields and filtering options. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + + @example: + If receive an error "Authorization Denied", or return empty list check policy **Run User** / **Access** in Access Management. + ```python + resources = Resources() + result = resources.run.listUsers({ + "page": 1, + "fields": ["id", "name", "email"], + "amount": 20 + }) + print(result) # [{'id': 'user-id-123', 'name': 'John Doe', 'email': 'example@email.com'}] + ``` + """ + if query is None: + query = {} if "orderBy" in query: firstArgument = query["orderBy"][0] secondArgument = query["orderBy"][1] @@ -74,6 +122,21 @@ def listUsers(self, query: Query) -> list[UserInfo]: return result def userInfo(self, userID: GenericID) -> UserInfo: + """ + @description: + Retrieves detailed information about a specific Run user. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Access** in Access Management. + ```python + resources = Resources() + result = resources.run.userInfo("user-id-123") + print(result) # {'id': 'user-id-123', 'name': 'John Doe', 'email': 'example@email.com', ...} + ``` + """ result = self.doRequest( { "path": f"/run/users/{userID}", @@ -85,7 +148,27 @@ def userInfo(self, userID: GenericID) -> UserInfo: return result - def userCreate(self, data: UserCreateInfo) -> str: + def userCreate(self, data: UserCreateInfo) -> Dict[str, str]: + """ + @description: + Creates a new user in the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Create** in Access Management. + ```python + resources = Resources() + result = resources.run.userCreate({ + "name": "John Doe", + "email": "john@example.com", + "password": "secure123", + "timezone": "America/New_York" + }) + print(result) # {'user': 'user-id-123'} + ``` + """ result = self.doRequest( { "path": "/run/users", @@ -96,7 +179,22 @@ def userCreate(self, data: UserCreateInfo) -> str: return result - def userEdit(self, userID: GenericID, data: UserInfo) -> str: + def userEdit(self, userID: GenericID, data: Dict) -> str: + """ + @description: + Updates information for an existing Run user. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Edit** in Access Management. + ```python + resources = Resources() + result = resources.run.userEdit("user-id-123", {"name": "Updated Name"}) + print(result) # TagoIO Run User Successfully Updated + ``` + """ result = self.doRequest( { "path": f"/run/users/{userID}", @@ -108,6 +206,21 @@ def userEdit(self, userID: GenericID, data: UserInfo) -> str: return result def userDelete(self, userID: GenericID) -> str: + """ + @description: + Permanently deletes a user from the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/191-tagorun TagoRun + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Delete** in Access Management. + ```python + resources = Resources() + result = resources.run.userDelete("user-id-123") + print(result) # Successfully Removed + ``` + """ result = self.doRequest( { "path": f"/run/users/{userID}", @@ -117,9 +230,19 @@ def userDelete(self, userID: GenericID) -> str: return result - def loginAsUser( - self, userID: GenericID, options: Optional[LoginAsUserOptions] - ) -> LoginResponse: + def loginAsUser(self, userID: GenericID, options: Optional[LoginAsUserOptions] = None) -> LoginResponse: + """ + @description: + Generates a login token to authenticate as a specific Run user. + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Login as user** in Access Management. + ```python + resources = Resources() + result = resources.run.loginAsUser("user-id-123") + print(result["token"]) # eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ... + ``` + """ result = self.doRequest( { "path": f"/run/users/{userID}/login", @@ -132,11 +255,18 @@ def loginAsUser( return result - class emailData(TypedDict): - subject: str - body: str - - def emailTest(self, data: emailData) -> str: + def emailTest(self, data: EmailTestData) -> str: + """ + @description: + Tests the email configuration by sending a test message. + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.emailTest({"subject": "Test Email", "body": "This is a test message"}) + print(result) # E-mail sent to example@email.com + ``` + """ result = self.doRequest( { "path": "/run/email_test", @@ -148,6 +278,21 @@ def emailTest(self, data: emailData) -> str: return result def notificationList(self, userID: GenericID) -> list[NotificationInfo]: + """ + @description: + Retrieves a list of notifications for a specific Run user. + + @see: + https://help.tago.io/portal/en/kb/articles/223-notifications-for-users Notifications for Users + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Access notification** in Access Management. + ```python + resources = Resources() + result = resources.run.notificationList("user-id-123") + print(result) # [{'id': 'notification-id-123', 'title': 'System Update', 'message': 'Features', ...}] + ``` + """ result = self.doRequest( { "path": f"/run/notification/{userID}", @@ -157,9 +302,25 @@ def notificationList(self, userID: GenericID) -> list[NotificationInfo]: return result - def notificationCreate( - self, userID: GenericID, data: NotificationCreate - ) -> NotificationCreateReturn: + def notificationCreate(self, userID: GenericID, data: NotificationCreate) -> NotificationCreateReturn: + """ + @description: + Creates a new notification for a Run user. + + @see: + https://help.tago.io/portal/en/kb/articles/223-notifications-for-users Notifications for Users + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Create notification** in Access Management. + ```python + resources = Resources() + result = resources.run.notificationCreate("user-id-123", { + "title": "Update", + "message": "New feature available" + }) + print(result) # {'id': 'notification-id-123'} + ``` + """ result = self.doRequest( { "path": "/run/notification/", @@ -173,9 +334,22 @@ def notificationCreate( return result - def notificationEdit( - self, notificationID: GenericID, data: NotificationCreate - ) -> str: + def notificationEdit(self, notificationID: GenericID, data: Dict) -> str: + """ + @description: + Updates an existing notification in the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/223-notifications-for-users Notifications for Users + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Edit notification** in Access Management. + ```python + resources = Resources() + result = resources.run.notificationEdit("notification-id-123", {"title": "Updated Title"}) + print(result) # TagoIO Notification User Successfully Updated + ``` + """ result = self.doRequest( { "path": f"/run/notification/{notificationID}", @@ -187,6 +361,21 @@ def notificationEdit( return result def notificationDelete(self, notificationID: GenericID) -> str: + """ + @description: + Deletes a notification from the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/223-notifications-for-users Notifications for Users + + @example: + If receive an error "Authorization Denied", check policy **Run User** / **Delete notification** in Access Management. + ```python + resources = Resources() + result = resources.run.notificationDelete("notification-id-123") + print(result) # Successfully Removed + ``` + """ result = self.doRequest( { "path": f"/run/notification/{notificationID}", @@ -198,9 +387,19 @@ def notificationDelete(self, notificationID: GenericID) -> str: def ssoSAMLInfo(self) -> RunSAMLInfo: """ - Get the SAML Single Sign-On information for the account's RUN. + @description: + Retrieves the SAML Single Sign-On configuration information for the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/491-single-sign-on-sso Single Sign-On (SSO) + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.ssoSAMLInfo() + print(result) # {'sp': {'entity_id': 'https://example.com', ...}, ...} + ``` """ - result = self.doRequest( { "path": "/run/sso/saml", @@ -212,10 +411,22 @@ def ssoSAMLInfo(self) -> RunSAMLInfo: def ssoSAMLEdit(self, data: RunSAMLEditInfo) -> str: """ - Edit the SAML Single Sign-On metadata and mappings for the account's RUN. - :param: data Updated data for a RUN's SAML Single Sign-On configuration. + @description: + Updates the SAML SSO configuration for the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/491-single-sign-on-sso Single Sign-On (SSO) + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.ssoSAMLEdit({ + "active": True, + "idp_metadata": "..." + }) + print(result) # TagoIO Run SAML SSO Successfully Updated + ``` """ - result = self.doRequest( { "path": "/run/sso/saml", @@ -226,16 +437,23 @@ def ssoSAMLEdit(self, data: RunSAMLEditInfo) -> str: return result - def createCustomDomain( - self, profile_id: str, customDomainData: CustomDomainCreate - ) -> str: + def createCustomDomain(self, profile_id: str, customDomainData: CustomDomainCreate) -> str: """ - Create a TagoRUN custom domain for the profile. - :param: profile_id ID of the profile - :param: customDomainData query params - :returns: Success message. + @description: + Creates a custom domain configuration for the Run environment. + + @see: + https://help.tago.io/portal/en/kb/articles/custom-domain-configuration Custom Domain Configuration + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.createCustomDomain("profile-id-123", { + "domain": "app.mycompany.com" + }) + print(result) # Custom domain created successfully + ``` """ - result = self.doRequest( { "path": f"/run/customdomain/{profile_id}", @@ -248,11 +466,19 @@ def createCustomDomain( def getCustomDomain(self, profile_id: str) -> CustomDomainInfo: """ - set details of TagoRun custom domain for the profile. - :param: profile_id ID of the profile - :returns: Data for the profile's custom DNS configuration. + @description: + Retrieves the custom domain configuration for a Run profile. + + @see: + https://help.tago.io/portal/en/kb/articles/custom-domain-configuration Custom Domain Configuration + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.getCustomDomain("profile-id-123") + print(result) # {'domain': 'app.mycompany.com', 'verified': True, ...} + ``` """ - result = self.doRequest( { "path": f"/run/customdomain/{profile_id}", @@ -266,11 +492,19 @@ def getCustomDomain(self, profile_id: str) -> CustomDomainInfo: def deleteCustomDomain(self, profile_id: str) -> str: """ - delete a TagoRUN custom domain for the profile. - :param: profile_id ID of the profile - :returns: Success message. + @description: + Removes the custom domain configuration from a Run profile. + + @see: + https://help.tago.io/portal/en/kb/articles/custom-domain-configuration Custom Domain Configuration + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.deleteCustomDomain("profile-id-123") + print(result) # Custom domain deleted successfully + ``` """ - result = self.doRequest( { "path": f"/run/customdomain/{profile_id}", @@ -281,11 +515,19 @@ def deleteCustomDomain(self, profile_id: str) -> str: def regenerateCustomDomain(self, profile_id: str) -> str: """ - Regenerate a TagoRUN custom domain for the profile. - :param: profile_id ID of the profile - :returns: Success message. + @description: + Regenerates the custom domain configuration for a Run profile. + + @see: + https://help.tago.io/portal/en/kb/articles/custom-domain-configuration Custom Domain Configuration + + @example: + ```python + resources = Resources({"token": "YOUR-PROFILE-TOKEN"}) + result = resources.run.regenerateCustomDomain("profile-id-123") + print(result) # Custom domain regenerated successfully + ``` """ - result = self.doRequest( { "path": f"/run/customdomain/regenerate/{profile_id}", diff --git a/src/tagoio_sdk/modules/Resources/Run_Type.py b/src/tagoio_sdk/modules/Resources/Run_Type.py index e18dcb8..6e22b66 100644 --- a/src/tagoio_sdk/modules/Resources/Run_Type.py +++ b/src/tagoio_sdk/modules/Resources/Run_Type.py @@ -255,6 +255,17 @@ class LoginAsUserOptions(TypedDict): """ +class EmailTestData(TypedDict): + subject: str + """ + Subject of the test email. + """ + body: str + """ + Body content of the test email. + """ + + class SAMLAttributeMappings(TypedDict): email: str firstName: str diff --git a/tests/Resources/test_run.py b/tests/Resources/test_run.py new file mode 100644 index 0000000..67216d8 --- /dev/null +++ b/tests/Resources/test_run.py @@ -0,0 +1,421 @@ +import os + +from requests_mock.mocker import Mocker + +from tagoio_sdk.modules.Resources.Resources import Resources + + +os.environ["T_ANALYSIS_TOKEN"] = "your_token_value" + + +def mockRunInfo() -> dict: + return { + "status": True, + "result": { + "profile": "profile_id_123", + "active": True, + "name": "My Run Environment", + "sub_title": "IoT Application", + "url": "myapp.run.tago.io", + "email_domain": None, + "signup_method": "default", + "favicon": None, + "logo": "https://example.com/logo.png", + "signup_logo": None, + "signup_logo_options": {}, + "sidebar_buttons": [], + "signup_fields": [], + "email_templates": {}, + "feature_devicewifisetup": {}, + "feature_geolocation": {}, + "theme": {}, + "integration": {}, + "sso_saml_active": False, + "security": {}, + }, + } + + +def mockRunEdit() -> dict: + return {"status": True, "result": "TagoIO Run Successfully Updated"} + + +def mockUserList() -> dict: + return { + "status": True, + "result": [ + { + "id": "user_id_1", + "name": "John Doe", + "email": "john@example.com", + "timezone": "America/New_York", + "created_at": "2023-02-21T15:17:35.759Z", + "updated_at": "2023-02-21T15:17:35.759Z", + "last_login": "2023-02-21T15:17:35.759Z", + }, + { + "id": "user_id_2", + "name": "Jane Smith", + "email": "jane@example.com", + "timezone": "America/Los_Angeles", + "created_at": "2023-02-21T16:17:35.759Z", + "updated_at": "2023-02-21T16:17:35.759Z", + "last_login": "2023-02-21T16:17:35.759Z", + }, + ], + } + + +def mockUserInfo() -> dict: + return { + "status": True, + "result": { + "id": "user_id_1", + "name": "John Doe", + "email": "john@example.com", + "timezone": "America/New_York", + "company": "ACME Corp", + "phone": "+1234567890", + "language": "en-US", + "profile": "profile_id_123", + "active": True, + "newsletter": False, + "last_login": "2023-02-21T15:17:35.759Z", + "created_at": "2023-02-21T15:17:35.759Z", + "updated_at": "2023-02-21T15:17:35.759Z", + "options": {}, + "tags": [{"key": "role", "value": "admin"}], + }, + } + + +def mockUserCreate() -> dict: + return {"status": True, "result": {"user": "user_id_new"}} + + +def mockUserEdit() -> dict: + return {"status": True, "result": "TagoIO Run User Successfully Updated"} + + +def mockUserDelete() -> dict: + return {"status": True, "result": "Successfully Removed"} + + +def mockLoginAsUser() -> dict: + return { + "status": True, + "result": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...", + "expire_date": "2024-02-21T15:17:35.759Z", + }, + } + + +def mockEmailTest() -> dict: + return {"status": True, "result": "E-mail sent to example@email.com"} + + +def mockNotificationList() -> dict: + return { + "status": True, + "result": [ + { + "id": "notification_id_1", + "title": "System Update", + "message": "New features available", + }, + { + "id": "notification_id_2", + "title": "Maintenance", + "message": "Scheduled maintenance tonight", + }, + ], + } + + +def mockNotificationCreate() -> dict: + return {"status": True, "result": {"id": "notification_id_new"}} + + +def mockNotificationEdit() -> dict: + return {"status": True, "result": "TagoIO Notification User Successfully Updated"} + + +def mockNotificationDelete() -> dict: + return {"status": True, "result": "Successfully Removed"} + + +def mockSSOSAMLInfo() -> dict: + return { + "status": True, + "result": { + "sp": { + "entity_id": "https://example.com", + "acs_url": "https://example.com/acs", + "metadata": "...", + }, + "idp": {"issuer": "https://idp.example.com"}, + "mapping": {"email": "email", "firstName": "firstName"}, + }, + } + + +def mockSSOSAMLEdit() -> dict: + return {"status": True, "result": "TagoIO Run SAML SSO Successfully Updated"} + + +def mockCustomDomainCreate() -> dict: + return {"status": True, "result": "Custom domain created successfully"} + + +def mockCustomDomainInfo() -> dict: + return { + "status": True, + "result": { + "active": True, + "domain": "mycompany.com", + "subdomain": "app", + "email": "app.mycompany.com", + "dns_ssl": {"status": True, "type": "TXT", "key": "key1", "value": "value1"}, + "dns_page": {"status": True, "type": "CNAME", "key": "key2", "value": "value2"}, + "dns_email_1": {"status": True, "type": "MX", "key": "key3", "value": "value3"}, + "dns_email_2": {"status": True, "type": "TXT", "key": "key4", "value": "value4"}, + "dns_email_3": {"status": True, "type": "TXT", "key": "key5", "value": "value5"}, + "created_at": "2023-02-21T15:17:35.759Z", + }, + } + + +def mockCustomDomainDelete() -> dict: + return {"status": True, "result": "Custom domain deleted successfully"} + + +def mockCustomDomainRegenerate() -> dict: + return {"status": True, "result": "Custom domain regenerated successfully"} + + +def testRunMethodInfo(requests_mock: Mocker) -> None: + """Test info method of Run class.""" + mock_response = mockRunInfo() + requests_mock.get("https://api.tago.io/run", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.info() + + assert result["name"] == "My Run Environment" + assert result["active"] is True + + +def testRunMethodEdit(requests_mock: Mocker) -> None: + """Test edit method of Run class.""" + mock_response = mockRunEdit() + requests_mock.put("https://api.tago.io/run", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.edit({"name": "Updated Name"}) + + assert result == "TagoIO Run Successfully Updated" + + +def testRunMethodListUsers(requests_mock: Mocker) -> None: + """Test listUsers method of Run class.""" + mock_response = mockUserList() + requests_mock.get("https://api.tago.io/run/users", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.listUsers({"page": 1, "amount": 20}) + + assert isinstance(result, list) + assert len(result) == 2 + assert result[0]["id"] == "user_id_1" + assert result[1]["id"] == "user_id_2" + + +def testRunMethodUserInfo(requests_mock: Mocker) -> None: + """Test userInfo method of Run class.""" + mock_response = mockUserInfo() + requests_mock.get("https://api.tago.io/run/users/user_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.userInfo("user_id_1") + + assert result["id"] == "user_id_1" + assert result["name"] == "John Doe" + assert result["email"] == "john@example.com" + + +def testRunMethodUserCreate(requests_mock: Mocker) -> None: + """Test userCreate method of Run class.""" + mock_response = mockUserCreate() + requests_mock.post("https://api.tago.io/run/users", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.userCreate( + { + "name": "New User", + "email": "newuser@example.com", + "password": "secure123", + "timezone": "America/New_York", + } + ) + + assert result["user"] == "user_id_new" + + +def testRunMethodUserEdit(requests_mock: Mocker) -> None: + """Test userEdit method of Run class.""" + mock_response = mockUserEdit() + requests_mock.put("https://api.tago.io/run/users/user_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.userEdit("user_id_1", {"name": "Updated Name"}) + + assert result == "TagoIO Run User Successfully Updated" + + +def testRunMethodUserDelete(requests_mock: Mocker) -> None: + """Test userDelete method of Run class.""" + mock_response = mockUserDelete() + requests_mock.delete("https://api.tago.io/run/users/user_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.userDelete("user_id_1") + + assert result == "Successfully Removed" + + +def testRunMethodLoginAsUser(requests_mock: Mocker) -> None: + """Test loginAsUser method of Run class.""" + mock_response = mockLoginAsUser() + requests_mock.get("https://api.tago.io/run/users/user_id_1/login", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.loginAsUser("user_id_1") + + assert "token" in result + assert result["token"].startswith("eyJ") + + +def testRunMethodEmailTest(requests_mock: Mocker) -> None: + """Test emailTest method of Run class.""" + mock_response = mockEmailTest() + requests_mock.post("https://api.tago.io/run/email_test", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.emailTest({"subject": "Test", "body": "Test message"}) + + assert result == "E-mail sent to example@email.com" + + +def testRunMethodNotificationList(requests_mock: Mocker) -> None: + """Test notificationList method of Run class.""" + mock_response = mockNotificationList() + requests_mock.get("https://api.tago.io/run/notification/user_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.notificationList("user_id_1") + + assert isinstance(result, list) + assert len(result) == 2 + assert result[0]["id"] == "notification_id_1" + + +def testRunMethodNotificationCreate(requests_mock: Mocker) -> None: + """Test notificationCreate method of Run class.""" + mock_response = mockNotificationCreate() + requests_mock.post("https://api.tago.io/run/notification/", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.notificationCreate("user_id_1", {"title": "Alert", "message": "Important message"}) + + assert result["id"] == "notification_id_new" + + +def testRunMethodNotificationEdit(requests_mock: Mocker) -> None: + """Test notificationEdit method of Run class.""" + mock_response = mockNotificationEdit() + requests_mock.put("https://api.tago.io/run/notification/notification_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.notificationEdit("notification_id_1", {"title": "Updated Title"}) + + assert result == "TagoIO Notification User Successfully Updated" + + +def testRunMethodNotificationDelete(requests_mock: Mocker) -> None: + """Test notificationDelete method of Run class.""" + mock_response = mockNotificationDelete() + requests_mock.delete("https://api.tago.io/run/notification/notification_id_1", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.notificationDelete("notification_id_1") + + assert result == "Successfully Removed" + + +def testRunMethodSSOSAMLInfo(requests_mock: Mocker) -> None: + """Test ssoSAMLInfo method of Run class.""" + mock_response = mockSSOSAMLInfo() + requests_mock.get("https://api.tago.io/run/sso/saml", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.ssoSAMLInfo() + + assert "sp" in result + assert "idp" in result + + +def testRunMethodSSOSAMLEdit(requests_mock: Mocker) -> None: + """Test ssoSAMLEdit method of Run class.""" + mock_response = mockSSOSAMLEdit() + requests_mock.put("https://api.tago.io/run/sso/saml", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.ssoSAMLEdit({"active": True, "idp_metadata": "..."}) + + assert result == "TagoIO Run SAML SSO Successfully Updated" + + +def testRunMethodCreateCustomDomain(requests_mock: Mocker) -> None: + """Test createCustomDomain method of Run class.""" + mock_response = mockCustomDomainCreate() + requests_mock.post("https://api.tago.io/run/customdomain/profile_id_123", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.createCustomDomain("profile_id_123", {"domain": "mycompany.com", "subdomain": "app"}) + + assert result == "Custom domain created successfully" + + +def testRunMethodGetCustomDomain(requests_mock: Mocker) -> None: + """Test getCustomDomain method of Run class.""" + mock_response = mockCustomDomainInfo() + requests_mock.get("https://api.tago.io/run/customdomain/profile_id_123", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.getCustomDomain("profile_id_123") + + assert result["domain"] == "mycompany.com" + assert result["active"] is True + + +def testRunMethodDeleteCustomDomain(requests_mock: Mocker) -> None: + """Test deleteCustomDomain method of Run class.""" + mock_response = mockCustomDomainDelete() + requests_mock.delete("https://api.tago.io/run/customdomain/profile_id_123", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.deleteCustomDomain("profile_id_123") + + assert result == "Custom domain deleted successfully" + + +def testRunMethodRegenerateCustomDomain(requests_mock: Mocker) -> None: + """Test regenerateCustomDomain method of Run class.""" + mock_response = mockCustomDomainRegenerate() + requests_mock.put("https://api.tago.io/run/customdomain/regenerate/profile_id_123", json=mock_response) + + resources = Resources({"token": "your_token_value"}) + result = resources.run.regenerateCustomDomain("profile_id_123") + + assert result == "Custom domain regenerated successfully"