Projet

Général

Profil

Development #69221

backend authn : faire que le backend login/mot de passe accepte le numéro de téléphone de l’usager

Ajouté par Paul Marillonnet il y a plus d'un an. Mis à jour il y a plus d'un an.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
19 septembre 2022
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Du code déjà présent en partie dans #65173, que je dois déplacer ici et accompagner de davantage de tests, diviser pour mieux régner etc.


Fichiers


Demandes liées

Lié à Publik - Development #49212: Création de compte avec un numéro de téléphone mobileEn cours01 octobre 2021

Actions
Lié à Authentic 2 - Development #70486: forms : avoir un champ et son widget pour l’authentification par numéro de téléphoneFermé19 octobre 2022

Actions
Lié à Authentic 2 - Development #72430: authn : lorsqu’actif faire apparaître le champ téléphone au dessus du champ par mot de passeFermé14 décembre 2022

Actions
Lié à Authentic 2 - Development #72440: authn mobile : XOR sur le username/email et le numéro de téléphoneNouveau14 décembre 2022

Actions
Lié à Authentic 2 - Development #72449: authn mobile : conserver le PhoneField custom pour l’enregistrement uniquement, basculer sur un unique champ username/email/tél pour la page de connexionFermé15 décembre 2022

Actions

Révisions associées

Révision f7d6895b (diff)
Ajouté par Paul Marillonnet il y a plus d'un an

authentication/forms: add user phone as identifier (#69221)

Historique

#1

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Lié à Development #49212: Création de compte avec un numéro de téléphone mobile ajouté
#2

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Statut changé de Nouveau à En cours
  • Assigné à mis à Paul Marillonnet
#3

Mis à jour par Paul Marillonnet il y a plus d'un an

La version au plus simple, qui ne nécessite pas de revoir complètement la façon dont on utilise le ModelBackend de Django. Le prix à payer pour ça est encore un peu de magie dans authentic2.forms.authentication.AuthenticationForm. Je pense que ça reste préférable.

Bien sûr en l’état l’affichage est moche, aucune aide à la sélection entre numéro de tél ou username/email, aucune aide à la saisie du numéro ni au choix du préfixe, aucune validation front de ce numéro -> tout ça c’est l’objet du ticket voisin #69222, que je m’empresse d’aller étudier là maintenant :)

#4

Mis à jour par A. Berriot il y a plus d'un an

Ça me parait top, une question : je vois qu'on concatène le phone_prefix et le numéro de téléphone pour construire l'identifiant pour la requête. Ça risque pas de bugger sur des inputs type 0612345678 (avec la concaténation, on aura un +330612345678), à matcher avec potentiellement un +33612345678, sans le zéro ? Il me semble qu'un·e utilisateur aura tendance à taper son numéro avec le 0 comme préfixe mais je peux me tromper.

Plus généralement, peut-être que ça a été déjà discuté ailleurs, comment se passe la normalisation des numéros avant stockage en base ?

À part ces questions, c'est okay pour moi :)

#5

Mis à jour par Thomas Noël il y a plus d'un an

Agate Berriot a écrit :

Ça me parait top, une question : je vois qu'on concatène le phone_prefix et le numéro de téléphone pour construire l'identifiant pour la requête. Ça risque pas de bugger sur des inputs type 0612345678 (avec la concaténation, on aura un +330612345678), à matcher avec potentiellement un +33612345678, sans le zéro ? Il me semble qu'un·e utilisateur aura tendance à taper son numéro avec le 0 comme préfixe mais je peux me tromper.

Agate a raison... bienvenue en enfer, Paul ;)

Je vais ajouter qu'il faut ajouter dans les settings les préfixes des DROM, qui font partie du https://fr.wikipedia.org/wiki/Plan_de_num%C3%A9rotation_en_France (bonne lecture).

#6

Mis à jour par Paul Marillonnet il y a plus d'un an

Agate Berriot a écrit :

