Allow administrators to impersonate other users

This commit is contained in:
Raphael Michel
2018-01-29 11:15:32 +01:00
parent 3a713541a2
commit 14da25bd9e
8 changed files with 64 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
{% load compress %}
{% load staticfiles %}
{% load i18n %}
{% load hijack_tags %}
{% load statici18n %}
{% load eventurl %}
<!DOCTYPE html>
@@ -258,6 +259,19 @@
</div>
</div>
</nav>
{% if request|is_hijacked %}
<div class="impersonate-warning">
<span class="fa fa-user-secret"></span>
{% blocktrans with user=request.user%}You are currently working on behalf of {{ user }}.{% endblocktrans %}
<form action="{% url 'control:users.impersonate.stop' %}" method="post" class="helper-display-inline">
{% csrf_token %}
<button class="btn btn-default btn-sm">
{% trans "Stop impersonating" %}
</button>
</form>
</div>
{% endif %}
<div id="page-wrapper">
<div class="container-fluid">
{% if messages %}

View File

@@ -9,6 +9,10 @@
{% csrf_token %}
<button class="btn btn-default">{% trans "Send password reset email" %}</button>
</form>
<form action="{% url "control:users.impersonate" id=user.pk %}" method="post" class="form-inline helper-display-inline">
{% csrf_token %}
<button class="btn btn-default">{% trans "Impersonate user" %}</button>
</form>
</p>
<div class="row">
<div class="col-md-10 col-xs-12">

View File

@@ -21,8 +21,10 @@ urlpatterns = [
url(r'^users/$', users.UserListView.as_view(), name='users'),
url(r'^users/select2$', typeahead.users_select2, name='users.select2'),
url(r'^users/add$', users.UserCreateView.as_view(), name='users.add'),
url(r'^users/impersonate/stop', users.UserImpersonateStopView.as_view(), name='users.impersonate.stop'),
url(r'^users/(?P<id>\d+)/$', users.UserEditView.as_view(), name='users.edit'),
url(r'^users/(?P<id>\d+)/reset$', users.UserResetView.as_view(), name='users.reset'),
url(r'^users/(?P<id>\d+)/impersonate', users.UserImpersonateView.as_view(), name='users.impersonate'),
url(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
url(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
url(r'^settings/notifications/$', user.UserNotificationsEditView.as_view(), name='user.settings.notifications'),

View File

@@ -1,11 +1,13 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.views import View
from django.views.generic import ListView
from hijack.helpers import login_user, release_hijack
from pretix.base.models import User
from pretix.base.services.mail import SendMailException
@@ -76,6 +78,9 @@ class UserEditView(AdministratorPermissionRequiredMixin, RecentAuthenticationReq
class UserResetView(AdministratorPermissionRequiredMixin, RecentAuthenticationRequiredMixin, View):
def get(self, request, *args, **kwargs):
return redirect(reverse('control:users.edit', kwargs=self.kwargs))
def post(self, request, *args, **kwargs):
self.object = get_object_or_404(User, pk=self.kwargs.get("id"))
try:
@@ -93,6 +98,24 @@ class UserResetView(AdministratorPermissionRequiredMixin, RecentAuthenticationRe
return reverse('control:users.edit', kwargs=self.kwargs)
class UserImpersonateView(AdministratorPermissionRequiredMixin, RecentAuthenticationRequiredMixin, View):
def get(self, request, *args, **kwargs):
return redirect(reverse('control:users.edit', kwargs=self.kwargs))
def post(self, request, *args, **kwargs):
self.object = get_object_or_404(User, pk=self.kwargs.get("id"))
login_user(request, self.object)
return redirect(reverse('control:index'))
class UserImpersonateStopView(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
release_hijack(request)
return redirect(reverse('control:index'))
class UserCreateView(AdministratorPermissionRequiredMixin, RecentAuthenticationRequiredMixin, CreateView):
template_name = 'pretixcontrol/users/create.html'
context_object_name = 'user'

View File

@@ -226,7 +226,9 @@ INSTALLED_APPS = [
'django_otp.plugins.otp_totp',
'django_otp.plugins.otp_static',
'statici18n',
'django_countries'
'django_countries',
'hijack',
'compat',
]
try:

View File

@@ -419,6 +419,22 @@ body.loading #wrapper {
width: 30%;
}
.impersonate-warning {
background-color: #ffe761;
background-image: -webkit-linear-gradient(-45deg, rgba(0, 0, 0, .04) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, .04) 50%, rgba(0, 0, 0, .04) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(-45deg, rgba(0, 0, 0, .04) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, .04) 50%, rgba(0, 0, 0, .04) 75%, transparent 75%, transparent);
background-image: linear-gradient(135deg, rgba(0, 0, 0, .04) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, .04) 50%, rgba(0, 0, 0, .04) 75%, transparent 75%, transparent);
padding: 15px;
}
@media(min-width:768px) {
.impersonate-warning {
position: inherit;
margin: 0 0 0 250px;
padding: 15px 30px;
}
}
.quotabox {
display: inline-block;
vertical-align: top;

View File

@@ -31,6 +31,7 @@ markdown
bleach==2.*
raven
django-i18nfield>=1.2.1
django-hijack==2.1.*
# Stripe
stripe==1.62.*
# PayPal

View File

@@ -109,6 +109,7 @@ setup(
'pyuca',
'defusedcsv',
'vat_moss==0.11.0',
'django-hijack==2.1.*'
],
extras_require={
'dev': [