middleware.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. """
  2. sudo.middleware
  3. ~~~~~~~~~~~~~~~
  4. :copyright: (c) 2020 by Matt Robenolt.
  5. :license: BSD, see LICENSE for more details.
  6. """
  7. from django.http.request import HttpRequest
  8. from django.http.response import HttpResponseBase
  9. from django.utils.deprecation import MiddlewareMixin
  10. from sudo.settings import (
  11. COOKIE_DOMAIN,
  12. COOKIE_HTTPONLY,
  13. COOKIE_NAME,
  14. COOKIE_PATH,
  15. COOKIE_SALT,
  16. COOKIE_SECURE,
  17. )
  18. from sudo.utils import has_sudo_privileges
  19. class SudoMiddleware(MiddlewareMixin):
  20. """
  21. Middleware that contributes ``request.is_sudo()`` and sets the required
  22. cookie for sudo mode to work correctly.
  23. """
  24. def has_sudo_privileges(self, request: HttpRequest) -> bool:
  25. # Override me to alter behavior
  26. return has_sudo_privileges(request)
  27. def process_request(self, request: HttpRequest) -> None:
  28. assert hasattr(request, "session"), (
  29. "The Sudo middleware requires session middleware to be installed."
  30. "Edit your MIDDLEWARE setting to insert "
  31. "'django.contrib.sessions.middleware.SessionMiddleware' before "
  32. "'sudo.middleware.SudoMiddleware'."
  33. )
  34. request.is_sudo = lambda: self.has_sudo_privileges(request)
  35. def process_response(
  36. self, request: HttpRequest, response: HttpResponseBase
  37. ) -> HttpResponseBase:
  38. is_sudo = getattr(request, "_sudo", None)
  39. if is_sudo is None:
  40. return response
  41. # We have explicitly had sudo revoked, so clean up cookie
  42. if is_sudo is False and COOKIE_NAME in request.COOKIES:
  43. response.delete_cookie(COOKIE_NAME)
  44. return response
  45. # Sudo mode has been granted,
  46. # and we have a token to send back to the user agent
  47. if (
  48. is_sudo is True
  49. and hasattr(request, "_sudo_token")
  50. and hasattr(request, "_sudo_max_age")
  51. ):
  52. token = request._sudo_token
  53. max_age = request._sudo_max_age
  54. response.set_signed_cookie(
  55. COOKIE_NAME,
  56. token,
  57. salt=COOKIE_SALT,
  58. max_age=max_age, # If max_age is None, it's a session cookie
  59. secure=request.is_secure() if COOKIE_SECURE is None else COOKIE_SECURE,
  60. httponly=COOKIE_HTTPONLY, # Not accessible by JavaScript
  61. path=COOKIE_PATH,
  62. domain=COOKIE_DOMAIN,
  63. )
  64. return response