8
0
Fork 0
mirror of https://gitlab.federez.net/re2o/re2o synced 2024-07-07 06:34:06 +00:00

Start implementing user-facing confirmation email mechanics

This commit is contained in:
Jean-Romain Garnier 2020-04-17 00:24:35 +02:00 committed by Jean-Romain Garnier
parent d4380f866f
commit b91efa3d29
6 changed files with 74 additions and 3 deletions

View file

@ -299,6 +299,11 @@ class ResetPasswordForm(forms.Form):
email = forms.EmailField(max_length=255) email = forms.EmailField(max_length=255)
class ResendConfirmationEmailForm(forms.Form):
"""Formulaire de renvoie du mail de confirmation"""
pass
class MassArchiveForm(forms.Form): class MassArchiveForm(forms.Form):
"""Formulaire d'archivage des users inactif. Prend en argument """Formulaire d'archivage des users inactif. Prend en argument
du formulaire la date de depart avant laquelle archiver les du formulaire la date de depart avant laquelle archiver les
@ -344,6 +349,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
self.fields["room"].label = _("Room") self.fields["room"].label = _("Room")
self.fields["room"].empty_label = _("No room") self.fields["room"].empty_label = _("No room")
self.fields["school"].empty_label = _("Select a school") self.fields["school"].empty_label = _("Select a school")
self.initial["email"] = kwargs["instance"].email
class Meta: class Meta:
model = Adherent model = Adherent
@ -390,6 +396,22 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
remove_user_room(room) remove_user_room(room)
return return
def save(self, commit=True):
"""On met à jour l'état de l'utilisateur en fonction de son mail"""
user = super(AdherentForm, self).save(commit=False)
if user.email != self.initial["email"]:
# Send a confirmation email
if user.state in [User.STATE_ACTIVE, User.STATE_DISABLED, User.STATE_NOT_YET_ACTIVE, User.STATE_EMAIL_NOT_YET_CONFIRMED]:
user.state = User.STATE_EMAIL_NOT_YET_CONFIRMED
user.confirm_email_address_mail()
# Always keep the oldest change date
if user.email_change_date is None:
user.email_change_date = timezone.now()
return user
class AdherentCreationForm(AdherentForm): class AdherentCreationForm(AdherentForm):
"""Formulaire de création d'un user. """Formulaire de création d'un user.

View file

@ -34,7 +34,8 @@ class Command(BaseCommand):
days = OptionalUser.get_cached_value("disable_emailnotyetconfirmed") days = OptionalUser.get_cached_value("disable_emailnotyetconfirmed")
users_to_disable = ( users_to_disable = (
User.objects.filter(state=User.STATE_EMAIL_NOT_YET_CONFIRMED) User.objects.filter(state=User.STATE_EMAIL_NOT_YET_CONFIRMED)
.filter(registered__lte=timezone.now() - timedelta(days=days)) .exclude(email_change_date__is_null=True)
.filter(email_change_date__lte=timezone.now() - timedelta(days=days))
.distinct() .distinct()
) )
print("Disabling " + str(users_to_disable.count()) + " users.") print("Disabling " + str(users_to_disable.count()) + " users.")

View file

