Projet

Général

Profil

0002-auth_fc-handle-case-of-multiple-FranceConnect-accoun.patch

Benjamin Dauvergne, 26 avril 2021 15:25

Télécharger (4,15 ko)

Voir les différences:

Subject: [PATCH 2/2] auth_fc: handle case of multiple FranceConnect accounts
 with same email (#53409)

 src/authentic2_auth_fc/views.py | 29 +++++++++++++++++++++--------
 tests/auth_fc/test_auth_fc.py   | 24 ++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 8 deletions(-)
src/authentic2_auth_fc/views.py
24 24
from django.contrib.auth.views import update_session_auth_hash
25 25
from django.core.cache import cache
26 26
from django.core.exceptions import PermissionDenied
27
from django.db import IntegrityError
27
from django.db import IntegrityError, transaction
28 28
from django.forms import Form
29 29
from django.http import Http404, HttpResponseRedirect
30 30
from django.urls import reverse
......
387 387
                    % email,
388 388
                )
389 389
                return None
390
            if not created and user.fc_accounts.exists():
391
                messages.warning(
392
                    request,
393
                    _(
394
                        'Your FranceConnect email address \'%s\' is already used by the '
395
                        'FranceConnect account of «%s», so we cannot create an account for you. Please create'
396
                        'an account with another email address then link it to FranceConnect '
397
                        'using your account management page.'
398
                    )
399
                    % (email, user.get_full_name()),
400
                )
390 401
        else:  # no email, we cannot disembiguate users, let's create it anyway
391 402
            user = User.objects.create()
392 403
            created = True
......
396 407
                user.set_unusable_password()
397 408
                user.save()
398 409

  
399
            models.FcAccount.objects.create(
400
                user=user,
401
                sub=sub,
402
                order=0,
403
                token=json.dumps(token),
404
                user_info=json.dumps(user_info),
405
            )
410
            # mandatory for the test to work :/, as test run in a transaction, we need a savepoint
411
            with transaction.atomic():
412
                models.FcAccount.objects.create(
413
                    user=user,
414
                    sub=sub,
415
                    order=0,
416
                    token=json.dumps(token),
417
                    user_info=json.dumps(user_info),
418
                )
406 419
        except IntegrityError:
407 420
            # uniqueness check failed, as the user is new, it can only mean that the sub is not unique
408 421
            # let's try again
tests/auth_fc/test_auth_fc.py
28 28
from django.urls import reverse
29 29
from django.utils.timezone import now
30 30

  
31
from authentic2.a2_rbac.models import OrganizationalUnit as OU
31 32
from authentic2.a2_rbac.utils import get_default_ou
32 33
from authentic2.apps.journal.models import Event
33 34
from authentic2.custom_user.models import DeletedUser
......
550 551

  
551 552
    # hook must have been called
552 553
    assert hooks.calls['event'][0]['kwargs']['name'] == 'fc-create'
554

  
555

  
556
def test_same_email_different_sub(app, franceconnect):
557
    OU.objects.all().update(email_is_unique=True)
558

  
559
    assert User.objects.count() == 0
560
    franceconnect.callback_params = {}
561

  
562
    franceconnect.login_with_fc_fixed_params(app)
563

  
564
    # ok user created
565
    assert User.objects.count() == 1
566
    # logout
567
    app.session.flush()
568

  
569
    # change sub
570
    franceconnect.sub = '4567'
571

  
572
    resp = franceconnect.login_with_fc_fixed_params(app).maybe_follow()
573

  
574
    # email collision, sub is different, no new user created
575
    assert User.objects.count() == 1
576
    assert 'another email address' in resp
553
-