/usr/lib/python3/dist-packages/impersonate/admin.py is in python3-django-impersonate 1.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | # -*- coding: utf-8 -*-
import logging
from django.contrib import admin
from django.utils.html import format_html
from .settings import settings
from .models import ImpersonationLog
from .helpers import User, check_allow_impersonate
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
logger = logging.getLogger(__name__)
def friendly_name(user):
'''Return proper name if exists, else username.'''
name = None
if hasattr(user, 'get_full_name'):
name = user.get_full_name()
return name or user.username
class SessionStateFilter(admin.SimpleListFilter):
''' Custom admin filter based on the session state.
Provides two filter values - 'complete' and 'incomplete'.
A session that has no session_ended_at timestamp is
considered incomplete. This field is set from the
session_end signal receiver.
'''
title = 'session state'
parameter_name = 'session'
def lookups(self, request, model_admin):
return (
('incomplete', 'Incomplete'),
('complete', 'Complete'),
)
def queryset(self, request, queryset):
if self.value() == 'incomplete':
return queryset.filter(session_ended_at__isnull=True)
if self.value() == 'complete':
return queryset.filter(session_ended_at__isnull=False)
else:
return queryset
class ImpersonatorFilter(admin.SimpleListFilter):
''' Custom admin filter based on the impersonator.
Provides a set of users who have impersonated at some point.
It is assumed that this is a small list of users - a subset
of staff and superusers. There is no corresponding filter
for users who have been impersonated, as this could be a
very large set of users.
If the number of unique impersonators exceeds MAX_FILTER_SIZE,
then the filter is removed (shows only 'All').
'''
title = 'impersonator'
parameter_name = 'impersonator'
def lookups(self, request, model_admin):
''' Return list of unique users who have been an impersonator.
'''
# the queryset containing the ImpersonationLog objects
MAX_FILTER_SIZE = settings.MAX_FILTER_SIZE
try:
# Evaluate here to raise exception if needed
ids = list(
model_admin.get_queryset(
request,
).order_by().values_list(
'impersonator_id',
flat=True,
).distinct('impersonator_id')
)
except NotImplementedError:
# Unit tests use sqlite db backend which doesn't support distinct.
qs = model_admin.get_queryset(request).only('impersonator_id')
ids = set([x.impersonator_id for x in qs])
if len(ids) > MAX_FILTER_SIZE:
logger.debug(
('Hiding admin list filter as number of impersonators [{0}] '
'exceeds MAX_FILTER_SIZE [{1}]').format(
len(ids),
MAX_FILTER_SIZE,
)
)
return
impersonators = \
User.objects.filter(id__in=ids).order_by(User.USERNAME_FIELD)
for i in impersonators:
yield (i.id, friendly_name(i))
def queryset(self, request, queryset):
if self.value() in (None, ''):
return queryset
else:
return queryset.filter(impersonator_id=self.value())
class UserAdminImpersonateMixin(object):
''' Mixin to easily add user impersonation support via the Django
admin change list page.
'''
open_new_window = False
def get_list_display(self, request):
if not check_allow_impersonate(request):
return self.list_display
list_display = list(self.list_display)
list_display.append('impersonate_user')
return list_display
def impersonate_user(self, obj):
target = ''
if self.open_new_window:
target = ' target="_blank"'
return format_html(
'<a href="{}"{}>Impersonate</a>',
reverse('impersonate-start', args=[obj.id]),
target,
)
impersonate_user.short_description = 'Impersonate User'
class ImpersonationLogAdmin(admin.ModelAdmin):
list_display = (
'_impersonator',
'_impersonating',
'session_key',
'session_started_at',
'duration'
)
readonly_fields = (
'impersonator',
'impersonating',
'session_key',
'session_started_at',
'session_ended_at',
)
list_filter = (
SessionStateFilter,
ImpersonatorFilter,
'session_started_at',
)
def _impersonator(self, obj):
return friendly_name(obj.impersonator)
def _impersonating(self, obj):
return friendly_name(obj.impersonating)
admin.site.register(ImpersonationLog, ImpersonationLogAdmin)
|