2 Commits

Author SHA1 Message Date
9bf65d4319 ...
Some checks failed
CI / test (pull_request) Failing after 28s
API CI / api-tests (pull_request) Failing after 38s
2026-07-25 22:23:57 +02:00
d72676710a auth log leftovers 2026-07-25 22:13:06 +02:00
4 changed files with 37 additions and 17 deletions

View File

@ -9,9 +9,11 @@ from django.shortcuts import redirect
from epdb.logic import UserManager, GroupManager from epdb.logic import UserManager, GroupManager
from epdb.models import Group from epdb.models import Group
from epdb.views import get_remote_address
auth_log = logging.getLogger("auth") auth_log = logging.getLogger("auth")
def get_msal_app_with_cache(request): def get_msal_app_with_cache(request):
""" """
Create MSAL app with session-based token cache. Create MSAL app with session-based token cache.
@ -31,16 +33,6 @@ def get_msal_app_with_cache(request):
return msal_app, cache return msal_app, cache
def get_remote_address(request):
remote_address = ""
if request is not None:
remote_address = request.META.get("HTTP_X_FORWARDED_FOR")
if not remote_address:
remote_address = request.META.get("REMOTE_ADDR", "")
return remote_address
def entra_login(request): def entra_login(request):
@ -102,7 +94,7 @@ def entra_callback(request):
auth_log.info(f"Registering {user_name} with OID {user_oid}") auth_log.info(f"Registering {user_name} with OID {user_oid}")
u = UserManager.create_user(user_name, user_email, None, uuid=user_oid, is_active=True) u = UserManager.create_user(user_name, user_email, None, uuid=user_oid, is_active=True)
auth_log.info(f"User {user_name} {"(admin)" if u.is_superuser else ""} with OID {user_oid} successfully logged in as {u.username} from {get_remote_address(request)}") auth_log.info(f"User {user_name} {'(admin) ' if u.is_superuser else ''}with OID {user_oid} successfully logged in as {u.username} from {get_remote_address(request)}")
login(request, u) login(request, u)
# EDIT START # EDIT START

View File

@ -1,3 +1,4 @@
import logging
from collections import defaultdict from collections import defaultdict
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
@ -9,13 +10,11 @@ from django.contrib.auth import get_user_model
from django.core.cache import cache from django.core.cache import cache
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from jwt import InvalidIssuerError
from ninja import Field, Form, Query, Router, Schema from ninja import Field, Form, Query, Router, Schema
from ninja.security import HttpBearer from ninja.security import HttpBearer
from utilities.chem import FormatConverter from utilities.chem import FormatConverter
from utilities.misc import PackageExporter from utilities.misc import PackageExporter
from .logic import ( from .logic import (
EPDBURLParser, EPDBURLParser,
GroupManager, GroupManager,
@ -46,9 +45,12 @@ from .models import (
User, User,
UserPackagePermission, UserPackagePermission,
) )
from .views import get_remote_address
Package = s.GET_PACKAGE_MODEL() Package = s.GET_PACKAGE_MODEL()
auth_log = logging.get_logger("auth")
def get_cached_jwks(tenant_id: str, force=False) -> Dict: def get_cached_jwks(tenant_id: str, force=False) -> Dict:
"""Get JWKS using Django cache""" """Get JWKS using Django cache"""
@ -116,15 +118,22 @@ def validate_token(token: str) -> dict:
class MSBearerTokenAuth(HttpBearer): class MSBearerTokenAuth(HttpBearer):
def authenticate(self, request, token): def authenticate(self, request, token):
auth_log.info(f"Authentication request by {get_remote_address(request)}")
if token is None: if token is None:
return None return None
claims = validate_token(token) claims = validate_token(token)
if not User.objects.filter(uuid=claims['oid']).exists(): if not User.objects.filter(uuid=claims['oid']).exists():
auth_log.info(f"Authentication request by {get_remote_address(request)} failed!")
return None return None
request.user = User.objects.get(uuid=claims['oid']) user = User.objects.get(uuid=claims['oid'])
request.user = user
auth_log.info(
f"User {user.username} {'(admin) ' if user.is_superuser else ''}with OID {user.uuid} successfully logged in as {user.username} from {get_remote_address(request)}")
return request.user return request.user

View File

@ -585,9 +585,11 @@ class PackageManager(object):
if isinstance(grantee, User): if isinstance(grantee, User):
perm_cls = UserPackagePermission perm_cls = UserPackagePermission
data["user"] = grantee data["user"] = grantee
grantee_name = grantee.username
else: else:
perm_cls = GroupPackagePermission perm_cls = GroupPackagePermission
data["group"] = grantee data["group"] = grantee
grantee_name = grantee.name
if new_perm is None: if new_perm is None:
qs = perm_cls.objects.filter(**data) qs = perm_cls.objects.filter(**data)
@ -596,7 +598,7 @@ class PackageManager(object):
if qs.count() != 0: if qs.count() != 0:
logger.info(f"Deleting Perm {qs.first()}") logger.info(f"Deleting Perm {qs.first()}")
qs.delete() qs.delete()
auth_log.info(f"{caller.username} ({caller.url}) revokes {grantee.name} ({grantee.url}) all Permissions on {package.name} ({package.url})") auth_log.info(f"{caller.username} ({caller.url}) revokes {grantee_name} ({grantee.url}) all Permissions on {package.name} ({package.url})")
else: else:
logger.debug(f"No Permission object for {perm_cls} with filter {data} found!") logger.debug(f"No Permission object for {perm_cls} with filter {data} found!")
else: else:
@ -608,8 +610,6 @@ class PackageManager(object):
_ = perm_cls.objects.update_or_create(defaults={"permission": new_perm}, **data) _ = perm_cls.objects.update_or_create(defaults={"permission": new_perm}, **data)
grantee_name = grantee.username if isinstance(grantee, User) else grantee.name
if old_perm is None: if old_perm is None:
auth_log.info(f"{caller.username} ({caller.url}) grants {grantee_name} ({grantee.url}) '{new_perm}' Permissions on {package.name} ({package.url})") auth_log.info(f"{caller.username} ({caller.url}) grants {grantee_name} ({grantee.url}) '{new_perm}' Permissions on {package.name} ({package.url})")
else: else:

View File

@ -72,6 +72,18 @@ def log_post_params(request):
logger.debug(f"{k}\t{v}") logger.debug(f"{k}\t{v}")
def get_remote_address(request):
remote_address = ""
if request is not None:
remote_address = request.META.get("HTTP_X_FORWARDED_FOR")
if not remote_address:
remote_address = request.META.get("REMOTE_ADDR", "")
return remote_address
def get_error_handler_context(request, for_user=None) -> Dict[str, Any]: def get_error_handler_context(request, for_user=None) -> Dict[str, Any]:
current_user = _anonymous_or_real(request) current_user = _anonymous_or_real(request)
@ -219,11 +231,18 @@ def login(request):
if user is not None: if user is not None:
login(request, user) login(request, user)
if user.is_superuser:
auth_log.error(f"admin ({user.username}) login attempt by {get_remote_address(request)} successful")
if next := request.POST.get("next"): if next := request.POST.get("next"):
return redirect(next) return redirect(next)
return redirect(reverse("index")) return redirect(reverse("index"))
else: else:
if _user := User.objects.get(email=email):
if _user.is_superuser:
auth_log.error(f"admin ({_user.username}) login attempt by {get_remote_address(request)} failed")
context["message"] = "Login failed!" context["message"] = "Login failed!"
return render(request, "static/login.html", context) return render(request, "static/login.html", context)
else: else: