kpsul/kfet/auth/tests.py
Aurélien Delobelle e56200a569 kfet -- LoginGenericView directly disconnects users.
Since allauth is installed, users are not automatically logged out of CAS
when logging out GestioCOF.
This change simplifies the view and avoid being stuck because of
the redirect to the logout page, which happened via a GET request and so
prompting to confirm.
2018-10-21 17:09:12 +02:00

296 lines
8.7 KiB
Python

from unittest import mock
from django.contrib.auth.models import Group, Permission, User
from django.core.urlresolvers import reverse
from django.test import RequestFactory, TestCase
from kfet.forms import UserGroupForm
from kfet.models import Account
from . import KFET_GENERIC_TRIGRAMME, KFET_GENERIC_USERNAME
from .backends import AccountBackend, GenericBackend
from .middleware import TemporaryAuthMiddleware
from .models import GenericTeamToken
from .utils import get_kfet_generic_user
##
# Forms
##
class UserGroupFormTests(TestCase):
"""Test suite for UserGroupForm."""
def setUp(self):
# create user
self.user = User.objects.create(username="foo", password="foo")
# create some K-Fêt groups
prefix_name = "K-Fêt "
names = ["Group 1", "Group 2", "Group 3"]
self.kfet_groups = [
Group.objects.create(name=prefix_name + name) for name in names
]
# create a non-K-Fêt group
self.other_group = Group.objects.create(name="Other group")
def test_choices(self):
"""Only K-Fêt groups are selectable."""
form = UserGroupForm(instance=self.user)
groups_field = form.fields["groups"]
self.assertQuerysetEqual(
groups_field.queryset, [repr(g) for g in self.kfet_groups], ordered=False
)
def test_keep_others(self):
"""User stays in its non-K-Fêt groups."""
user = self.user
# add user to a non-K-Fêt group
user.groups.add(self.other_group)
# add user to some K-Fêt groups through UserGroupForm
data = {"groups": [group.pk for group in self.kfet_groups]}
form = UserGroupForm(data, instance=user)
form.is_valid()
form.save()
self.assertQuerysetEqual(
user.groups.all(),
[repr(g) for g in [self.other_group] + self.kfet_groups],
ordered=False,
)
class KFetGenericUserTests(TestCase):
def test_exists(self):
"""
The account is set up when app is ready, so it should exist.
"""
generic = Account.objects.get_generic()
self.assertEqual(generic.trigramme, KFET_GENERIC_TRIGRAMME)
self.assertEqual(generic.user.username, KFET_GENERIC_USERNAME)
self.assertEqual(get_kfet_generic_user(), generic.user)
##
# Backends
##
class AccountBackendTests(TestCase):
def setUp(self):
self.request = RequestFactory().get("/")
def test_valid(self):
acc = Account(trigramme="000")
acc.change_pwd("valid")
acc.save({"username": "user"})
auth = AccountBackend().authenticate(self.request, kfet_password="valid")
self.assertEqual(auth, acc.user)
def test_invalid(self):
auth = AccountBackend().authenticate(self.request, kfet_password="invalid")
self.assertIsNone(auth)
class GenericBackendTests(TestCase):
def setUp(self):
self.request = RequestFactory().get("/")
def test_valid(self):
token = GenericTeamToken.objects.create_token()
auth = GenericBackend().authenticate(self.request, kfet_token=token.token)
self.assertEqual(auth, get_kfet_generic_user())
self.assertEqual(GenericTeamToken.objects.all().count(), 0)
def test_invalid(self):
auth = GenericBackend().authenticate(self.request, kfet_token="invalid")
self.assertIsNone(auth)
##
# Views
##
class GenericLoginViewTests(TestCase):
def setUp(self):
user_acc = Account(trigramme="000")
user_acc.save({"username": "user"})
self.user = user_acc.user
self.user.set_password("user")
self.user.save()
team_acc = Account(trigramme="100")
team_acc.save({"username": "team"})
self.team = team_acc.user
self.team.set_password("team")
self.team.save()
self.team.user_permissions.add(
Permission.objects.get(content_type__app_label="kfet", codename="is_team")
)
self.url = reverse("kfet.login.generic")
self.generic_user = get_kfet_generic_user()
def test_url(self):
self.assertEqual(self.url, "/k-fet/login/generic")
def test_get(self):
"""
Send confirmation for user to emit POST request, instead of GET.
"""
self.client.login(username="team", password="team")
r = self.client.get(self.url)
self.assertEqual(r.status_code, 200)
self.assertTemplateUsed(r, "kfet/confirm_form.html")
def test_post(self):
"""
The kfet generic user is logged in.
"""
self.client.login(username="team", password="team")
r = self.client.post(self.url)
self.assertRedirects(r, reverse("kfet.kpsul"))
self.assertEqual(r.wsgi_request.user, self.generic_user)
with self.assertRaises(GenericTeamToken.DoesNotExist):
GenericTeamToken.objects.get()
def test_not_team(self):
"""
Logged in user must be a team user to initiate login as generic user.
"""
self.client.login(username="user", password="user")
# With GET.
r = self.client.get(self.url)
self.assertRedirects(
r, "/profil/login/?next={}".format(self.url), fetch_redirect_response=False
)
# Also with POST.
r = self.client.post(self.url)
self.assertRedirects(
r, "/profil/login/?next={}".format(self.url), fetch_redirect_response=False
)
def test_post_redirect(self):
"""
A team user is logged in as the kfet generic user.
"""
self.client.login(username="team", password="team")
next_url = "/any-url/"
url = self.url + "?next=" + next_url
r = self.client.post(url)
self.assertRedirects(r, next_url, fetch_redirect_response=False)
self.assertEqual(r.wsgi_request.user, self.generic_user)
##
# Temporary authentication
#
# Includes:
# - TemporaryAuthMiddleware
# - temporary_auth context processor
##
class TemporaryAuthTests(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.middleware = TemporaryAuthMiddleware(mock.Mock())
user1_acc = Account(trigramme="000")
user1_acc.change_pwd("kfet_user1")
user1_acc.save({"username": "user1"})
self.user1 = user1_acc.user
self.user1.set_password("user1")
self.user1.save()
user2_acc = Account(trigramme="100")
user2_acc.change_pwd("kfet_user2")
user2_acc.save({"username": "user2"})
self.user2 = user2_acc.user
self.user2.set_password("user2")
self.user2.save()
self.perm = Permission.objects.get(
content_type__app_label="kfet", codename="is_team"
)
self.user2.user_permissions.add(self.perm)
def test_middleware_header(self):
"""
A user can be authenticated if ``HTTP_KFETPASSWORD`` header of a
request contains a valid kfet password.
"""
request = self.factory.get("/", HTTP_KFETPASSWORD="kfet_user2")
request.user = self.user1
self.middleware(request)
self.assertEqual(request.user, self.user2)
self.assertEqual(request.real_user, self.user1)
def test_middleware_post(self):
"""
A user can be authenticated if ``KFETPASSWORD`` of POST data contains
a valid kfet password.
"""
request = self.factory.post("/", {"KFETPASSWORD": "kfet_user2"})
request.user = self.user1
self.middleware(request)
self.assertEqual(request.user, self.user2)
self.assertEqual(request.real_user, self.user1)
def test_middleware_invalid(self):
"""
The given password must be a password of an Account.
"""
request = self.factory.post("/", {"KFETPASSWORD": "invalid"})
request.user = self.user1
self.middleware(request)
self.assertEqual(request.user, self.user1)
self.assertFalse(hasattr(request, "real_user"))
def test_context_processor(self):
"""
Context variables give the real authenticated user and his permissions.
"""
self.client.login(username="user1", password="user1")
r = self.client.get("/k-fet/accounts/", HTTP_KFETPASSWORD="kfet_user2")
self.assertEqual(r.context["user"], self.user1)
self.assertNotIn("kfet.is_team", r.context["perms"])
def test_auth_not_persistent(self):
"""
The authentication is temporary, i.e. for one request.
"""
self.client.login(username="user1", password="user1")
r1 = self.client.get("/k-fet/accounts/", HTTP_KFETPASSWORD="kfet_user2")
self.assertEqual(r1.wsgi_request.user, self.user2)
r2 = self.client.get("/k-fet/accounts/")
self.assertEqual(r2.wsgi_request.user, self.user1)