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

Rajout de champ mot de passe aux pages de Désinscription et de changements d'email #6334

Merged
merged 5 commits into from
Jul 30, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions templates/member/settings/unregister.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "member/settings/base.html" %}
{% load i18n %}

{% load crispy_forms_tags %}

{% block breadcrumb %}
<li>{% trans "Désinscription" %}</li>
Expand Down Expand Up @@ -89,17 +89,5 @@
<a href="#unregister" class="open-modal btn btn-cancel">{% trans "Me désinscrire" %}</a>
</p>

<form
method="post"
action="{% url "member-unregister" %}"
id="unregister"
class="modal modal-flex"
>
<p>
{% trans "C’est votre dernière chance de rester parmi nous" %}...
</p>

{% csrf_token %}
<button type="submit" class="btn btn-submit">{% trans "Me désinscrire" %}</button>
</form>
{% crispy unregister_form %}
{% endblock %}
60 changes: 39 additions & 21 deletions zds/member/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
validate_zds_password,
validate_raw_zds_username,
)
from zds.utils.forms import IncludeEasyMDE
from zds.utils.forms import IncludeEasyMDE, PasswordRequiredForm
from zds.utils.misc import contains_utf8mb4
from zds.utils.models import Licence, HatRequest, Hat
from zds.utils import get_current_user
Expand Down Expand Up @@ -366,7 +366,7 @@ def __init__(self, *args, **kwargs):
)


class ChangeUserForm(forms.Form):
class ChangeUserForm(PasswordRequiredForm):
"""
Update username and email
"""
Expand Down Expand Up @@ -402,13 +402,16 @@ def __init__(self, user, *args, **kwargs):
self.previous_username = user.username
self.fields["options"].initial = ""

self.user = user

if user.profile and user.profile.show_email:
self.fields["options"].initial += "show_email"

