auth_oidc: handle case of multiple users with same email but email should be unique (#48339)
This commit is contained in:
parent
7fdf868b5c
commit
b2f926388b
|
@ -239,6 +239,11 @@ class OIDCBackend(ModelBackend):
|
|||
linked = True
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
except User.MultipleObjectsReturned:
|
||||
logger.error('auth_oidc: cannot create user with sub "%s", '
|
||||
'too many users with the same email "%s" in ou "%s"',
|
||||
id_token.sub, email, provider.ou)
|
||||
return
|
||||
if not user:
|
||||
user = User.objects.create(ou=provider.ou)
|
||||
user.set_unusable_password()
|
||||
|
|
|
@ -862,3 +862,51 @@ def test_save_account_on_delete_user(db):
|
|||
'sub': '1234',
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_multiple_users_with_same_email(app, caplog, code, oidc_provider_jwkset, hooks):
|
||||
oidc_provider = make_oidc_provider(idtoken_algo=OIDCProvider.ALGO_HMAC)
|
||||
ou = get_default_ou()
|
||||
ou.email_is_unique = True
|
||||
ou.save()
|
||||
|
||||
user1 = User.objects.create(ou=ou, email='john.doe@example.com')
|
||||
|
||||
assert OIDCAccount.objects.count() == 0
|
||||
|
||||
response = app.get('/').maybe_follow()
|
||||
assert oidc_provider.name in response.text
|
||||
response = response.click(oidc_provider.name)
|
||||
location = urlparse.urlparse(response.location)
|
||||
query = QueryDict(location.query)
|
||||
state = query['state']
|
||||
nonce = query['nonce']
|
||||
|
||||
# sub=john.doe, MUST not work
|
||||
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, nonce=nonce):
|
||||
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
|
||||
|
||||
assert app.session['_auth_user_id'] == str(user1.id)
|
||||
assert OIDCAccount.objects.count() == 1
|
||||
|
||||
app.session.flush()
|
||||
OIDCAccount.objects.all().delete()
|
||||
User.objects.create(ou=ou, email='john.doe@example.com')
|
||||
|
||||
response = app.get('/').maybe_follow()
|
||||
assert oidc_provider.name in response.text
|
||||
response = response.click(oidc_provider.name)
|
||||
location = urlparse.urlparse(response.location)
|
||||
query = QueryDict(location.query)
|
||||
state = query['state']
|
||||
nonce = query['nonce']
|
||||
|
||||
assert OIDCAccount.objects.count() == 0
|
||||
|
||||
# sub=john.doe, MUST not work
|
||||
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, nonce=nonce):
|
||||
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
|
||||
|
||||
assert '_auth_user_id' not in app.session
|
||||
assert OIDCAccount.objects.count() == 0
|
||||
assert 'too many users' in caplog.records[-1].message
|
||||
|
|
Loading…
Reference in New Issue