Fix auth to handle JWT tokens without actor_id
- Default actor_id to @username when not in token claims - Support both artdag_session (base64 JSON) and auth_token (JWT) cookies - Check both 'username' and 'sub' claims for username - Check both 'actor_id' and 'actor' claims for actor_id This fixes authentication when L2 tokens don't include actor_id. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
BIN
artdag_common/middleware/__pycache__/auth.cpython-310.pyc
Normal file
BIN
artdag_common/middleware/__pycache__/auth.cpython-310.pyc
Normal file
Binary file not shown.
@@ -31,8 +31,9 @@ def get_user_from_cookie(request: Request) -> Optional[UserContext]:
|
||||
"""
|
||||
Extract user context from session cookie.
|
||||
|
||||
The cookie format is expected to be base64-encoded JSON:
|
||||
{"username": "user", "actor_id": "@user@server.com"}
|
||||
Supports two cookie formats:
|
||||
1. artdag_session: base64-encoded JSON {"username": "user", "actor_id": "@user@server.com"}
|
||||
2. auth_token: raw JWT token (used by L1 servers)
|
||||
|
||||
Args:
|
||||
request: FastAPI request
|
||||
@@ -40,19 +41,38 @@ def get_user_from_cookie(request: Request) -> Optional[UserContext]:
|
||||
Returns:
|
||||
UserContext if valid cookie found, None otherwise
|
||||
"""
|
||||
# Try artdag_session cookie first (base64-encoded JSON)
|
||||
cookie = request.cookies.get("artdag_session")
|
||||
if not cookie:
|
||||
return None
|
||||
if cookie:
|
||||
try:
|
||||
data = json.loads(base64.b64decode(cookie))
|
||||
username = data.get("username", "")
|
||||
actor_id = data.get("actor_id", "")
|
||||
if not actor_id and username:
|
||||
actor_id = f"@{username}"
|
||||
return UserContext(
|
||||
username=username,
|
||||
actor_id=actor_id,
|
||||
)
|
||||
except (json.JSONDecodeError, ValueError, KeyError):
|
||||
pass
|
||||
|
||||
try:
|
||||
# Decode base64 cookie
|
||||
data = json.loads(base64.b64decode(cookie))
|
||||
return UserContext(
|
||||
username=data.get("username", ""),
|
||||
actor_id=data.get("actor_id", ""),
|
||||
)
|
||||
except (json.JSONDecodeError, ValueError, KeyError):
|
||||
return None
|
||||
# Try auth_token cookie (raw JWT, used by L1)
|
||||
token = request.cookies.get("auth_token")
|
||||
if token:
|
||||
claims = decode_jwt_claims(token)
|
||||
if claims:
|
||||
username = claims.get("username") or claims.get("sub", "")
|
||||
actor_id = claims.get("actor_id") or claims.get("actor")
|
||||
if not actor_id and username:
|
||||
actor_id = f"@{username}"
|
||||
return UserContext(
|
||||
username=username,
|
||||
actor_id=actor_id or "",
|
||||
token=token,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_user_from_header(request: Request) -> Optional[UserContext]:
|
||||
@@ -76,9 +96,14 @@ def get_user_from_header(request: Request) -> Optional[UserContext]:
|
||||
# Attempt to decode JWT claims
|
||||
claims = decode_jwt_claims(token)
|
||||
if claims:
|
||||
username = claims.get("username") or claims.get("sub", "")
|
||||
actor_id = claims.get("actor_id") or claims.get("actor")
|
||||
# Default actor_id to @username if not provided
|
||||
if not actor_id and username:
|
||||
actor_id = f"@{username}"
|
||||
return UserContext(
|
||||
username=claims.get("username", ""),
|
||||
actor_id=claims.get("actor_id", ""),
|
||||
username=username,
|
||||
actor_id=actor_id or "",
|
||||
token=token,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user