CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-oauth-toolkit

OAuth2 Provider for Django web applications with complete server functionality, token management, and authorization endpoints.

Pending
Overview
Eval results
Files

models.mddocs/

OAuth2 Models

Django OAuth Toolkit provides comprehensive Django model classes for managing OAuth2 entities. These models handle applications, tokens, grants, and OIDC ID tokens with full ORM integration, validation, and admin interface support.

Capabilities

Application Management

OAuth2 client application registration and management with support for different client types and authorization grant types.

class Application(AbstractApplication):
    """
    OAuth2 client application model.
    
    Attributes:
        client_id (str): Unique client identifier
        client_secret (str): Confidential client secret (hashed)
        hash_client_secret (bool): Whether to hash client secret on save
        name (str): Human-readable application name
        user (User): Application owner
        redirect_uris (str): Space-separated allowed redirect URIs
        post_logout_redirect_uris (str): Space-separated OIDC logout URIs
        client_type (str): 'confidential' or 'public'
        authorization_grant_type (str): Grant type supported
        skip_authorization (bool): Skip user consent screen
        algorithm (str): OIDC signing algorithm
        allowed_origins (str): CORS allowed origins
        created (datetime): Application creation timestamp
        updated (datetime): Last modification timestamp
    """
    
    # Client types
    CLIENT_CONFIDENTIAL = "confidential"
    CLIENT_PUBLIC = "public"
    CLIENT_TYPES = (
        (CLIENT_CONFIDENTIAL, "Confidential"),
        (CLIENT_PUBLIC, "Public"),
    )
    
    # Grant types
    GRANT_AUTHORIZATION_CODE = "authorization-code"
    GRANT_IMPLICIT = "implicit"
    GRANT_PASSWORD = "password"
    GRANT_CLIENT_CREDENTIALS = "client-credentials"
    GRANT_OPENID_HYBRID = "openid-hybrid"
    GRANT_TYPES = (
        (GRANT_AUTHORIZATION_CODE, "Authorization code"),
        (GRANT_IMPLICIT, "Implicit"),
        (GRANT_PASSWORD, "Resource owner password-based"),
        (GRANT_CLIENT_CREDENTIALS, "Client credentials"),
        (GRANT_OPENID_HYBRID, "OpenID connect hybrid"),
    )
    
    # OIDC algorithms
    NO_ALGORITHM = ""
    RS256_ALGORITHM = "RS256"
    HS256_ALGORITHM = "HS256"
    ALGORITHM_TYPES = (
        (NO_ALGORITHM, "No OIDC support"),
        (RS256_ALGORITHM, "RSA with SHA-2 256"),
        (HS256_ALGORITHM, "HMAC with SHA-2 256"),
    )
    
    objects = ApplicationManager()
    
    def redirect_uri_allowed(self, uri: str) -> bool:
        """Check if URI is allowed for redirect"""
    
    def post_logout_redirect_uri_allowed(self, uri: str) -> bool:
        """Check if URI is allowed for OIDC logout redirect"""
    
    def origin_allowed(self, origin: str) -> bool:
        """Check if origin is allowed for CORS"""
    
    def allows_grant_type(self, *grant_types: str) -> bool:
        """Check if application supports given grant types"""
    
    def is_usable(self, request) -> bool:
        """Check if application can be used for request"""
    
    @property
    def default_redirect_uri(self) -> str:
        """Get default redirect URI if only one exists"""
    
    @property
    def jwk_key(self):
        """Get JWK key for OIDC signing"""

class ApplicationManager(models.Manager):
    def get_by_natural_key(self, client_id: str) -> Application:
        """Get application by client ID"""

Access Token Management

OAuth2 access tokens with scope validation, expiration checking, and revocation support.

class AccessToken(AbstractAccessToken):
    """
    OAuth2 access token model.
    
    Attributes:
        token (str): The access token value
        token_checksum (str): SHA-256 checksum of token
        user (User): Token owner
        application (Application): Associated client application
        expires (datetime): Token expiration time
        scope (str): Space-separated granted scopes
        source_refresh_token (RefreshToken): Source refresh token if any
        id_token (IDToken): Associated OIDC ID token if any
    """
    
    def is_valid(self, scopes=None) -> bool:
        """
        Check if access token is valid.
        
        Args:
            scopes: Optional list of required scopes
            
        Returns:
            True if token is not expired and has required scopes
        """
    
    def is_expired(self) -> bool:
        """Check if token has expired"""
    
    def allow_scopes(self, scopes) -> bool:
        """
        Check if token allows the provided scopes.
        
        Args:
            scopes: Iterable of scope names to check
            
        Returns:
            True if all scopes are allowed
        """
    
    def revoke(self) -> None:
        """Revoke the access token by deleting it"""
    
    @property
    def scopes(self) -> dict:
        """Get dictionary of allowed scope names with descriptions"""

Refresh Token Management

OAuth2 refresh tokens for obtaining new access tokens with revocation and family tracking.

class RefreshToken(AbstractRefreshToken):
    """
    OAuth2 refresh token model.
    
    Attributes:
        token (str): The refresh token value
        user (User): Token owner
        application (Application): Associated client application
        access_token (AccessToken): Associated access token
        token_family (UUID): Token family for rotation tracking
        revoked (datetime): Revocation timestamp if revoked
    """
    
    def revoke(self) -> None:
        """
        Revoke refresh token and associated access token.
        Handles atomic operations and prevents race conditions.
        """

