auth0-python
Advanced tools
| from __future__ import annotations | ||
| from typing import Any, List # List is being used as list is already a method. | ||
| from ..rest import RestClient, RestClientOptions | ||
| from ..types import TimeoutType | ||
| class SelfServiceProfiles: | ||
| """Auth0 Self Service Profiles endpoints | ||
| Args: | ||
| domain (str): Your Auth0 domain, e.g: 'username.auth0.com' | ||
| token (str): Management API v2 Token | ||
| telemetry (bool, optional): Enable or disable Telemetry | ||
| (defaults to True) | ||
| timeout (float or tuple, optional): Change the requests | ||
| connect and read timeout. Pass a tuple to specify | ||
| both values separately or a float to set both to it. | ||
| (defaults to 5.0 for both) | ||
| protocol (str, optional): Protocol to use when making requests. | ||
| (defaults to "https") | ||
| rest_options (RestClientOptions): Pass an instance of | ||
| RestClientOptions to configure additional RestClient | ||
| options, such as rate-limit retries. | ||
| (defaults to None) | ||
| """ | ||
| def __init__( | ||
| self, | ||
| domain: str, | ||
| token: str, | ||
| telemetry: bool = True, | ||
| timeout: TimeoutType = 5.0, | ||
| protocol: str = "https", | ||
| rest_options: RestClientOptions | None = None, | ||
| ) -> None: | ||
| self.domain = domain | ||
| self.protocol = protocol | ||
| self.client = RestClient( | ||
| jwt=token, telemetry=telemetry, timeout=timeout, options=rest_options | ||
| ) | ||
| def _url(self, profile_id: str | None = None) -> str: | ||
| url = f"{self.protocol}://{self.domain}/api/v2/self-service-profiles" | ||
| if profile_id is not None: | ||
| return f"{url}/{profile_id}" | ||
| return url | ||
| def all( | ||
| self, | ||
| page: int = 0, | ||
| per_page: int = 25, | ||
| include_totals: bool = True, | ||
| ) -> List[dict[str, Any]]: | ||
| """List self-service profiles. | ||
| Args: | ||
| page (int, optional): The result's page number (zero based). By default, | ||
| retrieves the first page of results. | ||
| per_page (int, optional): The amount of entries per page. By default, | ||
| retrieves 25 results per page. | ||
| include_totals (bool, optional): True if the query summary is | ||
| to be included in the result, False otherwise. Defaults to True. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profiles | ||
| """ | ||
| params = { | ||
| "page": page, | ||
| "per_page": per_page, | ||
| "include_totals": str(include_totals).lower(), | ||
| } | ||
| return self.client.get(self._url(), params=params) | ||
| def create(self, body: dict[str, Any]) -> dict[str, Any]: | ||
| """Create a new self-service profile. | ||
| Args: | ||
| body (dict): Attributes for the new self-service profile. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/post-self-service-profiles | ||
| """ | ||
| return self.client.post(self._url(), data=body) | ||
| def get(self, profile_id: str) -> dict[str, Any]: | ||
| """Get a self-service profile. | ||
| Args: | ||
| id (str): The id of the self-service profile to retrieve. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profiles-by-id | ||
| """ | ||
| return self.client.get(self._url(profile_id)) | ||
| def delete(self, profile_id: str) -> None: | ||
| """Delete a self-service profile. | ||
| Args: | ||
| id (str): The id of the self-service profile to delete. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/delete-self-service-profiles-by-id | ||
| """ | ||
| self.client.delete(self._url(profile_id)) | ||
| def update(self, profile_id: str, body: dict[str, Any]) -> dict[str, Any]: | ||
| """Update a self-service profile. | ||
| Args: | ||
| id (str): The id of the self-service profile to update. | ||
| body (dict): Attributes of the self-service profile to modify. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/patch-self-service-profiles-by-id | ||
| """ | ||
| return self.client.patch(self._url(profile_id), data=body) | ||
| def get_custom_text( | ||
| self, profile_id: str, language: str, page: str | ||
| ) -> dict[str, Any]: | ||
| """Get the custom text for a self-service profile. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profile-custom-text | ||
| """ | ||
| url = self._url(f"{profile_id}/custom-text/{language}/{page}") | ||
| return self.client.get(url) | ||
| def update_custom_text( | ||
| self, profile_id: str, language: str, page: str, body: dict[str, Any] | ||
| ) -> dict[str, Any]: | ||
| """Update the custom text for a self-service profile. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/put-self-service-profile-custom-text | ||
| """ | ||
| url = self._url(f"{profile_id}/custom-text/{language}/{page}") | ||
| return self.client.put(url, data=body) | ||
| def create_sso_ticket( | ||
| self, profile_id: str, body: dict[str, Any] | ||
| ) -> dict[str, Any]: | ||
| """Create a single sign-on ticket for a self-service profile. | ||
| Args: | ||
| id (str): The id of the self-service profile to create the ticket for. | ||
| body (dict): Attributes for the single sign-on ticket. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/post-sso-ticket | ||
| """ | ||
| url = self._url(f"{profile_id}/sso-ticket") | ||
| return self.client.post(url, data=body) | ||
| def revoke_sso_ticket(self, profile_id: str, ticket_id: str) -> None: | ||
| """Revoke a single sign-on ticket for a self-service profile. | ||
| Args: | ||
| id (str): The id of the self-service profile to revoke the ticket from. | ||
| ticket (str): The ticket to revoke. | ||
| See: https://auth0.com/docs/api/management/v2/self-service-profiles/post-revoke | ||
| """ | ||
| url = self._url(f"{profile_id}/sso-ticket/{ticket_id}/revoke") | ||
| self.client.post(url) |
| import pytest | ||
| import random | ||
| @pytest.fixture(autouse=True) | ||
| def set_random_seed(): | ||
| random.seed(42) | ||
| print("Random seeded to 42") |
| import pytest | ||
| import random | ||
| @pytest.fixture(autouse=True) | ||
| def set_random_seed(): | ||
| random.seed(42) | ||
| print("Random seeded to 42") |
| import unittest | ||
| from unittest import mock | ||
| from ...management.self_service_profiles import SelfServiceProfiles | ||
| class TestSelfServiceProfiles(unittest.TestCase): | ||
| def test_init_with_optionals(self): | ||
| t = SelfServiceProfiles( | ||
| domain="domain", token="jwttoken", telemetry=False, timeout=(10, 2) | ||
| ) | ||
| self.assertEqual(t.client.options.timeout, (10, 2)) | ||
| telemetry_header = t.client.base_headers.get("Auth0-Client", None) | ||
| self.assertEqual(telemetry_header, None) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_all(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.all() | ||
| mock_instance.get.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles", | ||
| params={"page": 0, "per_page": 25, "include_totals": "true"}, | ||
| ) | ||
| s.all(page=1, per_page=50, include_totals=False) | ||
| mock_instance.get.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles", | ||
| params={"page": 1, "per_page": 50, "include_totals": "false"}, | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_create(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.create({"name": "test"}) | ||
| mock_instance.post.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles", data={"name": "test"} | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_get(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.get("an-id") | ||
| mock_instance.get.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id" | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_delete(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.delete("an-id") | ||
| mock_instance.delete.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id" | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_update(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.update("an-id", {"a": "b", "c": "d"}) | ||
| mock_instance.patch.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id", | ||
| data={"a": "b", "c": "d"}, | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_get_custom_text(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.get_custom_text("an-id", "en", "page") | ||
| mock_instance.get.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id/custom-text/en/page" | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_update_custom_text(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.update_custom_text("an-id", "en", "page", {"a": "b", "c": "d"}) | ||
| mock_instance.put.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id/custom-text/en/page", | ||
| data={"a": "b", "c": "d"}, | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_create_sso_ticket(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.create_sso_ticket("an-id", {"a": "b", "c": "d"}) | ||
| mock_instance.post.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id/sso-ticket", | ||
| data={"a": "b", "c": "d"}, | ||
| ) | ||
| @mock.patch("auth0.management.self_service_profiles.RestClient") | ||
| def test_revoke_sso_ticket(self, mock_rc): | ||
| mock_instance = mock_rc.return_value | ||
| s = SelfServiceProfiles(domain="domain", token="jwttoken") | ||
| s.revoke_sso_ticket("an-id", "ticket-id") | ||
| mock_instance.post.assert_called_with( | ||
| "https://domain/api/v2/self-service-profiles/an-id/sso-ticket/ticket-id/revoke" | ||
| ) |
| # This value is updated by `poetry_dynamic_versioning` during build time from the latest git tag | ||
| __version__ = "4.9.0" | ||
| __version__ = "4.10.0" | ||
@@ -4,0 +4,0 @@ from auth0.exceptions import Auth0Error, RateLimitError, TokenValidationError |
@@ -1,6 +0,8 @@ | ||
| from typing import Any | ||
| from typing import Any, Optional, Union, List, Dict | ||
| from .base import AuthenticationBase | ||
| import json | ||
| class BackChannelLogin(AuthenticationBase): | ||
@@ -10,3 +12,8 @@ """Back-Channel Login endpoint""" | ||
| def back_channel_login( | ||
| self, binding_message: str, login_hint: str, scope: str, **kwargs | ||
| self, | ||
| binding_message: str, | ||
| login_hint: str, | ||
| scope: str, | ||
| authorization_details: Optional[Union[str, List[Dict]]] = None, | ||
| **kwargs | ||
| ) -> Any: | ||
@@ -19,3 +26,4 @@ """Send a Back-Channel Login. | ||
| login_hint (str): String containing information about the user to contact for authentication. | ||
| login_hint (str): JSON string containing user details for authentication in the iss_sub format.Ensure | ||
| serialization before passing. | ||
@@ -25,10 +33,12 @@ scope(str): "openid" is a required scope.Multiple scopes are separated | ||
| **kwargs: Other fields to send along with the PAR. | ||
| authorization_details (str, list of dict, optional): JSON string or a list of dictionaries representing | ||
| Rich Authorization Requests (RAR) details to include in the CIBA request. | ||
| **kwargs: Other fields to send along with the request. | ||
| Returns: | ||
| auth_req_id, expires_in, interval | ||
| """ | ||
| return self.authenticated_post( | ||
| f"{self.protocol}://{self.domain}/bc-authorize", | ||
| data={ | ||
| data = { | ||
| "client_id": self.client_id, | ||
@@ -39,4 +49,16 @@ "binding_message": binding_message, | ||
| **kwargs, | ||
| }, | ||
| } | ||
| if authorization_details is not None: | ||
| if isinstance(authorization_details, str): | ||
| data["authorization_details"] = authorization_details | ||
| elif isinstance(authorization_details, list): | ||
| data["authorization_details"] = json.dumps(authorization_details) | ||
| data.update(kwargs) | ||
| return self.authenticated_post( | ||
| f"{self.protocol}://{self.domain}/bc-authorize", | ||
| data = data, | ||
| headers={"Content-Type": "application/x-www-form-urlencoded"}, | ||
| ) |
@@ -25,2 +25,3 @@ from ..utils import is_async_available | ||
| from .rules_configs import RulesConfigs | ||
| from .self_service_profiles import SelfServiceProfiles | ||
| from .stats import Stats | ||
@@ -63,2 +64,3 @@ from .tenants import Tenants | ||
| "Rules", | ||
| "SelfServiceProfiles", | ||
| "Stats", | ||
@@ -65,0 +67,0 @@ "Tenants", |
@@ -29,2 +29,3 @@ from __future__ import annotations | ||
| from .rules_configs import RulesConfigs | ||
| from .self_service_profiles import SelfServiceProfiles | ||
| from .stats import Stats | ||
@@ -90,2 +91,5 @@ from .tenants import Tenants | ||
| self.rules = Rules(domain, token, rest_options=rest_options) | ||
| self.self_service_profiles = SelfServiceProfiles( | ||
| domain, token, rest_options=rest_options | ||
| ) | ||
| self.stats = Stats(domain, token, rest_options=rest_options) | ||
@@ -92,0 +96,0 @@ self.tenants = Tenants(domain, token, rest_options=rest_options) |
@@ -83,3 +83,3 @@ | ||
| binding_message="This is a binding message.", | ||
| login_hint={"format": "iss_sub", "iss": "https://my.domain.auth0.com/", "sub": "auth0|USER_ID"}, | ||
| login_hint= json.dumps({"format": "iss_sub", "iss": "https://my.domain.auth0.com/", "sub": "auth0|USER_ID"}), | ||
| scope="openid", | ||
@@ -110,5 +110,5 @@ authorization_details=[ | ||
| "binding_message": "This is a binding message.", | ||
| "login_hint": {"format": "iss_sub", "iss": "https://my.domain.auth0.com/", "sub": "auth0|USER_ID" }, | ||
| "login_hint": json.dumps({"format": "iss_sub", "iss": "https://my.domain.auth0.com/", "sub": "auth0|USER_ID"}), | ||
| "scope": "openid", | ||
| "authorization_details": [ | ||
| "authorization_details": json.dumps([ | ||
| { | ||
@@ -127,15 +127,15 @@ "type":"payment_initiation","locations":["https://example.com/payments"], | ||
| "remittanceInformationUnstructured":"Ref Number Merchant" | ||
| }], | ||
| } | ||
| ]), | ||
| } | ||
| actual_data = kwargs["data"] | ||
| self.assertEqual(args[0], "https://my.domain.com/bc-authorize") | ||
| self.assertEqual( | ||
| json.dumps(actual_data, sort_keys=True), | ||
| json.dumps(expected_data, sort_keys=True) | ||
| actual_data, | ||
| expected_data, | ||
| "Request data does not match expected data after JSON serialization." | ||
| ) | ||
+6
-3
@@ -1,6 +0,5 @@ | ||
| Metadata-Version: 2.1 | ||
| Metadata-Version: 2.3 | ||
| Name: auth0-python | ||
| Version: 4.9.0 | ||
| Version: 4.10.0 | ||
| Summary: | ||
| Home-page: https://auth0.com | ||
| License: MIT | ||
@@ -16,2 +15,4 @@ Author: Auth0 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Programming Language :: Python :: 3.12 | ||
| Classifier: Programming Language :: Python :: 3.13 | ||
| Requires-Dist: aiohttp (>=3.10.11) | ||
@@ -22,2 +23,3 @@ Requires-Dist: cryptography (>=43.0.1) | ||
| Requires-Dist: urllib3 (>=2.2.3) | ||
| Project-URL: Homepage, https://auth0.com | ||
| Project-URL: Repository, https://github.com/auth0/auth0-python | ||
@@ -150,2 +152,3 @@ Description-Content-Type: text/markdown | ||
| - Rules() ( `Auth0().rules` ) | ||
| - SelfServiceProfiles() ( `Auth0().self_service_profiles` ) | ||
| - Stats() ( `Auth0().stats` ) | ||
@@ -152,0 +155,0 @@ - Tenants() ( `Auth0().tenants` ) |
+1
-1
@@ -7,3 +7,3 @@ [build-system] | ||
| name = "auth0-python" | ||
| version = "4.9.0" # This is replaced by dynamic versioning | ||
| version = "4.10.0" # This is replaced by dynamic versioning | ||
| description = "" | ||
@@ -10,0 +10,0 @@ authors = ["Auth0 <support@auth0.com>"] |
+1
-0
@@ -125,2 +125,3 @@  | ||
| - Rules() ( `Auth0().rules` ) | ||
| - SelfServiceProfiles() ( `Auth0().self_service_profiles` ) | ||
| - Stats() ( `Auth0().stats` ) | ||
@@ -127,0 +128,0 @@ - Tenants() ( `Auth0().tenants` ) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
540430
2.31%114
3.64%11420
2.26%