auth0-python 4.2.0__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {auth0-python-4.2.0 → auth0-python-4.3.0}/PKG-INFO +1 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/__init__.py +1 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/asyncify.py +32 -23
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/async_token_verifier.py +30 -10
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/base.py +33 -13
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/client_authentication.py +17 -11
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/database.py +22 -16
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/delegated.py +11 -7
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/enterprise.py +4 -2
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/get_token.py +39 -25
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/passwordless.py +8 -4
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/revoke_token.py +3 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/social.py +3 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/token_verifier.py +61 -29
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/users.py +13 -7
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/exceptions.py +14 -3
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/branding.py +1 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/connections.py +4 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/rest.py +72 -40
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/rest_async.py +39 -15
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_get_token.py +16 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_branding.py +7 -5
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_connections.py +23 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test_async/test_asyncify.py +27 -0
- auth0-python-4.3.0/auth0/types.py +5 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/utils.py +1 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0_python.egg-info/PKG-INFO +1 -1
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0_python.egg-info/SOURCES.txt +1 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/LICENSE +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/README.md +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/authentication/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/actions.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/async_auth0.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/attack_protection.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/auth0.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/blacklists.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/client_credentials.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/client_grants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/clients.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/custom_domains.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/device_credentials.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/email_templates.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/emails.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/grants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/guardian.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/hooks.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/jobs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/log_streams.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/logs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/organizations.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/prompts.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/resource_servers.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/roles.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/rules.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/rules_configs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/stats.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/tenants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/tickets.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/user_blocks.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/users.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/management/users_by_email.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_base.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_database.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_delegated.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_enterprise.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_passwordless.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_revoke_token.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_social.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_token_verifier.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/authentication/test_users.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_actions.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_atack_protection.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_auth0.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_blacklists.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_client_credentials.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_client_grants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_clients.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_custom_domains.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_device_credentials.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_email_endpoints.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_emails.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_grants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_guardian.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_hooks.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_jobs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_log_streams.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_logs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_organizations.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_prompts.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_resource_servers.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_rest.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_roles.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_rules.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_rules_configs.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_stats.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_tenants.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_tickets.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_user_blocks.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_users.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test/management/test_users_by_email.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test_async/__init__.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test_async/test_async_auth0.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0/test_async/test_async_token_verifier.py +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0_python.egg-info/dependency_links.txt +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0_python.egg-info/requires.txt +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/auth0_python.egg-info/top_level.txt +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/setup.cfg +0 -0
- {auth0-python-4.2.0 → auth0-python-4.3.0}/setup.py +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import aiohttp
|
|
2
2
|
|
|
3
|
+
from auth0.authentication.base import AuthenticationBase
|
|
4
|
+
from auth0.rest import RestClientOptions
|
|
3
5
|
from auth0.rest_async import AsyncRestClient
|
|
4
6
|
|
|
5
7
|
|
|
@@ -19,7 +21,7 @@ def asyncify(cls):
|
|
|
19
21
|
if callable(getattr(cls, func)) and not func.startswith("_")
|
|
20
22
|
]
|
|
21
23
|
|
|
22
|
-
class
|
|
24
|
+
class AsyncManagementClient(cls):
|
|
23
25
|
def __init__(
|
|
24
26
|
self,
|
|
25
27
|
domain,
|
|
@@ -29,40 +31,47 @@ def asyncify(cls):
|
|
|
29
31
|
protocol="https",
|
|
30
32
|
rest_options=None,
|
|
31
33
|
):
|
|
32
|
-
|
|
33
|
-
# Wrap the auth client
|
|
34
|
-
super().__init__(domain, telemetry, timeout, protocol)
|
|
35
|
-
else:
|
|
36
|
-
# Wrap the mngtmt client
|
|
37
|
-
super().__init__(
|
|
38
|
-
domain, token, telemetry, timeout, protocol, rest_options
|
|
39
|
-
)
|
|
34
|
+
super().__init__(domain, token, telemetry, timeout, protocol, rest_options)
|
|
40
35
|
self.client = AsyncRestClient(
|
|
41
36
|
jwt=token, telemetry=telemetry, timeout=timeout, options=rest_options
|
|
42
37
|
)
|
|
43
38
|
|
|
44
|
-
class
|
|
39
|
+
class AsyncAuthenticationClient(cls):
|
|
45
40
|
def __init__(
|
|
46
41
|
self,
|
|
47
42
|
domain,
|
|
48
|
-
|
|
43
|
+
client_id,
|
|
44
|
+
client_secret=None,
|
|
45
|
+
client_assertion_signing_key=None,
|
|
46
|
+
client_assertion_signing_alg=None,
|
|
49
47
|
telemetry=True,
|
|
50
48
|
timeout=5.0,
|
|
51
49
|
protocol="https",
|
|
52
|
-
rest_options=None,
|
|
53
50
|
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
51
|
+
super().__init__(
|
|
52
|
+
domain,
|
|
53
|
+
client_id,
|
|
54
|
+
client_secret,
|
|
55
|
+
client_assertion_signing_key,
|
|
56
|
+
client_assertion_signing_alg,
|
|
57
|
+
telemetry,
|
|
58
|
+
timeout,
|
|
59
|
+
protocol,
|
|
60
|
+
)
|
|
61
|
+
self.client = AsyncRestClient(
|
|
62
|
+
None,
|
|
63
|
+
options=RestClientOptions(
|
|
64
|
+
telemetry=telemetry, timeout=timeout, retries=0
|
|
65
|
+
),
|
|
65
66
|
)
|
|
67
|
+
|
|
68
|
+
class Wrapper(cls):
|
|
69
|
+
def __init__(self, *args, **kwargs):
|
|
70
|
+
super().__init__(*args, **kwargs)
|
|
71
|
+
if AuthenticationBase in cls.__bases__:
|
|
72
|
+
self._async_client = AsyncAuthenticationClient(*args, **kwargs)
|
|
73
|
+
else:
|
|
74
|
+
self._async_client = AsyncManagementClient(*args, **kwargs)
|
|
66
75
|
for method in methods:
|
|
67
76
|
setattr(
|
|
68
77
|
self,
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"""Token Verifier module"""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
2
6
|
from .. import TokenValidationError
|
|
3
7
|
from ..rest_async import AsyncRestClient
|
|
4
8
|
from .token_verifier import AsymmetricSignatureVerifier, JwksFetcher, TokenVerifier
|
|
5
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from aiohttp import ClientSession
|
|
12
|
+
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
|
|
13
|
+
|
|
6
14
|
|
|
7
15
|
class AsyncAsymmetricSignatureVerifier(AsymmetricSignatureVerifier):
|
|
8
16
|
"""Async verifier for RSA signatures, which rely on public key certificates.
|
|
@@ -12,11 +20,11 @@ class AsyncAsymmetricSignatureVerifier(AsymmetricSignatureVerifier):
|
|
|
12
20
|
algorithm (str, optional): The expected signing algorithm. Defaults to "RS256".
|
|
13
21
|
"""
|
|
14
22
|
|
|
15
|
-
def __init__(self, jwks_url, algorithm="RS256"):
|
|
23
|
+
def __init__(self, jwks_url: str, algorithm: str = "RS256") -> None:
|
|
16
24
|
super().__init__(jwks_url, algorithm)
|
|
17
25
|
self._fetcher = AsyncJwksFetcher(jwks_url)
|
|
18
26
|
|
|
19
|
-
def set_session(self, session):
|
|
27
|
+
def set_session(self, session: ClientSession) -> None:
|
|
20
28
|
"""Set Client Session to improve performance by reusing session.
|
|
21
29
|
|
|
22
30
|
Args:
|
|
@@ -32,7 +40,7 @@ class AsyncAsymmetricSignatureVerifier(AsymmetricSignatureVerifier):
|
|
|
32
40
|
key_id (str): The key's key id."""
|
|
33
41
|
return await self._fetcher.get_key(key_id)
|
|
34
42
|
|
|
35
|
-
async def verify_signature(self, token):
|
|
43
|
+
async def verify_signature(self, token) -> dict[str, Any]:
|
|
36
44
|
"""Verifies the signature of the given JSON web token.
|
|
37
45
|
|
|
38
46
|
Args:
|
|
@@ -57,11 +65,11 @@ class AsyncJwksFetcher(JwksFetcher):
|
|
|
57
65
|
cache_ttl (str, optional): The lifetime of the JWK set cache in seconds. Defaults to 600 seconds.
|
|
58
66
|
"""
|
|
59
67
|
|
|
60
|
-
def __init__(self, *args, **kwargs):
|
|
68
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
61
69
|
super().__init__(*args, **kwargs)
|
|
62
70
|
self._async_client = AsyncRestClient(None)
|
|
63
71
|
|
|
64
|
-
def set_session(self, session):
|
|
72
|
+
def set_session(self, session: ClientSession) -> None:
|
|
65
73
|
"""Set Client Session to improve performance by reusing session.
|
|
66
74
|
|
|
67
75
|
Args:
|
|
@@ -70,7 +78,7 @@ class AsyncJwksFetcher(JwksFetcher):
|
|
|
70
78
|
"""
|
|
71
79
|
self._async_client.set_session(session)
|
|
72
80
|
|
|
73
|
-
async def _fetch_jwks(self, force=False):
|
|
81
|
+
async def _fetch_jwks(self, force: bool = False) -> dict[str, RSAPublicKey]:
|
|
74
82
|
"""Attempts to obtain the JWK set from the cache, as long as it's still valid.
|
|
75
83
|
When not, it will perform a network request to the jwks_url to obtain a fresh result
|
|
76
84
|
and update the cache value with it.
|
|
@@ -90,7 +98,7 @@ class AsyncJwksFetcher(JwksFetcher):
|
|
|
90
98
|
self._cache_is_fresh = False
|
|
91
99
|
return self._cache_value
|
|
92
100
|
|
|
93
|
-
async def get_key(self, key_id):
|
|
101
|
+
async def get_key(self, key_id: str) -> RSAPublicKey:
|
|
94
102
|
"""Obtains the JWK associated with the given key id.
|
|
95
103
|
|
|
96
104
|
Args:
|
|
@@ -126,7 +134,13 @@ class AsyncTokenVerifier(TokenVerifier):
|
|
|
126
134
|
Defaults to 60 seconds.
|
|
127
135
|
"""
|
|
128
136
|
|
|
129
|
-
def __init__(
|
|
137
|
+
def __init__(
|
|
138
|
+
self,
|
|
139
|
+
signature_verifier: AsyncAsymmetricSignatureVerifier,
|
|
140
|
+
issuer: str,
|
|
141
|
+
audience: str,
|
|
142
|
+
leeway: int = 0,
|
|
143
|
+
) -> None:
|
|
130
144
|
if not signature_verifier or not isinstance(
|
|
131
145
|
signature_verifier, AsyncAsymmetricSignatureVerifier
|
|
132
146
|
):
|
|
@@ -140,7 +154,7 @@ class AsyncTokenVerifier(TokenVerifier):
|
|
|
140
154
|
self._sv = signature_verifier
|
|
141
155
|
self._clock = None # legacy testing requirement
|
|
142
156
|
|
|
143
|
-
def set_session(self, session):
|
|
157
|
+
def set_session(self, session: ClientSession) -> None:
|
|
144
158
|
"""Set Client Session to improve performance by reusing session.
|
|
145
159
|
|
|
146
160
|
Args:
|
|
@@ -149,7 +163,13 @@ class AsyncTokenVerifier(TokenVerifier):
|
|
|
149
163
|
"""
|
|
150
164
|
self._sv.set_session(session)
|
|
151
165
|
|
|
152
|
-
async def verify(
|
|
166
|
+
async def verify(
|
|
167
|
+
self,
|
|
168
|
+
token: str,
|
|
169
|
+
nonce: str | None = None,
|
|
170
|
+
max_age: int | None = None,
|
|
171
|
+
organization: str | None = None,
|
|
172
|
+
) -> dict[str, Any]:
|
|
153
173
|
"""Attempts to verify the given ID token, following the steps defined in the OpenID Connect spec.
|
|
154
174
|
|
|
155
175
|
Args:
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
1
5
|
from auth0.rest import RestClient, RestClientOptions
|
|
6
|
+
from auth0.types import RequestData, TimeoutType
|
|
2
7
|
|
|
3
8
|
from .client_authentication import add_client_authentication
|
|
4
9
|
|
|
@@ -21,15 +26,15 @@ class AuthenticationBase:
|
|
|
21
26
|
|
|
22
27
|
def __init__(
|
|
23
28
|
self,
|
|
24
|
-
domain,
|
|
25
|
-
client_id,
|
|
26
|
-
client_secret=None,
|
|
27
|
-
client_assertion_signing_key=None,
|
|
28
|
-
client_assertion_signing_alg=None,
|
|
29
|
-
telemetry=True,
|
|
30
|
-
timeout=5.0,
|
|
31
|
-
protocol="https",
|
|
32
|
-
):
|
|
29
|
+
domain: str,
|
|
30
|
+
client_id: str,
|
|
31
|
+
client_secret: str | None = None,
|
|
32
|
+
client_assertion_signing_key: str | None = None,
|
|
33
|
+
client_assertion_signing_alg: str | None = None,
|
|
34
|
+
telemetry: bool = True,
|
|
35
|
+
timeout: TimeoutType = 5.0,
|
|
36
|
+
protocol: str = "https",
|
|
37
|
+
) -> None:
|
|
33
38
|
self.domain = domain
|
|
34
39
|
self.client_id = client_id
|
|
35
40
|
self.client_secret = client_secret
|
|
@@ -41,7 +46,7 @@ class AuthenticationBase:
|
|
|
41
46
|
options=RestClientOptions(telemetry=telemetry, timeout=timeout, retries=0),
|
|
42
47
|
)
|
|
43
48
|
|
|
44
|
-
def _add_client_authentication(self, payload):
|
|
49
|
+
def _add_client_authentication(self, payload: dict[str, Any]) -> dict[str, Any]:
|
|
45
50
|
return add_client_authentication(
|
|
46
51
|
payload,
|
|
47
52
|
self.domain,
|
|
@@ -51,13 +56,28 @@ class AuthenticationBase:
|
|
|
51
56
|
self.client_assertion_signing_alg,
|
|
52
57
|
)
|
|
53
58
|
|
|
54
|
-
def post(
|
|
59
|
+
def post(
|
|
60
|
+
self,
|
|
61
|
+
url: str,
|
|
62
|
+
data: RequestData | None = None,
|
|
63
|
+
headers: dict[str, str] | None = None,
|
|
64
|
+
) -> Any:
|
|
55
65
|
return self.client.post(url, data=data, headers=headers)
|
|
56
66
|
|
|
57
|
-
def authenticated_post(
|
|
67
|
+
def authenticated_post(
|
|
68
|
+
self,
|
|
69
|
+
url: str,
|
|
70
|
+
data: dict[str, Any],
|
|
71
|
+
headers: dict[str, str] | None = None,
|
|
72
|
+
) -> Any:
|
|
58
73
|
return self.client.post(
|
|
59
74
|
url, data=self._add_client_authentication(data), headers=headers
|
|
60
75
|
)
|
|
61
76
|
|
|
62
|
-
def get(
|
|
77
|
+
def get(
|
|
78
|
+
self,
|
|
79
|
+
url: str,
|
|
80
|
+
params: dict[str, Any] | None = None,
|
|
81
|
+
headers: dict[str, str] | None = None,
|
|
82
|
+
) -> Any:
|
|
63
83
|
return self.client.get(url, params, headers)
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import datetime
|
|
2
4
|
import uuid
|
|
5
|
+
from typing import Any
|
|
3
6
|
|
|
4
7
|
import jwt
|
|
5
8
|
|
|
6
9
|
|
|
7
10
|
def create_client_assertion_jwt(
|
|
8
|
-
domain
|
|
9
|
-
|
|
11
|
+
domain: str,
|
|
12
|
+
client_id: str,
|
|
13
|
+
client_assertion_signing_key: str,
|
|
14
|
+
client_assertion_signing_alg: str | None,
|
|
15
|
+
) -> str:
|
|
10
16
|
"""Creates a JWT for the client_assertion field.
|
|
11
17
|
|
|
12
18
|
Args:
|
|
13
19
|
domain (str): The domain of your Auth0 tenant
|
|
14
20
|
client_id (str): Your application's client ID
|
|
15
|
-
client_assertion_signing_key (str
|
|
21
|
+
client_assertion_signing_key (str): Private key used to sign the client assertion JWT
|
|
16
22
|
client_assertion_signing_alg (str, optional): Algorithm used to sign the client assertion JWT (defaults to 'RS256')
|
|
17
23
|
|
|
18
24
|
Returns:
|
|
@@ -35,20 +41,20 @@ def create_client_assertion_jwt(
|
|
|
35
41
|
|
|
36
42
|
|
|
37
43
|
def add_client_authentication(
|
|
38
|
-
payload,
|
|
39
|
-
domain,
|
|
40
|
-
client_id,
|
|
41
|
-
client_secret,
|
|
42
|
-
client_assertion_signing_key,
|
|
43
|
-
client_assertion_signing_alg,
|
|
44
|
-
):
|
|
44
|
+
payload: dict[str, Any],
|
|
45
|
+
domain: str,
|
|
46
|
+
client_id: str,
|
|
47
|
+
client_secret: str | None,
|
|
48
|
+
client_assertion_signing_key: str | None,
|
|
49
|
+
client_assertion_signing_alg: str | None,
|
|
50
|
+
) -> dict[str, Any]:
|
|
45
51
|
"""Adds the client_assertion or client_secret fields to authenticate a payload.
|
|
46
52
|
|
|
47
53
|
Args:
|
|
48
54
|
payload (dict): The POST payload that needs additional fields to be authenticated.
|
|
49
55
|
domain (str): The domain of your Auth0 tenant
|
|
50
56
|
client_id (str): Your application's client ID
|
|
51
|
-
client_secret (str): Your application's client secret
|
|
57
|
+
client_secret (str, optional): Your application's client secret
|
|
52
58
|
client_assertion_signing_key (str, optional): Private key used to sign the client assertion JWT
|
|
53
59
|
client_assertion_signing_alg (str, optional): Algorithm used to sign the client assertion JWT (defaults to 'RS256')
|
|
54
60
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
2
4
|
|
|
3
5
|
from .base import AuthenticationBase
|
|
4
6
|
|
|
@@ -12,17 +14,17 @@ class Database(AuthenticationBase):
|
|
|
12
14
|
|
|
13
15
|
def signup(
|
|
14
16
|
self,
|
|
15
|
-
email,
|
|
16
|
-
password,
|
|
17
|
-
connection,
|
|
18
|
-
username=None,
|
|
19
|
-
user_metadata=None,
|
|
20
|
-
given_name=None,
|
|
21
|
-
family_name=None,
|
|
22
|
-
name=None,
|
|
23
|
-
nickname=None,
|
|
24
|
-
picture=None,
|
|
25
|
-
):
|
|
17
|
+
email: str,
|
|
18
|
+
password: str,
|
|
19
|
+
connection: str,
|
|
20
|
+
username: str | None = None,
|
|
21
|
+
user_metadata: dict[str, Any] | None = None,
|
|
22
|
+
given_name: str | None = None,
|
|
23
|
+
family_name: str | None = None,
|
|
24
|
+
name: str | None = None,
|
|
25
|
+
nickname: str | None = None,
|
|
26
|
+
picture: str | None = None,
|
|
27
|
+
) -> dict[str, Any]:
|
|
26
28
|
"""Signup using email and password.
|
|
27
29
|
|
|
28
30
|
Args:
|
|
@@ -50,7 +52,7 @@ class Database(AuthenticationBase):
|
|
|
50
52
|
|
|
51
53
|
See: https://auth0.com/docs/api/authentication#signup
|
|
52
54
|
"""
|
|
53
|
-
body = {
|
|
55
|
+
body: dict[str, Any] = {
|
|
54
56
|
"client_id": self.client_id,
|
|
55
57
|
"email": email,
|
|
56
58
|
"password": password,
|
|
@@ -71,11 +73,14 @@ class Database(AuthenticationBase):
|
|
|
71
73
|
if picture:
|
|
72
74
|
body.update({"picture": picture})
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
data: dict[str, Any] = self.post(
|
|
75
77
|
f"{self.protocol}://{self.domain}/dbconnections/signup", data=body
|
|
76
78
|
)
|
|
79
|
+
return data
|
|
77
80
|
|
|
78
|
-
def change_password(
|
|
81
|
+
def change_password(
|
|
82
|
+
self, email: str, connection: str, password: str | None = None
|
|
83
|
+
) -> str:
|
|
79
84
|
"""Asks to change a password for a given user.
|
|
80
85
|
|
|
81
86
|
email (str): The user's email address.
|
|
@@ -88,7 +93,8 @@ class Database(AuthenticationBase):
|
|
|
88
93
|
"connection": connection,
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
|
|
96
|
+
data: str = self.post(
|
|
92
97
|
f"{self.protocol}://{self.domain}/dbconnections/change_password",
|
|
93
98
|
data=body,
|
|
94
99
|
)
|
|
100
|
+
return data
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
1
5
|
from .base import AuthenticationBase
|
|
2
6
|
|
|
3
7
|
|
|
@@ -10,13 +14,13 @@ class Delegated(AuthenticationBase):
|
|
|
10
14
|
|
|
11
15
|
def get_token(
|
|
12
16
|
self,
|
|
13
|
-
target,
|
|
14
|
-
api_type,
|
|
15
|
-
grant_type,
|
|
16
|
-
id_token=None,
|
|
17
|
-
refresh_token=None,
|
|
18
|
-
scope="openid",
|
|
19
|
-
):
|
|
17
|
+
target: str,
|
|
18
|
+
api_type: str,
|
|
19
|
+
grant_type: str,
|
|
20
|
+
id_token: str | None = None,
|
|
21
|
+
refresh_token: str | None = None,
|
|
22
|
+
scope: str = "openid",
|
|
23
|
+
) -> Any:
|
|
20
24
|
"""Obtain a delegation token."""
|
|
21
25
|
|
|
22
26
|
if id_token and refresh_token:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base import AuthenticationBase
|
|
2
4
|
|
|
3
5
|
|
|
@@ -9,7 +11,7 @@ class Enterprise(AuthenticationBase):
|
|
|
9
11
|
domain (str): Your auth0 domain (e.g: my-domain.us.auth0.com)
|
|
10
12
|
"""
|
|
11
13
|
|
|
12
|
-
def saml_metadata(self):
|
|
14
|
+
def saml_metadata(self) -> Any:
|
|
13
15
|
"""Get SAML2.0 Metadata."""
|
|
14
16
|
|
|
15
17
|
return self.get(
|
|
@@ -18,7 +20,7 @@ class Enterprise(AuthenticationBase):
|
|
|
18
20
|
)
|
|
19
21
|
)
|
|
20
22
|
|
|
21
|
-
def wsfed_metadata(self):
|
|
23
|
+
def wsfed_metadata(self) -> Any:
|
|
22
24
|
"""Returns the WS-Federation Metadata."""
|
|
23
25
|
|
|
24
26
|
url = "{}://{}/wsfed/FederationMetadata/2007-06/FederationMetadata.xml"
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
1
5
|
from .base import AuthenticationBase
|
|
2
|
-
from .client_authentication import add_client_authentication
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
class GetToken(AuthenticationBase):
|
|
@@ -12,10 +15,10 @@ class GetToken(AuthenticationBase):
|
|
|
12
15
|
|
|
13
16
|
def authorization_code(
|
|
14
17
|
self,
|
|
15
|
-
code,
|
|
16
|
-
redirect_uri,
|
|
17
|
-
grant_type="authorization_code",
|
|
18
|
-
):
|
|
18
|
+
code: str,
|
|
19
|
+
redirect_uri: str | None,
|
|
20
|
+
grant_type: str = "authorization_code",
|
|
21
|
+
) -> Any:
|
|
19
22
|
"""Authorization code grant
|
|
20
23
|
|
|
21
24
|
This is the OAuth 2.0 grant that regular web apps utilize in order
|
|
@@ -47,11 +50,11 @@ class GetToken(AuthenticationBase):
|
|
|
47
50
|
|
|
48
51
|
def authorization_code_pkce(
|
|
49
52
|
self,
|
|
50
|
-
code_verifier,
|
|
51
|
-
code,
|
|
52
|
-
redirect_uri,
|
|
53
|
-
grant_type="authorization_code",
|
|
54
|
-
):
|
|
53
|
+
code_verifier: str,
|
|
54
|
+
code: str,
|
|
55
|
+
redirect_uri: str | None,
|
|
56
|
+
grant_type: str = "authorization_code",
|
|
57
|
+
) -> Any:
|
|
55
58
|
"""Authorization code pkce grant
|
|
56
59
|
|
|
57
60
|
This is the OAuth 2.0 grant that mobile apps utilize in order to access an API.
|
|
@@ -86,9 +89,9 @@ class GetToken(AuthenticationBase):
|
|
|
86
89
|
|
|
87
90
|
def client_credentials(
|
|
88
91
|
self,
|
|
89
|
-
audience,
|
|
90
|
-
grant_type="client_credentials",
|
|
91
|
-
):
|
|
92
|
+
audience: str,
|
|
93
|
+
grant_type: str = "client_credentials",
|
|
94
|
+
) -> Any:
|
|
92
95
|
"""Client credentials grant
|
|
93
96
|
|
|
94
97
|
This is the OAuth 2.0 grant that server processes utilize in
|
|
@@ -116,13 +119,14 @@ class GetToken(AuthenticationBase):
|
|
|
116
119
|
|
|
117
120
|
def login(
|
|
118
121
|
self,
|
|
119
|
-
username,
|
|
120
|
-
password,
|
|
121
|
-
scope=None,
|
|
122
|
-
realm=None,
|
|
123
|
-
audience=None,
|
|
124
|
-
grant_type="http://auth0.com/oauth/grant-type/password-realm",
|
|
125
|
-
|
|
122
|
+
username: str,
|
|
123
|
+
password: str,
|
|
124
|
+
scope: str | None = None,
|
|
125
|
+
realm: str | None = None,
|
|
126
|
+
audience: str | None = None,
|
|
127
|
+
grant_type: str = "http://auth0.com/oauth/grant-type/password-realm",
|
|
128
|
+
forwarded_for: str | None = None,
|
|
129
|
+
) -> Any:
|
|
126
130
|
"""Calls /oauth/token endpoint with password-realm grant type
|
|
127
131
|
|
|
128
132
|
|
|
@@ -149,9 +153,16 @@ class GetToken(AuthenticationBase):
|
|
|
149
153
|
grant_type (str, optional): Denotes the flow you're using. For password realm
|
|
150
154
|
use http://auth0.com/oauth/grant-type/password-realm
|
|
151
155
|
|
|
156
|
+
forwarded_for (str, optional): End-user IP as a string value. Set this if you want
|
|
157
|
+
brute-force protection to work in server-side scenarios.
|
|
158
|
+
See https://auth0.com/docs/get-started/authentication-and-authorization-flow/avoid-common-issues-with-resource-owner-password-flow-and-attack-protection
|
|
159
|
+
|
|
152
160
|
Returns:
|
|
153
161
|
access_token, id_token
|
|
154
162
|
"""
|
|
163
|
+
headers = None
|
|
164
|
+
if forwarded_for:
|
|
165
|
+
headers = {"auth0-forwarded-for": forwarded_for}
|
|
155
166
|
|
|
156
167
|
return self.authenticated_post(
|
|
157
168
|
f"{self.protocol}://{self.domain}/oauth/token",
|
|
@@ -164,14 +175,15 @@ class GetToken(AuthenticationBase):
|
|
|
164
175
|
"audience": audience,
|
|
165
176
|
"grant_type": grant_type,
|
|
166
177
|
},
|
|
178
|
+
headers=headers,
|
|
167
179
|
)
|
|
168
180
|
|
|
169
181
|
def refresh_token(
|
|
170
182
|
self,
|
|
171
|
-
refresh_token,
|
|
172
|
-
scope="",
|
|
173
|
-
grant_type="refresh_token",
|
|
174
|
-
):
|
|
183
|
+
refresh_token: str,
|
|
184
|
+
scope: str = "",
|
|
185
|
+
grant_type: str = "refresh_token",
|
|
186
|
+
) -> Any:
|
|
175
187
|
"""Calls /oauth/token endpoint with refresh token grant type
|
|
176
188
|
|
|
177
189
|
Use this endpoint to refresh an access token, using the refresh token you got during authorization.
|
|
@@ -199,7 +211,9 @@ class GetToken(AuthenticationBase):
|
|
|
199
211
|
},
|
|
200
212
|
)
|
|
201
213
|
|
|
202
|
-
def passwordless_login(
|
|
214
|
+
def passwordless_login(
|
|
215
|
+
self, username: str, otp: str, realm: str, scope: str, audience: str
|
|
216
|
+
) -> Any:
|
|
203
217
|
"""Calls /oauth/token endpoint with http://auth0.com/oauth/grant-type/passwordless/otp grant type
|
|
204
218
|
|
|
205
219
|
Once the verification code was received, login the user using this endpoint with their
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
2
4
|
|
|
3
5
|
from .base import AuthenticationBase
|
|
4
6
|
|
|
@@ -11,7 +13,9 @@ class Passwordless(AuthenticationBase):
|
|
|
11
13
|
domain (str): Your auth0 domain (e.g: my-domain.us.auth0.com)
|
|
12
14
|
"""
|
|
13
15
|
|
|
14
|
-
def email(
|
|
16
|
+
def email(
|
|
17
|
+
self, email: str, send: str = "link", auth_params: dict[str, str] | None = None
|
|
18
|
+
) -> Any:
|
|
15
19
|
"""Start flow sending an email.
|
|
16
20
|
|
|
17
21
|
Given the user email address, it will send an email with:
|
|
@@ -35,7 +39,7 @@ class Passwordless(AuthenticationBase):
|
|
|
35
39
|
auth_params (dict, optional): Parameters to append or override.
|
|
36
40
|
"""
|
|
37
41
|
|
|
38
|
-
data = {
|
|
42
|
+
data: dict[str, Any] = {
|
|
39
43
|
"client_id": self.client_id,
|
|
40
44
|
"connection": "email",
|
|
41
45
|
"email": email,
|
|
@@ -48,7 +52,7 @@ class Passwordless(AuthenticationBase):
|
|
|
48
52
|
f"{self.protocol}://{self.domain}/passwordless/start", data=data
|
|
49
53
|
)
|
|
50
54
|
|
|
51
|
-
def sms(self, phone_number):
|
|
55
|
+
def sms(self, phone_number: str) -> Any:
|
|
52
56
|
"""Start flow sending an SMS message.
|
|
53
57
|
|
|
54
58
|
Given the user phone number, it will send an SMS with
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base import AuthenticationBase
|
|
2
4
|
|
|
3
5
|
|
|
@@ -8,7 +10,7 @@ class RevokeToken(AuthenticationBase):
|
|
|
8
10
|
domain (str): Your auth0 domain (e.g: my-domain.us.auth0.com)
|
|
9
11
|
"""
|
|
10
12
|
|
|
11
|
-
def revoke_refresh_token(self, token):
|
|
13
|
+
def revoke_refresh_token(self, token: str) -> Any:
|
|
12
14
|
"""Revokes a Refresh Token if it has been compromised
|
|
13
15
|
|
|
14
16
|
Each revocation request invalidates not only the specific token, but all other tokens
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base import AuthenticationBase
|
|
2
4
|
|
|
3
5
|
|
|
@@ -9,7 +11,7 @@ class Social(AuthenticationBase):
|
|
|
9
11
|
domain (str): Your auth0 domain (e.g: my-domain.us.auth0.com)
|
|
10
12
|
"""
|
|
11
13
|
|
|
12
|
-
def login(self, access_token, connection, scope="openid"):
|
|
14
|
+
def login(self, access_token: str, connection: str, scope: str = "openid") -> Any:
|
|
13
15
|
"""Login using a social provider's access token
|
|
14
16
|
|
|
15
17
|
Given the social provider's access_token and the connection specified,
|