Authorization Grant Management

OAuth2 authorization grants for the authorization code flow with PKCE support.

class Grant(AbstractGrant):
    """
    OAuth2 authorization grant model.
    
    Attributes:
        user (User): User who authorized the grant
        code (str): Authorization code
        application (Application): Client application
        expires (datetime): Grant expiration time
        redirect_uri (str): Redirect URI for this grant
        scope (str): Granted scopes
        code_challenge (str): PKCE code challenge
        code_challenge_method (str): PKCE challenge method ('plain' or 'S256')
        nonce (str): OIDC nonce value
        claims (str): OIDC claims parameter
    """
    
    CODE_CHALLENGE_PLAIN = "plain"
    CODE_CHALLENGE_S256 = "S256"
    CODE_CHALLENGE_METHODS = (
        (CODE_CHALLENGE_PLAIN, "plain"),
        (CODE_CHALLENGE_S256, "S256")
    )
    
    def is_expired(self) -> bool:
        """Check if grant has expired"""
    
    def redirect_uri_allowed(self, uri: str) -> bool:
        """Check if URI matches grant's redirect URI"""

OIDC ID Token Management

OpenID Connect ID tokens for identity information with JWT token ID tracking.

class IDToken(AbstractIDToken):
    """
    OIDC ID token model.
    
    Attributes:
        jti (UUID): JWT Token ID for unique identification
        user (User): Token subject
        application (Application): Client application
        expires (datetime): Token expiration time
        scope (str): Token scopes
    """
    
    def is_valid(self, scopes=None) -> bool:
        """Check if ID token is valid and has required scopes"""
    
    def is_expired(self) -> bool:
        """Check if token has expired"""
    
    def allow_scopes(self, scopes) -> bool:
        """Check if token allows the provided scopes"""
    
    def revoke(self) -> None:
        """Revoke the ID token by deleting it"""
    
    @property
    def scopes(self) -> dict:
        """Get dictionary of allowed scope names with descriptions"""

Model Factory Functions

Functions to get the active model classes, supporting Django's swappable model system.

def get_application_model():
    """Return the Application model class active in this project"""

def get_access_token_model():
    """Return the AccessToken model class active in this project"""

def get_refresh_token_model():
    """Return the RefreshToken model class active in this project"""

def get_grant_model():
    """Return the Grant model class active in this project"""

def get_id_token_model():
    """Return the IDToken model class active in this project"""

Token Cleanup Functions

Utility functions for managing token lifecycle and cleanup.

def clear_expired() -> None:
    """
    Remove all expired tokens and grants from the database.
    Handles batch deletion to avoid memory issues with large datasets.
    Processes refresh tokens, access tokens, ID tokens, and grants.
    """

Validation Utilities

Helper functions for URI and origin validation.

def redirect_to_uri_allowed(uri: str, allowed_uris: list) -> bool:
    """
    Check if URI can be redirected to based on allowed URIs.
    Handles exact matches and RFC 8252 loopback IP rules.
    
    Args:
        uri: URI to validate
        allowed_uris: List of allowed redirect URIs
        
    Returns:
        True if redirect is allowed
    """

def is_origin_allowed(origin: str, allowed_origins: list) -> bool:
    """
    Check if origin is allowed based on CORS configuration.
    
    Args:
        origin: Origin URI to validate
        allowed_origins: List of allowed origin URIs
        
    Returns:
        True if origin is allowed
    """

Model Admin Helpers

Factory functions for retrieving active admin classes for OAuth2 models. These functions return the admin classes configured through Django settings.

def get_application_admin_class():
    """Return the Application admin class that is active in this project."""

def get_access_token_admin_class():
    """Return the AccessToken admin class that is active in this project."""

def get_grant_admin_class():
    """Return the Grant admin class that is active in this project."""

def get_id_token_admin_class():
    """Return the IDToken admin class that is active in this project."""

def get_refresh_token_admin_class():
    """Return the RefreshToken admin class that is active in this project."""

Usage Examples

Creating Applications

from oauth2_provider.models import Application

# Confidential web application
web_app = Application.objects.create(
    name="My Web Application",
    client_type=Application.CLIENT_CONFIDENTIAL,
    authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
    redirect_uris="http://localhost:8000/callback/",
)

# Public mobile application
mobile_app = Application.objects.create(
    name="My Mobile App",
    client_type=Application.CLIENT_PUBLIC,
    authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
    redirect_uris="myapp://callback/",
)

Working with Tokens

from oauth2_provider.models import AccessToken, get_access_token_model

# Check token validity
token = AccessToken.objects.get(token="your-token-here")
if token.is_valid(['read', 'write']):
    print("Token is valid for read/write operations")

# Revoke tokens
token.revoke()

# Clean up expired tokens
from oauth2_provider.models import clear_expired
clear_expired()

Model Relationships

# Access related objects
application = Application.objects.get(client_id="your-client-id")
tokens = application.accesstoken_set.filter(expires__gt=timezone.now())

# Get user's applications
user_apps = Application.objects.filter(user=request.user)

# Get user's authorized tokens
user_tokens = AccessToken.objects.filter(user=request.user)

Install with Tessl CLI

npx tessl i tessl/pypi-django-oauth-toolkit

docs

drf-integration.md

index.md

management-commands.md

management-views.md

models.md

oauth2-endpoints.md

oidc.md

settings.md

view-protection.md

tile.json