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
|
import starlette.status as status
|
||||||
from fastapi import Depends, FastAPI, HTTPException, Request, Response
|
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.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from sqlalchemy import create_engine, select
|
from sqlalchemy import create_engine, select
|
||||||
@@ -132,7 +132,7 @@ async def past_events(request: Request, session: SessionDep):
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/subscribe")
|
@app.get("/subscribe")
|
||||||
async def subscribe(request: Request, session: SessionDep):
|
async def subscribe(request: Request, session: SessionDep, user: UserDep):
|
||||||
statement = select(Household)
|
statement = select(Household)
|
||||||
households = session.scalars(statement)
|
households = session.scalars(statement)
|
||||||
|
|
||||||
@@ -146,7 +146,11 @@ async def subscribe(request: Request, session: SessionDep):
|
|||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request=request,
|
request=request,
|
||||||
name="subscribe.html",
|
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")
|
@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)
|
statement = select(Subscription).where(Subscription.household_id == household_id)
|
||||||
sub = session.scalars(statement).one()
|
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")
|
@app.get("/event/{event_id}/registration/{household_id}/delete")
|
||||||
async def delete_registration(
|
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
|
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,
|
event_id: int,
|
||||||
entry_id: int,
|
entry_id: int,
|
||||||
session: SessionDep,
|
session: SessionDep,
|
||||||
|
user: StrictUserDep,
|
||||||
):
|
):
|
||||||
statement = select(TeamRegistration).where(TeamRegistration.id == entry_id)
|
statement = select(TeamRegistration).where(TeamRegistration.id == entry_id)
|
||||||
session.delete(session.scalars(statement).one())
|
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_min: Mapped[int] = mapped_column(default=1, nullable=False)
|
||||||
team_prep_max: 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")
|
registrations: Mapped[list["Registration"]] = relationship(
|
||||||
team: Mapped[list["TeamRegistration"]] = relationship("TeamRegistration", cascade="all, delete")
|
"Registration", cascade="all, delete"
|
||||||
|
)
|
||||||
|
team: Mapped[list["TeamRegistration"]] = relationship(
|
||||||
|
"TeamRegistration", cascade="all, delete"
|
||||||
|
)
|
||||||
|
|
||||||
def team_min_reached(self, work_type: WorkTypes):
|
def team_min_reached(self, work_type: WorkTypes):
|
||||||
threshold = {
|
threshold = {
|
||||||
@@ -62,6 +66,14 @@ class Event(Base):
|
|||||||
self.team_max_reached(work_type) for work_type in typing.get_args(WorkTypes)
|
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):
|
class TeamRegistration(Base):
|
||||||
__tablename__ = "teamregistration"
|
__tablename__ = "teamregistration"
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
{% for entry in event.team | selectattr("work_type", "equalto", work_type)%}
|
{% 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">
|
<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>
|
<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">
|
<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">
|
<a href="/event/{{event.id}}/register_team/{{entry.id}}/delete">
|
||||||
<i class="bi bi-trash"></i>
|
<i class="bi bi-trash"></i>
|
||||||
</a>
|
</a>
|
||||||
</button>
|
</button>
|
||||||
|
{% endif -%}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
@@ -24,10 +26,10 @@
|
|||||||
<div class="col-md-4 d-flex justify-content-center align-items-center flex-column">
|
<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>
|
<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 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
|
Anmeldung hinzufügen
|
||||||
</button>
|
</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
|
Dienst übernehmen
|
||||||
</button>
|
</button>
|
||||||
{% if event.recipe_link %}
|
{% if event.recipe_link %}
|
||||||
@@ -129,7 +131,7 @@
|
|||||||
<th scope="col">Kinder</th>
|
<th scope="col">Kinder</th>
|
||||||
<th scope="col">Kleinkinder</th>
|
<th scope="col">Kleinkinder</th>
|
||||||
<th scope="col">Kommentar</th>
|
<th scope="col">Kommentar</th>
|
||||||
<th scope="col">Löschen</th>
|
{% if user %}<th scope="col">Löschen</th>{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -140,7 +142,7 @@
|
|||||||
<td>{{ reg.num_children_meals }}</td>
|
<td>{{ reg.num_children_meals }}</td>
|
||||||
<td>{{ reg.num_small_children_meals }}</td>
|
<td>{{ reg.num_small_children_meals }}</td>
|
||||||
<td>{% if reg.comment %}{{ reg.comment }}{% endif %}</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>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -154,9 +156,9 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||||
<h5 class="card-title mb-0">{{ reg.household.name }}</h5>
|
<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>
|
<i class="bi bi-trash"></i>
|
||||||
</a>
|
</a>{% endif -%}
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
<div class="col-3 text-center">
|
<div class="col-3 text-center">
|
||||||
|
|||||||
@@ -106,9 +106,9 @@
|
|||||||
<div class="card-body py-2 px-3">
|
<div class="card-body py-2 px-3">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||||
<h6 class="mb-0">{{ sub.household.name }}</h6>
|
<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>
|
<i class="bi bi-trash"></i>
|
||||||
</a>
|
</a>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="row g-2">
|
<div class="row g-2">
|
||||||
<div class="col-3 text-center">
|
<div class="col-3 text-center">
|
||||||
|
|||||||
Reference in New Issue
Block a user