Simple user auth using ssowat. Meal creation only for logged in users
This commit is contained in:
@@ -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",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
2
uv.lock
generated
@@ -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" },
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user