From dbc4bf0d711a19fdd37a21a91570befc3cf0646b Mon Sep 17 00:00:00 2001 From: Jason Date: Sat, 7 Oct 2023 14:17:26 -0400 Subject: [PATCH] feat: added django-hijack for only Mine & Ken's usage --- core/urls.py | 1 + core/utils/hijack.py | 37 +++++++++++++++++++++++++++++++++++++ metropolis/settings.py | 7 +++++++ poetry.lock | 30 +++++++++++++++++++++++++++++- pyproject.toml | 2 ++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 core/utils/hijack.py diff --git a/core/urls.py b/core/urls.py index 2660b353..97b00af0 100644 --- a/core/urls.py +++ b/core/urls.py @@ -72,6 +72,7 @@ path("tv/clubs", views.TVClubView.as_view(), name="tvclub"), path("c/", views.OrganizationShort.as_view(), name="organization_short"), path("raffle", views.RaffleRedirect.as_view(), name="raffle"), + path("hijack/", include("hijack.urls")), ] if settings.LAZY_LOADING: diff --git a/core/utils/hijack.py b/core/utils/hijack.py new file mode 100644 index 00000000..e64914eb --- /dev/null +++ b/core/utils/hijack.py @@ -0,0 +1,37 @@ +import logging + +import cachetools +from django.conf import settings + +logger = logging.getLogger(__name__) +from hijack import signals + + +@cachetools.cached(cache=cachetools.LRUCache(maxsize=4096)) +def hijack_permissions_check(*, hijacker, hijacked) -> bool: + """Staff members may hijack other staff and regular users, but not superusers.""" + if all( + [ + hijacker.id in settings.ALLOWED_HIJACKERS, + hijacked.id not in settings.ALLOWED_HIJACKERS, + hijacker.is_superuser, + hijacked.is_active, + not hijacked, + ] + ): + return True + return False + + +def print_hijack_started(sender, hijacker, hijacked, request, **kwargs): + print(f"{hijacker} has hijacked {hijacked}") # todo replace with logging + + +signals.hijack_started.connect(print_hijack_started) + + +def print_hijack_ended(sender, hijacker, hijacked, request, **kwargs): + print(f"{hijacker} has released {hijacked}") + + +signals.hijack_ended.connect(print_hijack_ended) diff --git a/metropolis/settings.py b/metropolis/settings.py index e92a3e4e..033ba1a8 100644 --- a/metropolis/settings.py +++ b/metropolis/settings.py @@ -41,6 +41,8 @@ "django_select2", "pwa", "oauth2_provider", + "hijack", + "hijack.contrib.admin", ] MIDDLEWARE = [ @@ -56,6 +58,7 @@ "core.middleware.TimezoneMiddleware", "core.middleware.CustomRedirectFallbackTemporaryMiddleware", "oauth2_provider.middleware.OAuth2TokenMiddleware", + "hijack.middleware.HijackUserMiddleware", ] ROOT_URLCONF = "metropolis.urls" @@ -985,6 +988,10 @@ API_VERSION = "3.2.0" +HIJACK_PERMISSION_CHECK = "core.utils.hijack.hijack_permissions_check" +ALLOWED_HIJACKERS = [746, 165] # Jason Cameron & Ken Shibata + + DEFAULT_TIMEZONE = "UTC" ANNOUNCEMENT_APPROVAL_BCC_LIST = [] diff --git a/poetry.lock b/poetry.lock index 554b18f8..07caa289 100644 --- a/poetry.lock +++ b/poetry.lock @@ -146,6 +146,17 @@ packaging = "*" six = ">=1.9.0" webencodings = "*" +[[package]] +name = "cachetools" +version = "5.3.1" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, +] + [[package]] name = "celery" version = "5.3.4" @@ -516,6 +527,23 @@ files = [ [package.dependencies] django = ">=3.2" +[[package]] +name = "django-hijack" +version = "3.4.1" +description = "django-hijack allows superusers to hijack (=login as) and work on behalf of another user." +optional = false +python-versions = "*" +files = [ + {file = "django-hijack-3.4.1.tar.gz", hash = "sha256:2bdd7ffa42198637f49c195468b8330ea51dc36b7c2bee0f3c220c9d7de78764"}, + {file = "django_hijack-3.4.1-py3-none-any.whl", hash = "sha256:d49b4b6426f4c4694ee0c7591990f9ccb91a7910ba22a8f10e11e0b1f3e0b5b4"}, +] + +[package.dependencies] +django = ">=2.2" + +[package.extras] +test = ["pytest", "pytest-cov", "pytest-django"] + [[package]] name = "django-ical" version = "1.8.3" @@ -1423,4 +1451,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "0e9521267a3153c974db86258410f84f5690f7b595a4ff36e9abf48d313bda8a" +content-hash = "ecd39da22f9873d9654fd59d1a949f25c0db3de219b6593ce3c83f03a7c9dcae" diff --git a/pyproject.toml b/pyproject.toml index 5d393722..98949b1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,6 +71,8 @@ isort = "*" #[tool.mypy] #plugins = ["mypy_django_plugin.main"] +django-hijack = "^3.4.1" +cachetools = "^5.3.1" [tool.django-stubs] django_settings_module = "metropolis.settings"