Skip to content

Commit

Permalink
fix(openid_connect): EmailInUseException false positive
Browse files Browse the repository at this point in the history
  • Loading branch information
calummackervoy committed Sep 23, 2024
1 parent c0e5990 commit 07f1575
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
10 changes: 9 additions & 1 deletion itou/openid_connect/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ def check_valid_kind(self, user, user_data_dict, is_login):
if user.kind not in self.login_allowed_user_kinds or (user.kind != user_data_dict["kind"] and not is_login):
raise InvalidKindException(user)

def handle_email_conflict_on_sso(self, user):
"""
By default if there is an email conflict between two usernames,
we will update the existing account with the new username.
This hook allows providers (notably PE Connect) to override this behaviour
"""
pass

def create_or_update_user(self, is_login=False):
"""
Create or update a user managed by another identity provider.
Expand Down Expand Up @@ -138,7 +146,7 @@ def create_or_update_user(self, is_login=False):
# Don't update a user handled by another SSO provider.
return user, created
if user.identity_provider == self.identity_provider:
raise EmailInUseException(user)
self.handle_email_conflict_on_sso(user)
except User.DoesNotExist:
# User.objects.create_user does the following:
# - set User.is_active to true,
Expand Down
5 changes: 4 additions & 1 deletion itou/openid_connect/pe_connect/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from itou.users.enums import IdentityProvider, UserKind

from ..models import OIDConnectState, OIDConnectUserData
from ..models import EmailInUseException, OIDConnectState, OIDConnectUserData


class PoleEmploiConnectState(OIDConnectState):
Expand All @@ -17,3 +17,6 @@ class PoleEmploiConnectUserData(OIDConnectUserData):
kind: str = UserKind.JOB_SEEKER
identity_provider: IdentityProvider = IdentityProvider.PE_CONNECT
login_allowed_user_kinds = [UserKind.JOB_SEEKER]

def handle_email_conflict_on_sso(self, user):
raise EmailInUseException(user)
15 changes: 15 additions & 0 deletions tests/openid_connect/france_connect/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@ def test_create_django_user_with_already_existing_fc_email_django(self):
assert user.identity_provider == IdentityProvider.FRANCE_CONNECT
assert user.external_data_source_history != {}

def test_create_django_user_with_already_existing_fc_email(self):
fc_user_data = FranceConnectUserData.from_user_info(FC_USERINFO)
JobSeekerFactory(
username="another_username",
email=fc_user_data.email,
identity_provider=IdentityProvider.FRANCE_CONNECT,
)
user, created = fc_user_data.create_or_update_user()
assert not created
assert user.last_name == FC_USERINFO["family_name"]
assert user.first_name == FC_USERINFO["given_name"]
assert user.username == FC_USERINFO["sub"]
assert user.identity_provider == IdentityProvider.FRANCE_CONNECT
assert user.external_data_source_history != {}

def test_create_django_user_with_already_existing_fc_email_other_sso_job_seeker(self):
"""
If there already is an existing job seeker with the email FranceConnect sent us, we do not create it again,
Expand Down

0 comments on commit 07f1575

Please sign in to comment.