diff --git a/keycloak_collective_portal/config.py b/keycloak_collective_portal/config.py index 72b3a1d..262e549 100644 --- a/keycloak_collective_portal/config.py +++ b/keycloak_collective_portal/config.py @@ -1,6 +1,6 @@ """Application configuraiton.""" -from datetime import timedelta +import logging from os import environ from pathlib import Path @@ -29,3 +29,12 @@ TEMPLATE_DIR = Path(".").absolute() / "keycloak_collective_portal" / "templates" # Theme selection APP_THEME = environ.get("APP_THEME", "default") + +# Log level +LOG_LEVEL = environ.get("APP_LOG_LEVEL", "info") +if LOG_LEVEL == "info": + APP_LOG_LEVEL = logging.INFO +elif LOG_LEVEL == "debug": + APP_LOG_LEVEL = logging.DEBUG +else: + APP_LOG_LEVEL = logging.INFO diff --git a/keycloak_collective_portal/dependencies.py b/keycloak_collective_portal/dependencies.py index 0605eac..d0110e0 100644 --- a/keycloak_collective_portal/dependencies.py +++ b/keycloak_collective_portal/dependencies.py @@ -12,8 +12,10 @@ async def logged_in(request: Request): from keycloak_collective_portal.exceptions import RequiresLoginException user = request.session.get("user") + if not user: raise RequiresLoginException + return user diff --git a/keycloak_collective_portal/main.py b/keycloak_collective_portal/main.py index 0628733..4067615 100644 --- a/keycloak_collective_portal/main.py +++ b/keycloak_collective_portal/main.py @@ -1,5 +1,7 @@ """App entrypoint.""" +import logging + from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles @@ -8,6 +10,7 @@ from starlette.exceptions import HTTPException from starlette.middleware.sessions import SessionMiddleware from keycloak_collective_portal.config import ( + APP_LOG_LEVEL, APP_SECRET_KEY, APP_THEME, REDIS_DB, @@ -28,6 +31,9 @@ from keycloak_collective_portal.routes import ( root, ) +log = logging.getLogger("uvicorn") +log.setLevel(APP_LOG_LEVEL) + app = FastAPI(docs_url=None, redoc_url=None) @@ -60,9 +66,14 @@ app.add_middleware(SessionMiddleware, secret_key=APP_SECRET_KEY) app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") app.state.oidc = init_oidc() +log.info("Initialised OpenID Connect client (for Keycloak logins)") + app.state.keycloak = init_keycloak() +log.info("Initialised Keycloak admin client (for Keycloak REST API)") + app.state.templates = Jinja2Templates(directory=TEMPLATE_DIR) app.state.theme = APP_THEME +app.state.log = log app.include_router(invite.router) app.include_router(oidc.router) diff --git a/keycloak_collective_portal/routes/invite.py b/keycloak_collective_portal/routes/invite.py index 4162633..fcb838f 100644 --- a/keycloak_collective_portal/routes/invite.py +++ b/keycloak_collective_portal/routes/invite.py @@ -22,6 +22,7 @@ async def invite_keycloak_create( username = user["preferred_username"] new_invite = {"link": str(uuid4()), "time": str(dt.now())} + request.app.state.log.info(f"Generated new invite: {new_invite}") invites = await request.app.state.redis.get(username) if invites: @@ -39,10 +40,13 @@ async def invite_keycloak_delete( request: Request, user=Depends(get_user), invites=Depends(get_invites) ): username = user["preferred_username"] - invite_to_delete = request.query_params.get("invite") + invites = await request.app.state.redis.get(username) + request.app.state.log.info(f"Retrieved invites: {invites}") + purged = [i for i in invites if i["link"] != invite_to_delete] + request.app.state.log.info(f"Purged invites: {invites}") await request.app.state.redis.set(user["preferred_username"], purged) diff --git a/keycloak_collective_portal/routes/register.py b/keycloak_collective_portal/routes/register.py index ee9ec57..17a3388 100644 --- a/keycloak_collective_portal/routes/register.py +++ b/keycloak_collective_portal/routes/register.py @@ -82,6 +82,9 @@ def form_keycloak_register( ) request.app.state.keycloak.send_verify_email(user_id=user_id) except Exception as exception: + request.app.state.log.error( + f"Keycloak user registration failed, saw: {exception}" + ) message = json.loads(exception.error_message).get( "errorMessage", "Unknown reason!" )