Ça me parait top, une question : je vois qu'on concatène le phone_prefix et le numéro de téléphone pour construire l'identifiant pour la requête. Ça risque pas de bugger sur des inputs type 0612345678 (avec la concaténation, on aura un +330612345678), à matcher avec potentiellement un +33612345678, sans le zéro ? Il me semble qu'un·e utilisateur aura tendance à taper son numéro avec le 0 comme préfixe mais je peux me tromper.

Je m’imaginais faire d’abord un truc qui marche pour les numéros français, avec dans #69222 une aide à la saisie lorsque le préfixe français est sélectionné (par exemple en isolant le premier chiffre puis en regroupant deux par deux les huit chiffres suivants, afin que l’usager capte bien que le zéro initial saute). Mais j’ai zappé ce que Thomas met ici et donc il me faut revoir ma copie :)

Sans cette hypothèse, j’avoue que je ne sais pas trop de quelle façon on peut restreindre davantage ici, notamment parce que https://en.wikipedia.org/wiki/Telephone_numbers_in_Belgium, page à laquelle je ne comprends rien :)

Plus généralement, peut-être que ça a été déjà discuté ailleurs, comment se passe la normalisation des numéros avant stockage en base ?

Non, pas discuté ailleurs, et ici et maintenant peut être l’occasion d’en discuter. J’avais en tête de faire dans #69222 un maximum de sanitization de l’input en front, pour réduire au maximum les écarts entre les données collectées par le formulaire et la version stockée en base. Typiquement juste une suite de chiffres sans le zéro initial, qu’on pourrait vérifier facilement ensuite sans normalisation à proprement parler. J’avais peur qu’à tolérer de trop grands écarts on loupe des choses à la normalisation, genre l’usager qui tape un caractère d’espacement exotique (espace semi-fine insécable " ", tirets typographiques "–" ou encore "—", etc.) qui casserait toute l’affaire. Mais peut-être cette approche est une mauvaise idée, on peut en discuter ici.

À part ces questions, c'est okay pour moi :)

Cool, merci pour ta relecture. Je vais avancer sur les autres tickets liés à #49212 pour pouvoir proposer une démo complète avant qu’on envisage passer tous ces patches.

#7

Mis à jour par A. Berriot il y a plus d'un an

Thomas Noël a écrit :

Agate Berriot a écrit :

Ça me parait top, une question : je vois qu'on concatène le phone_prefix et le numéro de téléphone pour construire l'identifiant pour la requête. Ça risque pas de bugger sur des inputs type 0612345678 (avec la concaténation, on aura un +330612345678), à matcher avec potentiellement un +33612345678, sans le zéro ? Il me semble qu'un·e utilisateur aura tendance à taper son numéro avec le 0 comme préfixe mais je peux me tromper.

Agate a raison... bienvenue en enfer, Paul ;)

Je vais ajouter qu'il faut ajouter dans les settings les préfixes des DROM, qui font partie du https://fr.wikipedia.org/wiki/Plan_de_num%C3%A9rotation_en_France (bonne lecture).

Pour moi la solution durable, c'est de prendre une bibliothèque type https://pypi.org/project/phonenumbers/#description et tout normaliser via ce biais avant de stocker ou faire des comparaisons. Ça nous permettra de gérer du même coup les espaces, tirets, tous les formats un peu chelous avec les parenthèses, les préfixes avec + ou les doubles 00. Surtout si on commence à accepter des numéros d'autres pays ou de territoires avec des préfixes ou des structures différentes et qu'on bricole un truc maison, ça va être ingérable.

#8

Mis à jour par Paul Marillonnet il y a plus d'un an

Agate Berriot a écrit :

Pour moi la solution durable, c'est de prendre une bibliothèque type https://pypi.org/project/phonenumbers/#description et tout normaliser via ce biais avant de stocker ou faire des comparaisons. Ça nous permettra de gérer du même coup les espaces, tirets, tous les formats un peu chelous avec les parenthèses, les préfixes avec + ou les doubles 00. Surtout si on commence à accepter des numéros d'autres pays ou de territoires avec des préfixes ou des structures différentes et qu'on bricole un truc maison, ça va être ingérable.

