Simple user auth using ssowat. Meal creation only for logged in users

This commit is contained in:
2025-10-14 12:32:54 +02:00
parent d9330ec8ac
commit 7980a112a3
4 changed files with 47 additions and 6 deletions

View File

@@ -7,6 +7,7 @@ requires-python = "~=3.13.0"
dependencies = [ dependencies = [
"alembic>=1.17.0", "alembic>=1.17.0",
"fastapi[standard]>=0.116.0", "fastapi[standard]>=0.116.0",
"python-dotenv>=1.1.1",
"sqlalchemy>=2.0.44", "sqlalchemy>=2.0.44",
"uvicorn[standard]>=0.35.0", "uvicorn[standard]>=0.35.0",
] ]

View File

@@ -1,10 +1,11 @@
import locale import locale
import os
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Annotated from typing import Annotated
import starlette.status as status import starlette.status as status
from fastapi import Depends, FastAPI, Request from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.responses import RedirectResponse from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
@@ -33,6 +34,15 @@ def get_session():
with Session(engine) as session: with Session(engine) as session:
yield session yield session
def get_user(request: Request) -> dict | None:
if os.environ.get("MEAL_MANAGER_FAKE_USER", False):
return {"username": "fake_user"}
if "ynh_user" in request.headers:
return {
"username": request.headers["ynh_user"],
}
else:
return None
def create_db_and_tables(): def create_db_and_tables():
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
@@ -51,9 +61,9 @@ templates = Jinja2Templates(directory="src/meal_manager/templates")
SessionDep = Annotated[Session, Depends(get_session)] SessionDep = Annotated[Session, Depends(get_session)]
UserDep = Annotated[dict, Depends(get_user)]
@app.get("/") @app.get("/")
async def index(request: Request, session: SessionDep): async def index(request: Request, session: SessionDep, user : UserDep):
"""Displays coming events and a button to register new ones""" """Displays coming events and a button to register new ones"""
now = datetime.now() now = datetime.now()
# TODO: Once we refactored to use SQLAlchemy directly, we can probably do a nicer filtering on the date alone # TODO: Once we refactored to use SQLAlchemy directly, we can probably do a nicer filtering on the date alone
@@ -66,7 +76,7 @@ async def index(request: Request, session: SessionDep):
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="index.html", name="index.html",
context={"events": events, "current_page": "home", "now": now}, context={"events": events, "current_page": "home", "now": now, "user": user},
) )
@@ -155,7 +165,9 @@ async def delete_subscription(request: Request, session: SessionDep, household_i
@app.get("/event/add") @app.get("/event/add")
async def add_event_form(request: Request, session: SessionDep): async def add_event_form(request: Request, user: UserDep):
if not user:
raise HTTPException(status_code=401, detail="Only allowed for logged in users")
return templates.TemplateResponse(request=request, name="add_event.html") return templates.TemplateResponse(request=request, name="add_event.html")

View File

@@ -3,9 +3,15 @@
<div class="row mt-4 mb-3"> <div class="row mt-4 mb-3">
<div class="col d-flex justify-content-between align-items-center"> <div class="col d-flex justify-content-between align-items-center">
<h2>{% if current_page == "home" %}Kommende{% else %}Vergangene{% endif %} Kochabende</h2> <h2>{% if current_page == "home" %}Kommende{% else %}Vergangene{% endif %} Kochabende</h2>
{% if user %}
<a href="/event/add" class="btn btn-primary"> <a href="/event/add" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Neues Event erstellen <i class="bi bi-plus-circle"></i> Neues Event erstellen
</a> </a>
{% else %}
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
<i class="bi bi-plus-circle"></i> Neues Event erstellen
</button>
{% endif %}
</div> </div>
</div> </div>
<div class="mb-4"> <div class="mb-4">
@@ -40,4 +46,24 @@
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endblock %}
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Bitte einloggen</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Einige Funktionen, wie das erstellen neuer Koch-Events, stehen nur zur Verfügung, wenn du in die Allmende-Cloud
eingeloggt bist. Gehe dazu auf <a href="https://cloud.allmende-gufi.de">cloud.allmende-gufi.de</a> und logge dich ein.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Verstanden</button>
</div>
</div>
</div>
</div>
{% endblock %}

2
uv.lock generated
View File

@@ -339,6 +339,7 @@ source = { editable = "." }
dependencies = [ dependencies = [
{ name = "alembic" }, { name = "alembic" },
{ name = "fastapi", extra = ["standard"] }, { name = "fastapi", extra = ["standard"] },
{ name = "python-dotenv" },
{ name = "sqlalchemy" }, { name = "sqlalchemy" },
{ name = "uvicorn", extra = ["standard"] }, { name = "uvicorn", extra = ["standard"] },
] ]
@@ -353,6 +354,7 @@ dev = [
requires-dist = [ requires-dist = [
{ name = "alembic", specifier = ">=1.17.0" }, { name = "alembic", specifier = ">=1.17.0" },
{ name = "fastapi", extras = ["standard"], specifier = ">=0.116.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.116.0" },
{ name = "python-dotenv", specifier = ">=1.1.1" },
{ name = "sqlalchemy", specifier = ">=2.0.44" }, { name = "sqlalchemy", specifier = ">=2.0.44" },
{ name = "uvicorn", extras = ["standard"], specifier = ">=0.35.0" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.35.0" },
] ]