Implements both IndieAuth flows per W3C specification: - Authentication flow (response_type=id): Code redeemed at authorization endpoint, returns only user identity - Authorization flow (response_type=code): Code redeemed at token endpoint, returns access token Changes: - Authorization endpoint GET: Accept response_type=id (default) and code - Authorization endpoint POST: Handle code verification for authentication flow - Token endpoint: Validate response_type=code for authorization flow - Store response_type in authorization code metadata - Update metadata endpoint: response_types_supported=[code, id], code_challenge_methods_supported=[S256] The default behavior now correctly defaults to response_type=id when omitted, per IndieAuth spec section 5.2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
"""OAuth 2.0 Authorization Server Metadata endpoint (RFC 8414)."""
|
|
import json
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Depends, Response
|
|
|
|
from gondulf.config import Config
|
|
from gondulf.dependencies import get_config
|
|
|
|
logger = logging.getLogger("gondulf.metadata")
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/.well-known/oauth-authorization-server")
|
|
async def get_metadata(config: Config = Depends(get_config)) -> Response:
|
|
"""
|
|
OAuth 2.0 Authorization Server Metadata (RFC 8414).
|
|
|
|
Returns server capabilities for IndieAuth client discovery.
|
|
This endpoint is publicly accessible and cacheable.
|
|
|
|
Returns:
|
|
Response: JSON response with server metadata and Cache-Control header
|
|
"""
|
|
logger.debug("Metadata endpoint requested")
|
|
|
|
metadata = {
|
|
"issuer": config.BASE_URL,
|
|
"authorization_endpoint": f"{config.BASE_URL}/authorize",
|
|
"token_endpoint": f"{config.BASE_URL}/token",
|
|
"response_types_supported": ["code", "id"],
|
|
"grant_types_supported": ["authorization_code"],
|
|
"code_challenge_methods_supported": ["S256"],
|
|
"token_endpoint_auth_methods_supported": ["none"],
|
|
"revocation_endpoint_auth_methods_supported": ["none"],
|
|
"scopes_supported": []
|
|
}
|
|
|
|
logger.debug(f"Returning metadata for issuer: {config.BASE_URL}")
|
|
|
|
return Response(
|
|
content=json.dumps(metadata, indent=2),
|
|
media_type="application/json",
|
|
headers={
|
|
"Cache-Control": "public, max-age=86400"
|
|
}
|
|
)
|