Skip to content

Commit

Permalink
#354 Remodel AdminLoginAsBackend
Browse files Browse the repository at this point in the history
  • Loading branch information
viliambalaz committed Nov 25, 2021
1 parent 7136080 commit 2f94d1b
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 170 deletions.
12 changes: 2 additions & 10 deletions chcemvediet/apps/accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
from django import forms
from django.conf.urls import patterns, url
from django.contrib import admin
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404

from poleno.utils.admin import simple_list_filter_factory, admin_obj_format
from poleno.utils.misc import decorate
Expand Down Expand Up @@ -90,13 +87,8 @@ def get_queryset(self, request):
queryset = queryset.select_undecided_emails_count()
return queryset

def login_as_view(self, request, id):
admin_login_as = request.session.get(u'admin_login_as')
user = get_object_or_404(User, pk=id)
if not hasattr(user, u'backend'):
user.backend = u'chcemvediet.apps.accounts.backends.AdminLoginAsBackend'
login(request, user)
request.session[u'admin_login_as'] = admin_login_as
def login_as_view(self, request, obj_pk):
request.session[u'admin_login_as'] = obj_pk
return HttpResponseRedirect(reverse(u'inforequests:mine'))

def get_urls(self):
Expand Down
23 changes: 4 additions & 19 deletions chcemvediet/apps/accounts/backends.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.contrib.auth import login
from django.contrib.auth.backends import ModelBackend
from django.core.urlresolvers import resolve

Expand All @@ -12,28 +11,14 @@ def is_admin_path(self, path):
u'django.contrib.admin.options',
u'django.contrib.admin.sites',
u'adminplus.sites',
u'chcemvediet.apps.accounts.admin',
]

def get_user(self, user_id):
request = get_request()
admin_login_as = request.session.get(u'admin_login_as')
user = super(AdminLoginAsBackend, self).get_user(user_id)
admin_user = super(AdminLoginAsBackend, self).get_user(admin_login_as)
if not user:
return None
if user.is_staff:
request.session[u'admin_login_as'] = user.id

# todo: - je potrebne odlisit admin-url od "specialnej" admin-url, ktora sluzi na prihlasenie ineho usera
# - aby nebolo explictne uvedene `'/login-as/'` ale nieco vseobecne
# Ak by dana if vetva neexistovala, nebolo by mozne pouzit multiple_login (vid. test).
if request.path.endswith(u'/login-as/') and admin_login_as:
return admin_user

if self.is_admin_path(request.path) and not user.is_staff and admin_login_as:
if admin_user:
if not hasattr(admin_user, u'backend'):
admin_user.backend = u'chcemvediet.apps.accounts.backends.AdminLoginAsBackend'
login(request, admin_user)
return admin_user
admin_login_as_user = super(AdminLoginAsBackend, self).get_user(admin_login_as)
if user and user.is_staff and not self.is_admin_path(request.path) and admin_login_as:
return admin_login_as_user
return user
51 changes: 0 additions & 51 deletions chcemvediet/apps/accounts/tests/test_admin.py

This file was deleted.

128 changes: 73 additions & 55 deletions chcemvediet/apps/accounts/tests/test_backend.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
import mock

from django.conf.urls import patterns, url
from django.contrib.auth import get_user
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.test import TestCase
from django.test.utils import override_settings

from poleno.utils.urls import reverse
from poleno.utils.http import _local


class AdminLoginAsBackendTest(TestCase):

def mock_view(request):
return HttpResponse()

class AdminLoginAsBackend(TestCase):
def set_admin_login_as_attribute_view(request, id):
request.session[u'admin_login_as'] = id
return HttpResponse()

urls = tuple(patterns(u'',
url(r'^$', mock_view),
url(r'^(.+)/login-as/$', set_admin_login_as_attribute_view),
))

