From 8a6c4afb10770b6c50d6291cab056389c886da23 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 22 Apr 2020 04:14:03 +0200 Subject: [PATCH 3/4] misc: logout all sessions when SLO does not contain a SessionIndex (#41949) --- mellon/views.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git mellon/views.py mellon/views.py index 1a77819..7a777c1 100644 --- mellon/views.py +++ mellon/views.py @@ -27,6 +27,7 @@ import django.http from django.views.generic import View from django.http import HttpResponseRedirect, HttpResponse from django.contrib import auth +from django.contrib.sessions.models import Session from django.conf import settings from django.views.decorators.csrf import csrf_exempt from django.shortcuts import render, resolve_url @@ -514,6 +515,18 @@ class LogoutView(ProfileMixin, LogMixin, View): def post(self, request, *args, **kwargs): return self.idp_logout(request, force_str(request.body)) + def logout_all_sessions(self, request): + if not ('.cached_db' in settings.SESSION_ENGINE or '.db' in settings.SESSION_ENGINE): + self.log.error('cannot logout from all sessions, session are not in database') + return + user_id = request.user.id + session_keys = [] + for session in Session.objects.all(): + if (session.get_decoded().get('_auth_user_id') == str(user_id) + and session.session_key != request.session.session_key): + session_keys.append(session.session_key) + Session.objects.filter(session_key__in=session_keys).delete() + def idp_logout(self, request, msg): '''Handle logout request emitted by the IdP''' self.profile = logout = utils.create_logout(request) @@ -523,12 +536,19 @@ class LogoutView(ProfileMixin, LogMixin, View): return HttpResponseBadRequest('error processing logout request: %r' % e) try: logout.validateRequest() + except lasso.LogoutErrorUnknownPrincipal: + self.log.warning('invalid SessionIndex or NameID') except lasso.Error as e: self.log.warning('error validating logout request: %r' % e) + full_logout = not (logout.request.sessionIndexes) issuer = request.session.get('mellon_session', {}).get('issuer') if issuer == logout.remoteProviderId: + if full_logout: + self.log.info('no SessionIndex logging out all sessions') + self.logout_all_sessions(request) self.log.info('user logged out by IdP SLO request') auth.logout(request) + try: logout.buildResponseMsg() except lasso.Error as e: -- 2.26.0