-
Notifications
You must be signed in to change notification settings - Fork 25
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
Connexion: Renvoie de e-mail de confirmation #5428
base: master
Are you sure you want to change the base?
Conversation
Remove direct use of EmailAddress for verification
For creating a user with an unverified EmailAddress
Testing redirect and authentication behavior during email confirmation
Add ResendConfirmationView which triggers the sending of new confirmation emails if provided an expired confirmation. Adapt ConfirmEmailView so that a link to the resend view can be provided directly
Prevent a user from being able to trigger more than 3 emails to a given email address daily, to limit misuse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je ne comprends pas bien pourquoi on ajoute des fonctionnalités à allauth avant de le remplacer ? Je m’attendais à ce qu’on remplace des fonctionnalités existantes. Si une fonctionnalité n’est actuellement pas supportée, pourquoi ne pas attendre d’avoir fait la migration pour l’implémenter ?
En l’état, je ne vois pas en quoi cette PR nous facilite la transition pour quitter allauth ?
@@ -339,6 +340,7 @@ | |||
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True | |||
ACCOUNT_USERNAME_REQUIRED = False | |||
ACCOUNT_USER_DISPLAY = "itou.users.models.get_allauth_account_user_display" | |||
ACCOUNT_MAX_DAILY_EMAIL_CONFIRMATION_REQUESTS = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Peut-être être un poil plus généreux, histoire d’éviter de la charge au support ? J’imagine que 20 ne posera pas de problème de sécurité.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK pour moi !
pk = signing.loads(key, salt=app_settings.SALT) | ||
return EmailConfirmationHMAC(EmailAddress.objects.get(pk=pk, verified=False)).email_address | ||
except ( | ||
signing.SignatureExpired, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On ne veut pas traiter différemment SignatureExpired
pour continuer à afficher la possibilité de renvoyer un email de confirmation ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oui, bien vu
En fait ce serait jamais enlévé car j'ai rétiré le paramètre expiration - je devrais rétirer l'exception aussi
raise Http404() | ||
|
||
|
||
class ConfirmEmailView(BaseConfirmEmailView, ExpiredConfirmationMixin): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Les mixins devraient être avant les classes concrètes pour éviter des surprises dans la MRO.
try: | ||
self.get_object_with_expired_key() # Raises error for invalid keys. | ||
key = self.kwargs["key"] | ||
except Http404: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pourquoi utiliser une Http404 si on ne veut pas afficher de 404 à l’utilisateur ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C'est du code copié de django-allauth. J'ai considéré des autres exceptions sans remarquer qu'on pourrait juste répondre None
dans get_object_with_expired_key()
🤦
key = self.kwargs["key"] | ||
except Http404: | ||
key = None | ||
context.update({"provided_key": key}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plus clair et plus performant.
context.update({"provided_key": key}) | |
context["provided_key"] = key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bien sûr 😅 merci
if ( | ||
Email.objects.filter( | ||
to__contains=[email_address.email], | ||
created_at__gte=this_morning, | ||
subject__icontains=confirmation_subject_query, | ||
).count() | ||
>= settings.ACCOUNT_MAX_DAILY_EMAIL_CONFIRMATION_REQUESTS | ||
): | ||
return redirect(reverse("account_email_rate_limit_exceeded")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Humpf. On a Redis pour implémenter des rate limiting. Demander à la DB de filtrer sur une table avec des millions d’entrées me semble coûteux et complexe, se baser sur le sujet de l’email me semble très instable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
En reflexion t'as raison, je vais suggerer une nouvelle solution en utilisant le cache. Je vois que le cache est utilisé par des autres solutions rate limiting et au bout d'un jour, ces données ne sont plus intéressantes. Je suis sous l'impression qu'on a bien besoin de logique sur mesure pour ce besoin.
J'avais ces deux concernes, je pensais qu'avec l'indexe sur le champ to
ce ne serait pas si couteux mais je n'ai pas testé. Autrement le test va se planter si le contenu du sujet change, je pense que cette partie est stable en practique (même si c'est un peu hacky).
|
||
# Do not send a confirmation to a verified address. | ||
if email_address.verified: | ||
return self.fail() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On devrait ajouter un message pour indiquer que l’email est déjà vérifié.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On devrait ajouter un message pour indiquer que l’email est déjà vérifié.
C'est une bonne idée merci.
En ce moment si un utilisateur manque la fenêtre de son e-mail de confirmation il ne peut plus le valider, je pense que c'est un bug qui est à l'extérieur du cadre remplacer allauth ? La façon dont j'ai corrigé a un oeil sur le PR supprimer django-allauth, j'ai besoin de supprimer nos utilisations du |
🤔 Pourquoi ?
Actuellement, si je m'inscris sur le site, mais que je confirme mon courriel après son expiration (dans 3 jours, par défaut), je verrai apparaître la page indiquant que le jeton n'est pas valide. Si je clique sur « nouvelle demande de confirmation », je serai en fait redirigé vers la page de connexion, ce qui est également le comportement par défaut d'allauth. Ceci peut arriver pour les nouveaux utilisateurs, mais aussi pour les utilisateurs qui a changé leur adresse e-mail.
🍰 Comment ?
Dans le cadre de mes travails à remplacer django-allauth avec notre propre logique, j'ai proposé stocké la logique dans une nouvelle application,
accounts
. J'ai l'intention de continuer à étendre cette application dans des futurs PRs afin de préparer le remplacement d'allauth et réduire la taille du PR qui va aufin le supprimer.Je ne peux pas réutiliser les liens de confirmation, et je ne suis pas connecté avec le lien de confirmation.
🚨 À vérifier
🏝️ Comment tester
Tu peux créer une confirmation expirée dans le shell et visiter l'URL récupéré :
💻 Captures d'écran
Lien de confirmation invalide :
Lien de confirmation expiré :
Reconfirmation envoyée :