Add messages on auth success & failure

Refactor auth code to use class based views
This commit is contained in:
Guillaume Bertholon 2020-11-29 22:35:42 +01:00
parent 1850746975
commit 02aaa79047
3 changed files with 87 additions and 54 deletions

View file

@ -40,7 +40,7 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware", "django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
'django_cas_ng.middleware.CASMiddleware' "django_cas_ng.middleware.CASMiddleware",
] ]
ROOT_URLCONF = "gestiojeux.urls" ROOT_URLCONF = "gestiojeux.urls"
@ -64,8 +64,8 @@ TEMPLATES = [
WSGI_APPLICATION = "gestiojeux.wsgi.application" WSGI_APPLICATION = "gestiojeux.wsgi.application"
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', "django.contrib.auth.backends.ModelBackend",
'django_cas_ng.backends.CASBackend', "django_cas_ng.backends.CASBackend",
) )
# Password validation # Password validation
@ -90,8 +90,10 @@ STATIC_URL = "/static/"
MEDIA_URL = "/media/" MEDIA_URL = "/media/"
CAS_SERVER_URL = "https://cas.eleves.ens.fr/" CAS_SERVER_URL = "https://cas.eleves.ens.fr/"
CAS_VERSION = "2" CAS_VERIFY_URL = "https://cas.eleves.ens.fr/"
CAS_LOGIN_MSG = None CAS_VERSION = "CAS_2_SAML_1_0"
CAS_IGNORE_REFERER = True CAS_IGNORE_REFERER = True
CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" CAS_FORCE_CHANGE_USERNAME_CASE = "lower"
CAS_LOGIN_MSG = None
CAS_LOGIN_URL_NAME = "gestiojeux_auth:cas_ng_login"
CAS_LOGOUT_URL_NAME = "gestiojeux_auth:cas_ng_logout"

View file

@ -1,6 +1,6 @@
from django.urls import include, path from django.urls import include, path
import django.contrib.auth.views as dj_auth_views import django.contrib.auth.views as dj_auth_views
from .views import login, logout from .views import LoginView, LogoutView
import django_cas_ng.views import django_cas_ng.views
app_name = "gestiojeux_auth" app_name = "gestiojeux_auth"
@ -17,8 +17,8 @@ cas_patterns = [
accounts_patterns = [ accounts_patterns = [
path("cas/", include(cas_patterns)), path("cas/", include(cas_patterns)),
path("login/", login, name="login"), path("login/", LoginView.as_view(), name="login"),
path("logout/", logout, name="logout"), path("logout/", LogoutView.as_view(), name="logout"),
path("password_login/", dj_auth_views.LoginView.as_view(), name="password_login"), path("password_login/", dj_auth_views.LoginView.as_view(), name="password_login"),
] ]

View file

@ -1,52 +1,83 @@
from django.shortcuts import render, redirect from django.views.generic import TemplateView, RedirectView
from django.shortcuts import redirect
from django.urls import reverse from django.urls import reverse
from django.dispatch import receiver
from django.contrib.auth import logout as auth_logout from django.contrib.auth import logout as auth_logout
from django.contrib.auth.decorators import login_required from django.contrib.auth import user_logged_in, user_logged_out, user_login_failed
from django.contrib import messages
from urllib.parse import quote as urlquote from urllib.parse import quote as urlquote
def login(req): class LoginView(TemplateView):
if req.user.is_authenticated: template_name = "registration/login_switch.html"
return redirect("mainsite:home")
if req.method == "GET": def dispatch(self, request, *args, **kwargs):
reqDict = req.GET if request.user.is_authenticated:
elif req.method == "POST": messages.warning(
reqDict = req.POST request,
if "next" in reqDict: "Vous êtes déjà connecté·e en tant que {}.".format(
nextUrl = reqDict["next"] request.user.username
context = { ),
"pass_url": "{}?next={}".format(
reverse("gestiojeux_auth:password_login"), urlquote(nextUrl, safe="")
),
"cas_url": "{}?next={}".format(
reverse("gestiojeux_auth:cas_ng_login"), urlquote(nextUrl, safe="")
),
}
else:
context = {
"pass_url": reverse("gestiojeux_auth:password_login"),
"cas_url": reverse("gestiojeux_auth:cas_ng_login"),
}
return render(req, "registration/login_switch.html", context=context)
@login_required
def logout(req):
CAS_BACKEND_NAME = "django_cas_ng.backends.CASBackend"
if req.session["_auth_user_backend"] != CAS_BACKEND_NAME:
auth_logout(req)
if "next" in req.GET:
return redirect(req.GET["next"])
return redirect("mainsite:home")
if "next" in req.GET:
return redirect(
"{}?next={}".format(
reverse("gestiojeux_auth:cas_ng_logout"),
urlquote(req.GET["next"], safe=""),
) )
) return redirect(self.get_next_url() or "/")
return redirect("gestiojeux_auth:cas_ng_logout")
return super().dispatch(request, *args, **kwargs)
def get_next_url(self):
if self.request.method == "GET":
req_dict = self.request.GET
elif self.request.method == "POST":
req_dict = self.request.POST
return req_dict.get("next")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
next_url = self.get_next_url()
if next_url:
context["pass_url"] = "{}?next={}".format(
reverse("gestiojeux_auth:password_login"), urlquote(next_url, safe="")
)
context["cas_url"] = "{}?next={}".format(
reverse("gestiojeux_auth:cas_ng_login"), urlquote(next_url, safe="")
)
else:
context["pass_url"] = reverse("gestiojeux_auth:password_login")
context["cas_url"] = reverse("gestiojeux_auth:cas_ng_login")
return context
class LogoutView(RedirectView):
permanent = False
def get_redirect_url(self, *args, **kwargs):
CAS_BACKEND_NAME = "django_cas_ng.backends.CASBackend"
if self.request.session["_auth_user_backend"] != CAS_BACKEND_NAME:
auth_logout(self.request)
if "next" in self.request.GET:
return self.request.GET["next"]
return reverse("mainsite:home")
if "next" in self.request.GET:
return "{}?next={}".format(
reverse("gestiojeux_auth:cas_ng_logout"),
urlquote(self.request.GET["next"], safe=""),
)
return reverse("gestiojeux_auth:cas_ng_logout")
@receiver(user_logged_in)
def on_login(request, user, **kwargs):
messages.success(request, "Connexion réussie. Bienvenue, {}.".format(user))
@receiver(user_logged_out)
def on_logout(request, **kwargs):
messages.info(request, "Vous avez bien été déconnecté·e.")
@receiver(user_login_failed)
def on_login_failed(request, **kwargs):
messages.error(request, "Connexion échouée.")