diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 99fa2d9..4bfa563 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.0.0", "devDependencies": { + "@fortawesome/fontawesome-free": "^6.2.0", "@sveltejs/vite-plugin-svelte": "^1.0.1", "@tsconfig/svelte": "^3.0.0", "bulma": "^0.9.4", @@ -36,6 +37,16 @@ "node": ">=12" } }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz", + "integrity": "sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ==", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -1492,6 +1503,12 @@ "dev": true, "optional": true }, + "@fortawesome/fontawesome-free": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz", + "integrity": "sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ==", + "dev": true + }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 8a39bd4..940ae92 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,15 +10,16 @@ "check": "svelte-check --tsconfig ./tsconfig.json" }, "devDependencies": { + "@fortawesome/fontawesome-free": "^6.2.0", "@sveltejs/vite-plugin-svelte": "^1.0.1", "@tsconfig/svelte": "^3.0.0", + "bulma": "^0.9.4", + "sass": "^1.53.0", "svelte": "^3.49.0", "svelte-check": "^2.8.0", "svelte-preprocess": "^4.10.7", "tslib": "^2.4.0", "typescript": "^4.6.4", - "vite": "^3.0.7", - "sass": "^1.53.0", - "bulma": "^0.9.4" + "vite": "^3.0.7" } } diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 8d699de..ed046cc 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -1,8 +1,17 @@
- Hallo i bims 1 frontend +

Hallo i bims 1 frontend

diff --git a/frontend/src/Navbar.svelte b/frontend/src/Navbar.svelte index f0f8d8a..aaf0325 100644 --- a/frontend/src/Navbar.svelte +++ b/frontend/src/Navbar.svelte @@ -1,13 +1,71 @@ diff --git a/frontend/src/app.scss b/frontend/src/app.scss index 58f765d..052ec15 100644 --- a/frontend/src/app.scss +++ b/frontend/src/app.scss @@ -9,3 +9,10 @@ @import "bulma/sass/grid/_all"; @import "bulma/sass/helpers/_all"; @import "bulma/sass/layout/_all"; + +$fa-font-path: "@fortawesome/fontawesome-free/webfonts"; +@import "@fortawesome/fontawesome-free/scss/fontawesome.scss"; +@import "@fortawesome/fontawesome-free/scss/regular.scss"; +@import "@fortawesome/fontawesome-free/scss/solid.scss"; +@import "@fortawesome/fontawesome-free/scss/brands.scss"; +@import "@fortawesome/fontawesome-free/scss/v4-shims.scss"; diff --git a/frontend/src/stores.ts b/frontend/src/stores.ts new file mode 100644 index 0000000..1181e3f --- /dev/null +++ b/frontend/src/stores.ts @@ -0,0 +1,9 @@ +import { writable, type Writable } from "svelte/store"; + +type User = { + name: string, + email: string, + picture: string, +} + +export const user: Writable = writable(null); \ No newline at end of file diff --git a/server/server/__init__.py b/server/server/__init__.py index c25ff89..ba2b375 100644 --- a/server/server/__init__.py +++ b/server/server/__init__.py @@ -7,18 +7,11 @@ from starlette.responses import HTMLResponse, RedirectResponse from authlib.integrations.starlette_client import OAuth, OAuthError from .settings import settings - -config = Config("secret.env") # TODO unify this with settings - -oauth = OAuth(config) -oauth.register( - name="gitea", - server_metadata_url="https://git.leafbla.de/.well-known/openid-configuration", -) +from .user import user_auth app = FastAPI() -app.add_middleware(SessionMiddleware, secret_key=config.get("SESSION_SECRET_KEY")) +app.mount("/user/", user_auth) templates = Jinja2Templates(directory="templates") @@ -38,29 +31,5 @@ async def index(request: Request): ) -@app.get("/login") -async def login(request: Request): - redirect_uri = request.url_for("auth") - return await oauth.gitea.authorize_redirect(request, redirect_uri) - - -@app.get("/auth") -async def auth(request: Request): - try: - token = await oauth.gitea.authorize_access_token(request) - except OAuthError as e: - return HTMLResponse(f"

{e.error}

") - user = await oauth.gitea.userinfo(token=token) - if user: - request.session["user"] = dict(user) - return RedirectResponse(url="/") - - -@app.get("/logout") -async def logout(request: Request): - request.session.pop("user", None) - return RedirectResponse(url="/") - - if not settings.dev_mode: app.mount("/", StaticFiles(directory=settings.frontend_path)) diff --git a/server/server/user.py b/server/server/user.py new file mode 100644 index 0000000..0ed0596 --- /dev/null +++ b/server/server/user.py @@ -0,0 +1,78 @@ +from fastapi import FastAPI, Request +from pydantic import BaseModel, HttpUrl +from starlette.config import Config +from starlette.middleware.sessions import SessionMiddleware +from starlette.responses import HTMLResponse, RedirectResponse +from authlib.integrations.starlette_client import OAuth, OAuthError + +config = Config("secret.env") # TODO unify this with settings + +oauth = OAuth(config) +oauth.register( + name="gitea", + server_metadata_url="https://git.leafbla.de/.well-known/openid-configuration", +) + +user_auth = FastAPI() +user_auth.add_middleware(SessionMiddleware, secret_key=config.get("SESSION_SECRET_KEY")) + + +@user_auth.get("/login") +async def login(request: Request): + redirect_uri = request.url_for("auth") + return await oauth.gitea.authorize_redirect(request, redirect_uri) + + +@user_auth.get("/auth") +async def auth(request: Request): + try: + token = await oauth.gitea.authorize_access_token(request) + except OAuthError as e: + return HTMLResponse(f"

{e.error}

") + user = await oauth.gitea.userinfo(token=token) + if user: + request.session["user"] = dict(user) + return RedirectResponse(url="/") + + +@user_auth.get("/logout") +async def logout(request: Request): + request.session.pop("user", None) + return RedirectResponse(url="/") + + +""" +user={ + 'sub': '1', + 'name': 'Kai Vogelgesang', + 'preferred_username': 'kai', + 'email': 'kai@leafbla.de', + 'picture': 'https://git.leafbla.de/avatars/279a0c06517e4dd112b291cf78c0c659', + 'groups': [ + 'gitolite-legacy', + 'gitolite-legacy:owners', + 'infrastructure', + 'infrastructure:owners', + 'next-website', + 'next-website:owners', + 'turtles', + 'turtles:owners' + ] +} """ + + +class MeResponse(BaseModel): + name: str + email: str + picture: HttpUrl + + +@user_auth.get("/me", response_model=MeResponse | None) +async def display_current_user(request: Request): + user = request.session.get("user") + if user is None: + return None + print(f"[/me] {user=}") + return MeResponse( + name=user["preferred_username"], email=user["email"], picture=user["picture"] + )