diff --git a/zds/member/forms.py b/zds/member/forms.py index 1f1dbccd69..1002d5fd81 100644 --- a/zds/member/forms.py +++ b/zds/member/forms.py @@ -13,7 +13,7 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Layout, Submit, Field, ButtonHolder, Hidden, Div -from zds.member.models import Profile, KarmaNote, BannedEmailProvider +from zds.member.models import Profile, KarmaNote, BannedEmailProvider, Ban from zds.member.validators import ( validate_not_empty, validate_zds_email, @@ -48,7 +48,9 @@ class LoginForm(AuthenticationForm): "Vous n’avez pas encore activé votre compte, vous devez le faire pour pouvoir vous connecter sur le site." " <a href={}>Vous n’avez pas reçu le courriel d'activation ?</a>" ), - "banned": _("Vous n’êtes pas autorisé à vous connecter sur le site, vous avez été banni par un modérateur."), + "banned": _( + "Vous n’êtes pas autorisé à vous connecter sur le site, vous avez été banni par un modérateur pour la raison suivante : « {} »." + ), } def __init__(self, request=None, next="", *args, **kwargs): @@ -81,9 +83,10 @@ def confirm_login_allowed(self, user): error_text, code="inactive", ) - elif not user.profile.is_banned(): + elif user.profile.is_banned(): + ban_rationale = Ban.objects.filter(user=user).order_by("-pubdate").first().note raise ValidationError( - self.error_messages["banned"], + self.error_messages["banned"].format(ban_rationale), code="banned", ) diff --git a/zds/member/models.py b/zds/member/models.py index 63bb0683da..856e844404 100644 --- a/zds/member/models.py +++ b/zds/member/models.py @@ -330,8 +330,8 @@ def can_read_now(self): def is_banned(self): """Return True if the user is permanently or temporarily banned.""" if self.end_ban_read: - return self.can_read or (self.end_ban_read < datetime.now()) - return self.can_read + return not self.can_read and (self.end_ban_read >= datetime.now()) + return not self.can_read def can_write_now(self): if self.user.is_active: diff --git a/zds/member/tests/views/tests_login.py b/zds/member/tests/views/tests_login.py index a02917e81e..cd90826803 100644 --- a/zds/member/tests/views/tests_login.py +++ b/zds/member/tests/views/tests_login.py @@ -6,8 +6,8 @@ from django.utils.html import escape from zds.member.forms import LoginForm -from zds.member.models import Profile -from zds.member.tests.factories import ProfileFactory, NonAsciiProfileFactory +from zds.member.models import Profile, Ban +from zds.member.tests.factories import ProfileFactory, NonAsciiProfileFactory, StaffProfileFactory class LoginTests(TestCase): @@ -22,6 +22,20 @@ def setUp(self): self.assertNotEqual(self.test_ip, ProfileFactory.last_ip_address) settings.SESSION_COOKIE_AGE = 1337 + self.staff_profile = StaffProfileFactory() + self.banned_profile = ProfileFactory() + self.banned_profile.end_ban_read = None + self.banned_profile.can_read = False + self.banned_profile.save() + self.ban = Ban.objects.create( + user=self.banned_profile.user, + moderator=self.staff_profile.user, + type="Bannissement illimité", + note="Test message", + pubdate=datetime.now(), + ) + self.ban.save() + def test_form_action_redirect(self): """The form shall have the 'next' parameter in the action url of the form.""" next_fragment = "?next=" + reverse("member-detail", args=[self.correct_username]) @@ -157,20 +171,16 @@ def test_banned_user(self): Expected: cannot log in, error associated with the ban. """ - # Equivalent to a permanently banned user - self.profile.can_read = False - self.profile.save() - result = self.client.post( self.login_url, { - "username": self.correct_username, + "username": self.banned_profile.user.username, "password": self.correct_password, "remember": "remember", }, follow=False, ) - self.assertContains(result, escape(LoginForm.error_messages["banned"])) + self.assertContains(result, escape(LoginForm.error_messages["banned"].format(self.ban.note))) def test_previously_temp_banned_user(self): """ diff --git a/zds/middlewares/setlastvisitmiddleware.py b/zds/middlewares/setlastvisitmiddleware.py index 347ae4ba39..6ab567afb1 100644 --- a/zds/middlewares/setlastvisitmiddleware.py +++ b/zds/middlewares/setlastvisitmiddleware.py @@ -34,6 +34,6 @@ def process_response(self, request, response): profile.last_visit = datetime.datetime.now() profile.last_ip_address = get_client_ip(request) profile.save() - if not profile.is_banned(): + if profile.is_banned(): logout(request) return response