diff --git a/auth/oidc.py b/auth/oidc.py
index 70c1408..aef1650 100644
--- a/auth/oidc.py
+++ b/auth/oidc.py
@@ -3,6 +3,8 @@ from fastapi.responses import RedirectResponse
from authlib.integrations.starlette_client import OAuth
from starlette.requests import Request
+from db.models import User, SessionLocal
+
from dotenv import load_dotenv
import os
@@ -40,7 +42,7 @@ oauth.register(
@router.get("/login/oidc")
async def login(request: Request):
auth0_client = oauth.create_client("auth0")
- redirect_uri = os.getenv("OIDC_REDIRECT_URI")
+ redirect_uri = os.getenv("OIDC_REDIRECT_URL")
return await auth0_client.authorize_redirect(request, redirect_uri)
@router.route("/authorize")
@@ -55,6 +57,22 @@ async def authorize(request: Request):
# save user info in session
request.session["user"] = profile
+ # check if user is already in the database
+ db = SessionLocal()
+ user_db = db.query(User).filter(User.username == profile["preferred_username"]).first()
+ if not user_db:
+ print("Create User in DB")
+ user_db = User(
+ username=profile["preferred_username"],
+ role="user" # Default role
+ )
+ db.add(user_db)
+ db.commit()
+ db.refresh(user_db)
+ db.close()
+
+ print("User in DB:", user_db)
+
return RedirectResponse(url="/", status_code=303)
@router.get("/logout")
diff --git a/auth/webauthn.py b/auth/webauthn.py
index a44247d..e69de29 100644
--- a/auth/webauthn.py
+++ b/auth/webauthn.py
@@ -1,86 +0,0 @@
-from fastapi import APIRouter, Request, Response, HTTPException
-from fastapi.responses import JSONResponse, RedirectResponse
-from webauthn import (
- generate_authentication_options,
- verify_authentication_response,
-)
-from webauthn import (
- generate_registration_options,
- verify_registration_response,
- options_to_json,
- base64url_to_bytes,
-)
-from webauthn.helpers.cose import COSEAlgorithmIdentifier
-from webauthn.helpers.structs import (
- AttestationConveyancePreference,
- AuthenticatorAttachment,
- AuthenticatorSelectionCriteria,
- PublicKeyCredentialDescriptor,
- PublicKeyCredentialHint,
- ResidentKeyRequirement,
-)
-
-import os
-
-router = APIRouter()
-
-# Simulierte Userdatenbank (nur zum Testen!)
-fake_users = {
- "admin@example.com": {
- "id": b"user-id-in-bytes",
- "credential_id": b"credential-id-in-bytes",
- "public_key": b"public-key-in-bytes",
- "sign_count": 0
- }
-}
-
-RP_ID = "localhost" # Oder deine Domain bei Produktivbetrieb
-ORIGIN = "http://localhost:8000"
-
-@router.get("/login/webauthn/start")
-async def start_webauthn(request: Request):
- email = "admin@example.com" # Hardcoded Demo-User
-
- if email not in fake_users:
- raise HTTPException(status_code=404, detail="User nicht gefunden")
-
- user = fake_users[email]
-
- options = PublicKeyCredentialRequestOptions(
- challenge=os.urandom(32),
- rp_id=RP_ID,
- allow_credentials=[...],
- timeout=60000,
-)
-
- # Speichere Challenge für später
- request.session["challenge"] = options.challenge
- return JSONResponse(content=options.model_dump())
-
-@router.post("/login/webauthn/finish")
-async def finish_webauthn(request: Request):
- body = await request.json()
- email = "admin@example.com" # Again, Demo-User
-
- if email not in fake_users:
- raise HTTPException(status_code=404, detail="User nicht gefunden")
-
- user = fake_users[email]
-
- try:
- verified_auth = verify_authentication_response(
- credential=AuthenticationCredential.parse_obj(body),
- expected_challenge=request.session.get("challenge"),
- expected_rp_id=RP_ID,
- expected_origin=ORIGIN,
- credential_public_key=user["public_key"],
- credential_current_sign_count=user["sign_count"],
- credential_id=user["credential_id"]
- )
-
- # Erfolg – setze Session
- request.session["user"] = email
- return RedirectResponse(url="/", status_code=303)
-
- except Exception as e:
- return JSONResponse({"detail": f"WebAuthn fehlgeschlagen: {str(e)}"}, status_code=400)
diff --git a/db/models.py b/db/models.py
index c2f66cc..c1d2842 100644
--- a/db/models.py
+++ b/db/models.py
@@ -1,5 +1,5 @@
-from sqlalchemy import Column, Integer, String
-from sqlalchemy.orm import declarative_base, sessionmaker
+from sqlalchemy import Column, Integer, String, Float
+from sqlalchemy.orm import declarative_base, sessionmaker, Session
from sqlalchemy import create_engine
from fastapi import Depends
@@ -17,6 +17,17 @@ class User(Base):
id = Column(Integer, primary_key=True)
username = Column(String, unique=True, index=True)
role = Column(String) # z. B. "admin" oder "user"
+ money = Column(Float, default=0) # money of user
+
+def create_user(db: Session, username: str, role: str):
+ db_user = User(username=username, role=role)
+ db.add(db_user)
+ db.commit()
+ db.refresh(db_user)
+ return db_user
+
+def get_user(db: Session, user_id: int):
+ return db.query(User).filter(User.id == user_id).first()
def get_db():
diff --git a/main.py b/main.py
index 142a8fb..d1b7947 100644
--- a/main.py
+++ b/main.py
@@ -4,18 +4,18 @@ from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from starlette.middleware.sessions import SessionMiddleware
-from db.models import Base, engine, SessionLocal, get_db, User
+from db.models import Base, engine, get_db, User
-from auth.session import get_current_user, login_user, logout_user
+from auth.session import get_current_user
-from auth import webauthn, oidc
+from auth import oidc
import uvicorn
+from sqlalchemy.orm import Session
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="my_secret_key")
-app.include_router(webauthn.router)
app.include_router(oidc.router)
app.mount("/static", StaticFiles(directory="static"), name="static")
@@ -25,14 +25,42 @@ templates = Jinja2Templates(directory="templates")
Base.metadata.create_all(bind=engine)
@app.get("/", response_class=HTMLResponse)
-def home(request: Request, user: User = Depends(get_current_user)):
+def home(request: Request, user: User = Depends(get_current_user), db: Session = Depends(get_db)):
if not user:
return RedirectResponse(url="/login", status_code=303)
- return templates.TemplateResponse("index.html", {"request": request, "user": user})
+ db_user = db.query(User).filter_by(username=user["preferred_username"]).first()
+ if not db_user:
+ raise HTTPException(status_code=404, detail="User nicht gefunden")
+ users = None
+ if "Fachschaft Admins" in user["groups"]:
+ users = db.query(User).all()
+ return templates.TemplateResponse("index.html", {"request": request, "user": user, "users": users, "db_user": db_user})
@app.get("/login", response_class=HTMLResponse)
def login_form(request: Request):
return templates.TemplateResponse("login.html", {"request": request})
+@app.post("/set_money")
+def set_money(request: Request, username: str = Form(...), money: float = Form(...), db: Session = Depends(get_db), user: User = Depends(get_current_user)):
+ if not user or "Fachschaft Admins" not in user["groups"]:
+ raise HTTPException(status_code=403, detail="Nicht erlaubt")
+ db_user = db.query(User).filter_by(username=username).first()
+ if not db_user:
+ raise HTTPException(status_code=404, detail="User nicht gefunden")
+ db_user.money = money*100
+ db.commit()
+ return RedirectResponse(url="/", status_code=303)
+
+@app.post("/drink")
+def drink(request: Request, db: Session = Depends(get_db), user: User = Depends(get_current_user)):
+ if not user or "Fachschaft" not in user["groups"]:
+ raise HTTPException(status_code=403, detail="Nicht erlaubt")
+ db_user = db.query(User).filter_by(username=user["preferred_username"]).first()
+ if not db_user:
+ raise HTTPException(status_code=404, detail="User nicht gefunden")
+ db_user.money -= 100
+ db.commit()
+ 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 88f79c8..7ca5eb0 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -9,11 +9,32 @@
Meine Beispielseite
{% if user %}
- Angemeldet als {{ user.preferred_username }} ({{ user.groups }}) – Logout
+ Angemeldet als {{ user.preferred_username }}{% if 'Fachschaft Admins' in user.groups %} (Admin){% endif %} – Logout
{% endif %}
{% block content %}{% endblock %}
+ {% if user %}
+ {% if 'Fachschaft' in user.groups %}
+ Du bist Teil der Fachschaft Informatik.
+ {% endif %}
+ {% if 'Fachschaft Admins' in user.groups %}
+ Admin Interface
+ Users in database:
+
+ {% for db_user in users %}
+ - {{ db_user.username }} ({{ db_user.role }}) - {{ db_user.money / 100 }}
+ {% endfor %}
+
+
+ Set user money:
+
+ {% endif %}
+ {% endif %}