You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

auth0-python

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

auth0-python - pypi Package Compare versions

Comparing version
4.5.0
to
4.6.0
+1
-1
auth0/__init__.py
# This value is updated by `poetry_dynamic_versioning` during build time from the latest git tag
__version__ = "4.5.0"
__version__ = "4.6.0"

@@ -4,0 +4,0 @@ from auth0.exceptions import Auth0Error, RateLimitError, TokenValidationError

@@ -82,3 +82,7 @@ from __future__ import annotations

def change_password(
self, email: str, connection: str, password: str | None = None
self,
email: str,
connection: str,
password: str | None = None,
organization: str | None = None,
) -> str:

@@ -90,2 +94,4 @@ """Asks to change a password for a given user.

connection (str): The name of the database connection where this user should be created.
organization (str, optional): The id of the Organization associated with the user.
"""

@@ -97,2 +103,4 @@ body = {

}
if organization:
body["organization"] = organization

@@ -99,0 +107,0 @@ data: str = self.post(

@@ -94,2 +94,3 @@ from __future__ import annotations

grant_type: str = "client_credentials",
organization: str | None = None,
) -> Any:

@@ -108,2 +109,5 @@ """Client credentials grant

organization (str, optional): Optional Organization name or ID. When included, the access token returned
will include the org_id and org_name claims
Returns:

@@ -119,2 +123,3 @@ access_token

"grant_type": grant_type,
"organization": organization,
},

@@ -121,0 +126,0 @@ )

@@ -62,2 +62,3 @@ from __future__ import annotations

client_id: str | None = None,
allow_any_organization: bool | None = None,
):

@@ -81,2 +82,4 @@ """Retrieves all client grants.

allow_any_organization (bool, optional): Optional filter on allow_any_organization.
See: https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants

@@ -91,2 +94,3 @@ """

"client_id": client_id,
"allow_any_organization": allow_any_organization,
}

@@ -130,1 +134,41 @@

return self.client.patch(self._url(id), data=body)
def get_organizations(
self,
id: str,
page: int | None = None,
per_page: int | None = None,
include_totals: bool = False,
from_param: str | None = None,
take: int | None = None,
):
"""Get the organizations associated to a client grant.
Args:
id (str): Id of client grant.
page (int, optional): The result's page number (zero based). When not set,
the default value is up to the server.
per_page (int, optional): The amount of entries per page. When not set,
the default value is up to the server.
include_totals (bool, optional): True if the query summary is
to be included in the result, False otherwise. Defaults to False.
from_param (str, optional): Id to start retrieving entries. You can
limit the amount of entries using the take parameter.
take (int, optional): The total amount of entries to retrieve when
using the from parameter. When not set, the default value is up to the server.
"""
params = {
"per_page": per_page,
"page": page,
"include_totals": str(include_totals).lower(),
"from": from_param,
"take": take,
}
return self.client.get(self._url(f"{id}/organizations"), params=params)

@@ -463,1 +463,63 @@ from __future__ import annotations

return self.client.delete(self._url(id, "invitations", invitation_id))
def get_client_grants(
self,
id: str,
audience: str | None = None,
client_id: str | None = None,
page: int | None = None,
per_page: int | None = None,
include_totals: bool = False,
):
"""Get client grants associated to an organization.
Args:
id (str): Id of organization.
audience (str, optional): URL encoded audience of a Resource Server
to filter.
client_id (string, optional): The id of a client to filter.
page (int, optional): The result's page number (zero based). When not set,
the default value is up to the server.
per_page (int, optional): The amount of entries per page. When not set,
the default value is up to the server.
include_totals (bool, optional): True if the query summary is
to be included in the result, False otherwise. Defaults to False.
"""
params = {
"audience": audience,
"client_id": client_id,
"page": page,
"per_page": per_page,
"include_totals": str(include_totals).lower(),
}
return self.client.get(self._url(id, "client-grants"), params=params)
def add_client_grant(self, id: str, grant_id: str) -> dict[str, Any]:
"""Associate a client grant with an organization.
Args:
id (str): the ID of the organization.
grant_id (string) A Client Grant ID to add to the organization.
"""
return self.client.post(
self._url(id, "client-grants"), data={"grant_id": grant_id}
)
def delete_client_grant(self, id: str, grant_id: str) -> dict[str, Any]:
"""Remove a client grant from an organization.
Args:
id (str): the ID of the organization.
grant_id (string) A Client Grant ID to remove from the organization.
"""
return self.client.delete(self._url(id, "client-grants", grant_id))

@@ -214,3 +214,3 @@ from __future__ import annotations

def remove_permissions(self, id: str, permissions: List[str]) -> Any:
def remove_permissions(self, id: str, permissions: List[dict[str, str]]) -> Any:
"""Unassociates permissions from a role.

