48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import structlog
|
|
|
|
from app.tasks.celery_app import celery_app
|
|
|
|
logger = structlog.get_logger("tasks.auth")
|
|
|
|
|
|
@celery_app.task(name="app.tasks.auth_tasks.cleanup_expired_tokens")
|
|
def cleanup_expired_tokens() -> dict:
|
|
"""Remove expired and revoked refresh tokens from the database."""
|
|
import asyncio
|
|
|
|
from sqlalchemy import delete
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
from datetime import datetime
|
|
|
|
from app.core.config import settings
|
|
from app.models.mariadb.auth import RefreshToken
|
|
|
|
async def _cleanup() -> int:
|
|
engine = create_async_engine(settings.MARIADB_DSN)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as session:
|
|
stmt = delete(RefreshToken).where(
|
|
(RefreshToken.expires_at < datetime.utcnow()) | (RefreshToken.is_revoked == True) # noqa: E712
|
|
)
|
|
result = await session.execute(stmt)
|
|
await session.commit()
|
|
count = result.rowcount # type: ignore[assignment]
|
|
|
|
await engine.dispose()
|
|
return count
|
|
|
|
count = asyncio.get_event_loop().run_until_complete(_cleanup())
|
|
logger.info("tokens_cleaned", count=count)
|
|
return {"cleaned": count}
|
|
|
|
|
|
@celery_app.task(name="app.tasks.auth_tasks.send_verification_email")
|
|
def send_verification_email(user_id: int, email: str, token: str) -> dict:
|
|
"""Send email verification link to user."""
|
|
logger.info("verification_email_sent", user_id=user_id, email=email)
|
|
return {"status": "sent", "email": email}
|