@ -226,6 +226,7 @@ class User(
shortcuts_enabled = models.BooleanField( shortcuts_enabled = models.BooleanField(
verbose_name=_("enable shortcuts on Re2o website"), default=True verbose_name=_("enable shortcuts on Re2o website"), default=True
) )
email_change_date = None
USERNAME_FIELD = "pseudo" USERNAME_FIELD = "pseudo"
REQUIRED_FIELDS = ["surname", "email"] REQUIRED_FIELDS = ["surname", "email"]
@ -879,7 +880,10 @@ class User(
def confirm_mail(self): def confirm_mail(self):
"""Marque l'email de l'utilisateur comme confirmé""" """Marque l'email de l'utilisateur comme confirmé"""
# Let the "set_active" method handle # Reset the email change date
self.email_change_date = None
# Let the "set_active" method handle the rest
self.state = self.STATE_NOT_YET_ACTIVE self.state = self.STATE_NOT_YET_ACTIVE
self.set_active() self.set_active()

View file

@ -38,7 +38,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<h2>{% blocktrans with name=users.name surname=users.surname %}Profile of {{ name }} {{ surname }}{% endblocktrans %}</h2> <h2>{% blocktrans with name=users.name surname=users.surname %}Profile of {{ name }} {{ surname }}{% endblocktrans %}</h2>
{% endif %} {% endif %}
</div> </div>
<div class="dashboard_container"> <div class="dashboard_container">
{% if users.state == Users.STATE_NOT_YET_ACTIVE %}
<h2>{% blocktrans with name=users.name surname=users.surname %}Welcome {{ name }} {{ surname }}{% endblocktrans %}</h2>
{% else %}
<h2>{% blocktrans with name=users.name surname=users.surname %}Profile of {{ name }} {{ surname }}{% endblocktrans %}</h2>
{% endif %}
</div>
<div class="dashboard_container">
{% if users.state == Users.STATE_NOT_YET_ACTIVE %}
<div class="row">
<div class="alert alert-warning">
{% blocktrans %}Please confirm your email address{% endblocktrans %}
<br/>
<a href="{% url 'users:resend-confirmation-email' users.id %}">
{% blocktrans %}Resend the email{% endblocktrans %}
</a>
</div>
</div>
{% elif users.state == Users.STATE_DISABLED %}
<div class="row">
<div class="alert alert-danger">
{% blocktrans %}Your account has been disabled{% endblocktrans %}
</div>
</div>
{% endif %}
<div class="row"> <div class="row">
<div class="col-sm-6 {% if solde_activated %}col-md-4{% else %}col_md-6{% endif %}"> <div class="col-sm-6 {% if solde_activated %}col-md-4{% else %}col_md-6{% endif %}">
{% if users.is_ban%} {% if users.is_ban%}
@ -181,7 +210,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="col-md-6"> <div class="col-md-6">
<dt>{% trans "Email address" %}</dt> <dt>{% trans "Email address" %}</dt>
<dd><a href="mailto:{{ users.email }}">{{ users.email }}</a></dd> <dd><a href="mailto:{{ users.email }}">{{ users.email }}</a>{% if users.email_change_date is not None %}<i class="text-danger">{% trans "Pending confirmation..." %}</i>{% endif %}</dd>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">

View file

@ -42,6 +42,7 @@ urlpatterns = [
url(r"^state/(?P<userid>[0-9]+)$", views.state, name="state"), url(r"^state/(?P<userid>[0-9]+)$", views.state, name="state"),
url(r"^groups/(?P<userid>[0-9]+)$", views.groups, name="groups"), url(r"^groups/(?P<userid>[0-9]+)$", views.groups, name="groups"),
url(r"^password/(?P<userid>[0-9]+)$", views.password, name="password"), url(r"^password/(?P<userid>[0-9]+)$", views.password, name="password"),
url(r"^confirm_email/(?P<userid>[0-9]+)$", views.resend_confirmation_email, name="resend-confirmation-email"),
url( url(
r"^del_group/(?P<userid>[0-9]+)/(?P<listrightid>[0-9]+)$", r"^del_group/(?P<userid>[0-9]+)/(?P<listrightid>[0-9]+)$",
views.del_group, views.del_group,

View file

@ -107,6 +107,7 @@ from .forms import (
PassForm, PassForm,
ConfirmMailForm, ConfirmMailForm,
ResetPasswordForm, ResetPasswordForm,
ResendConfirmationEmailForm,
ClubAdminandMembersForm, ClubAdminandMembersForm,
GroupForm, GroupForm,
InitialRegisterForm, InitialRegisterForm,
@ -1023,6 +1024,19 @@ def process_passwd(request, req):
) )
def resend_confirmation_email(request):
""" Renvoie du mail de confirmation """
userform = ResendConfirmationEmailForm(request.POST or None)
if userform.is_valid():
request.user.confirm_email_address_mail()
messages.success(request, _("An email to confirm your address was sent."))
return redirect(reverse("index"))
return form(
{"userform": userform, "action_name": _("Send")}, "users/user.html", request
)
def confirm_email(request, token): def confirm_email(request, token):
"""Lien pour la confirmation de l'email""" """Lien pour la confirmation de l'email"""
valid_reqs = Request.objects.filter(expires_at__gt=timezone.now()) valid_reqs = Request.objects.filter(expires_at__gt=timezone.now())