@@ -229,3 +229,3 @@

def add_permissions(self, id: str, permissions: List[str]) -> dict[str, Any]:
def add_permissions(self, id: str, permissions: List[dict[str, str]]) -> dict[str, Any]:
"""Associates permissions with a role.

@@ -232,0 +232,0 @@

@@ -380,3 +380,3 @@ from __future__ import annotations

def get_guardian_enrollments(self, user_id: str) -> dict[str, Any]:
"""Retrieves all Guardian enrollments.
"""Retrieve the first confirmed Guardian enrollment for a user.

@@ -383,0 +383,0 @@ Args:

@@ -55,23 +55,5 @@ from __future__ import annotations

async def _request(self, *args: Any, **kwargs: Any) -> Any:
kwargs["headers"] = kwargs.get("headers", self.base_headers)
kwargs["timeout"] = self.timeout
if self._session is not None:
# Request with re-usable session
async with self._session.request(*args, **kwargs) as response:
return await self._process_response(response)
else:
# Request without re-usable session
async with aiohttp.ClientSession() as session:
async with session.request(*args, **kwargs) as response:
return await self._process_response(response)
async def get(
self,
url: str,
params: dict[str, Any] | None = None,
headers: dict[str, str] | None = None,
async def _request_with_session(
self, session: aiohttp.ClientSession, *args: Any, **kwargs: Any
) -> Any:
request_headers = self.base_headers.copy()
request_headers.update(headers or {})
# Track the API request attempt number

@@ -83,3 +65,2 @@ attempt = 0

params = _clean_params(params)
while True:

@@ -90,6 +71,5 @@ # Increment attempt number

try:
response = await self._request(
"get", url, params=params, headers=request_headers
)
return response
async with session.request(*args, **kwargs) as response:
return await self._process_response(response)
except RateLimitError as e:

@@ -107,2 +87,26 @@ # If the attempt number is greater than the configured retries, raise RateLimitError

async def _request(self, *args: Any, **kwargs: Any) -> Any:
kwargs["headers"] = kwargs.get("headers", self.base_headers)
kwargs["timeout"] = self.timeout
if self._session is not None:
# Request with re-usable session
return self._request_with_session(self.session, *args, **kwargs)
else:
# Request without re-usable session
async with aiohttp.ClientSession() as session:
return self._request_with_session(session, *args, **kwargs)
async def get(
self,
url: str,
params: dict[str, Any] | None = None,
headers: dict[str, str] | None = None,
) -> Any:
request_headers = self.base_headers.copy()
request_headers.update(headers or {})
return await self._request(
"get", url, params=_clean_params(params), headers=request_headers
)
async def post(

@@ -125,3 +129,3 @@ self,

headers = self.base_headers.copy()
headers.pop("Content-Type", None)
headers.pop("Content-Type")
return await self._request("post", url, data={**data, **files}, headers=headers)

@@ -128,0 +132,0 @@

from __future__ import annotations
import base64
import json
import platform
import sys
from json import dumps, loads
from random import randint

@@ -98,3 +98,3 @@ from time import sleep

auth0_client = json.dumps(
auth0_client = dumps(
{

@@ -140,11 +140,12 @@ "name": "auth0-python",

def get(
def _request(
self,
method: str,
url: str,
params: dict[str, Any] | None = None,
data: RequestData | None = None,
json: RequestData | None = None,
headers: dict[str, str] | None = None,
files: dict[str, Any] | None = None,
) -> Any:
request_headers = self.base_headers.copy()
request_headers.update(headers or {})
# Track the API request attempt number

@@ -156,2 +157,15 @@ attempt = 0

kwargs = {
k: v
for k, v in {
"params": params,
"json": json,
"data": data,
"headers": headers,
"files": files,
"timeout": self.options.timeout,
}.items()
if v is not None
}
while True:

@@ -162,8 +176,3 @@ # Increment attempt number

# Issue the request
response = requests.get(
url,
params=params,
headers=request_headers,
timeout=self.options.timeout,
)
response = requests.request(method, url, **kwargs)

@@ -184,2 +193,12 @@ # If the response did not have a 429 header, or the attempt number is greater than the configured retries, break

def get(
self,
url: str,
params: dict[str, Any] | None = None,
headers: dict[str, str] | None = None,
) -> Any:
request_headers = self.base_headers.copy()
request_headers.update(headers or {})
return self._request("GET", url, params=params, headers=request_headers)
def post(

@@ -193,8 +212,4 @@ self,

request_headers.update(headers or {})
return self._request("POST", url, json=data, headers=request_headers)
response = requests.post(
url, json=data, headers=request_headers, timeout=self.options.timeout
)
return self._process_response(response)
def file_post(

@@ -208,24 +223,12 @@ self,

headers.pop("Content-Type", None)
return self._request("POST", url, data=data, files=files, headers=headers)
response = requests.post(
url, data=data, files=files, headers=headers, timeout=self.options.timeout
)
return self._process_response(response)
def patch(self, url: str, data: RequestData | None = None) -> Any:
headers = self.base_headers.copy()
return self._request("PATCH", url, json=data, headers=headers)
response = requests.patch(
url, json=data, headers=headers, timeout=self.options.timeout
)
return self._process_response(response)
def put(self, url: str, data: RequestData | None = None) -> Any:
headers = self.base_headers.copy()
return self._request("PUT", url, json=data, headers=headers)
response = requests.put(
url, json=data, headers=headers, timeout=self.options.timeout
)
return self._process_response(response)
def delete(

@@ -238,12 +241,4 @@ self,

headers = self.base_headers.copy()
return self._request("DELETE", url, params=params, json=data, headers=headers)
response = requests.delete(
url,
headers=headers,
params=params or {},
json=data,
timeout=self.options.timeout,
)
return self._process_response(response)
def _calculate_wait(self, attempt: int) -> int:

@@ -328,3 +323,3 @@ # Retry the request. Apply a exponential backoff for subsequent attempts, using this formula:

def __init__(self, response: requests.Response | RequestsResponse) -> None:
content = json.loads(response.text)
content = loads(response.text)
super().__init__(response.status_code, content, response.headers)

@@ -331,0 +326,0 @@

@@ -238,2 +238,16 @@ import base64

@aioresponses()
async def test_rate_limit_post(self, mocked):
callback, mock = get_callback(status=429)
await mocked.post(clients, callback=callback)
await mocked.post(clients, callback=callback)
await mocked.post(clients, callback=callback)
await mocked.post(clients, payload=payload)
c = asyncify(Clients)(domain="example.com", token="jwt")
rest_client = c._async_client.client
rest_client._skip_sleep = True
self.assertEqual(await c.all_async(), payload)
self.assertEqual(3, mock.call_count)
@pytest.mark.asyncio
@aioresponses()
async def test_timeout(self, mocked):

@@ -240,0 +254,0 @@ callback, mock = get_callback()

@@ -45,12 +45,13 @@ import base64

@mock.patch("requests.post")
def test_post(self, mock_post):
@mock.patch("requests.request")
def test_post(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False, timeout=(10, 2))
mock_post.return_value.status_code = 200
mock_post.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'
data = ab.post("the-url", data={"a": "b"}, headers={"c": "d"})
mock_post.assert_called_with(
mock_request.assert_called_with(
"POST",
"the-url",

@@ -64,8 +65,8 @@ json={"a": "b"},

@mock.patch("requests.post")
def test_post_with_defaults(self, mock_post):
@mock.patch("requests.request")
def test_post_with_defaults(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
mock_post.return_value.status_code = 200
mock_post.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'

@@ -75,5 +76,5 @@ # Only required params are passed

mock_post.assert_called_with(
mock_request.assert_called_with(
"POST",
"the-url",
json=None,
headers={"Content-Type": "application/json"},

@@ -85,14 +86,15 @@ timeout=5.0,

@mock.patch("requests.post")
def test_post_includes_telemetry(self, mock_post):
@mock.patch("requests.request")
def test_post_includes_telemetry(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid")
mock_post.return_value.status_code = 200
mock_post.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'
data = ab.post("the-url", data={"a": "b"}, headers={"c": "d"})
self.assertEqual(mock_post.call_count, 1)
call_args, call_kwargs = mock_post.call_args
self.assertEqual(call_args[0], "the-url")
self.assertEqual(mock_request.call_count, 1)
call_args, call_kwargs = mock_request.call_args
self.assertEqual(call_args[0], "POST")
self.assertEqual(call_args[1], "the-url")
self.assertEqual(call_kwargs["json"], {"a": "b"})

@@ -107,9 +109,11 @@ headers = call_kwargs["headers"]

@mock.patch("requests.post")
def test_post_error(self, mock_post):
@mock.patch("requests.request")
def test_post_error(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = '{"error": "e0","error_description": "desc"}'
mock_request.return_value.status_code = error_status
mock_request.return_value.text = (
'{"error": "e0","error_description": "desc"}'
)

@@ -123,8 +127,8 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_mfa_required(self, mock_post):
@mock.patch("requests.request")
def test_post_error_mfa_required(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
mock_post.return_value.status_code = 403
mock_post.return_value.text = '{"error": "mfa_required", "error_description": "Multifactor authentication required", "mfa_token": "Fe26...Ha"}'
mock_request.return_value.status_code = 403
mock_request.return_value.text = '{"error": "mfa_required", "error_description": "Multifactor authentication required", "mfa_token": "Fe26...Ha"}'

@@ -141,11 +145,11 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_rate_limit_error(self, mock_post):
@mock.patch("requests.request")
def test_post_rate_limit_error(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
mock_post.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "error": "e0", "error_description": "desc"}'
)
mock_post.return_value.status_code = 429
mock_post.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -165,11 +169,11 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.post")
def test_post_rate_limit_error_without_headers(self, mock_post):
@mock.patch("requests.request")
def test_post_rate_limit_error_without_headers(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
mock_post.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "error": "e0", "error_description": "desc"}'
)
mock_post.return_value.status_code = 429
mock_post.return_value.headers = {}
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {}

@@ -185,9 +189,11 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_code_property(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_code_property(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = '{"code": "e0","error_description": "desc"}'
mock_request.return_value.status_code = error_status
mock_request.return_value.text = (
'{"code": "e0","error_description": "desc"}'
)

@@ -201,9 +207,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_no_error_code(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_no_error_code(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = '{"error_description": "desc"}'
mock_request.return_value.status_code = error_status
mock_request.return_value.text = '{"error_description": "desc"}'

@@ -217,9 +223,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_text_response(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_text_response(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = "there has been a terrible error"
mock_request.return_value.status_code = error_status
mock_request.return_value.text = "there has been a terrible error"

@@ -235,9 +241,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_no_response_text(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_no_response_text(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = None
mock_request.return_value.status_code = error_status
mock_request.return_value.text = None

@@ -251,12 +257,13 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.get")
def test_get(self, mock_get):
@mock.patch("requests.request")
def test_get(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False, timeout=(10, 2))
mock_get.return_value.status_code = 200
mock_get.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'
data = ab.get("the-url", params={"a": "b"}, headers={"c": "d"})
mock_get.assert_called_with(
mock_request.assert_called_with(
"GET",
"the-url",

@@ -270,8 +277,8 @@ params={"a": "b"},

@mock.patch("requests.get")
def test_get_with_defaults(self, mock_get):
@mock.patch("requests.request")
def test_get_with_defaults(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid", telemetry=False)
mock_get.return_value.status_code = 200
mock_get.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'

@@ -281,5 +288,5 @@ # Only required params are passed

mock_get.assert_called_with(
mock_request.assert_called_with(
"GET",
"the-url",
params=None,
headers={"Content-Type": "application/json"},

@@ -291,14 +298,15 @@ timeout=5.0,

@mock.patch("requests.get")
def test_get_includes_telemetry(self, mock_get):
@mock.patch("requests.request")
def test_get_includes_telemetry(self, mock_request):
ab = AuthenticationBase("auth0.com", "cid")
mock_get.return_value.status_code = 200
mock_get.return_value.text = '{"x": "y"}'
mock_request.return_value.status_code = 200
mock_request.return_value.text = '{"x": "y"}'
data = ab.get("the-url", params={"a": "b"}, headers={"c": "d"})
self.assertEqual(mock_get.call_count, 1)
call_args, call_kwargs = mock_get.call_args
self.assertEqual(call_args[0], "the-url")
self.assertEqual(mock_request.call_count, 1)
call_args, call_kwargs = mock_request.call_args
self.assertEqual(call_args[0], "GET")
self.assertEqual(call_args[1], "the-url")
self.assertEqual(call_kwargs["params"], {"a": "b"})

@@ -305,0 +313,0 @@ headers = call_kwargs["headers"]

@@ -81,1 +81,23 @@ import unittest

)
@mock.patch("auth0.rest.RestClient.post")
def test_change_password_with_organization_param(self, mock_post):
d = Database("my.domain.com", "cid")
# ignores the password argument
d.change_password(
email="a@b.com", password="pswd", connection="conn", organization="org_id"
)
args, kwargs = mock_post.call_args
self.assertEqual(args[0], "https://my.domain.com/dbconnections/change_password")
self.assertEqual(
kwargs["data"],
{
"client_id": "cid",
"email": "a@b.com",
"connection": "conn",
"organization": "org_id",
},
)

@@ -114,2 +114,3 @@ import unittest

"grant_type": "gt",
"organization": None,
},

@@ -137,2 +138,3 @@ )

"grant_type": "gt",
"organization": None,
},

@@ -144,2 +146,22 @@ )

@mock.patch("auth0.rest.RestClient.post")
def test_client_credentials_with_organization(self, mock_post):
g = GetToken("my.domain.com", "cid", client_secret="clsec")
g.client_credentials("aud", organization="my-org")
args, kwargs = mock_post.call_args
self.assertEqual(args[0], "https://my.domain.com/oauth/token")
self.assertEqual(
kwargs["data"],
{
"client_id": "cid",
"grant_type": "client_credentials",
"client_secret": "clsec",
"audience": "aud",
"organization": "my-org",
},
)
@mock.patch("auth0.rest.RestClient.post")
def test_login(self, mock_post):

@@ -146,0 +168,0 @@ g = GetToken("my.domain.com", "cid", client_secret="clsec")

@@ -62,3 +62,3 @@ import unittest

@mock.patch("auth0.rest.requests.put")
@mock.patch("auth0.rest.requests.request")
def test_update_template_universal_login(self, mock_rc):

@@ -72,2 +72,3 @@ mock_rc.return_value.status_code = 200

mock_rc.assert_called_with(
"PUT",
"https://domain/api/v2/branding/templates/universal-login",

@@ -74,0 +75,0 @@ json={"template": {"a": "b", "c": "d"}},

@@ -36,2 +36,3 @@ import unittest

"client_id": None,
"allow_any_organization": None,
},

@@ -54,2 +55,3 @@ )

"client_id": None,
"allow_any_organization": None,
},

@@ -72,2 +74,3 @@ )

"client_id": None,
"allow_any_organization": None,
},

@@ -90,5 +93,24 @@ )

"client_id": "exampleid",
"allow_any_organization": None,
},
)
# With allow any organization
c.all(allow_any_organization=True)
args, kwargs = mock_instance.get.call_args
self.assertEqual("https://domain/api/v2/client-grants", args[0])
self.assertEqual(
kwargs["params"],
{
"audience": None,
"page": None,
"per_page": None,
"include_totals": "false",
"client_id": None,
"allow_any_organization": True,
},
)
@mock.patch("auth0.management.client_grants.RestClient")

@@ -127,1 +149,24 @@ def test_create(self, mock_rc):

self.assertEqual(kwargs["data"], {"a": "b", "c": "d"})
@mock.patch("auth0.management.client_grants.RestClient")
def test_get_organizations(self, mock_rc):
mock_instance = mock_rc.return_value
c = ClientGrants(domain="domain", token="jwttoken")
c.get_organizations("cgid")
args, kwargs = mock_instance.get.call_args
self.assertEqual(
"https://domain/api/v2/client-grants/cgid/organizations", args[0]
)
self.assertEqual(
kwargs["params"],
{
"page": None,
"per_page": None,
"include_totals": "false",
"from": None,
"take": None,
},
)

@@ -482,1 +482,42 @@ import unittest

)
@mock.patch("auth0.management.organizations.RestClient")
def test_get_client_grants(self, mock_rc):
mock_instance = mock_rc.return_value
c = Organizations(domain="domain", token="jwttoken")
c.get_client_grants("test-org")
mock_instance.get.assert_called_with(
"https://domain/api/v2/organizations/test-org/client-grants",
params={
"audience": None,
"client_id": None,
"page": None,
"per_page": None,
"include_totals": "false",
},
)
@mock.patch("auth0.management.organizations.RestClient")
def test_add_client_grant(self, mock_rc):
mock_instance = mock_rc.return_value
c = Organizations(domain="domain", token="jwttoken")
c.add_client_grant("test-org", "test-cg")
mock_instance.post.assert_called_with(
"https://domain/api/v2/organizations/test-org/client-grants",
data={"grant_id": "test-cg"},
)
@mock.patch("auth0.management.organizations.RestClient")
def test_delete_client_grant(self, mock_rc):
mock_instance = mock_rc.return_value
c = Organizations(domain="domain", token="jwttoken")
c.delete_client_grant("test-org", "test-cg")
mock_instance.delete.assert_called_with(
"https://domain/api/v2/organizations/test-org/client-grants/test-cg",
)

@@ -7,4 +7,2 @@ import base64

import requests
from auth0.rest import RestClient, RestClientOptions

@@ -139,4 +137,4 @@

@mock.patch("requests.get")
def test_get_custom_timeout(self, mock_get):
@mock.patch("requests.request")
def test_get_custom_timeout(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False, timeout=(10, 2))

@@ -147,12 +145,12 @@ headers = {

}
mock_get.return_value.text = '["a", "b"]'
mock_get.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
rc.get("the-url")
mock_get.assert_called_with(
"the-url", params=None, headers=headers, timeout=(10, 2)
mock_request.assert_called_with(
"GET", "the-url", headers=headers, timeout=(10, 2)
)
@mock.patch("requests.post")
def test_post_custom_timeout(self, mock_post):
@mock.patch("requests.request")
def test_post_custom_timeout(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False, timeout=(10, 2))

@@ -163,12 +161,12 @@ headers = {

}
mock_post.return_value.text = '["a", "b"]'
mock_post.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
rc.post("the-url")
mock_post.assert_called_with(
"the-url", json=None, headers=headers, timeout=(10, 2)
mock_request.assert_called_with(
"POST", "the-url", headers=headers, timeout=(10, 2)
)
@mock.patch("requests.put")
def test_put_custom_timeout(self, mock_put):
@mock.patch("requests.request")
def test_put_custom_timeout(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False, timeout=(10, 2))

@@ -179,12 +177,12 @@ headers = {

}
mock_put.return_value.text = '["a", "b"]'
mock_put.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
rc.put("the-url")
mock_put.assert_called_with(
"the-url", json=None, headers=headers, timeout=(10, 2)
mock_request.assert_called_with(
"PUT", "the-url", headers=headers, timeout=(10, 2)
)
@mock.patch("requests.patch")
def test_patch_custom_timeout(self, mock_patch):
@mock.patch("requests.request")
def test_patch_custom_timeout(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False, timeout=(10, 2))

@@ -195,12 +193,12 @@ headers = {

}
mock_patch.return_value.text = '["a", "b"]'
mock_patch.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
rc.patch("the-url")
mock_patch.assert_called_with(
"the-url", json=None, headers=headers, timeout=(10, 2)
mock_request.assert_called_with(
"PATCH", "the-url", headers=headers, timeout=(10, 2)
)
@mock.patch("requests.delete")
def test_delete_custom_timeout(self, mock_delete):
@mock.patch("requests.request")
def test_delete_custom_timeout(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False, timeout=(10, 2))

@@ -211,12 +209,12 @@ headers = {

}
mock_delete.return_value.text = '["a", "b"]'
mock_delete.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
rc.delete("the-url")
mock_delete.assert_called_with(
"the-url", params={}, json=None, headers=headers, timeout=(10, 2)
mock_request.assert_called_with(
"DELETE", "the-url", headers=headers, timeout=(10, 2)
)
@mock.patch("requests.get")
def test_get(self, mock_get):
@mock.patch("requests.request")
def test_get(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -228,9 +226,7 @@ headers = {

mock_get.return_value.text = '["a", "b"]'
mock_get.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
response = rc.get("the-url")
mock_get.assert_called_with(
"the-url", params=None, headers=headers, timeout=5.0
)
mock_request.assert_called_with("GET", "the-url", headers=headers, timeout=5.0)

@@ -240,19 +236,23 @@ self.assertEqual(response, ["a", "b"])

response = rc.get(url="the/url", params={"A": "param", "B": "param"})
mock_get.assert_called_with(
"the/url", params={"A": "param", "B": "param"}, headers=headers, timeout=5.0
mock_request.assert_called_with(
"GET",
"the/url",
params={"A": "param", "B": "param"},
headers=headers,
timeout=5.0,
)
self.assertEqual(response, ["a", "b"])
mock_get.return_value.text = ""
mock_request.return_value.text = ""
response = rc.get("the/url")
self.assertEqual(response, "")
@mock.patch("requests.get")
def test_get_errors(self, mock_get):
@mock.patch("requests.request")
def test_get_errors(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 999, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -266,4 +266,4 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.get")
def test_get_rate_limit_error(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_error(self, mock_request):
options = RestClientOptions(telemetry=False, retries=0)

@@ -273,7 +273,7 @@ rc = RestClient(jwt="a-token", options=options)

mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_get.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -295,13 +295,13 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.get")
def test_get_rate_limit_error_without_headers(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_error_without_headers(self, mock_request):
options = RestClientOptions(telemetry=False, retries=1)
rc = RestClient(jwt="a-token", options=options)
mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_request.return_value.status_code = 429
mock_get.return_value.headers = {}
mock_request.return_value.headers = {}
with self.assertRaises(Auth0Error) as context:

@@ -318,4 +318,4 @@ rc.get("the/url")

@mock.patch("requests.get")
def test_get_rate_limit_custom_retries(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_custom_retries(self, mock_request):
options = RestClientOptions(telemetry=False, retries=5)

@@ -325,7 +325,7 @@ rc = RestClient(jwt="a-token", options=options)

mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_get.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -348,4 +348,4 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.get")
def test_get_rate_limit_invalid_retries_below_min(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_invalid_retries_below_min(self, mock_request):
options = RestClientOptions(telemetry=False, retries=-1)

@@ -355,7 +355,7 @@ rc = RestClient(jwt="a-token", options=options)

mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_get.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -377,4 +377,4 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.get")
def test_get_rate_limit_invalid_retries_above_max(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_invalid_retries_above_max(self, mock_request):
options = RestClientOptions(telemetry=False, retries=11)

@@ -384,7 +384,7 @@ rc = RestClient(jwt="a-token", options=options)

mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_get.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -406,4 +406,4 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.get")
def test_get_rate_limit_retries_use_exponential_backoff(self, mock_get):
@mock.patch("requests.request")
def test_get_rate_limit_retries_use_exponential_backoff(self, mock_request):
options = RestClientOptions(telemetry=False, retries=10)

@@ -413,7 +413,7 @@ rc = RestClient(jwt="a-token", options=options)

mock_get.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_get.return_value.status_code = 429
mock_get.return_value.headers = {
mock_request.return_value.status_code = 429
mock_request.return_value.headers = {
"x-ratelimit-limit": "3",

@@ -496,4 +496,22 @@ "x-ratelimit-remaining": "6",

@mock.patch("requests.post")
def test_post(self, mock_post):
@mock.patch("requests.request")
def test_post_rate_limit_retries(self, mock_request):
options = RestClientOptions(telemetry=False, retries=10)
rc = RestClient(jwt="a-token", options=options)
rc._skip_sleep = True
mock_request.return_value.text = (
'{"statusCode": 429, "errorCode": "code", "message": "message"}'
)
mock_request.return_value.status_code = 429
with self.assertRaises(Auth0Error) as context:
rc.post("the/url")
self.assertEqual(context.exception.status_code, 429)
self.assertEqual(len(rc._metrics["backoff"]), 10)
@mock.patch("requests.request")
def test_post(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -505,20 +523,22 @@ headers = {

mock_post.return_value.text = '{"a": "b"}'
mock_request.return_value.text = '{"a": "b"}'
data = {"some": "data"}
mock_post.return_value.status_code = 200
mock_request.return_value.status_code = 200
response = rc.post("the/url", data=data)
mock_post.assert_called_with("the/url", json=data, headers=headers, timeout=5.0)
mock_request.assert_called_with(
"POST", "the/url", json=data, headers=headers, timeout=5.0
)
self.assertEqual(response, {"a": "b"})
@mock.patch("requests.post")
def test_post_errors(self, mock_post):
@mock.patch("requests.request")
def test_post_errors(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_post.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 999, "errorCode": "code", "message": "message"}'
)
mock_post.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -532,10 +552,10 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_errors_with_no_message_property(self, mock_post):
@mock.patch("requests.request")
def test_post_errors_with_no_message_property(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_post.return_value.text = json.dumps(
mock_request.return_value.text = json.dumps(
{"statusCode": 999, "errorCode": "code", "error": "error"}
)
mock_post.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -549,10 +569,10 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_errors_with_no_message_or_error_property(self, mock_post):
@mock.patch("requests.request")
def test_post_errors_with_no_message_or_error_property(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_post.return_value.text = json.dumps(
mock_request.return_value.text = json.dumps(
{"statusCode": 999, "errorCode": "code"}
)
mock_post.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -566,7 +586,7 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_errors_with_message_and_error_property(self, mock_post):
@mock.patch("requests.request")
def test_post_errors_with_message_and_error_property(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_post.return_value.text = json.dumps(
mock_request.return_value.text = json.dumps(
{

@@ -579,3 +599,3 @@ "statusCode": 999,

)
mock_post.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -589,9 +609,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_code_property(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_code_property(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = '{"errorCode": "e0","message": "desc"}'
mock_request.return_value.status_code = error_status
mock_request.return_value.text = '{"errorCode": "e0","message": "desc"}'

@@ -605,9 +625,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_no_error_code(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_no_error_code(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = '{"message": "desc"}'
mock_request.return_value.status_code = error_status
mock_request.return_value.text = '{"message": "desc"}'

@@ -621,9 +641,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_text_response(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_text_response(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = "there has been a terrible error"
mock_request.return_value.status_code = error_status
mock_request.return_value.text = "there has been a terrible error"

@@ -639,9 +659,9 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_post_error_with_no_response_text(self, mock_post):
@mock.patch("requests.request")
def test_post_error_with_no_response_text(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
for error_status in [400, 500, None]:
mock_post.return_value.status_code = error_status
mock_post.return_value.text = None
mock_request.return_value.status_code = error_status
mock_request.return_value.text = None

@@ -655,8 +675,8 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.post")
def test_file_post_content_type_is_none(self, mock_post):
@mock.patch("requests.request")
def test_file_post_content_type_is_none(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
headers = {"Authorization": "Bearer a-token"}
mock_post.return_value.status_code = 200
mock_post.return_value.text = "Success"
mock_request.return_value.status_code = 200
mock_request.return_value.text = "Success"

@@ -668,8 +688,8 @@ data = {"some": "data"}

mock_post.assert_called_once_with(
"the-url", data=data, files=files, headers=headers, timeout=5.0
mock_request.assert_called_once_with(
"POST", "the-url", data=data, files=files, headers=headers, timeout=5.0
)
@mock.patch("requests.put")
def test_put(self, mock_put):
@mock.patch("requests.request")
def test_put(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -681,4 +701,4 @@ headers = {

mock_put.return_value.text = '["a", "b"]'
mock_put.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200

@@ -688,14 +708,16 @@ data = {"some": "data"}

response = rc.put(url="the-url", data=data)
mock_put.assert_called_with("the-url", json=data, headers=headers, timeout=5.0)
mock_request.assert_called_with(
"PUT", "the-url", json=data, headers=headers, timeout=5.0
)
self.assertEqual(response, ["a", "b"])
@mock.patch("requests.put")
def test_put_errors(self, mock_put):
@mock.patch("requests.request")
def test_put_errors(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_put.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 999, "errorCode": "code", "message": "message"}'
)
mock_put.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -709,4 +731,4 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.patch")
def test_patch(self, mock_patch):
@mock.patch("requests.request")
def test_patch(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -718,4 +740,4 @@ headers = {

mock_patch.return_value.text = '["a", "b"]'
mock_patch.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200

@@ -725,4 +747,4 @@ data = {"some": "data"}

response = rc.patch(url="the-url", data=data)
mock_patch.assert_called_with(
"the-url", json=data, headers=headers, timeout=5.0
mock_request.assert_called_with(
"PATCH", "the-url", json=data, headers=headers, timeout=5.0
)

@@ -732,10 +754,10 @@

@mock.patch("requests.patch")
def test_patch_errors(self, mock_patch):
@mock.patch("requests.request")
def test_patch_errors(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_patch.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 999, "errorCode": "code", "message": "message"}'
)
mock_patch.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -749,4 +771,4 @@ with self.assertRaises(Auth0Error) as context:

@mock.patch("requests.delete")
def test_delete(self, mock_delete):
@mock.patch("requests.request")
def test_delete(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -758,8 +780,8 @@ headers = {

mock_delete.return_value.text = '["a", "b"]'
mock_delete.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200
response = rc.delete(url="the-url/ID")
mock_delete.assert_called_with(
"the-url/ID", headers=headers, params={}, json=None, timeout=5.0
mock_request.assert_called_with(
"DELETE", "the-url/ID", headers=headers, timeout=5.0
)

@@ -769,4 +791,4 @@

@mock.patch("requests.delete")
def test_delete_with_body_and_params(self, mock_delete):
@mock.patch("requests.request")
def test_delete_with_body_and_params(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)

@@ -778,4 +800,4 @@ headers = {

mock_delete.return_value.text = '["a", "b"]'
mock_delete.return_value.status_code = 200
mock_request.return_value.text = '["a", "b"]'
mock_request.return_value.status_code = 200

@@ -786,4 +808,9 @@ data = {"some": "data"}

response = rc.delete(url="the-url/ID", params=params, data=data)
mock_delete.assert_called_with(
"the-url/ID", headers=headers, params=params, json=data, timeout=5.0
mock_request.assert_called_with(
"DELETE",
"the-url/ID",
headers=headers,
params=params,
json=data,
timeout=5.0,
)

@@ -793,10 +820,10 @@

@mock.patch("requests.delete")
def test_delete_errors(self, mock_delete):
@mock.patch("requests.request")
def test_delete_errors(self, mock_request):
rc = RestClient(jwt="a-token", telemetry=False)
mock_delete.return_value.text = (
mock_request.return_value.text = (
'{"statusCode": 999, "errorCode": "code", "message": "message"}'
)
mock_delete.return_value.status_code = 999
mock_request.return_value.status_code = 999

@@ -803,0 +830,0 @@ with self.assertRaises(Auth0Error) as context:

Metadata-Version: 2.1
Name: auth0-python
Version: 4.5.0
Version: 4.6.0
Summary:

@@ -18,6 +18,7 @@ Home-page: https://auth0.com

Requires-Dist: aiohttp (>=3.8.5,<4.0.0)
Requires-Dist: cryptography (>=41.0.3,<42.0.0)
Requires-Dist: cryptography (>=41.0.5,<42.0.0)
Requires-Dist: pyjwt (>=2.8.0,<3.0.0)
Requires-Dist: pyopenssl (>=23.2.0,<24.0.0)
Requires-Dist: requests (>=2.31.0,<3.0.0)
Requires-Dist: urllib3 (>=2.0.7,<3.0.0)
Project-URL: Repository, https://github.com/auth0/auth0-python

@@ -24,0 +25,0 @@ Description-Content-Type: text/markdown

@@ -7,3 +7,3 @@ [build-system]

name = "auth0-python"
version = "4.5.0" # This is replaced by dynamic versioning
version = "4.6.0" # This is replaced by dynamic versioning
description = ""

@@ -32,6 +32,7 @@ authors = ["Auth0 <support@auth0.com>"]

aiohttp = "^3.8.5"
cryptography = "^41.0.5" # pyjwt has a weak dependency on cryptography
pyjwt = "^2.8.0"
cryptography = "^41.0.3" # pyjwt has a weak dependency on cryptography
pyopenssl = "^23.2.0" # pyopenssl is required to work with cryptography 41+
requests = "^2.31.0"
urllib3 = "^2.0.7" # requests has a weak dependency on urllib3

@@ -38,0 +39,0 @@ [tool.poetry.group.dev.dependencies]