def create_users(self):
self.user1 = User.objects.create_user(
username=u'user1',
email=u'[email protected]',
password=u'test',
)
self.user2 = User.objects.create_user(
username=u'user2',
email=u'[email protected]',
self.user = User.objects.create_user(
username=u'user',
email=u'[email protected]',
password=u'test',
)
self.superuser1 = User.objects.create_superuser(
username=u'superuser1',
email=u'superuser1@example.com',
self.superuser = User.objects.create_superuser(
username=u'superuser',
email=u'superuser@example.com',
password=u'test',
)
self.superuser2 = User.objects.create_superuser(
username=u'superuser2',
email=u'[email protected]',
password=u'test',
)

def setUp(self):
self.settings_override = override_settings(
Expand All @@ -41,42 +48,53 @@ def tearDown(self):
self.settings_override.disable()


def test_multiple_requests(self):
def test_get_user_returns_anonymous_user(self):
response = self.client.get(u'/')
request = response.wsgi_request
user = get_user(request)
self.assertIsNotNone(user)
self.assertTrue(user.is_anonymous())

def test_get_user_returns_logged_non_admin_user(self):
self.assertTrue(self.client.login(
username=self.superuser1.username, password=u'test'
username=self.user.username, password=u'test'
))
url1 = reverse(u'admin:accounts_profile_login_as', args=(self.user1.pk,))
url2 = reverse(u'admin:accounts_profile_login_as', args=(self.user2.pk,))
expected_url = reverse(u'inforequests:mine')
self.assertRedirects(self.client.get(url1, follow=True), expected_url)
self.assertEqual(self.client.session[u'_auth_user_id'], self.user1.pk)
self.assertRedirects(self.client.get(url2, follow=True), expected_url)
self.assertEqual(self.client.session[u'_auth_user_id'], self.user2.pk)

def test_logging_back_admin(self):
self.client.login(username=self.superuser1.username, password=u'test')
url = reverse(u'admin:accounts_profile_login_as', args=(self.user1.pk,))
self.client.get(url, follow=True)
self.assertEqual(self.client.session[u'_auth_user_id'], self.user1.pk)
response = self.client.get(reverse(u'admin:index'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, u'adminplus/index.html')
self.assertEqual(self.client.session[u'_auth_user_id'], self.superuser1.pk)

def test_staff_user_login_as_other_staff_user(self):
self.client.login(username=self.superuser1.username, password=u'test')
self.assertEqual(self.client.session[u'_auth_user_id'], self.superuser1.pk)
url = reverse(u'admin:accounts_profile_login_as', args=(self.superuser2.pk,))
response = self.client.get(url, follow=True)
self.assertRedirects(response, reverse(u'inforequests:mine'))
self.assertEqual(self.client.session[u'_auth_user_id'], self.superuser2.pk)
response2 = self.client.get(reverse(u'admin:index'))
self.assertEqual(response2.status_code, 200)
self.assertTemplateUsed(response2, u'adminplus/index.html')
self.assertEqual(self.client.session[u'_auth_user_id'], self.superuser2.pk)

def test_login_to_non_existing_user(self):
self.client.login(username=self.superuser1, password=u'test')
url = reverse(u'admin:accounts_profile_login_as', args=(344,))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
response = self.client.get(u'/')
request = response.wsgi_request
_local.request = request
user = get_user(request)
self.assertEqual(user, self.user)

def test_get_user_returns_logged_admin_user_on_admin_page(self):
with mock.patch(u'chcemvediet.apps.accounts.backends.AdminLoginAsBackend.is_admin_path', return_value=True):
self.assertTrue(self.client.login(
username=self.superuser.username, password=u'test'
))
response = self.client.get(u'/')
request = response.wsgi_request
_local.request = request
user = get_user(request)
self.assertEqual(user, self.superuser)

def test_get_user_returns_logged_admin_user_if_admin_login_as_attribute_is_not_set(self):
with mock.patch(u'chcemvediet.apps.accounts.backends.AdminLoginAsBackend.is_admin_path', return_value=False):
self.assertTrue(self.client.login(
username=self.superuser.username, password=u'test'
))
response = self.client.get(u'/')
request = response.wsgi_request
_local.request = request
user = get_user(request)
self.assertEqual(user, self.superuser)

def test_get_user_returns_selected_user_if_admin_login_as_attribute_is_set(self):
with mock.patch(u'chcemvediet.apps.accounts.backends.AdminLoginAsBackend.is_admin_path', return_value=False):
self.assertTrue(self.client.login(
username=self.superuser.username, password=u'test'
))
self.client.get(u'/{}/login-as/'.format(self.user.pk))
response = self.client.get(u'/')
request = response.wsgi_request
_local.request = request
user = get_user(request)
self.assertEqual(user, self.user)
35 changes: 0 additions & 35 deletions poleno/utils/backends.py

This file was deleted.

0 comments on commit 2f94d1b

Please sign in to comment.