Auth: Require logged in user to delete registrations, team_registrations and subscriptions
This commit is contained in:
@@ -7,7 +7,7 @@ from typing import Annotated
|
||||
|
||||
import starlette.status as status
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request, Response
|
||||
from fastapi.responses import RedirectResponse, FileResponse
|
||||
from fastapi.responses import FileResponse, RedirectResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy import create_engine, select
|
||||
@@ -132,7 +132,7 @@ async def past_events(request: Request, session: SessionDep):
|
||||
|
||||
|
||||
@app.get("/subscribe")
|
||||
async def subscribe(request: Request, session: SessionDep):
|
||||
async def subscribe(request: Request, session: SessionDep, user: UserDep):
|
||||
statement = select(Household)
|
||||
households = session.scalars(statement)
|
||||
|
||||
@@ -146,7 +146,11 @@ async def subscribe(request: Request, session: SessionDep):
|
||||
return templates.TemplateResponse(
|
||||
request=request,
|
||||
name="subscribe.html",
|
||||
context={"households": households, "subscriptions": subscriptions},
|
||||
context={
|
||||
"households": households,
|
||||
"subscriptions": subscriptions,
|
||||
"user": user,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -187,7 +191,9 @@ async def add_subscribe(request: Request, session: SessionDep):
|
||||
|
||||
|
||||
@app.get("/subscribe/{household_id}/delete")
|
||||
async def delete_subscription(request: Request, session: SessionDep, household_id: int):
|
||||
async def delete_subscription(
|
||||
request: Request, session: SessionDep, household_id: int, user: StrictUserDep
|
||||
):
|
||||
|
||||
statement = select(Subscription).where(Subscription.household_id == household_id)
|
||||
sub = session.scalars(statement).one()
|
||||
@@ -345,7 +351,11 @@ async def add_registration(request: Request, event_id: int, session: SessionDep)
|
||||
|
||||
@app.get("/event/{event_id}/registration/{household_id}/delete")
|
||||
async def delete_registration(
|
||||
request: Request, event_id: int, household_id: int, session: SessionDep
|
||||
request: Request,
|
||||
event_id: int,
|
||||
household_id: int,
|
||||
session: SessionDep,
|
||||
user: StrictUserDep,
|
||||
):
|
||||
"""
|
||||
Deletes a registration record for a specific household at a given event. This endpoint
|
||||
@@ -388,6 +398,7 @@ async def delete_team_registration(
|
||||
event_id: int,
|
||||
entry_id: int,
|
||||
session: SessionDep,
|
||||
user: StrictUserDep,
|
||||
):
|
||||
statement = select(TeamRegistration).where(TeamRegistration.id == entry_id)
|
||||
session.delete(session.scalars(statement).one())
|
||||
|
||||
@@ -33,8 +33,12 @@ class Event(Base):
|
||||
team_prep_min: Mapped[int] = mapped_column(default=1, nullable=False)
|
||||
team_prep_max: Mapped[int] = mapped_column(default=1, nullable=False)
|
||||
|
||||
registrations: Mapped[list["Registration"]] = relationship("Registration", cascade="all, delete")
|
||||
team: Mapped[list["TeamRegistration"]] = relationship("TeamRegistration", cascade="all, delete")
|
||||
registrations: Mapped[list["Registration"]] = relationship(
|
||||
"Registration", cascade="all, delete"
|
||||
)
|
||||
team: Mapped[list["TeamRegistration"]] = relationship(
|
||||
"TeamRegistration", cascade="all, delete"
|
||||
)
|
||||
|
||||
def team_min_reached(self, work_type: WorkTypes):
|
||||
threshold = {
|
||||
@@ -62,6 +66,14 @@ class Event(Base):
|
||||
self.team_max_reached(work_type) for work_type in typing.get_args(WorkTypes)
|
||||
)
|
||||
|
||||
@property
|
||||
def registration_open(self):
|
||||
return datetime.now() < self.registration_deadline
|
||||
|
||||
@property
|
||||
def in_the_past(self):
|
||||
return datetime.now() > self.event_time
|
||||
|
||||
|
||||
class TeamRegistration(Base):
|
||||
__tablename__ = "teamregistration"
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
{% for entry in event.team | selectattr("work_type", "equalto", work_type)%}
|
||||
<div class="d-inline-flex align-items-center bg-light border rounded-pill px-3 py-1 m-1">
|
||||
<span class="me-2">{{ entry.person_name }}</span>
|
||||
{% if user and event.registration_open -%}
|
||||
<button type="button" class="btn btn-sm p-0 border-0 bg-transparent text-muted">
|
||||
<a href="/event/{{event.id}}/register_team/{{entry.id}}/delete">
|
||||
<i class="bi bi-trash"></i>
|
||||
</a>
|
||||
</button>
|
||||
{% endif -%}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
@@ -24,10 +26,10 @@
|
||||
<div class="col-md-4 d-flex justify-content-center align-items-center flex-column">
|
||||
<p class="text-muted w-100 mb-2">Anmeldung schließt {{ event.registration_deadline.strftime('%A, %d.%m.%Y, %H:%M Uhr') }}</p>
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary mb-2 w-100" {% if event.registration_deadline < now %}disabled{% endif%} data-bs-toggle="modal" data-bs-target="#registration">
|
||||
<button type="button" class="btn btn-primary mb-2 w-100" {% if not (event.registration_open or (user and user.admin)) %}disabled{% endif%} data-bs-toggle="modal" data-bs-target="#registration">
|
||||
Anmeldung hinzufügen
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary mb-2 w-100" {% if event.all_teams_max() or event.event_time < now %}disabled{% endif %} data-bs-toggle="modal" data-bs-target="#teamRegistration">
|
||||
<button type="button" class="btn btn-primary mb-2 w-100" {% if event.all_teams_max() or event.in_the_past %}disabled{% endif %} data-bs-toggle="modal" data-bs-target="#teamRegistration">
|
||||
Dienst übernehmen
|
||||
</button>
|
||||
{% if event.recipe_link %}
|
||||
@@ -129,7 +131,7 @@
|
||||
<th scope="col">Kinder</th>
|
||||
<th scope="col">Kleinkinder</th>
|
||||
<th scope="col">Kommentar</th>
|
||||
<th scope="col">Löschen</th>
|
||||
{% if user %}<th scope="col">Löschen</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -140,7 +142,7 @@
|
||||
<td>{{ reg.num_children_meals }}</td>
|
||||
<td>{{ reg.num_small_children_meals }}</td>
|
||||
<td>{% if reg.comment %}{{ reg.comment }}{% endif %}</td>
|
||||
<td><a href="/event/{{event.id}}/registration/{{reg.household_id}}/delete"><i class="bi bi-trash"></i></a></td>
|
||||
{% if user %}<td><a href="/event/{{event.id}}/registration/{{reg.household_id}}/delete"><i class="bi bi-trash"></i></a></td>{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -154,9 +156,9 @@
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<h5 class="card-title mb-0">{{ reg.household.name }}</h5>
|
||||
<a href="/event/{{event.id}}/registration/{{reg.household_id}}/delete" class="text-danger">
|
||||
{% if user %}<a href="/event/{{event.id}}/registration/{{reg.household_id}}/delete" class="text-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</a>
|
||||
</a>{% endif -%}
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-3 text-center">
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
<div class="card-body py-2 px-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<h6 class="mb-0">{{ sub.household.name }}</h6>
|
||||
<a href="/subscribe/{{sub.household.id}}/delete" class="text-danger">
|
||||
{% if user %}<a href="/subscribe/{{sub.household.id}}/delete" class="text-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</a>
|
||||
</a>{% endif %}
|
||||
</div>
|
||||
<div class="row g-2">
|
||||
<div class="col-3 text-center">
|
||||
|
||||
Reference in New Issue
Block a user