Projet

Général

Profil

0003-views-allow-overriding-the-default-return-url-after-.patch

Benjamin Dauvergne, 05 octobre 2022 19:55

Télécharger (4,65 ko)

Voir les différences:

Subject: [PATCH 3/8] views: allow overriding the default return url after
 logout (#69740)

 mellon/views.py       | 14 +++++++-------
 tests/test_sso_slo.py | 26 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 7 deletions(-)
mellon/views.py
612 612

  
613 613

  
614 614
class LogoutView(ProfileMixin, LogMixin, View):
615
    def get(self, request, *args, **kwargs):
615
    def get(self, request, *args, logout_next_url='/', **kwargs):
616 616
        if 'SAMLRequest' in request.GET:
617 617
            return self.idp_logout(request, request.META['QUERY_STRING'], 'redirect')
618 618
        elif 'SAMLResponse' in request.GET:
619
            return self.sp_logout_response(request)
619
            return self.sp_logout_response(request, logout_next_url=logout_next_url)
620 620
        else:
621
            return self.sp_logout_request(request)
621
            return self.sp_logout_request(request, logout_next_url=logout_next_url)
622 622

  
623 623
    def post(self, request, *args, **kwargs):
624 624
        return self.idp_logout(request, force_str(request.body), 'soap')
......
721 721
        else:
722 722
            return HttpResponseRedirect(logout.msgUrl)
723 723

  
724
    def sp_logout_request(self, request):
724
    def sp_logout_request(self, request, logout_next_url=None):
725 725
        '''Launch a logout request to the identity provider'''
726 726
        referer = request.headers.get('Referer')
727 727
        field_next_url = request.GET.get(REDIRECT_FIELD_NAME)
728 728
        next_url = None
729 729
        if field_next_url and utils.same_origin(request.build_absolute_uri(), field_next_url):
730 730
            next_url = field_next_url
731
        next_url = next_url or '/'
731
        next_url = next_url or logout_next_url
732 732
        if not referer or utils.same_origin(request.build_absolute_uri(), referer):
733 733
            if hasattr(request, 'user') and request.user.is_authenticated:
734 734
                logout = None
......
763 763
            self.log.warning('logout refused referer %r is not of the same origin', referer)
764 764
        return HttpResponseRedirect(next_url)
765 765

  
766
    def sp_logout_response(self, request):
766
    def sp_logout_response(self, request, logout_next_url='/'):
767 767
        '''Launch a logout request to the identity provider'''
768 768
        self.profile = logout = utils.create_logout(request)
769 769
        logout.msgRelayState = request.GET.get('RelayState')
......
778 778
            self.log.warning('partial logout')
779 779
        except lasso.Error as e:
780 780
            self.log.warning('unable to process a logout response: %s', e)
781
        return HttpResponseRedirect(self.get_next_url() or '/')
781
        return HttpResponseRedirect(self.get_next_url() or logout_next_url)
782 782

  
783 783

  
784 784
logout = csrf_exempt(LogoutView.as_view())
tests/test_sso_slo.py
270 270
    assert response.location == '/some/path/'
271 271

  
272 272

  
273
def test_sso_slo_default_next_url(db, app, idp, caplog, sp_settings, rf):
274
    from mellon.views import logout
275

  
276
    response = app.get(reverse('mellon_login'))
277
    url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
278
    response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state})
279

  
280
    request = rf.get('/logout/')
281
    request.session = app.session
282
    request.user = mock.Mock()
283
    request.user.is_authenticated = True
284
    response = logout(request, logout_next_url='/other/path/')
285
    assert list(request.session.values()) == ['/other/path/']
286

  
287
    response = app.get(reverse('mellon_login'))
288
    url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
289
    response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state})
290

  
291
    request = rf.get('/logout/?next=/some/path/')
292
    request.session = app.session
293
    request.user = mock.Mock()
294
    request.user.is_authenticated = True
295
    response = logout(request, logout_next_url='/other/path/')
296
    assert list(request.session.values()) == ['/some/path/']
297

  
298

  
273 299
def test_sso_idp_slo(db, app, idp, caplog, sp_settings):
274 300
    assert Session.objects.count() == 0
275 301
    assert User.objects.count() == 0
276
-