Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ docs/build/
.DS_Store

# AI tools
.claude/
.claude/
error.txt
21 changes: 21 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
repos:
- repo: local
hooks:
- id: ruff
name: ruff
entry: ruff check --force-exclude
language: system
types_or: [python, pyi]
require_serial: true
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-merge-conflict
- repo: local
hooks:
- id: ggshield
name: ggshield
entry: ggshield secret scan pre-commit
language: system
stages: [pre-commit]
4 changes: 2 additions & 2 deletions src/auth0/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file was auto-generated by Fern from our API Definition.

from . import management
from . import authentication
from . import authentication, management

from auth0.management.version import __version__

__all__ = ["management", "authentication", "__version__"]
5 changes: 2 additions & 3 deletions src/auth0/authentication/back_channel_login.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from typing import Any, Optional, Union, List, Dict
import json
from typing import Any, Dict, List, Optional, Union

from .base import AuthenticationBase

import json


class BackChannelLogin(AuthenticationBase):
"""Back-Channel Login endpoint"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from .base import AuthenticationBase



class PushedAuthorizationRequests(AuthenticationBase):
"""Pushed Authorization Request (PAR) endpoint"""

Expand Down
4 changes: 1 addition & 3 deletions src/auth0/authentication/rest_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
from typing import Any

import aiohttp

from .exceptions import RateLimitError
from .types import RequestData

from .rest import EmptyResponse, JsonResponse, PlainResponse, Response, RestClient
from .types import RequestData


def _clean_params(params: dict[Any, Any] | None) -> dict[Any, Any] | None:
Expand Down
1 change: 0 additions & 1 deletion src/auth0/authentication/token_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import jwt
import requests

from .exceptions import TokenValidationError

if TYPE_CHECKING:
Expand Down
17 changes: 15 additions & 2 deletions src/auth0/management/types/user_response_schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This file was auto-generated by Fern from our API Definition.

import typing
from typing import Annotated

import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
Expand All @@ -9,6 +10,16 @@
from .user_identity_schema import UserIdentitySchema
from .user_metadata_schema import UserMetadataSchema

StrBool = Annotated[
bool,
pydantic.BeforeValidator(
lambda x: bool(x) if isinstance(x, bool) else bool(x and str(x).strip())
), # Coerces input values (like "", "email_address") into a bool
pydantic.PlainSerializer(
lambda x: 1 if x else 0, return_type=int
), # Serializes bool to 0 or 1
]


class UserResponseSchema(UniversalBaseModel):
user_id: typing.Optional[str] = pydantic.Field(default=None)
Expand All @@ -21,7 +32,7 @@ class UserResponseSchema(UniversalBaseModel):
Email address of this user.
"""

email_verified: typing.Optional[bool] = pydantic.Field(default=None)
email_verified: typing.Optional[StrBool] = pydantic.Field(default=None)
"""
Whether this email address is verified (true) or unverified (false).
"""
Expand All @@ -43,7 +54,9 @@ class UserResponseSchema(UniversalBaseModel):

created_at: typing.Optional[UserDateSchema] = None
updated_at: typing.Optional[UserDateSchema] = None
identities: typing.Optional[typing.List[UserIdentitySchema]] = pydantic.Field(default=None)
identities: typing.Optional[typing.List[UserIdentitySchema]] = pydantic.Field(
default=None
)
"""
Array of user identity objects when accounts are linked.
"""
Expand Down
5 changes: 3 additions & 2 deletions tests/authentication/test_back_channel_login.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

import json
import unittest
from unittest import mock
import json

import requests
from auth0.authentication.exceptions import Auth0Error, RateLimitError

from auth0.authentication.back_channel_login import BackChannelLogin
from auth0.authentication.exceptions import Auth0Error


class TestBackChannelLogin(unittest.TestCase):
@mock.patch("auth0.authentication.rest.RestClient.post")
Expand Down
2 changes: 1 addition & 1 deletion tests/authentication/test_get_token.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import unittest
import requests
from fnmatch import fnmatch
from unittest import mock
from unittest.mock import ANY

import requests
from cryptography.hazmat.primitives import asymmetric, serialization

from auth0.authentication.exceptions import RateLimitError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import unittest
import json
import unittest
from unittest import mock

from auth0.authentication.pushed_authorization_requests import PushedAuthorizationRequests
Expand Down
2 changes: 1 addition & 1 deletion tests/authentication/test_token_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

import jwt

from auth0.authentication.exceptions import TokenValidationError
from auth0.authentication.token_verifier import (
AsymmetricSignatureVerifier,
JwksFetcher,
SignatureVerifier,
SymmetricSignatureVerifier,
TokenVerifier,
)
from auth0.authentication.exceptions import TokenValidationError

RSA_PUB_KEY_1_PEM = b"""-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4\nyCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9\n83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs\nWXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT\n69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8\nAziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0\nYwIDAQAB\n-----END PUBLIC KEY-----\n"""
RSA_PUB_KEY_2_PEM = b"""-----BEGIN PUBLIC KEY-----\nMDowDQYJKoZIhvcNAQEBBQADKQAwJgIfAI7TBUCn8e1hj/fNpb5dqMf8Jj6Ja6qN\npqyeOGYEzAIDAQAB\n-----END PUBLIC KEY-----\n"""
Expand Down
53 changes: 53 additions & 0 deletions tests/management/test_user_response_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from auth0.management.types.user_response_schema import UserResponseSchema


class TestEmailVerifiedStrBool:
"""Tests that email_verified accepts both bool and string values."""

def test_bool_true(self):
user = UserResponseSchema(email_verified=True)
assert user.email_verified is True

def test_bool_false(self):
user = UserResponseSchema(email_verified=False)
assert user.email_verified is False

def test_none(self):
user = UserResponseSchema(email_verified=None)
assert user.email_verified is None

def test_default_none(self):
user = UserResponseSchema()
assert user.email_verified is None

def test_nonempty_string_is_true(self):
user = UserResponseSchema(email_verified="user@example.com")
assert user.email_verified is True

def test_empty_string_is_false(self):
user = UserResponseSchema(email_verified="")
assert user.email_verified is False

def test_whitespace_only_string_is_false(self):
user = UserResponseSchema(email_verified=" ")
assert user.email_verified is False

def test_serialization_true_to_int(self):
user = UserResponseSchema(email_verified=True)
data = user.dict()
assert data["email_verified"] == 1

def test_serialization_false_to_int(self):
user = UserResponseSchema(email_verified=False)
data = user.dict()
assert data["email_verified"] == 0

def test_serialization_string_true_to_int(self):
user = UserResponseSchema(email_verified="verified")
data = user.dict()
assert data["email_verified"] == 1

def test_serialization_empty_string_to_int(self):
user = UserResponseSchema(email_verified="")
data = user.dict()
assert data["email_verified"] == 0