4 Commits

Author SHA1 Message Date
5147299c0e advise to fill in email 2025-12-21 08:27:21 +01:00
07a121200a remove from team instead of disable 2025-12-21 08:26:44 +01:00
a654b12c64 permit team managers to see the team 2025-12-21 08:26:16 +01:00
b2b6f4af14 add logo to Register page 2025-12-21 07:25:24 +01:00
2 changed files with 65 additions and 8 deletions

View File

@@ -110,6 +110,32 @@ class DisablePlayerRequest(BaseModel):
player_id: int player_id: int
def remove_player_from_team(
r: DisablePlayerRequest,
request: Annotated[TeamScopedRequest, Depends(verify_team_scope)],
):
if request.team_id == 42:
raise DEMO_TEAM_REQUEST
with Session(engine) as session:
player = session.exec(
select(P)
.join(PlayerTeamLink)
.join(Team)
.where(Team.id == request.team_id, P.id == r.player_id)
).one_or_none()
if player:
team = session.exec(select(Team).where(Team.id == request.team_id)).one()
player.teams.remove(team)
session.add(team)
session.commit()
return PlainTextResponse(f"removed {player.display_name} from {team.name}.")
else:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="no such player found in your team",
)
def disable_player_team( def disable_player_team(
r: DisablePlayerRequest, r: DisablePlayerRequest,
request: Annotated[TeamScopedRequest, Depends(verify_team_scope)], request: Annotated[TeamScopedRequest, Depends(verify_team_scope)],
@@ -185,6 +211,8 @@ async def list_players(
) )
] + demo_players ] + demo_players
allowed_scopes = set(user.scopes.split())
with Session(engine) as session: with Session(engine) as session:
current_user = session.exec( current_user = session.exec(
select(P) select(P)
@@ -192,7 +220,7 @@ async def list_players(
.join(Team) .join(Team)
.where(Team.id == team_id, P.disabled == False, P.id == user.id) .where(Team.id == team_id, P.disabled == False, P.id == user.id)
).one_or_none() ).one_or_none()
if not current_user: if not current_user and f"team:{team_id}" not in allowed_scopes:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="you're not in this team", detail="you're not in this team",
@@ -223,10 +251,28 @@ async def list_players(
def read_teams_me(user: Annotated[P, Depends(get_current_active_user)]): def read_teams_me(user: Annotated[P, Depends(get_current_active_user)]):
allowed_scopes = set(user.scopes.split())
team_ids = {
int(scope.split(":")[1])
for scope in allowed_scopes
if scope.startswith("team:")
}
with Session(engine) as session: with Session(engine) as session:
return [p.teams for p in session.exec(select(P).where(P.id == user.id))][0] + [ member_in = [p.teams for p in session.exec(select(P).where(P.id == user.id))][0]
{"country": "nowhere", "id": 42, "location": "everywhere", "name": "DEMO"} team_ids -= {team.id for team in member_in}
team_manager_in = session.exec(select(Team).where(Team.id.in_(team_ids))).all()
return (
member_in
+ list(team_manager_in)
+ [
{
"country": "nowhere",
"id": 42,
"location": "everywhere",
"name": "DEMO",
}
] ]
)
player_router.add_api_route( player_router.add_api_route(
@@ -241,7 +287,7 @@ player_router.add_api_route(
) )
player_router.add_api_route( player_router.add_api_route(
"/{team_id}", "/{team_id}",
endpoint=disable_player_team, endpoint=remove_player_from_team,
methods=["DELETE"], methods=["DELETE"],
) )
player_router.add_api_route( player_router.add_api_route(

View File

@@ -98,6 +98,16 @@ export const Register = () => {
return ( return (
<section className="section"> <section className="section">
<div className="container is-max-tablet"> <div className="container is-max-tablet">
<div className="block">
<p className="level-item has-text-centered">
<img
className="image"
alt="cool ultimate team tool"
src="cutt.svg"
style={{ width: 200 }}
/>
</p>
</div>
<h1 className="title"> <h1 className="title">
Register {teamName && `in team "${teamName}"`} Register {teamName && `in team "${teamName}"`}
</h1> </h1>
@@ -220,11 +230,12 @@ export const Register = () => {
}} }}
/> />
</div> </div>
<p className="help">helpful in case of a forgotten password</p>
</div>
</div>
<p className={"help" + (error ? " is-danger" : " is-success")}> <p className={"help" + (error ? " is-danger" : " is-success")}>
{error} {error}
</p> </p>
</div>
</div>
<div className="field is-grouped is-grouped-centered"> <div className="field is-grouped is-grouped-centered">
<button className="button is-light is-success">register</button> <button className="button is-light is-success">register</button>
</div> </div>