Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GEN-1937] Connexion: Empêcher l'écrasement des comptes France Travail (courriels dupliqués) #4619

Merged

Conversation

calummackervoy
Copy link
Contributor

🤔 Pourquoi ?

Le SSO permet l’existence de plusieurs comptes avec le même email, ce qui fait qu’à chaque connexion depuis un compte ou un autre attaché au même email, on va écraser les données.

🚨 À vérifier

  • Mettre à jour le CHANGELOG_breaking_changes.md ?

💻 Captures d'écran

Screenshot 2024-08-29 at 18 15 06

@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 508064e to 5930ce1 Compare September 2, 2024 09:46
@calummackervoy calummackervoy marked this pull request as ready for review September 2, 2024 09:46
@calummackervoy calummackervoy changed the title [ GEN-1937 ] Connexion: Empêcher l'écrasement des comptes France Travail (courriels dupliqués) [GEN-1937] Connexion: Empêcher l'écrasement des comptes France Travail (courriels dupliqués) Sep 2, 2024
Copy link
Contributor

@tonial tonial left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beau travail !

Il reste à peaufiner la fonction qui masque partiellement le prénom et le nom.

itou/users/models.py Outdated Show resolved Hide resolved
itou/users/models.py Show resolved Hide resolved
@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 5930ce1 to 1aab8ac Compare September 3, 2024 08:49
@calummackervoy calummackervoy added the 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC label Sep 3, 2024
Copy link

github-actions bot commented Sep 3, 2024

🥁 La recette jetable est prête ! 👉 Je veux tester cette PR !

@calummackervoy calummackervoy added this pull request to the merge queue Sep 3, 2024
@calummackervoy calummackervoy removed this pull request from the merge queue due to a manual request Sep 3, 2024
Copy link
Contributor

@tonial tonial left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En fait, j'ai pensé à une amélioration pour éviter que le problème se produise sur d'autres SSO dans le futur ^^

itou/openid_connect/models.py Show resolved Hide resolved
itou/openid_connect/models.py Outdated Show resolved Hide resolved
@@ -124,6 +133,8 @@ def create_or_update_user(self, is_login=False):
self.check_valid_kind(user, user_data_dict, is_login)
# Don't update a user handled by another SSO provider.
return user, created
if user.identity_provider == self.identity_provider:
self.handle_email_overloaded_on_new_identity(user)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je te propose finalement de directement mettre ici le raise EmailInUseException car si jamais un autre SSO s'amuse à faire pareil on voudra empêcher que le problème s'y produise aussi

Copy link
Contributor Author

@calummackervoy calummackervoy Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ça va casser quelques comportements existants, comme par example :

If there already is an existing user from InclusionConnect with this email, but under another username, we overwrite the username of the existing account.

J'ai créé handle_email_overloaded_on_new_identity pour que les fournisseurs peuvent choisir leur propre comportement quand il y a un e-mail surchargé, j'aime que cette proposition impacte au minimum les autres SSO dans le cadre de ce ticket ?

Copy link
Contributor

@tonial tonial Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there already is an existing user from InclusionConnect with this email, but under another username, we overwrite the username of the existing account.

Non, dans ce cas là, on a une erreur qui indique à l'utilisateur que l'email est déjà utilisé.
Il vient d'où cet exemple ?

