Projet

Général

Profil

0001-adapters-update-new-UserSAMLIdentifier-fields-on-eac.patch

Benjamin Dauvergne, 06 octobre 2022 15:24

Télécharger (5,64 ko)

Voir les différences:

Subject: [PATCH] adapters: update new UserSAMLIdentifier fields on each SSO
 (#69955)

On existing UserSAMLIdentifier missing values for nid_format especially,
will break the SLO code as the emitted LogoutRequest will have an
unknown NameID when analyzed by the identity provider (NameID content
and attributes must match exactly).
 mellon/adapters.py | 27 +++++++++++++++++++++++----
 mellon/views.py    | 13 +++++++++----
 2 files changed, 32 insertions(+), 8 deletions(-)
mellon/adapters.py
331 331
            name_id = saml_attributes['name_id_content']
332 332
        entity_id = saml_attributes['issuer']
333 333
        try:
334
            to_update = {
335
                'nid_format': saml_attributes['name_id_format'],
336
                'nid_name_qualifier': saml_attributes.get('name_id_name_qualifier'),
337
                'nid_sp_name_qualifier': saml_attributes.get('name_id_sp_name_qualifier'),
338
                'nid_sp_provided_id': saml_attributes.get('name_id_sp_provided_id'),
339
            }
334 340
            saml_identifier = models.UserSAMLIdentifier.objects.select_related('user').get(
335 341
                name_id=name_id, issuer=models_utils.get_issuer(entity_id)
336 342
            )
343
            # nid_* attributes are new, we must update them if they are not initialized, eventually
344
            for key in to_update:
345
                if getattr(saml_identifier, key) != to_update[key]:
346
                    models.UserSAMLIdentifier.objects.filter(pk=saml_identifier.pk).update(**to_update)
347
                    break
337 348
            user = saml_identifier.user
338 349
            user.saml_identifier = saml_identifier
339 350
            logger.info('mellon: looked up user %s with name_id %s from issuer %s', user, name_id, entity_id)
......
463 474
        name_id_content = saml_attributes['name_id_content']
464 475
        if saml_attributes['name_id_format'] == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT:
465 476
            name_id_content = saml_attributes['transient_name_id_content']
477
        to_update = {
478
            'nid_format': saml_attributes['name_id_format'],
479
            'nid_name_qualifier': saml_attributes.get('name_id_name_qualifier'),
480
            'nid_sp_name_qualifier': saml_attributes.get('name_id_sp_name_qualifier'),
481
            'nid_sp_provided_id': saml_attributes.get('name_id_sp_provided_id'),
482
        }
466 483
        saml_id, created = models.UserSAMLIdentifier.objects.get_or_create(
467 484
            name_id=name_id_content,
468 485
            issuer=models_utils.get_issuer(saml_attributes['issuer']),
469 486
            defaults={
470 487
                'user': user,
471
                'nid_format': saml_attributes['name_id_format'],
472
                'nid_name_qualifier': saml_attributes.get('name_id_name_qualifier'),
473
                'nid_sp_name_qualifier': saml_attributes.get('name_id_sp_name_qualifier'),
474
                'nid_sp_provided_id': saml_attributes.get('name_id_sp_provided_id'),
488
                **to_update,
475 489
            },
476 490
        )
491
        # nid_* attributes are new, we must update them eventually
492
        for key in to_update:
493
            if getattr(saml_id, key) != to_update[key]:
494
                models.UserSAMLIdentifier.objects.filter(pk=saml_id.pk).update(**to_update)
495
                break
477 496
        if created:
478 497
            user.saml_identifier = saml_id
479 498
            return user
mellon/views.py
753 753
                        self.get_relay_state(create=True)
754 754
                        try:
755 755
                            session_indexes = models.SessionIndex.objects.filter(
756
                                saml_identifier__user=request.user, saml_identifier__issuer__entity_id=issuer
757
                            ).order_by('-id')
756
                                saml_identifier__user=request.user,
757
                                saml_identifier__issuer__entity_id=issuer,
758
                                session_key=request.session.session_key,
759
                            )
758 760
                            if not session_indexes:
759 761
                                self.log.error('unable to find lasso session dump')
760 762
                            else:
761
                                session_dump = utils.make_session_dump(session_indexes[:1])
763
                                session_dump = utils.make_session_dump(session_indexes)
762 764
                                logout.setSessionFromDump(session_dump)
763 765
                            session_indexes.update(logout_timestamp=now())
764 766
                            logout.initRequest(issuer, lasso.HTTP_METHOD_REDIRECT)
......
812 814
        token_content = signing.loads(token, salt=self.TOKEN_SALT)
813 815
        next_url = token_content['next_url'] or logout_next_url
814 816
        session_index_pk = token_content['session_index_pk']
815
        session_indexes = models.SessionIndex.objects.filter(pk=session_index_pk)
817
        session_index = models.SessionIndex.objects.filter(pk=session_index_pk).first()
818
        session_indexes = models.SessionIndex.objects.filter(
819
            saml_identifier=session_index.saml_identifier, session_key=session_index.session_key
820
        )
816 821
        if session_indexes:
817 822
            session_dump = utils.make_session_dump(session_indexes)
818 823
            logout = utils.create_logout(request)
819
-