Skip to content

Commit

Permalink
Add django-impersonate when admin is enabled (#11894)
Browse files Browse the repository at this point in the history
This used to live in .com, but I also find it useful to debug things in
.org, specially now with the new dashboard. We used to check if the
IMPERSONATE setting was defined in order to add the URLs, but since we
are always using this when the admin is enabled, I'm just checking for
that, that will allow us to have less code on .com/ops.
  • Loading branch information
stsewd authored Jan 9, 2025
1 parent 18c31c9 commit af26138
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 1 deletion.
6 changes: 5 additions & 1 deletion readthedocs/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from impersonate.admin import UserAdminImpersonateMixin
from rest_framework.authtoken.admin import TokenAdmin

from readthedocs.core.history import ExtraSimpleHistoryAdmin
Expand Down Expand Up @@ -64,7 +65,7 @@ def queryset(self, request, queryset):
return queryset.filter(projects__builds__date__gt=recent_date)


class UserAdminExtra(ExtraSimpleHistoryAdmin, UserAdmin):
class UserAdminExtra(ExtraSimpleHistoryAdmin, UserAdminImpersonateMixin, UserAdmin):

"""Admin configuration for User."""

Expand All @@ -80,6 +81,9 @@ class UserAdminExtra(ExtraSimpleHistoryAdmin, UserAdmin):
actions = ["ban_user", "sync_remote_repositories_action"]
inlines = [UserProjectInline]

# Open a new tab when impersonating a user.
open_new_window = True

@admin.display(
description="Banned",
boolean=True,
Expand Down
13 changes: 13 additions & 0 deletions readthedocs/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ def INSTALLED_APPS(self): # noqa
"allauth.socialaccount.providers.gitlab",
"allauth.socialaccount.providers.bitbucket_oauth2",
"allauth.mfa",
# Others
# NOTE: impersonate functionality is only enabled when ALLOW_ADMIN is True,
# but we still need to include it even when not enabled, since it has objects
# related to the user model that Django needs to know about when deleting users.
"impersonate",
"cacheops",
]
if ext:
Expand Down Expand Up @@ -348,6 +353,8 @@ def MIDDLEWARE(self):
]
if self.SHOW_DEBUG_TOOLBAR:
middlewares.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware")
if self.ALLOW_ADMIN:
middlewares.append("impersonate.middleware.ImpersonateMiddleware")
return middlewares

AUTHENTICATION_BACKENDS = (
Expand Down Expand Up @@ -830,6 +837,12 @@ def SOCIALACCOUNT_PROVIDERS(self):

INTERNAL_IPS = ("127.0.0.1",)

# django-impersonate.
IMPERSONATE = {
# By default, only staff users can impersonate.
"REQUIRE_SUPERUSER": True,
}

# Taggit
# https://django-taggit.readthedocs.io
TAGGIT_TAGS_FROM_STRING = "readthedocs.projects.tag_utils.rtd_parse_tags"
Expand Down
18 changes: 18 additions & 0 deletions readthedocs/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib import admin
from django.urls import include, path, re_path
from django.views.generic.base import RedirectView, TemplateView
from impersonate.views import impersonate, stop_impersonate

from readthedocs.core.views import ErrorView, HomepageView, SupportView, do_not_track
from readthedocs.search.views import GlobalSearchView
Expand Down Expand Up @@ -105,6 +106,22 @@
re_path(r"^admin/", admin.site.urls),
]

impersonate_urls = [
# We don't use ``include('impersonate.urls')`` here because we don't want to
# define ``/search`` and ``/list`` URLs
path(
"impersonate/stop/",
stop_impersonate,
name="impersonate-stop",
),
path(
"impersonate/<path:uid>/",
impersonate,
name="impersonate-start",
),
]


dnt_urls = [
re_path(r"^\.well-known/dnt/$", do_not_track),
# https://github.com/EFForg/dnt-guide#12-how-to-assert-dnt-compliance
Expand Down Expand Up @@ -158,6 +175,7 @@

if settings.ALLOW_ADMIN:
groups.append(admin_urls)
groups.append(impersonate_urls)

if settings.SHOW_DEBUG_TOOLBAR:
import debug_toolbar
Expand Down
2 changes: 2 additions & 0 deletions requirements/deploy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ django-formtools==2.5.1
# via -r requirements/pip.txt
django-gravatar2==1.4.5
# via -r requirements/pip.txt
django-impersonate==1.9.4
# via -r requirements/pip.txt
django-ipware==5.0.2
# via
# -r requirements/pip.txt
Expand Down
2 changes: 2 additions & 0 deletions requirements/docker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ django-formtools==2.5.1
# via -r requirements/pip.txt
django-gravatar2==1.4.5
# via -r requirements/pip.txt
django-impersonate==1.9.4
# via -r requirements/pip.txt
django-ipware==5.0.2
# via
# -r requirements/pip.txt
Expand Down
3 changes: 3 additions & 0 deletions requirements/pip.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jsonfield

django-safemigrate

# Impersonate users in the Django admin for support.
django-impersonate

# The latest version of requests isn't compatible with the
# version of the docker-py library we're using.
# See https://github.com/docker/docker-py/issues/3256.
Expand Down
2 changes: 2 additions & 0 deletions requirements/pip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ django-formtools==2.5.1
# via -r requirements/pip.in
django-gravatar2==1.4.5
# via -r requirements/pip.in
django-impersonate==1.9.4
# via -r requirements/pip.in
django-ipware==5.0.2
# via
# -r requirements/pip.in
Expand Down
2 changes: 2 additions & 0 deletions requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ django-formtools==2.5.1
# via -r requirements/pip.txt
django-gravatar2==1.4.5
# via -r requirements/pip.txt
django-impersonate==1.9.4
# via -r requirements/pip.txt
django-ipware==5.0.2
# via
# -r requirements/pip.txt
Expand Down

0 comments on commit af26138

Please sign in to comment.