mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 22:52:26 +00:00
Create STATE_SUSPENDED
This commit is contained in:
parent
ffdb32df90
commit
0dcd8b79e2
17 changed files with 59 additions and 32 deletions
|
@ -513,8 +513,9 @@ class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
queryset = users.User.objects.exclude(
|
queryset = users.User.objects.exclude(
|
||||||
Q(state=users.User.STATE_DISABLED)
|
Q(state=users.User.STATE_DISABLED)
|
||||||
| Q(state=users.User.STATE_NOT_YET_ACTIVE)
|
| Q(state=users.User.STATE_NOT_YET_ACTIVE)
|
||||||
| Q(state=users.STATE_EMAIL_NOT_YET_CONFIRMED)
|
| Q(state=users.User.STATE_EMAIL_NOT_YET_CONFIRMED)
|
||||||
| Q(state=users.User.STATE_FULL_ARCHIVE)
|
| Q(state=users.User.STATE_FULL_ARCHIVE)
|
||||||
|
| Q(state=users.User.STATE_SUSPENDED)
|
||||||
)
|
)
|
||||||
serializer_class = serializers.BasicUserSerializer
|
serializer_class = serializers.BasicUserSerializer
|
||||||
|
|
||||||
|
|
|
@ -247,6 +247,10 @@ msgstr "Utilisateurs pas encore actifs"
|
||||||
msgid "Waiting for email confirmation users"
|
msgid "Waiting for email confirmation users"
|
||||||
msgstr "Utilisateurs en attente de confirmation d'email"
|
msgstr "Utilisateurs en attente de confirmation d'email"
|
||||||
|
|
||||||
|
#: logs/views.py:273
|
||||||
|
msgid "Suspended users"
|
||||||
|
msgstr "Utilisateurs suspendus"
|
||||||
|
|
||||||
#: logs/views.py:273
|
#: logs/views.py:273
|
||||||
msgid "Contributing members"
|
msgid "Contributing members"
|
||||||
msgstr "Adhérents cotisants"
|
msgstr "Adhérents cotisants"
|
||||||
|
|
|
@ -270,6 +270,16 @@ def stats_general(request):
|
||||||
),
|
),
|
||||||
Club.objects.filter(state=Club.STATE_EMAIL_NOT_YET_CONFIRMED).count(),
|
Club.objects.filter(state=Club.STATE_EMAIL_NOT_YET_CONFIRMED).count(),
|
||||||
],
|
],
|
||||||
|
"suspended_users": [
|
||||||
|
_("Suspended users"),
|
||||||
|
User.objects.filter(state=User.STATE_SUSPENDED).count(),
|
||||||
|
(
|
||||||
|
Adherent.objects.filter(
|
||||||
|
state=Adherent.STATE_SUSPENDED
|
||||||
|
).count()
|
||||||
|
),
|
||||||
|
Club.objects.filter(state=Club.STATE_SUSPENDED).count(),
|
||||||
|
],
|
||||||
"adherent_users": [
|
"adherent_users": [
|
||||||
_("Contributing members"),
|
_("Contributing members"),
|
||||||
_all_adherent.count(),
|
_all_adherent.count(),
|
||||||
|
|
|
@ -66,7 +66,7 @@ class EditOptionalUserForm(ModelForm):
|
||||||
self.fields["gpg_fingerprint"].label = _("GPG fingerprint")
|
self.fields["gpg_fingerprint"].label = _("GPG fingerprint")
|
||||||
self.fields["all_can_create_club"].label = _("All can create a club")
|
self.fields["all_can_create_club"].label = _("All can create a club")
|
||||||
self.fields["all_can_create_adherent"].label = _("All can create a member")
|
self.fields["all_can_create_adherent"].label = _("All can create a member")
|
||||||
self.fields["disable_emailnotyetconfirmed"].label = _("Delay before disabling accounts without a verified email")
|
self.fields["suspend_emailnotyetconfirmed"].label = _("Delay before suspending accounts without a verified email")
|
||||||
self.fields["self_adhesion"].label = _("Self registration")
|
self.fields["self_adhesion"].label = _("Self registration")
|
||||||
self.fields["shell_default"].label = _("Default shell")
|
self.fields["shell_default"].label = _("Default shell")
|
||||||
self.fields["allow_set_password_during_user_creation"].label = _("Allow directly setting a password during account creation")
|
self.fields["allow_set_password_during_user_creation"].label = _("Allow directly setting a password during account creation")
|
||||||
|
|
|
@ -287,11 +287,11 @@ msgstr ""
|
||||||
|
|
||||||
#: preferences/models.py:111
|
#: preferences/models.py:111
|
||||||
msgid ""
|
msgid ""
|
||||||
"Users with an email address not yet confirmed will be disabled after"
|
"Users with an email address not yet confirmed will be suspended after"
|
||||||
" this number of days."
|
" this number of days."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les utilisateurs n'ayant pas confirmé leur addresse mail seront"
|
"Les utilisateurs n'ayant pas confirmé leur addresse mail seront"
|
||||||
" désactivés après ce nombre de jours"
|
" suspendus après ce nombre de jours"
|
||||||
|
|
||||||
#: preferences/models.py:114
|
#: preferences/models.py:114
|
||||||
msgid "A new user can create their account on Re2o."
|
msgid "A new user can create their account on Re2o."
|
||||||
|
@ -1083,8 +1083,8 @@ msgid "Allow directly entering a password during account creation"
|
||||||
msgstr "Permettre le choix d'un mot de passe directement lors de la création du compte"
|
msgstr "Permettre le choix d'un mot de passe directement lors de la création du compte"
|
||||||
|
|
||||||
#: preferences/templates/preferences/display_preferences.html:136
|
#: preferences/templates/preferences/display_preferences.html:136
|
||||||
msgid "Delay before disabling accounts without a verified email"
|
msgid "Delay before suspending accounts without a verified email"
|
||||||
msgstr "Délai avant la désactivation des comptes sans adresse mail confirmé"
|
msgstr "Délai avant la suspension des comptes sans adresse mail confirmé"
|
||||||
|
|
||||||
#: preferences/templates/preferences/display_preferences.html:136
|
#: preferences/templates/preferences/display_preferences.html:136
|
||||||
msgid "Users general permissions"
|
msgid "Users general permissions"
|
||||||
|
|
|
@ -14,8 +14,8 @@ class Migration(migrations.Migration):
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='optionaluser',
|
model_name='optionaluser',
|
||||||
name='disable_emailnotyetconfirmed',
|
name='suspend_emailnotyetconfirmed',
|
||||||
field=models.IntegerField(default=2, help_text='Users with an email address not yet confirmed will be disabled after this number of days.')
|
field=models.IntegerField(default=2, help_text='Users with an email address not yet confirmed will be suspended after this number of days.')
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -107,10 +107,10 @@ class OptionalUser(AclMixin, PreferencesModel):
|
||||||
"Not yet active users will be deleted after this number of days."
|
"Not yet active users will be deleted after this number of days."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
disable_emailnotyetconfirmed = models.IntegerField(
|
suspend_emailnotyetconfirmed = models.IntegerField(
|
||||||
default=2,
|
default=2,
|
||||||
help_text=_(
|
help_text=_(
|
||||||
"Users with an email address not yet confirmed will be disabled after this number of days."
|
"Users with an email address not yet confirmed will be suspended after this number of days."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self_adhesion = models.BooleanField(
|
self_adhesion = models.BooleanField(
|
||||||
|
|
|
@ -131,8 +131,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Allow directly entering a password during account creation" %}</th>
|
<th>{% trans "Allow directly entering a password during account creation" %}</th>
|
||||||
<td>{{ useroptions.allow_set_password_during_user_creation|tick }}</td>
|
<td>{{ useroptions.allow_set_password_during_user_creation|tick }}</td>
|
||||||
<th>{% trans "Delay before disabling accounts without a verified email" %}</th>
|
<th>{% trans "Delay before suspending accounts without a verified email" %}</th>
|
||||||
<td>{% blocktrans with disable_emailnotyetconfirmed=useroptions.disable_emailnotyetconfirmed %}{{ disable_emailnotyetconfirmed }} days{% endblocktrans %}</td>
|
<td>{% blocktrans with suspend_emailnotyetconfirmed=useroptions.suspend_emailnotyetconfirmed %}{{ suspend_emailnotyetconfirmed }} days{% endblocktrans %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ CHOICES_USER = (
|
||||||
("3", _("Not yet active")),
|
("3", _("Not yet active")),
|
||||||
("4", _("Fully archived")),
|
("4", _("Fully archived")),
|
||||||
("5", _("Waiting for email confirmation")),
|
("5", _("Waiting for email confirmation")),
|
||||||
|
("6", _("Suspended")),
|
||||||
)
|
)
|
||||||
|
|
||||||
CHOICES_AFF = (
|
CHOICES_AFF = (
|
||||||
|
|
|
@ -54,6 +54,10 @@ msgstr "Complètement archivés"
|
||||||
msgid "Waiting for email confirmation"
|
msgid "Waiting for email confirmation"
|
||||||
msgstr "En attente de confirmation d'email"
|
msgstr "En attente de confirmation d'email"
|
||||||
|
|
||||||
|
#: search/forms.py:39
|
||||||
|
msgid "Suspended"
|
||||||
|
msgstr "Suspendu"
|
||||||
|
|
||||||
#: search/forms.py:41
|
#: search/forms.py:41
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "Utilisateurs"
|
msgstr "Utilisateurs"
|
||||||
|
|
|
@ -388,10 +388,14 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
|
||||||
if not self.is_anon and self.initial["email"] and user.email != self.initial["email"]:
|
if not self.is_anon and self.initial["email"] and user.email != self.initial["email"]:
|
||||||
# Send a confirmation 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]:
|
# Don't do this for archived or disabled users
|
||||||
user.state = User.STATE_EMAIL_NOT_YET_CONFIRMED
|
if user.state not in [User.STATE_ARCHIVE, User.STATE_FULL_ARCHIVE, User.STATE_DISABLED]:
|
||||||
self.should_send_confirmation_email = True
|
self.should_send_confirmation_email = True
|
||||||
|
|
||||||
|
# Suspend users stay suspended
|
||||||
|
if user.state == User.STATE_SUSPENDED:
|
||||||
|
user.state = User.STATE_EMAIL_NOT_YET_CONFIRMED
|
||||||
|
|
||||||
# Always keep the oldest change date
|
# Always keep the oldest change date
|
||||||
if user.email_change_date is None:
|
if user.email_change_date is None:
|
||||||
user.email_change_date = timezone.now()
|
user.email_change_date = timezone.now()
|
||||||
|
|
|
@ -28,13 +28,13 @@ from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Delete non members users (not yet active or disabled too long ago without an invoice)."
|
help = "Delete non members users (not yet active or suspended too long ago without an invoice)."
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
"""First deleting invalid invoices, and then deleting the users"""
|
"""First deleting invalid invoices, and then deleting the users"""
|
||||||
days = OptionalUser.get_cached_value("disable_emailnotyetconfirmed")
|
days = OptionalUser.get_cached_value("delete_notyetactive")
|
||||||
users_to_delete = (
|
users_to_delete = (
|
||||||
User.objects.filter(Q(state=User.STATE_NOT_YET_ACTIVE) | Q(state=User.STATE_DISABLED))
|
User.objects.filter(Q(state=User.STATE_NOT_YET_ACTIVE) | Q(state=User.STATE_SUSPENDED))
|
||||||
.filter(registered__lte=timezone.now() - timedelta(days=days))
|
.filter(registered__lte=timezone.now() - timedelta(days=days))
|
||||||
.exclude(facture__valid=True)
|
.exclude(facture__valid=True)
|
||||||
.distinct()
|
.distinct()
|
||||||
|
|
|
@ -25,19 +25,19 @@ from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Disable users who haven't confirmed their email."
|
help = "Suspend users who haven't confirmed their email."
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
"""First deleting invalid invoices, and then deleting the users"""
|
"""First deleting invalid invoices, and then deleting the users"""
|
||||||
days = OptionalUser.get_cached_value("disable_emailnotyetconfirmed")
|
days = OptionalUser.get_cached_value("suspend_emailnotyetconfirmed")
|
||||||
users_to_disable = (
|
users_to_suspend = (
|
||||||
User.objects.filter(state=User.STATE_EMAIL_NOT_YET_CONFIRMED)
|
User.objects.filter(state=User.STATE_EMAIL_NOT_YET_CONFIRMED)
|
||||||
.filter(email_change_date__lte=timezone.now() - timedelta(days=days))
|
.filter(email_change_date__lte=timezone.now() - timedelta(days=days))
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
print("Disabling " + str(users_to_disable.count()) + " users.")
|
print("Suspending " + str(users_to_suspend.count()) + " users.")
|
||||||
|
|
||||||
for user in users_to_disable:
|
for user in users_to_suspend:
|
||||||
user.state = User.STATE_DISABLED
|
user.state = User.STATE_SUSPENDED
|
||||||
user.notif_disable()
|
user.notif_suspension()
|
||||||
user.save()
|
user.save()
|
||||||
|
|
|
@ -174,12 +174,13 @@ class User(
|
||||||
Champs principaux : name, surnname, pseudo, email, room, password
|
Champs principaux : name, surnname, pseudo, email, room, password
|
||||||
Herite du django BaseUser et du système d'auth django"""
|
Herite du django BaseUser et du système d'auth django"""
|
||||||
|
|
||||||
STATE_ACTIVE = 0
|
STATE_ACTIVE = 0 # Can login and has Internet (if invoice is valid)
|
||||||
STATE_DISABLED = 1
|
STATE_DISABLED = 1 # Cannot login to Re2o and doesn't have Internet
|
||||||
STATE_ARCHIVE = 2
|
STATE_ARCHIVE = 2
|
||||||
STATE_NOT_YET_ACTIVE = 3
|
STATE_NOT_YET_ACTIVE = 3
|
||||||
STATE_FULL_ARCHIVE = 4
|
STATE_FULL_ARCHIVE = 4
|
||||||
STATE_EMAIL_NOT_YET_CONFIRMED = 5
|
STATE_EMAIL_NOT_YET_CONFIRMED = 5
|
||||||
|
STATE_SUSPENDED = 6 # Can login to Re2o but doesn't have Internet
|
||||||
STATES = (
|
STATES = (
|
||||||
(0, _("Active")),
|
(0, _("Active")),
|
||||||
(1, _("Disabled")),
|
(1, _("Disabled")),
|
||||||
|
@ -187,6 +188,7 @@ class User(
|
||||||
(3, _("Not yet active")),
|
(3, _("Not yet active")),
|
||||||
(4, _("Fully archived")),
|
(4, _("Fully archived")),
|
||||||
(5, _("Waiting for email confirmation")),
|
(5, _("Waiting for email confirmation")),
|
||||||
|
(5, _("Suspended")),
|
||||||
)
|
)
|
||||||
|
|
||||||
surname = models.CharField(max_length=255)
|
surname = models.CharField(max_length=255)
|
||||||
|
@ -395,7 +397,7 @@ class User(
|
||||||
@cached_property
|
@cached_property
|
||||||
def get_shadow_expire(self):
|
def get_shadow_expire(self):
|
||||||
"""Return the shadow_expire value for the user"""
|
"""Return the shadow_expire value for the user"""
|
||||||
if self.state == self.STATE_DISABLED:
|
if self.state == self.STATE_DISABLED or self.STATE_SUSPENDED:
|
||||||
return str(0)
|
return str(0)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
@ -690,6 +692,7 @@ class User(
|
||||||
or self.state == self.STATE_EMAIL_NOT_YET_CONFIRMED
|
or self.state == self.STATE_EMAIL_NOT_YET_CONFIRMED
|
||||||
or self.state == self.STATE_ARCHIVE
|
or self.state == self.STATE_ARCHIVE
|
||||||
or self.state == self.STATE_DISABLED
|
or self.state == self.STATE_DISABLED
|
||||||
|
or self.state == self.STATE_SUSPENDED
|
||||||
):
|
):
|
||||||
self.refresh_from_db()
|
self.refresh_from_db()
|
||||||
try:
|
try:
|
||||||
|
@ -810,7 +813,7 @@ class User(
|
||||||
if self.email_change_date is None or self.state != self.STATE_EMAIL_NOT_YET_CONFIRMED:
|
if self.email_change_date is None or self.state != self.STATE_EMAIL_NOT_YET_CONFIRMED:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
days = OptionalUser.get_cached_value("disable_emailnotyetconfirmed")
|
days = OptionalUser.get_cached_value("suspend_emailnotyetconfirmed")
|
||||||
return self.email_change_date + timedelta(days=days)
|
return self.email_change_date + timedelta(days=days)
|
||||||
|
|
||||||
def confirm_email_address_mail(self, request):
|
def confirm_email_address_mail(self, request):
|
||||||
|
@ -897,9 +900,9 @@ class User(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def notif_disable(self):
|
def notif_suspension(self):
|
||||||
"""Envoi un mail de notification informant que l'adresse mail n'a pas été confirmée"""
|
"""Envoi un mail de notification informant que l'adresse mail n'a pas été confirmée"""
|
||||||
template = loader.get_template("users/email_disable_notif")
|
template = loader.get_template("users/email_suspension_notif")
|
||||||
context = {
|
context = {
|
||||||
"name": self.get_full_name(),
|
"name": self.get_full_name(),
|
||||||
"asso_name": AssoOption.get_cached_value("name"),
|
"asso_name": AssoOption.get_cached_value("name"),
|
||||||
|
|
|
@ -50,7 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% blocktrans %}Didn't receive the email?{% endblocktrans %}
|
{% blocktrans %}Didn't receive the email?{% endblocktrans %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% elif users.state == users.STATE_DISABLED %}
|
{% elif users.state == users.STATE_SUSPENDED %}
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
{% blocktrans %}Your account has been suspended.{% endblocktrans %}
|
{% blocktrans %}Your account has been suspended.{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -981,7 +981,7 @@ def reset_password(request):
|
||||||
user = User.objects.get(
|
user = User.objects.get(
|
||||||
pseudo=userform.cleaned_data["pseudo"],
|
pseudo=userform.cleaned_data["pseudo"],
|
||||||
email=userform.cleaned_data["email"],
|
email=userform.cleaned_data["email"],
|
||||||
state__in=[User.STATE_ACTIVE, User.STATE_NOT_YET_ACTIVE, User.STATE_EMAIL_NOT_YET_CONFIRMED],
|
state__in=[User.STATE_ACTIVE, User.STATE_NOT_YET_ACTIVE, User.STATE_EMAIL_NOT_YET_CONFIRMED, User.STATE_SUSPENDED],
|
||||||
)
|
)
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
messages.error(request, _("The user doesn't exist."))
|
messages.error(request, _("The user doesn't exist."))
|
||||||
|
|
Loading…
Reference in a new issue