"""passbook admin Middleware to impersonate users""" from logging import Logger from threading import local from typing import Callable from uuid import uuid4 from django.http import HttpRequest, HttpResponse SESSION_IMPERSONATE_USER = "passbook_impersonate_user" SESSION_IMPERSONATE_ORIGINAL_USER = "passbook_impersonate_original_user" LOCAL = local() class ImpersonateMiddleware: """Middleware to impersonate users""" get_response: Callable[[HttpRequest], HttpResponse] def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]): self.get_response = get_response def __call__(self, request: HttpRequest) -> HttpResponse: # No permission checks are done here, they need to be checked before # SESSION_IMPERSONATE_USER is set. if SESSION_IMPERSONATE_USER in request.session: request.user = request.session[SESSION_IMPERSONATE_USER] return self.get_response(request) class RequestIDMiddleware: """Add a unique ID to every request""" get_response: Callable[[HttpRequest], HttpResponse] def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]): self.get_response = get_response def __call__(self, request: HttpRequest) -> HttpResponse: if not hasattr(request, "request_id"): request_id = uuid4().hex setattr(request, "request_id", request_id) LOCAL.passbook = {"request_id": request_id} response = self.get_response(request) response["X-passbook-id"] = request.request_id del LOCAL.passbook["request_id"] return response # pylint: disable=unused-argument def structlog_add_request_id(logger: Logger, method_name: str, event_dict): """If threadlocal has passbook defined, add request_id to log""" if hasattr(LOCAL, "passbook"): event_dict["request_id"] = LOCAL.passbook.get("request_id", "") return event_dict