From 750f869e5f996fb67fa8571f0b5c9a74924260aa Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 7 Nov 2022 15:53:34 +0100 Subject: [PATCH] misc: do not send logout requests if SingleLogout profile is not supported (#71041) --- mellon/utils.py | 15 ++++++++++++++- mellon/views.py | 5 ++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mellon/utils.py b/mellon/utils.py index 04c2caa..34df3d0 100644 --- a/mellon/utils.py +++ b/mellon/utils.py @@ -68,7 +68,7 @@ def create_metadata(request): return render_to_string('mellon/metadata.xml', ctx) -def create_server(request): +def create_server(request, remote_provider_id=None): root = request.build_absolute_uri('/') cache = getattr(settings, '_MELLON_SERVER_CACHE', {}) if root not in cache: @@ -109,11 +109,15 @@ def create_server(request): key = key[0] server.setEncryptionPrivateKeyWithPassword(key, password) for idp in get_idps(): + if remote_provider_id and idp.get('ENTITY_ID') != remote_provider_id: + continue if idp and idp.get('METADATA'): try: server.addProviderFromBuffer(lasso.PROVIDER_ROLE_IDP, idp['METADATA']) except lasso.Error as e: logger.error('bad metadata in idp %s, %s', idp['ENTITY_ID'], e) + if not server.providers and remote_provider_id: + logger.warning('mellon: create_server, no provider found for issuer %r', remote_provider_id) cache[root] = server settings._MELLON_SERVER_CACHE = cache return cache.get(root) @@ -344,3 +348,12 @@ def get_local_path(request, url): if request.META.get('SCRIPT_NAME'): path = path[len(request.META['SCRIPT_NAME']) :] return path + + +def is_slo_supported(request, issuer): + server = create_server(request, remote_provider_id=issuer) + # verify that at least one logout method is supported + return ( + server.getFirstHttpMethod(server.providers[issuer], lasso.MD_PROTOCOL_TYPE_SINGLE_LOGOUT) + != lasso.HTTP_METHOD_NONE + ) diff --git a/mellon/views.py b/mellon/views.py index d6b80fd..69f9b9c 100644 --- a/mellon/views.py +++ b/mellon/views.py @@ -748,7 +748,7 @@ class LogoutView(ProfileMixin, LogMixin, View): logout = None try: issuer = request.session.get('mellon_session', {}).get('issuer') - if issuer: + if issuer and utils.is_slo_supported(request, issuer=issuer): self.profile = logout = utils.create_logout(request) self.get_relay_state(create=True) try: @@ -851,6 +851,9 @@ class LogoutView(ProfileMixin, LogMixin, View): issuer = request.session.get('mellon_session', {}).get('issuer') if not issuer: return None + # verify that at least one binding the logout profile is supported + if not utils.is_slo_supported(request, issuer=issuer): + return None session_indexes = models.SessionIndex.objects.filter( saml_identifier__user=request.user, saml_identifier__issuer__entity_id=issuer ).order_by('-id')