59 lines
2.6 KiB
Python
59 lines
2.6 KiB
Python
# app/api/v1/endpoints/invites.py
|
|
import logging
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database import get_db
|
|
from app.api.dependencies import get_current_user
|
|
from app.models import User as UserModel, UserRoleEnum
|
|
from app.schemas.invite import InviteAccept
|
|
from app.schemas.message import Message
|
|
from app.crud import invite as crud_invite
|
|
from app.crud import group as crud_group
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
@router.post(
|
|
"/accept", # Route relative to prefix "/invites"
|
|
response_model=Message,
|
|
summary="Accept Group Invite",
|
|
tags=["Invites"]
|
|
)
|
|
async def accept_invite(
|
|
invite_in: InviteAccept,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: UserModel = Depends(get_current_user),
|
|
):
|
|
"""Allows an authenticated user to accept an invite using its code."""
|
|
code = invite_in.code
|
|
logger.info(f"User {current_user.email} attempting to accept invite code: {code}")
|
|
|
|
# Find the active, non-expired invite
|
|
invite = await crud_invite.get_active_invite_by_code(db=db, code=code)
|
|
if not invite:
|
|
logger.warning(f"Invite code '{code}' not found, expired, or already used.")
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Invite code is invalid or expired")
|
|
|
|
group_id = invite.group_id
|
|
|
|
# Check if user is already in the group
|
|
is_member = await crud_group.is_user_member(db=db, group_id=group_id, user_id=current_user.id)
|
|
if is_member:
|
|
logger.info(f"User {current_user.email} is already a member of group {group_id}. Invite '{code}' still deactivated.")
|
|
# Deactivate invite even if already member, to prevent reuse
|
|
await crud_invite.deactivate_invite(db=db, invite=invite)
|
|
return Message(detail="You are already a member of this group.")
|
|
|
|
# Add user to the group as a member
|
|
added = await crud_group.add_user_to_group(db=db, group_id=group_id, user_id=current_user.id, role=UserRoleEnum.member)
|
|
if not added:
|
|
# Should not happen if is_member check was correct, but handle defensively
|
|
logger.error(f"Failed to add user {current_user.email} to group {group_id} via invite '{code}' despite not being a member.")
|
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Could not join group.")
|
|
|
|
# Deactivate the invite (single-use)
|
|
await crud_invite.deactivate_invite(db=db, invite=invite)
|
|
|
|
logger.info(f"User {current_user.email} successfully joined group {group_id} using invite '{code}'.")
|
|
return Message(detail="Successfully joined the group.") |