self.helper.layout = Layout(
Field("username", value=user.username),
Field("email", value=user.email),
Field("options"),
Field("password"),
ButtonHolder(
StrictButton(_("Enregistrer"), type="submit"),
),
Expand All @@ -430,13 +433,40 @@ def clean(self):
return cleaned_data


# TODO: Updates the password --> requires a better name
class ChangePasswordForm(forms.Form):
class UnregisterForm(PasswordRequiredForm):
"""
Unregister form
"""

password_old = forms.CharField(
label=_("Mot de passe actuel"),
widget=forms.PasswordInput,
)
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = "unregister"
self.helper.form_class = "modal modal-flex"
self.helper.form_method = "post"
self.helper.form_action = reverse("member-unregister")

self.user = user

self.helper.layout = Layout(
Field("password"),
HTML(
_(
"""
<p>
C’est votre dernière chance de rester parmi nous ...
</p>
"""
)
),
ButtonHolder(
StrictButton(_("Me désinscrire"), type="submit"),
),
)


# TODO: Updates the password --> requires a better name
class ChangePasswordForm(PasswordRequiredForm):

password_new = forms.CharField(
label=_("Nouveau mot de passe"),
Expand All @@ -461,7 +491,7 @@ def __init__(self, user, *args, **kwargs):
self.user = user

self.helper.layout = Layout(
Field("password_old"),
Field("password"),
Field("password_new"),
Field("password_confirm"),
ButtonHolder(
Expand All @@ -471,18 +501,6 @@ def __init__(self, user, *args, **kwargs):

def clean(self):
cleaned_data = super().clean()

password_old = cleaned_data.get("password_old")

# Check if the actual password is not empty
if password_old:
user_exist = authenticate(username=self.user.username, password=password_old)
# Check if the user exist with old informations.
if not user_exist and password_old != "":
self._errors["password_old"] = self.error_class([_("Mot de passe incorrect.")])
if "password_old" in cleaned_data:
del cleaned_data["password_old"]

return validate_passwords(cleaned_data, password_label="password_new", username=self.user.username)


Expand Down
59 changes: 44 additions & 15 deletions zds/member/tests/tests_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
NewPasswordForm,
KarmaForm,
UsernameAndEmailForm,
UnregisterForm,
)
from zds.member.models import BannedEmailProvider
from zds.member.tests.factories import StaffProfileFactory
Expand Down Expand Up @@ -163,6 +164,21 @@ def test_username_slash_register_form(self):
self.assertFalse(form.is_valid())


class UnregisterFormTest(TestCase):
"""
Check the unregistering form.
"""

def setUp(self):
self.user1 = ProfileFactory()

def test_password_is_required(self):
data = {}
form = UnregisterForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())
self.assertIn("password", form.errors.keys())


class MiniProfileFormTest(TestCase):
"""
Check the miniprofile form.
Expand Down Expand Up @@ -235,58 +251,59 @@ def setUp(self):
self.user2 = ProfileFactory()

def test_valid_change_username_user_form(self):
data = {"username": "MyNewPseudo", "email": self.user1.user.email}
data = {"username": "MyNewPseudo", "email": self.user1.user.email, "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertTrue(form.is_valid())

def test_valid_change_email_user_form(self):
data = {"username": self.user1.user.username, "email": "test@gmail.com"}
data = {"username": self.user1.user.username, "email": "test@gmail.com", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertTrue(form.is_valid())

def test_already_used_username_user_form(self):
data = {"username": self.user2.user.username, "email": self.user1.user.email}
data = {"username": self.user2.user.username, "email": self.user1.user.email, "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_already_used_email_user_form(self):
data = {"username": self.user1.user.username, "email": self.user2.user.email}
data = {"username": self.user1.user.username, "email": self.user2.user.email, "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_forbidden_email_provider_user_form(self):
moderator = StaffProfileFactory().user
if not BannedEmailProvider.objects.filter(provider="yopmail.com").exists():
BannedEmailProvider.objects.create(provider="yopmail.com", moderator=moderator)
data = {"username": self.user1.user.username, "email": "test@yopmail.com"}
data = {"username": self.user1.user.username, "email": "test@yopmail.com", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_wrong_email_user_form(self):
data = {"username": self.user1.user.username, "email": "wrong@"}
data = {"username": self.user1.user.username, "email": "wrong@", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

data = {"username": self.user1.user.username, "email": "@test.com"}
data = {"username": self.user1.user.username, "email": "@test.com", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

data = {"username": self.user1.user.username, "email": "wrong@test"}
data = {"username": self.user1.user.username, "email": "wrong@test", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

data = {"username": self.user1.user.username, "email": "wrong@.com"}
data = {"username": self.user1.user.username, "email": "wrong@.com", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

data = {"username": self.user1.user.username, "email": "wrongtest.com"}
data = {"username": self.user1.user.username, "email": "wrongtest.com", "password": "hostel77"}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_username_spaces_register_form(self):
ProfileFactory()
data = {
"username": " ZeTester ",
"password": "hostel77",
"email": self.user1.user.email,
}
form = ChangeUserForm(data=data, user=self.user1.user)
Expand All @@ -296,6 +313,7 @@ def test_username_coma_register_form(self):
ProfileFactory()
data = {
"username": "Ze,Tester",
"password": "hostel77",
"email": self.user1.user.email,
}
form = ChangeUserForm(data=data, user=self.user1.user)
Expand All @@ -305,10 +323,21 @@ def test_username_slash_changeuser_form(self):
ProfileFactory()
data = {
"username": "Ze/Tester",
"password": "hostel77",
"email": self.user1.user.email,
}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_password_is_required(self):
ProfileFactory()
data = {
"username": "ZeTester",
"email": self.user1.user.email,
}
form = ChangeUserForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())
self.assertIn("password", form.errors.keys())


class ChangePasswordFormTest(TestCase):
Expand All @@ -323,33 +352,33 @@ def setUp(self):

def test_valid_change_password_form(self):
data = {
"password_old": self.old_password,
"password": self.old_password,
"password_new": self.new_password,
"password_confirm": self.new_password,
}
form = ChangePasswordForm(data=data, user=self.user1.user)
self.assertTrue(form.is_valid())

def test_old_wrong_change_password_form(self):
data = {"password_old": "Wronnnng", "password_new": self.new_password, "password_confirm": self.new_password}
data = {"password": "Wronnnng", "password_new": self.new_password, "password_confirm": self.new_password}
form = ChangePasswordForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_not_matching_change_password_form(self):
data = {"password_old": self.old_password, "password_new": self.new_password, "password_confirm": "Wronnnng"}
data = {"password": self.old_password, "password_new": self.new_password, "password_confirm": "Wronnnng"}
form = ChangePasswordForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_too_short_change_password_form(self):
too_short = "short"
data = {"password_old": self.old_password, "password_new": too_short, "password_confirm": too_short}
data = {"password": self.old_password, "password_new": too_short, "password_confirm": too_short}
form = ChangePasswordForm(data=data, user=self.user1.user)
self.assertFalse(form.is_valid())

def test_match_username_change_password_form(self):
self.user1.user.username = "LongName"
data = {
"password_old": self.old_password,
"password": self.old_password,
"password_new": self.user1.user.username,
"password_confirm": self.user1.user.username,
}
Expand Down
2 changes: 1 addition & 1 deletion zds/member/tests/views/tests_emailproviders.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_new_provider_with_email_edit(self):
# Edit the email with an unknown provider
self.client.post(
reverse("update-username-email-member"),
{"username": user.username, "email": "test@unknown-provider-edit.com"},
{"username": user.username, "email": "test@unknown-provider-edit.com", "password": "hostel77"},
follow=False,
)
# A new provider object should have been created
Expand Down
2 changes: 1 addition & 1 deletion zds/member/tests/views/tests_moderation.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def test_karma_and_pseudo_change(self):
tester = ProfileFactory()
old_pseudo = tester.user.username
self.client.force_login(tester.user)
data = {"username": "dummy", "email": tester.user.email}
data = {"username": "dummy", "email": tester.user.email, "password": "hostel77"}
result = self.client.post(reverse("update-username-email-member"), data, follow=False)

self.assertEqual(result.status_code, 302)
Expand Down
6 changes: 3 additions & 3 deletions zds/member/tests/views/tests_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ def test_unregister(self):

# test not logged user can't unregister.
self.client.logout()
result = self.client.post(reverse("member-unregister"), follow=False)
result = self.client.post(reverse("member-unregister"), {"password": "hostel77"}, follow=False)
self.assertEqual(result.status_code, 302)

# test logged user can unregister.
user = ProfileFactory()
self.client.force_login(user.user)
result = self.client.post(reverse("member-unregister"), follow=False)
result = self.client.post(reverse("member-unregister"), {"password": "hostel77"}, follow=False)
self.assertEqual(result.status_code, 302)
self.assertEqual(User.objects.filter(username=user.user.username).count(), 0)

Expand Down Expand Up @@ -190,7 +190,7 @@ def test_unregister(self):

# login and unregister:
self.client.force_login(user.user)
result = self.client.post(reverse("member-unregister"), follow=False)
result = self.client.post(reverse("member-unregister"), {"password": "hostel77"}, follow=False)
self.assertEqual(result.status_code, 302)

# check that the bot have taken authorship of tutorial:
Expand Down
17 changes: 15 additions & 2 deletions zds/member/views/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
ProfileCreate,
TokenGenerator,
)
from zds.member.forms import RegisterForm, UsernameAndEmailForm, LoginForm
from zds.member.forms import RegisterForm, UsernameAndEmailForm, LoginForm, UnregisterForm
from zds.member.models import (
Profile,
TokenRegister,
Expand Down Expand Up @@ -158,7 +158,10 @@ def warning_unregister(request):
Display a warning page showing what will happen when the user
unregisters.
"""
return render(request, "member/settings/unregister.html", {"user": request.user})
unregister_form = UnregisterForm(request.user)
return render(
request, "member/settings/unregister.html", {"user": request.user, "unregister_form": unregister_form}
)


@login_required
Expand All @@ -167,6 +170,16 @@ def warning_unregister(request):
def unregister(request):
"""Allow members to unregister."""

unregister_form = UnregisterForm(request.user, data=request.POST)

if not unregister_form.is_valid():
for field, errors in unregister_form.errors.items():
for error in errors:
messages.error(request, error)
return render(
request, "member/settings/unregister.html", {"user": request.user, "unregister_form": unregister_form}
)

anonymous = get_object_or_404(User, username=settings.ZDS_APP["member"]["anonymous_account"])
external = get_object_or_404(User, username=settings.ZDS_APP["member"]["external_account"])
current = request.user
Expand Down
Loading