Oui, sûr, surtout ne rien bricoler. Je vais regarder cette bibliothèque, déjà empaquetée dans Debian. Je note aussi que des gens ont fait le taff d’intégration directe de cette bibliothèque nativement dans Django, ça donne https://django-phonenumber-field.readthedocs.io/en/latest/, ça a l’air maintenu et c’est aussi disponible dans les dépôts standards Debian.

#9

Mis à jour par Paul Marillonnet il y a plus d'un an

Paul Marillonnet a écrit :

[…] Je note aussi que des gens ont fait le taff d’intégration directe de cette bibliothèque nativement dans Django, ça donne https://django-phonenumber-field.readthedocs.io/en/latest/, ça a l’air maintenu et c’est aussi disponible dans les dépôts standards Debian.

Et non, raté, packagé que dans sid.

#10

Mis à jour par Frédéric Péters il y a plus d'un an

Et non, raté, packagé que dans sid.

Pas un gros problème ça.

#11

Mis à jour par Paul Marillonnet il y a plus d'un an

Frédéric Péters a écrit :

Pas un gros problème ça.

Ok, noté, je regarde plus en détails.

#12

Mis à jour par Benjamin Dauvergne il y a plus d'un an

Thomas Noël a écrit :

Je vais ajouter qu'il faut ajouter dans les settings les préfixes des DROM, qui font partie du https://fr.wikipedia.org/wiki/Plan_de_num%C3%A9rotation_en_France (bonne lecture).

Ça dit :

Tous les correspondants du territoire national (métropole ou DOM) peuvent s'appeler entre eux en utilisant le plan de numérotation français à dix chiffres, sans composer le code pays pour la voix, les SMS et les MMS. À Saint-Pierre-et-Miquelon, les abonnés peuvent se joindre en composant les six derniers chiffres de leurs numéros. 

je pense que les numéros mobiles sont exposés sur les toutes les indicatifs nationaux du plan de numérotation, donc on peut mettre +33 tout le temps.

#13

Mis à jour par Benjamin Dauvergne il y a plus d'un an

