2020-09-17 14:24:53 +00:00
|
|
|
"""passbook admin Middleware to impersonate users"""
|
2020-09-21 17:31:01 +00:00
|
|
|
from logging import Logger
|
|
|
|
from threading import local
|
2020-09-17 14:24:53 +00:00
|
|
|
from typing import Callable
|
2020-09-21 17:31:01 +00:00
|
|
|
from uuid import uuid4
|
2020-09-17 14:24:53 +00:00
|
|
|
|
|
|
|
from django.http import HttpRequest, HttpResponse
|
|
|
|
|
|
|
|
SESSION_IMPERSONATE_USER = "passbook_impersonate_user"
|
|
|
|
SESSION_IMPERSONATE_ORIGINAL_USER = "passbook_impersonate_original_user"
|
2020-09-21 17:31:01 +00:00
|
|
|
LOCAL = local()
|
2020-09-17 14:24:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
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)
|
2020-09-21 17:31:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
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
|