diff --git a/kfet/auth/views.py b/kfet/auth/views.py index 5dd048e9..a931512e 100644 --- a/kfet/auth/views.py +++ b/kfet/auth/views.py @@ -1,3 +1,4 @@ +from django.conf import settings as django_settings from django.contrib import messages from django.contrib.auth import authenticate, login from django.contrib.auth.decorators import permission_required @@ -42,7 +43,7 @@ class GenericLoginView(View): if request.method == "POST": # Step 1: set token and logout user. - return self.prepare_auth() + return self.prepare_auth(request) else: # GET request should not change server/client states. Send a # confirmation template to emit a POST request. @@ -61,7 +62,7 @@ class GenericLoginView(View): # Step 2: validate token. return self.validate_auth(token) - def prepare_auth(self): + def prepare_auth(self, request): # Issue token. token = GenericTeamToken.objects.create_token() @@ -73,10 +74,23 @@ class GenericLoginView(View): here_qd["next"] = self.request.GET["next"] here_url += "?{}".format(here_qd.urlencode()) - logout_url = reverse("cof-logout") - logout_qd = QueryDict(mutable=True) - logout_qd["next"] = here_url - logout_url += "?{}".format(logout_qd.urlencode(safe="/")) + # When CAS logs the user out, the generic login has to be called back. + # The corresponding callback URL is provided as a GET parameter. + # The renaming of the CAS logout "url" parameter to "service" is being forced, + # which is why the CAS logout URL with callback is constructed ad hoc, + # without relying on Django redirection to Django CAS. + + # An HTTP absolute URL as callback seems to be required for the K-Psul link + # to work. + generic_login_url = "http://" + request.get_host() + here_url + generic_login_qd = QueryDict(mutable=True) + generic_login_qd["service"] = generic_login_url + + cas_server_url = django_settings.CAS_SERVER_URL + cas_logout_url = cas_server_url+"logout" + cas_callback_url = cas_logout_url + "?{}".format(generic_login_qd.urlencode()) + + logout_url = cas_callback_url resp = redirect(logout_url) resp.set_signed_cookie(self.TOKEN_COOKIE_NAME, token.token, httponly=True)