6306abf6d9
- Created architecture overview in development/architecture.md - Added installation guide in getting-started/installation.md - Developed user guide with detailed instructions in user-guide/overview.md, user-guide/teams.md, user-guide/qr-codes.md - Implemented social login setup documentation in social_login_setup.md - Updated index.md to include links to new documentation sections - Configured mkdocs.yml for site structure and theme - Added requirements.txt for documentation dependencies
162 lines
4.9 KiB
Python
162 lines
4.9 KiB
Python
"""
|
|
Authentication utilities for LeagueLedger.
|
|
This module provides backward compatibility with the existing code while leveraging
|
|
the new Starlette authentication system.
|
|
"""
|
|
from typing import Optional
|
|
from fastapi import Request, Depends
|
|
from sqlalchemy.orm import Session
|
|
from ..db import get_db
|
|
from ..models import User, TeamMembership
|
|
from starlette.authentication import UnauthenticatedUser
|
|
|
|
async def get_current_user(request: Request, db: Session = Depends(get_db)) -> Optional[User]:
|
|
"""
|
|
Get the current authenticated user from the request.
|
|
Now uses request.user from Starlette authentication with fallback to session.
|
|
|
|
Args:
|
|
request: The FastAPI request object
|
|
db: SQLAlchemy database session
|
|
|
|
Returns:
|
|
User object if authenticated, None otherwise
|
|
"""
|
|
# First try to get user from Starlette authentication
|
|
if hasattr(request, "user") and request.user.is_authenticated:
|
|
return request.user
|
|
|
|
# Fallback to session-based authentication (for backward compatibility)
|
|
user_id = request.session.get("user_id")
|
|
|
|
if not user_id:
|
|
return None
|
|
|
|
# Fetch the user from the database
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
|
|
if not user:
|
|
# If user doesn't exist in database but has a session, clear the session
|
|
request.session.clear()
|
|
return None
|
|
|
|
return user
|
|
|
|
async def is_team_captain(
|
|
team_id: int,
|
|
user: Optional[User] = None,
|
|
request: Optional[Request] = None,
|
|
db: Session = Depends(get_db)
|
|
) -> bool:
|
|
"""
|
|
Check if the current user is a captain of the specified team.
|
|
|
|
Args:
|
|
team_id: ID of the team to check
|
|
user: Optional pre-loaded user object
|
|
request: Optional FastAPI request object (used if user is not provided)
|
|
db: SQLAlchemy database session
|
|
|
|
Returns:
|
|
True if the user is a team captain, False otherwise
|
|
"""
|
|
if not user and request:
|
|
user = await get_current_user(request, db)
|
|
|
|
if not user:
|
|
return False
|
|
|
|
# Check if the user is a captain of the team
|
|
is_captain = db.query(TeamMembership).filter(
|
|
TeamMembership.team_id == team_id,
|
|
TeamMembership.user_id == user.id,
|
|
TeamMembership.is_captain == True # Changed from role="captain" to is_captain=True
|
|
).first()
|
|
|
|
return bool(is_captain)
|
|
|
|
async def is_admin(request: Request, db: Session = Depends(get_db)) -> bool:
|
|
"""
|
|
Check if the current user is an admin.
|
|
Now checks Starlette auth scopes first.
|
|
|
|
Args:
|
|
request: FastAPI request object
|
|
db: SQLAlchemy database session
|
|
|
|
Returns:
|
|
True if the user is an admin, False otherwise
|
|
"""
|
|
# Check for 'admin' scope in Starlette auth
|
|
if hasattr(request, "auth") and request.auth and "admin" in request.auth.scopes:
|
|
return True
|
|
|
|
# Fallback to user object check
|
|
user = await get_current_user(request, db)
|
|
|
|
if not user:
|
|
return False
|
|
|
|
return user.is_admin
|
|
|
|
async def requires_login(request: Request, db: Session = Depends(get_db)) -> Optional[User]:
|
|
"""
|
|
Dependency to ensure the user is logged in.
|
|
|
|
Args:
|
|
request: FastAPI request object
|
|
db: SQLAlchemy database session
|
|
|
|
Returns:
|
|
User object if authenticated, raises HTTPException otherwise
|
|
"""
|
|
from fastapi import HTTPException, status
|
|
|
|
# Check Starlette auth first
|
|
if hasattr(request, "user") and request.user.is_authenticated:
|
|
return request.user
|
|
|
|
# Fallback to session check
|
|
user = await get_current_user(request, db)
|
|
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Authentication required",
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
)
|
|
|
|
return user
|
|
|
|
async def requires_admin(request: Request, db: Session = Depends(get_db)) -> User:
|
|
"""
|
|
Dependency to ensure the user is an admin.
|
|
|
|
Args:
|
|
request: FastAPI request object
|
|
db: SQLAlchemy database session
|
|
|
|
Returns:
|
|
User object if authenticated and is admin, raises HTTPException otherwise
|
|
"""
|
|
from fastapi import HTTPException, status
|
|
|
|
# Check for admin scope in Starlette auth
|
|
if hasattr(request, "auth") and request.auth and "admin" in request.auth.scopes:
|
|
if hasattr(request, "user") and request.user.is_authenticated:
|
|
return request.user
|
|
|
|
# Fallback to user object check
|
|
user = await get_current_user(request, db)
|
|
|
|
if not user or not user.is_admin:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Admin privileges required",
|
|
)
|
|
|
|
return user
|
|
|
|
# Note: For new code, consider using the decorators in app.auth.permissions instead
|
|
# of these dependency functions directly
|