mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 11:18:22 +00:00
Add new application structure: - app/main.py - application entry point - app/plugins/ - plugin system with auth plugin: - api/ - REST API endpoints and schemas - authorization/ - auth policies, providers, hooks - domain/ - business logic (service, models, jwt, password) - injection/ - route injection and guards - ops/ - operational utilities - runtime/ - runtime configuration - security/ - middleware, CSRF, dependencies - storage/ - user repositories and models - app/static/ - static assets (scalar.js for API docs) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
38 lines
1.2 KiB
Python
38 lines
1.2 KiB
Python
"""JWT token creation and verification."""
|
|
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
import jwt
|
|
from pydantic import BaseModel
|
|
|
|
from app.plugins.auth.domain.errors import TokenError
|
|
from app.plugins.auth.runtime.config_state import get_auth_config
|
|
|
|
|
|
class TokenPayload(BaseModel):
|
|
sub: str
|
|
exp: datetime
|
|
iat: datetime | None = None
|
|
ver: int = 0
|
|
|
|
|
|
def create_access_token(user_id: str, expires_delta: timedelta | None = None, token_version: int = 0) -> str:
|
|
config = get_auth_config()
|
|
expiry = expires_delta or timedelta(days=config.token_expiry_days)
|
|
now = datetime.now(UTC)
|
|
payload = {"sub": user_id, "exp": now + expiry, "iat": now, "ver": token_version}
|
|
return jwt.encode(payload, config.jwt_secret, algorithm="HS256")
|
|
|
|
|
|
def decode_token(token: str) -> TokenPayload | TokenError:
|
|
config = get_auth_config()
|
|
try:
|
|
payload = jwt.decode(token, config.jwt_secret, algorithms=["HS256"])
|
|
return TokenPayload(**payload)
|
|
except jwt.ExpiredSignatureError:
|
|
return TokenError.EXPIRED
|
|
except jwt.InvalidSignatureError:
|
|
return TokenError.INVALID_SIGNATURE
|
|
except jwt.PyJWTError:
|
|
return TokenError.MALFORMED
|