Commit c90bf692 by Bach Dániel

Merge branch 'feature-sudo' into 'master'

Feature Sudo
parents aaa3e50b ab7a278b
...@@ -10,6 +10,12 @@ ...@@ -10,6 +10,12 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
{% if request.user.is_superuser %}
<a href="{{ login_token }}"
class="pull-right btn btn-danger btn-xs"
title="{% trans "Log in as this user. Recommended to open in an incognito window." %}">
{% trans "Login as this user" %}</a>
{% endif %}
<a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.index" %}">{% trans "Back" %}</a> <a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.index" %}">{% trans "Back" %}</a>
<h3 class="no-margin"> <h3 class="no-margin">
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
......
...@@ -45,7 +45,7 @@ from .views import ( ...@@ -45,7 +45,7 @@ from .views import (
VmTraitsUpdate, VmRawDataUpdate, VmTraitsUpdate, VmRawDataUpdate,
GroupPermissionsView, GroupPermissionsView,
LeaseAclUpdateView, LeaseAclUpdateView,
ClientCheck, ClientCheck, TokenLogin,
) )
autocomplete_light.autodiscover() autocomplete_light.autodiscover()
...@@ -207,4 +207,6 @@ urlpatterns = patterns( ...@@ -207,4 +207,6 @@ urlpatterns = patterns(
name="dashboard.views.store-refresh-toplist"), name="dashboard.views.store-refresh-toplist"),
url(r"^client/check$", ClientCheck.as_view(), url(r"^client/check$", ClientCheck.as_view(),
name="dashboard.views.client-check"), name="dashboard.views.client-check"),
url(r'^token-login/(?P<token>.*)/$', TokenLogin.as_view(),
name="dashboard.views.token-login"),
) )
...@@ -29,8 +29,9 @@ import requests ...@@ -29,8 +29,9 @@ import requests
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.contrib.auth.views import login, redirect_to_login from django.contrib.auth.views import login as login_view, redirect_to_login
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth import login
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import ( from django.core.exceptions import (
PermissionDenied, SuspiciousOperation, PermissionDenied, SuspiciousOperation,
...@@ -2985,12 +2986,55 @@ def circle_login(request): ...@@ -2985,12 +2986,55 @@ def circle_login(request):
extra_context = { extra_context = {
'saml2': saml_available, 'saml2': saml_available,
} }
response = login(request, authentication_form=authentication_form, response = login_view(request, authentication_form=authentication_form,
extra_context=extra_context) extra_context=extra_context)
set_language_cookie(request, response) set_language_cookie(request, response)
return response return response
class TokenLogin(View):
token_max_age = 120 # seconds
@classmethod
def get_salt(cls):
return unicode(cls)
@classmethod
def get_token(cls, user, sudoer):
return signing.dumps((sudoer.pk, user.pk),
salt=cls.get_salt(), compress=True)
@classmethod
def get_token_url(cls, user, sudoer):
key = cls.get_token(user, sudoer)
return reverse("dashboard.views.token-login", args=(key, ))
def get(self, request, token, *args, **kwargs):
try:
data = signing.loads(token, salt=self.get_salt(),
max_age=self.token_max_age)
logger.debug('TokenLogin token data: %s', unicode(data))
sudoer, user = data
logger.debug('Extracted TokenLogin data: sudoer: %s, user: %s',
unicode(sudoer), unicode(user))
except (signing.BadSignature, ValueError, TypeError) as e:
logger.warning('Tried invalid TokenLogin token. '
'Token: %s, user: %s. %s',
token, unicode(self.request.user), unicode(e))
raise SuspiciousOperation()
sudoer = User.objects.get(pk=sudoer)
if not sudoer.is_superuser:
raise PermissionDenied()
user = User.objects.get(pk=user)
user.backend = 'django.contrib.auth.backends.ModelBackend'
logger.warning('%s %d logged in as user %s %d',
unicode(sudoer), sudoer.pk, unicode(user), user.pk)
login(request, user)
messages.info(request, _("Logged in as user %s.") % unicode(user))
return redirect("/")
class MyPreferencesView(UpdateView): class MyPreferencesView(UpdateView):
model = Profile model = Profile
...@@ -3327,6 +3371,9 @@ class ProfileView(LoginRequiredMixin, DetailView): ...@@ -3327,6 +3371,9 @@ class ProfileView(LoginRequiredMixin, DetailView):
template__in=it) template__in=it)
context['instances_with_access'] = context[ context['instances_with_access'] = context[
'instances_with_access'].filter(template__in=it) 'instances_with_access'].filter(template__in=it)
if self.request.user.is_superuser:
context['login_token'] = TokenLogin.get_token_url(
user, self.request.user)
return context return context
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment