diff --git a/auth/oidc.py b/auth/oidc.py index 21b25c0..971158d 100644 --- a/auth/oidc.py +++ b/auth/oidc.py @@ -27,7 +27,7 @@ Functions: logout(request): Logs the user out and redirects to the identity provider's logout endpoint. """ import os -from fastapi import APIRouter +from fastapi import APIRouter, Form, HTTPException from fastapi.responses import RedirectResponse from authlib.integrations.starlette_client import OAuth from starlette.requests import Request @@ -126,8 +126,23 @@ async def logout(request: Request): """ request.session.pop(SESSION_KEY, None) - request.session.pop("user_db", None) + request.session.pop("user_db_id", None) logout_url = oauth.auth0.server_metadata.get("end_session_endpoint") if not logout_url: logout_url = os.getenv("OIDC_LOGOUT_URL") return RedirectResponse(url=logout_url, status_code=303) + +@router.post("/login/prepaid") +def login_prepaid(request: Request, prepaid_user_key: str = Form(...)): + t = text("SELECT id, username FROM users_prepaid WHERE user_key = :prepaid_user_key") + with engine.connect() as conn: + result = conn.execute(t, {"prepaid_user_key": prepaid_user_key}).fetchone() + if result: + user_db_id = result[0] + username = result[1] + else: + raise HTTPException(status_code=404, detail="User not found") + + request.session["user_db_id"] = user_db_id + request.session[SESSION_KEY] = {"name": username, "preferred_username": username, "groups": [], "prepaid": True} + return RedirectResponse(url="/", status_code=303) diff --git a/db/models.py b/db/models.py index c2ff2a8..2ee55a1 100644 --- a/db/models.py +++ b/db/models.py @@ -24,6 +24,8 @@ DATABASE_URL = "sqlite:///./test.db" engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False}) +DRINK_COST = 100 # cent + with engine.connect() as conn: # Create a new table for postpaid users conn.execute(text(""" @@ -180,7 +182,7 @@ def drink_postpaid_user(user_id: int): prev_money = get_postpaid_user(user_id)["money"] t = text("UPDATE users_postpaid SET money = :money, last_drink = CURRENT_TIMESTAMP WHERE id = :id") with engine.connect() as connection: - result = connection.execute(t, {"id": user_id, "money": prev_money - 100}) + result = connection.execute(t, {"id": user_id, "money": prev_money - DRINK_COST}) if result.rowcount == 0: raise HTTPException(status_code=404, detail="User not found") connection.commit() @@ -271,3 +273,49 @@ def create_prepaid_user(prepaid_username: str, postpaid_user_id: int, start_mone connection.commit() return result.lastrowid + +def drink_prepaid_user(user_db_id: int): + user_dict = get_prepaid_user(user_db_id) + if not user_dict["activated"]: + raise HTTPException(status_code=403, detail="User not activated") + + prev_money = user_dict["money"] + if prev_money < DRINK_COST: + raise HTTPException(status_code=403, detail="Not enough money") + t = text("UPDATE users_prepaid SET money = :money, last_drink = CURRENT_TIMESTAMP WHERE id = :id") + with engine.connect() as connection: + result = connection.execute(t, {"id": user_db_id, "money": prev_money - DRINK_COST}) + if result.rowcount == 0: + raise HTTPException(status_code=404, detail="User not found") + connection.commit() + + with engine.connect() as connection: + t = text("INSERT INTO drinks (prepaid_user_id, timestamp) VALUES (:prepaid_user_id, CURRENT_TIMESTAMP)") + result = connection.execute(t, {"prepaid_user_id": user_db_id}) + if result.rowcount == 0: + raise HTTPException(status_code=500, detail="Failed to create drink entry") + connection.commit() + return result.rowcount + +def toggle_activate_prepaid_user(user_id: int): + prev_activated = get_prepaid_user(user_id)["activated"] + t = text("UPDATE users_prepaid SET activated = :activated WHERE id = :id") + with engine.connect() as connection: + result = connection.execute(t, {"id": user_id, "activated": not prev_activated}) + if result.rowcount == 0: + raise HTTPException(status_code=404, detail="User not found") + connection.commit() + return result.rowcount + +def set_prepaid_user_money(user_id: int, money: int, postpaid_user_id: int): + t1 = text("UPDATE users_prepaid SET money = :money WHERE id = :id") + t2 = text("UPDATE users_prepaid SET postpaid_user_id = :postpaid_user_id WHERE id = :id") + with engine.connect() as connection: + result = connection.execute(t1, {"id": user_id, "money": money}) + if result.rowcount == 0: + raise HTTPException(status_code=404, detail="User not found") + result = connection.execute(t2, {"id": user_id, "postpaid_user_id": postpaid_user_id}) + if result.rowcount == 0: + raise HTTPException(status_code=404, detail="User not found") + connection.commit() + return result.rowcount diff --git a/main.py b/main.py index ae6edb2..8964792 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from fastapi import FastAPI, Request, Depends, Form, HTTPException +from fastapi import FastAPI, Request, Form, HTTPException from fastapi.responses import RedirectResponse, HTMLResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates @@ -16,8 +16,9 @@ from db.models import toggle_activate_postpaid_user from db.models import get_prepaid_user from db.models import get_prepaid_user_by_username from db.models import create_prepaid_user - -from auth.session import get_current_user +from db.models import drink_prepaid_user +from db.models import toggle_activate_prepaid_user +from db.models import set_prepaid_user_money from auth import oidc @@ -44,6 +45,8 @@ def home(request: Request): user_authentik = request.session.get("user_authentik") if not user_db_id or not user_authentik: raise HTTPException(status_code=404, detail="User nicht gefunden") + print(f"Current user: {user_authentik}") + print(f"Current user db id: {user_db_id}") users = None db_users_prepaid = None if ADMIN_GROUP in user_authentik["groups"]: @@ -58,15 +61,22 @@ def home(request: Request): users.append(user_db) t = text("SELECT id FROM users_prepaid") result = conn.execute(t).fetchall() - print(f"Result: {result}") if result: db_users_prepaid = [] for row in result: prepaid_user = get_prepaid_user(row[0]) if prepaid_user: db_users_prepaid.append(prepaid_user) - db_user = get_postpaid_user(user_db_id) - print("db_users_prepaid", db_users_prepaid) + try: + if user_authentik["prepaid"]: + print("Prepaid user") + db_user = get_prepaid_user(user_db_id) + else: + print("Postpaid user") + db_user = get_postpaid_user(user_db_id) + except KeyError: + print("Postpaid user") + db_user = get_postpaid_user(user_db_id) return templates.TemplateResponse("index.html", { "request": request, "user": user_authentik, @@ -211,6 +221,54 @@ def add_prepaid_user(request: Request, username: str = Form(...), start_money: f return RedirectResponse(url="/", status_code=303) +@app.post("/drink_prepaid") +def drink_prepaid(request: Request): + user_db_id = request.session.get("user_db_id") + if not user_db_id: + raise HTTPException(status_code=404, detail="User nicht gefunden") + user_authentik = request.session.get("user_authentik") + if not user_authentik: + raise HTTPException(status_code=404, detail="User nicht gefunden") + if not user_authentik["prepaid"]: + raise HTTPException(status_code=403, detail="Nicht erlaubt") + + drink_prepaid_user(user_db_id) + return RedirectResponse(url="/", status_code=303) + +@app.post("/toggle_activated_user_prepaid") +def toggle_activated_user_prepaid(request: Request, username: str = Form(...)): + user_auth = request.session.get("user_authentik") + if not user_auth or ADMIN_GROUP not in user_auth["groups"]: + raise HTTPException(status_code=403, detail="Nicht erlaubt") + + user_db_id = get_prepaid_user_by_username(username)["id"] + if not user_db_id: + raise HTTPException(status_code=404, detail="User nicht gefunden") + + toggle_activate_prepaid_user(user_db_id) + + return RedirectResponse(url="/", status_code=303) + +@app.post("/add_money_prepaid_user") +def add_money_prepaid_user(request: Request, username: str = Form(...), money: float = Form(...)): + curr_user_auth = request.session.get("user_authentik") + if not curr_user_auth or ADMIN_GROUP not in curr_user_auth["groups"]: + raise HTTPException(status_code=403, detail="Nicht erlaubt") + curr_user_db_id = request.session.get("user_db_id") + if not curr_user_db_id: + raise HTTPException(status_code=404, detail="Logged In User not found") + + prepaid_user_dict = get_prepaid_user_by_username(username) + prepaid_user_db_id = prepaid_user_dict["id"] + if not prepaid_user_db_id: + raise HTTPException(status_code=404, detail="Prepaid User not found") + curr_user_money = get_postpaid_user(curr_user_db_id)["money"] + prepaid_user_money = prepaid_user_dict["money"] + + set_postpaid_user_money(curr_user_db_id, curr_user_money - money*100) + set_prepaid_user_money(prepaid_user_db_id, prepaid_user_money + money*100, curr_user_db_id) + + return RedirectResponse(url="/", status_code=303) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/templates/base.html b/templates/base.html index 6b39af0..4a29990 100644 --- a/templates/base.html +++ b/templates/base.html @@ -91,6 +91,76 @@ Add User +

Füge bestehendem Prepaid-User Geld hinzu:

+
+ + + + + +
{% endif %} {% if 'Fachschaft Admins' in user.groups %}

Admin Interface

@@ -393,6 +463,57 @@ {% endif %} +

(De-)Activate User

+
+ + + +
{% endif %} {% endif %} diff --git a/templates/index.html b/templates/index.html index 965d149..021856d 100644 --- a/templates/index.html +++ b/templates/index.html @@ -72,4 +72,39 @@ content %} -{% endif %} {% endif %} {% endblock %} +{% endif %} {% endif %} + +{% if user.prepaid %} +
+
+ +
+
+

Deine aktuelle Ansprechperson ist:

+
+ ID {{ db_user.postpaid_user_id }} +
+{% endif %} +{% endblock %} diff --git a/templates/login.html b/templates/login.html index 378a25d..2fb4e1c 100644 --- a/templates/login.html +++ b/templates/login.html @@ -1,7 +1,6 @@ {% extends "base.html" %} {% block title %}Login{% endblock %} {% block content %} -

Login

- +

Postpaid-Liste:

+
+ + + +
+