Améliore l'ergonomie de cof_required et buro_required

Ce patch rend les décorateurs `cof_required` et `buro_required` plus
agréables pour les utilisateurs; en particulier, ils ne font plus une
redirection sur la page de connexion si la condition n'est pas remplie.

Dans les deux cas :

 - Si l'utilisateur n'est pas connecté, il est renvoyé sur la page de
   connexion

 - Si l'utilisateur est connecté mais pas membre du COF/du Burô, une
   page d'erreur "403 Forbidden" est affichée.  Dans le cas de
   `cof_required` cette page demande à l'utilisateur de s'inscrire au
   COF; dans le cas `buro_required` elle indique simplement que la page
   est réservée au Burô.

gestioncof/
 * gestioncof/templates/buro-denied.html:  Ajouté.
 * decorators.py:

bda/
 * tests/test_views.py:
       Modifié pour correctement gérer le nouveau fonctionnement des
       décorateurs.
This commit is contained in:
Basile Clement 2018-11-25 17:42:14 +01:00
parent d82c9baf20
commit 2e08951d44
3 changed files with 60 additions and 27 deletions

View file

@ -60,24 +60,20 @@ class BdATestHelpers:
def check_restricted_access( def check_restricted_access(
self, url, validate_user=user_is_cof, redirect_url=None self, url, validate_user=user_is_cof, redirect_url=None
): ):
def craft_redirect_url(user): for (user, client) in self.client_matrix:
if redirect_url: resp = client.get(url, follow=True)
return redirect_url if validate_user(user):
self.assertEqual(200, resp.status_code)
elif redirect_url:
self.assertRedirects(resp, redirect_url)
elif user is None: elif user is None:
# client is not logged in # client is not logged in
login_url = "/login" login_url = "/login"
if url: if url:
login_url += "?{}".format(urlencode({"next": url}, safe="/")) login_url += "?{}".format(urlencode({"next": url}, safe="/"))
return login_url self.assertRedirects(resp, login_url)
else: else:
return "/" self.assertEqual(403, resp.status_code)
for (user, client) in self.client_matrix:
resp = client.get(url, follow=True)
if validate_user(user):
self.assertEqual(200, resp.status_code)
else:
self.assertRedirects(resp, craft_redirect_url(user))
class TestBdAViews(BdATestHelpers, TestCase): class TestBdAViews(BdATestHelpers, TestCase):

View file

@ -1,23 +1,55 @@
from django.contrib.auth.decorators import user_passes_test from functools import wraps
from django.contrib.auth.decorators import user_passes_test, login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import render
def cof_required(view_func):
"""Décorateur qui vérifie que l'utilisateur est connecté et membre du COF.
- Si l'utilisteur n'est pas connecté, il est redirigé vers la page de
connexion
- Si l'utilisateur est connecté mais pas membre du COF, il obtient une
page d'erreur lui demandant de s'inscrire au COF
"""
def is_cof(user): def is_cof(user):
try: try:
profile = user.profile return user.profile.is_cof
return profile.is_cof except AttributeError:
except Exception:
return False return False
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if is_cof(request.user):
return view_func(request, *args, **kwargs)
cof_required = user_passes_test(is_cof) return render(request, "cof-denied.html", status=403)
return login_required(_wrapped_view)
def buro_required(view_func):
"""Décorateur qui vérifie que l'utilisateur est connecté et membre du burô.
- Si l'utilisateur n'est pas connecté, il est redirigé vers la page de
connexion
- Si l'utilisateur est connecté mais pas membre du burô, il obtient une
page d'erreur 403 Forbidden
"""
def is_buro(user): def is_buro(user):
try: try:
profile = user.profile return user.profile.is_buro
return profile.is_buro except AttributeError:
except Exception:
return False return False
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if is_buro(request.user):
return view_func(request, *args, **kwargs)
buro_required = user_passes_test(is_buro) return render(request, "buro-denied.html", status=403)
return login_required(_wrapped_view)

View file

@ -0,0 +1,5 @@
{% extends "base_title.html" %}
{% block realcontent %}
<h2>Section réservée au Burô.</h2>
{% endblock %}