Dans un SSO Openid Connect, la clé d'identification unique d'un utilisateur est le sub (qu'on stocke dans le username chez nous).
Donc si l'utilisateur qui a le même email, a le meme identity provider mais un sub différent, c'est un utilisateur différent.
C'est le problème qu'on a sur pe_connect, et c'est une erreur de notre code que l'on cherche à corriger ici, pour tous les sub.

Donc si tu regardes le code :

  1. d'abord on cherche un utilisateur qui a le sub renvoyé par le SSO
    user = User.objects.get(username=self.username, identity_provider=self.identity_provider)
    S'il existe, on met à jour ses infos avec celles du SSO.

  2. Sinon, on cherche un utilisateur qui a le même email
    Si c'est un utilisateur django, on le converti en utilisateur de self.identity_provider
    si c'est un utilisateur d'un autre SSO, on accepte de le connecter, sans le changer
    Si c'est un utilisateur du même SSO c'est un problème (c'est le bug que tu corriges)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK ! Merci pour le détail. J'ai modifié divers tests échouants sur le signup - je pense que ces tests passaient mais sans l'état préliminaire prévu

itou/users/models.py Show resolved Hide resolved
itou/openid_connect/pe_connect/views.py Outdated Show resolved Hide resolved
@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 1aab8ac to 4c132f8 Compare September 4, 2024 14:37
@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 4c132f8 to 8a1532a Compare September 4, 2024 14:39
@calummackervoy calummackervoy removed the 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC label Sep 4, 2024
itou/openid_connect/models.py Outdated Show resolved Hide resolved
if predicate:
return value

return " ".join(part[0] + "…" for part in re.split(f"[{re.escape(string.whitespace)}]+", value) if part)
return " ".join(mask_function(part) for part in re.split(f"[{re.escape(string.whitespace)}]+", value) if part)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn, j'avais oublié qu'on avait cette fonction.
Je pense que tu pourrais juste garder mask_unless sans la changer, tant pis pour la dernière lettre des prénoms.noms.

Copy link
Contributor Author

@calummackervoy calummackervoy Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi enlèver le paramètre mask_function, juste pour impacter moins du code ?

Son ajout à ce fonction ne touche pas les utilisations existantes et il nous permet à rendre "P****m N*m" en place de "P… N…", et dans cette utilisation et je pense que ce n'est pas seulement une question d'esthétique - on veut donner assez des indices au utilisateurs qui connaisent le nom de cette personne parmis plusieurs autres possibilités.

Dans les autres cas on pourrait vouloir rédacter tous qu'un <redacted>, et j'avais pensé aussi que dans la prochaine on pourrait paramétrer la génération de liste (re.split) afin de remplacer / simplifier le fonction de redact_email_address et fournir un outil plus évolué etc

last_char = part[-1] if visible_chars > 1 else ""
return part[0] + "*" * (min(len(part) - visible_chars, 10)) + last_char

return mask_unless(f"{self.first_name} {self.last_name}", False, get_mask_for_part)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tu peux mettre un commentaire pour expliquer pourquoi tu n'utilises pas self.get_full_name()

Copy link
Contributor Author

@calummackervoy calummackervoy Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonne rémarque sur le commentaire - du coup je voulais éviter les transformations appliqué par get_full_name - le nom capitalisé et que Mary Sue deviendra M*****e (qui perturberait l'utilisateur dans ce cas)

J'aimais pas qu'on utilise pas le get_full_name dans une méthode appelée get_redacted_full_name... mais je voulais pas parametriser le comportement dans get_full_name. Je pourrais rénommer la fonction, ou le déplacer du modèle à une fonction utilitaire plus spécialisée ?

@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 8a1532a to 9b4b69d Compare September 9, 2024 13:47
@calummackervoy
Copy link
Contributor Author

@tonial mes retours te semble rationnels ?

fix(PoleEmploiConnectUserData): raise EmailInUseException on duplicate emails

France Travail allows users to overload the same email, and we allow only one

feat(pe_connect_callback): catch EmailInUseException

feat: render messages as modals

fix: quality

feat(france_travail_registration_failure.html): redirect to jobseeker registration

fix: tests

feat(users/tests): test_get_redacted_full_name

fix: solution should work for other identity providers

refactor(User.get_redacted_full_name): extend existing utility

fix(pe_connect/views.py): security best practice

fix: remove unused code

fix: requested changes

refactor: move modals messages to modals block
@calummackervoy calummackervoy force-pushed the calum/duplicats-emails-ft-empecher-ecrasement branch from 9b4b69d to ec6500a Compare September 18, 2024 08:44
@tonial
Copy link
Contributor

tonial commented Sep 19, 2024

Désolé, j'ai du manquer la notification, c'est bon pour moi

@calummackervoy calummackervoy added this pull request to the merge queue Sep 19, 2024
Merged via the queue into master with commit 2e309ec Sep 19, 2024
11 checks passed
@calummackervoy calummackervoy deleted the calum/duplicats-emails-ft-empecher-ecrasement branch September 19, 2024 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants