join (or register) with invite link

This commit is contained in:
2026-01-03 17:02:44 +01:00
parent aff3b9f7be
commit bb41513571
7 changed files with 107 additions and 46 deletions

View File

@@ -13,6 +13,7 @@ from cutt.analysis import analysis_router
from cutt.mail import send_forgotten_password_link
from cutt.security import (
get_current_active_user,
join_team_token,
login_for_access_token,
logout,
register,
@@ -59,6 +60,9 @@ team_router = APIRouter(
)
team_router.add_api_route("/list", endpoint=list_teams, methods=["GET"])
team_router.add_api_route("/add", endpoint=add_team, methods=["POST"])
team_router.add_api_route(
"/join_link/{team_id}", endpoint=join_team_token, methods=["GET"]
)
wrong_user_id_exception = HTTPException(

View File

@@ -10,6 +10,7 @@ from cutt.security import (
change_password,
get_current_active_user,
read_player_me,
verify_one_time_token,
verify_team_scope,
)
from cutt.demo import demo_players
@@ -197,14 +198,46 @@ def add_player_to_team(player_id: int, team_id: int):
player = session.exec(select(P).where(P.id == player_id)).one()
team = session.exec(select(Team).where(Team.id == team_id)).one()
if player and team:
team.players.append(player)
session.add(team)
session.commit()
return PlainTextResponse(
f"added {player.display_name} ({player.username}) to {team.name}"
if player in team.players:
return PlainTextResponse(
f"{player.display_name} ({player.username}) is already part of {team.name}"
)
else:
team.players.append(player)
session.add(team)
session.commit()
return PlainTextResponse(
f"added {player.display_name} ({player.username}) to {team.name}"
)
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="something went wrong",
)
class JoinRequest(BaseModel):
token: str
team_id: int
def join_team(r: JoinRequest, user: Annotated[P, Depends(get_current_active_user)]):
payload = verify_one_time_token(r.token)
action: str = payload.get("sub")
if action != "join":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="wrong type of token.",
)
team_id: int = payload.get("team_id")
if team_id != r.team_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="wrong team",
)
return add_player_to_team(user.id, r.team_id)
def add_players(players: list[P]):
with Session(engine) as session:
for player in players:
@@ -218,7 +251,7 @@ async def list_all_players():
async def list_players(
team_id: int, user: Annotated[Player, Depends(get_current_active_user)]
team_id: int, user: Annotated[P, Depends(get_current_active_user)]
):
if team_id == 42:
return [
@@ -313,6 +346,11 @@ player_router.add_api_route(
endpoint=remove_player_from_team,
methods=["DELETE"],
)
player_router.add_api_route(
"/{team_id}/join",
endpoint=join_team,
methods=["POST"],
)
player_router.add_api_route(
"/{team_id}/list",
endpoint=list_players,

View File

@@ -225,16 +225,19 @@ def set_password_token(user: Player):
return token
def register_token(team_id: int):
def join_team_token(team_id: int):
with Session(engine) as session:
team = session.exec(select(Team).where(Team.id == team_id)).one()
if team:
expire = timedelta(days=30)
token = create_access_token(
data={"sub": "register", "team_id": team_id, "name": team.name},
data={"sub": "join", "team_id": team_id, "name": team.name},
expires_delta=expire,
)
return token
if token:
session.add(TokenDB(token=token))
session.commit()
return PlainTextResponse(f"https://cutt.0124816.xyz/join?token={token}")
def verify_one_time_token(token: str):
@@ -344,7 +347,7 @@ class RegisterRequest(BaseModel):
async def register(req: RegisterRequest):
payload = verify_one_time_token(req.token)
action: str = payload.get("sub")
if action != "register":
if action != "join":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="wrong type of token.",