From 2e08951d44b99f19828307a05f0e1d47b9431040 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Sun, 25 Nov 2018 17:42:14 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Am=C3=A9liore=20l'ergonomie=20de=20`cof=5Fr?= =?UTF-8?q?equired`=20et=20`buro=5Frequired`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- bda/tests/test_views.py | 20 ++++----- gestioncof/decorators.py | 62 ++++++++++++++++++++------- gestioncof/templates/buro-denied.html | 5 +++ 3 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 gestioncof/templates/buro-denied.html diff --git a/bda/tests/test_views.py b/bda/tests/test_views.py index 6bfa3257..7204a320 100644 --- a/bda/tests/test_views.py +++ b/bda/tests/test_views.py @@ -60,24 +60,20 @@ class BdATestHelpers: def check_restricted_access( self, url, validate_user=user_is_cof, redirect_url=None ): - def craft_redirect_url(user): - if redirect_url: - return redirect_url + for (user, client) in self.client_matrix: + resp = client.get(url, follow=True) + if validate_user(user): + self.assertEqual(200, resp.status_code) + elif redirect_url: + self.assertRedirects(resp, redirect_url) elif user is None: # client is not logged in login_url = "/login" if url: login_url += "?{}".format(urlencode({"next": url}, safe="/")) - return login_url + self.assertRedirects(resp, login_url) else: - return "/" - - 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)) + self.assertEqual(403, resp.status_code) class TestBdAViews(BdATestHelpers, TestCase): diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index ef811730..9ccbac96 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -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 is_cof(user): - try: - profile = user.profile - return profile.is_cof - except Exception: - return False +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): + try: + return user.profile.is_cof + except AttributeError: + return False + + @wraps(view_func) + def _wrapped_view(request, *args, **kwargs): + if is_cof(request.user): + return view_func(request, *args, **kwargs) + + return render(request, "cof-denied.html", status=403) + + return login_required(_wrapped_view) -cof_required = user_passes_test(is_cof) +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): - try: - profile = user.profile - return profile.is_buro - except Exception: - return False + def is_buro(user): + try: + return user.profile.is_buro + except AttributeError: + 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) diff --git a/gestioncof/templates/buro-denied.html b/gestioncof/templates/buro-denied.html new file mode 100644 index 00000000..1e477751 --- /dev/null +++ b/gestioncof/templates/buro-denied.html @@ -0,0 +1,5 @@ +{% extends "base_title.html" %} + +{% block realcontent %} +

Section réservée au Burô.

+{% endblock %} From 5f9695ef8e7c31bfccca2bd1feff5e3dd0e8362e Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Sun, 25 Nov 2018 18:32:04 +0100 Subject: [PATCH 2/2] isort --- gestioncof/decorators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gestioncof/decorators.py b/gestioncof/decorators.py index 9ccbac96..37d93c7f 100644 --- a/gestioncof/decorators.py +++ b/gestioncof/decorators.py @@ -1,6 +1,6 @@ from functools import wraps -from django.contrib.auth.decorators import user_passes_test, login_required +from django.contrib.auth.decorators import login_required, user_passes_test from django.core.exceptions import PermissionDenied from django.shortcuts import render