0002-auth_fc-handle-case-of-multiple-FranceConnect-accoun.patch
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 |
- |