feat: invite code

This commit is contained in:
2025-03-05 18:39:54 +03:00
parent c75ff66f27
commit 6c2698679d
7 changed files with 107 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
from datetime import datetime
from typing import Union, Annotated
from fastapi import Depends, HTTPException
@@ -11,7 +12,7 @@ import backend.config
import constants
from backend.session import get_session
from enums.user import UserRole
from models import User
from models import User, InviteCode
from schemas.auth import *
from services.base import BaseService
@@ -62,20 +63,37 @@ class AuthService(BaseService):
return jwt.encode(payload, backend.config.SECRET_KEY, algorithm=algorithm)
async def authenticate(self, request: AuthLoginRequest):
if request.id not in constants.allowed_telegram_ids:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid credentials')
user: Union[User, None] = await self.session.scalar(select(User).where(User.telegram_id == request.id))
user: Optional[User] = await self.session.scalar(select(User).where(User.telegram_id == request.id))
if user and (user.is_deleted or user.is_blocked):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Invalid credentials')
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Пользователь заблокирован или удален')
if not user and request.invite_code:
invite_code = await self.session.scalar(
select(
InviteCode
)
.where(
InviteCode.code == request.invite_code,
InviteCode.is_activated == False
)
)
if not invite_code:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Неверный код приглашения')
# check if code is expired
delta = datetime.now() - invite_code.created_at
if delta.seconds >= constants.INVITE_CODE_EXPIRY:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Код приглашения устарел')
user = User(
telegram_id=request.id,
is_admin=False,
role_key=UserRole.user
)
self.session.add(user)
await self.session.flush()
invite_code.is_activated = True
invite_code.activated_by_id = user.id
await self.session.commit()
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Пользователь не найден')
payload = {
'sub': str(user.id),
'role': user.role_key,