Je suis d'avis de ne rien faire de tout ça, d'accepter seulement ^0[67][0-9]{8}$ et l'équivalent pour la Belgique et d'avoir en dur une fonction pour convertir ça vers le numéro à appeler (et idem à l'enregistrement/la modification).

#14

Mis à jour par Paul Marillonnet il y a plus d'un an

Benjamin Dauvergne a écrit :

Je vais ajouter qu'il faut ajouter dans les settings les préfixes des DROM, qui font partie du https://fr.wikipedia.org/wiki/Plan_de_num%C3%A9rotation_en_France (bonne lecture).

Ça dit :
[...]
je pense que les numéros mobiles sont exposés sur les toutes les indicatifs nationaux du plan de numérotation, donc on peut mettre +33 tout le temps.

Hmm, à lire de la doc ici et là à ce sujet, il est dit que ça marche parce que les opérateurs savent “en général” reconstituer le code pays lorsqu’on tape un numéro à dix chiffres sans préfixe. Donc j’ai l’impression que justement non on ne peut pas mettre +33 tout le temps, l’intelligence est du côté opérateur qui retrouve le code. Quelqu’un a une compréhension différente de l’affaire ?

Est-ce qu’on est sûr que ça va marcher quand on a recours à un service tiers d’envoi de SMS ? Notamment est-ce que ces services acceptent systématiquement d’envoyer à numéros à dix chiffres sans mention du code pays ? Ou bien est-ce à nous de retrouver ce code avant l’appel au service d’envoi (auquel cas il faut aller dans le sens de ce que propose Agate) ?

Bref trop d’interrogations, avant de poursuivre je dois me renseigner là-dessus.

#15

Mis à jour par A. Berriot il y a plus d'un an

Paul Marillonnet a écrit :

Benjamin Dauvergne a écrit :

Je vais ajouter qu'il faut ajouter dans les settings les préfixes des DROM, qui font partie du https://fr.wikipedia.org/wiki/Plan_de_num%C3%A9rotation_en_France (bonne lecture).

Ça dit :
[...]
je pense que les numéros mobiles sont exposés sur les toutes les indicatifs nationaux du plan de numérotation, donc on peut mettre +33 tout le temps.

Hmm, à lire de la doc ici et là à ce sujet, il est dit que ça marche parce que les opérateurs savent “en général” reconstituer le code pays lorsqu’on tape un numéro à dix chiffres sans préfixe. Donc j’ai l’impression que justement non on ne peut pas mettre +33 tout le temps, l’intelligence est du côté opérateur qui retrouve le code. Quelqu’un a une compréhension différente de l’affaire ?

Est-ce qu’on est sûr que ça va marcher quand on a recours à un service tiers d’envoi de SMS ? Notamment est-ce que ces services acceptent systématiquement d’envoyer à numéros à dix chiffres sans mention du code pays ? Ou bien est-ce à nous de retrouver ce code avant l’appel au service d’envoi (auquel cas il faut aller dans le sens de ce que propose Agate) ?

Bref trop d’interrogations, avant de poursuivre je dois me renseigner là-dessus.

Pour moi, si on doit s'interfacer avec des services / APIs tiers type Twilio ou SMS Factor, c'est quasiment sûr qu'il faudra un format unique et standard avec le prefixe (par exemple sms factor demande le prefixe 33 pour la france métropolitaine et si je me base sur https://www.smsfactor.com/tarifs-api-sms, il y a un pricing différent pour la Guyane ou la Réunion, et ça m'étonnerait fortement qu'ils fassent de la magie pour reconnaître quoi envoyer où si on ne fournit pas le bon indicateur pays).

#16

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Statut changé de Solution proposée à En cours

Agate Berriot a écrit :

Pour moi, si on doit s'interfacer avec des services / APIs tiers type Twilio ou SMS Factor, c'est quasiment sûr qu'il faudra un format unique et standard avec le prefixe (par exemple sms factor demande le prefixe 33 pour la france métropolitaine et si je me base sur https://www.smsfactor.com/tarifs-api-sms, il y a un pricing différent pour la Guyane ou la Réunion, et ça m'étonnerait fortement qu'ils fassent de la magie pour reconnaître quoi envoyer où si on ne fournit pas le bon indicateur pays).

Oui c’est ma compréhension de l’affaire, je vais partir là-dessus.

J’ai poussé une branche qui reprend le premier patche mais avec l’usage d’un MultiValueField de Django, avec son MultiWidget qui va avec. Ça simplifie le code du formulaire et facilitera l’usage de phonenumbers. Je reprends ça demain.

#17

Mis à jour par Paul Marillonnet il y a plus d'un an

Paul Marillonnet a écrit :

J’ai poussé une branche qui reprend le premier patche mais avec l’usage d’un MultiValueField de Django, avec son MultiWidget qui va avec. Ça simplifie le code du formulaire et facilitera l’usage de phonenumbers. Je reprends ça demain.

Voilà, ça simplifie les choses en effet, en particulier l’usage de phonenumbers, la possibilité de réutiliser cette class PhoneField(MultiValueField): pour l’enregistrement du compte de l’usager, et le travail d’affichage du champ à l’usager (#69222).

#18

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à En cours
  • je ne suis pas pour l'ajout d'un PhoneField dans LoginForm, ça complexifie, il faut prendre n'importe quelle entrée qui ressemble à un numéro de téléphone, éventuellement la normaliser et chercher la desssus (comme on peut le faire en recherche libre sur les utilisateur).
  • le PhoneField devrait sélectionner le pays par défaut
  • le champ indicatif devrait rappeler le territoire avant l'indicatif "Guyane française (+xxx)", y a peut-être moyen d'extraire ça de libphonenumber d'aillerus
#19

Mis à jour par Benjamin Dauvergne il y a plus d'un an

On peut peut-être poussé tout ce qui est widget/field ici, et garder les aspects formulaire d'authent dans un autre ticket, pour avancer.

#20

Mis à jour par Paul Marillonnet il y a plus d'un an

Benjamin Dauvergne a écrit :

On peut peut-être poussé tout ce qui est widget/field ici, et garder les aspects formulaire d'authent dans un autre ticket, pour avancer.

Ok, je fais un autre ticket.

#21

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Lié à Development #70486: forms : avoir un champ et son widget pour l’authentification par numéro de téléphone ajouté
#22

Mis à jour par Paul Marillonnet il y a plus d'un an

Benjamin Dauvergne a écrit :

  • je ne suis pas pour l'ajout d'un PhoneField dans LoginForm, ça complexifie,

L’idée est de faire dans #69222 le travail en front de simplification, avoir un switch pour que l’un ou l’autre des champs email et téléphone s’affiche à l’usager dans la mire d’authentification, mais pas les deux à là fois.

  • le PhoneField devrait sélectionner le pays par défaut

Ok.

  • le champ indicatif devrait rappeler le territoire avant l'indicatif "Guyane française (+xxx)", y a peut-être moyen d'extraire ça de libphonenumber d'aillerus

Ok.

#23

Mis à jour par Paul Marillonnet il y a plus d'un an

Paul Marillonnet a écrit :

  • le PhoneField devrait sélectionner le pays par défaut

Ok.

Dans le champ PhoneField :

    def __init__(self, **kwargs):
        fields = (
            CharField(max_length=8, initial=settings.DEFAULT_COUNTRY_CODE),
            # […]
        )

  • le champ indicatif devrait rappeler le territoire avant l'indicatif "Guyane française (+xxx)", y a peut-être moyen d'extraire ça de libphonenumber d'aillerus

Ok.

Dans le widget associé, PhoneWidget :

        prefixes = (
            (code, '{area} (+{code})'.format(area=value['area'], code=code))
            for code, value in settings.PHONE_COUNTRY_CODES.items()
        )

et dans les settings :
PHONE_COUNTRY_CODES = {
    '32': {'lang': 'BE', 'area': _('Belgium')},
    '33': {'lang': 'FR', 'area': _('Metropolitan France')},
    '262': {'lang': 'FR', 'area': _('Réunion')},
    '508': {'lang': 'FR', 'area': _('Saint Pierre and Miquelon')},
    '590': {'lang': 'FR', 'area': _('Guadeloupe')},
    '594': {'lang': 'FR', 'area': _('French Guiana')},
    '596': {'lang': 'FR', 'area': _('Martinique')},
}

#24

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à Solution validée
#25

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Statut changé de Solution validée à Résolu (à déployer)
commit f7d6895b94a102abdcace776366e4a41d9942559
Author: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date:   Mon Sep 19 09:52:12 2022 +0200

    authentication/forms: add user phone as identifier (#69221)
#26

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Lié à Development #72430: authn : lorsqu’actif faire apparaître le champ téléphone au dessus du champ par mot de passe ajouté
#27

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Lié à Development #72440: authn mobile : XOR sur le username/email et le numéro de téléphone ajouté
#28

Mis à jour par Paul Marillonnet il y a plus d'un an

  • Lié à Development #72449: authn mobile : conserver le PhoneField custom pour l’enregistrement uniquement, basculer sur un unique champ username/email/tél pour la page de connexion ajouté
#29

Mis à jour par Transition automatique il y a plus d'un an

  • Statut changé de Résolu (à déployer) à Solution déployée
#30

Mis à jour par Transition automatique il y a environ un an

Automatic expiration

Formats disponibles : Atom PDF