8
0
Fork 0
mirror of https://gitlab.federez.net/re2o/re2o synced 2024-06-18 08:38:09 +00:00

Merge branch '217-better-management-of-desactivated-account' into 'dev'

Resolve "Desactivated account unable to log in"

See merge request federez/re2o!434
This commit is contained in:
chirac 2019-09-19 22:59:43 +02:00
commit 3bb010b9b8
9 changed files with 124 additions and 58 deletions

View file

@ -246,9 +246,10 @@ class Facture(BaseInvoice):
def can_change_control(user_request, *_args, **_kwargs):
""" Returns True if the user can change the 'controlled' status of
this invoice """
can = user_request.has_perm('cotisations.change_facture_control')
return (
user_request.has_perm('cotisations.change_facture_control'),
_("You don't have the right to edit the \"controlled\" state."),
can,
_("You don't have the right to edit the \"controlled\" state.") if not can else None,
('cotisations.change_facture_control',)
)
@ -746,11 +747,12 @@ class Article(RevMixin, AclMixin, models.Model):
A boolean stating if usage is granted and an explanation
message if the boolean is `False`.
"""
can = self.available_for_everyone \
or user.has_perm('cotisations.buy_every_article') \
or user.has_perm('cotisations.add_facture')
return (
self.available_for_everyone
or user.has_perm('cotisations.buy_every_article')
or user.has_perm('cotisations.add_facture'),
_("You can't buy this article."),
can,
_("You can't buy this article.") if not can else None,
('cotisations.buy_every_article', 'cotisations.add_facture')
)
@ -902,11 +904,12 @@ class Paiement(RevMixin, AclMixin, models.Model):
A boolean stating if usage is granted and an explanation
message if the boolean is `False`.
"""
can = self.available_for_everyone \
or user.has_perm('cotisations.use_every_payment') \
or user.has_perm('cotisations.add_facture')
return (
self.available_for_everyone
or user.has_perm('cotisations.use_every_payment')
or user.has_perm('cotisations.add_facture'),
_("You can't use this payment method."),
can,
_("You can't use this payment method.") if not can else None,
('cotisations.use_every_payment', 'cotisations.add_facture')
)

View file

@ -105,9 +105,10 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
A tuple with a boolean stating if edition is allowed and an
explanation message.
"""
can = user_request.has_perm('machines.change_machine_user')
return (
user_request.has_perm('machines.change_machine_user'),
_("You don't have the right to change the machine's user."),
can,
_("You don't have the right to change the machine's user.") if not can else None,
('machines.change_machine_user',)
)
@ -803,9 +804,10 @@ class Extension(RevMixin, AclMixin, models.Model):
restrictions
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison de l'échec le cas échéant"""
can = user_request.has_perm('machines.use_all_extension')
return (
user_request.has_perm('machines.use_all_extension'),
_("You cannot use all extensions."),
can,
_("You cannot use all extensions.") if not can else None,
('machines.use_all_extension',)
)
@ -1294,9 +1296,10 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
def can_change_machine(user_request, *_args, **_kwargs):
"""Check if a user can change the machine associated with an
Interface object """
can = user_request.has_perm('machines.change_interface_machine')
return (
user_request.has_perm('machines.change_interface_machine'),
_("Permission required to edit the machine."),
can,
_("Permission required to edit the machine.") if not can else None,
('machines.change_interface_machine',)
)
@ -1421,10 +1424,11 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
@staticmethod
def can_change_slaac_ip(user_request, *_args, **_kwargs):
""" Check if a user can change the slaac value """
can = user_request.has_perm('machines.change_ipv6list_slaac_ip')
return (
user_request.has_perm('machines.change_ipv6list_slaac_ip'),
can,
_("Permission required to change the SLAAC value of an IPv6"
" address"),
" address") if not can else None,
('machines.change_ipv6list_slaac_ip',)
)

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-09-09 09:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0060_auto_20190712_1821'),
]
operations = [
migrations.AddField(
model_name='optionaluser',
name='allow_archived_connexion',
field=models.BooleanField(default=False, help_text='If True, archived users are allowed to connect.'),
),
]

View file

@ -123,6 +123,10 @@ class OptionalUser(AclMixin, PreferencesModel):
help_text=_("If True, all new created and connected users are active."
" If False, only when a valid registration has been paid.")
)
allow_archived_connexion = models.BooleanField(
default=False,
help_text=_("If True, archived users are allowed to connect.")
)
class Meta:
permissions = (

View file

@ -125,6 +125,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "All users are active by default" %}</th>
<td>{{ useroptions.all_users_active|tick }}</td>
<th>{% trans "Allow archived users to log-in" %}</th>
<td>{{ useroptions.allow_archived_connexion|tick }}</td>
</tr>
</table>

View file

@ -41,6 +41,8 @@ from re2o.utils import get_group_having_permission
def acl_error_message(msg, permissions):
"""Create an error message for msg and permissions."""
if permissions is None:
return msg
groups = ", ".join([
g.name for g in get_group_having_permission(*permissions)
])
@ -76,9 +78,11 @@ def acl_base_decorator(method_name, *targets, on_instance=True):
permission was granted. This is to allow you to run ACL tests on
fields only. If the method exists, it has to return a 2-tuple
`(can, reason, permissions)` with `can` being a boolean stating
whether the access is granted, `reason` a message to be
whether the access is granted, `reason` an arror message to be
displayed if `can` equals `False` (can be `None`) and `permissions`
a list of permissions needed for access (can be `None`).
a list of permissions needed for access (can be `None`). If can is
True and permission is not `None`, a warning message will be
displayed.
*targets: The targets. Targets are specified like a sequence of models
and fields names. As an example
```
@ -172,10 +176,17 @@ ModelC)
yield can_change_fct(request.user, *args, **kwargs)
error_messages = []
warning_messages = []
for target, fields in group_targets():
for can, msg, permissions in process_target(target, fields):
if not can:
error_messages.append(acl_error_message(msg, permissions))
elif msg:
warning_messages.append(acl_error_message(msg, permissions))
if warning_messages:
for msg in warning_messages:
messages.warning(request, msg)
if error_messages:
for msg in error_messages:

View file

@ -105,10 +105,11 @@ class AclMixin(object):
:param user_request: instance utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
permission = cls.get_modulename() + '.add_' + cls.get_classname()
can = user_request.has_perm(permission)
return (
user_request.has_perm(permission),
can,
_("You don't have the right to create a %s object.")
% cls.get_classname(),
% cls.get_classname() if not can else None,
(permission,)
)
@ -119,10 +120,11 @@ class AclMixin(object):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
permission = self.get_modulename() + '.change_' + self.get_classname()
can = user_request.has_perm(permission)
return (
user_request.has_perm(permission),
can,
_("You don't have the right to edit a %s object.")
% self.get_classname(),
% self.get_classname() if not can else None,
(permission,)
)
@ -133,10 +135,11 @@ class AclMixin(object):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
permission = self.get_modulename() + '.delete_' + self.get_classname()
can = user_request.has_perm(permission)
return (
user_request.has_perm(permission),
can,
_("You don't have the right to delete a %s object.")
% self.get_classname(),
% self.get_classname() if not can else None,
(permission,)
)
@ -147,10 +150,11 @@ class AclMixin(object):
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison de l'échec le cas échéant"""
permission = cls.get_modulename() + '.view_' + cls.get_classname()
can = user_request.has_perm(permission)
return (
user_request.has_perm(permission),
can,
_("You don't have the right to view every %s object.")
% cls.get_classname(),
% cls.get_classname() if not can else None,
(permission,)
)
@ -161,10 +165,11 @@ class AclMixin(object):
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison de l'échec le cas échéant"""
permission = self.get_modulename() + '.view_' + self.get_classname()
can = user_request.has_perm(permission)
return (
user_request.has_perm(permission),
can,
_("You don't have the right to view a %s object.")
% self.get_classname(),
% self.get_classname() if not can else None,
(permission,)
)

View file

@ -86,9 +86,10 @@ class Ticket(AclMixin, models.Model):
@staticmethod
def can_view_all(user_request, *_args, **_kwargs):
""" Check that the user has access to the list of all tickets"""
can = user_request.has_perm('tickets.view_tickets')
return(
user_request.has_perm('tickets.view_tickets'),
_("You don't have the right to view the list of tickets."),
can,
_("You don't have the right to view the list of tickets.") if not can else None,
('tickets.view_tickets',)
)

View file

@ -333,7 +333,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
@property
def is_active(self):
""" Renvoie si l'user est à l'état actif"""
return self.state == self.STATE_ACTIVE or self.state == self.STATE_NOT_YET_ACTIVE
allow_archived = OptionalUser.get_cached_value('allow_archived_connexion')
return self.state == self.STATE_ACTIVE or self.state == self.STATE_NOT_YET_ACTIVE or (allow_archived and self.state in (self.STATE_ARCHIVE, self.STATE_FULL_ARCHIVE))
def set_active(self):
"""Enable this user if he subscribed successfully one time before
@ -858,18 +859,23 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
user_request one of its member, or if user_request is self, or if
user_request has the 'cableur' right.
"""
if self.state in (self.STATE_ARCHIVE, self.STATE_FULL_ARCHIVE):
warning_message = _("This user is archived.")
else:
warning_message = None
if self.is_class_club and user_request.is_class_adherent:
if (self == user_request or
user_request.has_perm('users.change_user') or
user_request.adherent in self.club.administrators.all()):
return True, None, None
return True, warning_message, None
else:
return False, _("You don't have the right to edit this club."), ('users.change_user',)
else:
if self == user_request:
return True, None, None
return True, warning_message, None
elif user_request.has_perm('users.change_all_users'):
return True, None, None
return True, warning_message, None
elif user_request.has_perm('users.change_user'):
if self.groups.filter(listright__critical=True):
return (
@ -885,9 +891,9 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
('users.change_all_users', )
)
else:
return True, None, None
return True, warning_message, None
elif user_request.has_perm('users.change_all_users'):
return True, None, None
return True, warning_message, None
else:
return (
False,
@ -962,9 +968,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:returns: a message and a boolean which is True if the user has
the right to change a state
"""
can = user_request.has_perm('users.change_user_state')
return (
user_request.has_perm('users.change_user_state'),
_("Permission required to change the state."),
can,
_("Permission required to change the state.") if not can else None,
('users.change_user_state',)
)
@ -993,9 +1000,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:returns: a message and a boolean which is True if the user has
the right to change a redirection
"""
can = OptionalUser.get_cached_value('local_email_accounts_enabled')
return (
OptionalUser.get_cached_value('local_email_accounts_enabled'),
_("Local email accounts must be enabled."),
can,
_("Local email accounts must be enabled.") if not can else None,
None
)
@ -1007,9 +1015,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:returns: a message and a boolean which is True if the user has
the right to change internal address
"""
can = OptionalUser.get_cached_value('local_email_accounts_enabled')
return (
OptionalUser.get_cached_value('local_email_accounts_enabled'),
_("Local email accounts must be enabled."),
can,
_("Local email accounts must be enabled.") if not can else None,
None
)
@ -1021,9 +1030,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:returns: a message and a boolean which is True if the user has
the right to change a force
"""
can = user_request.has_perm('users.change_user_force')
return (
user_request.has_perm('users.change_user_force'),
_("Permission required to force the move."),
can,
_("Permission required to force the move.") if not can else None,
('users.change_user_force',)
)
@ -1035,9 +1045,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:returns: a message and a boolean which is True if the user has
the right to change a group
"""
can = user_request.has_perm('users.change_user_grou')
return (
user_request.has_perm('users.change_user_groups'),
_("Permission required to edit the user's groups of rights."),
can,
_("Permission required to edit the user's groups of rights.") if not can else None,
('users.change_user_groups')
)
@ -1048,9 +1059,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:param user_request: The user who request
:returns: a message and a boolean which is True if permission is granted.
"""
can = user_request.is_superuser
return (
user_request.is_superuser,
_("'superuser' right required to edit the superuser flag."),
can,
_("'superuser' right required to edit the superuser flag.") if not can else None,
[]
)
@ -1093,9 +1105,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:return: True if the user can view the list and an explanation
message.
"""
can = user_request.has_perm('use.view_user')
return (
user_request.has_perm('users.view_user'),
_("You don't have the right to view the list of users."),
can,
_("You don't have the right to view the list of users.") if not can else None,
('users.view_user',)
)
@ -1107,9 +1120,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
:return: True if user_request has the right 'bureau', and a
message.
"""
can = user_request.has_perm('users.delete_user')
return (
user_request.has_perm('users.delete_user'),
_("You don't have the right to delete this user."),
can,
_("You don't have the right to delete this user.") if not can else None,
('users.delete_user',)
)
@ -1203,9 +1217,10 @@ class Adherent(User):
OptionalUser.get_cached_value('self_adhesion')):
return True, None, None
else:
can = user_request.has_perm('users.add_user')
return (
user_request.has_perm('users.add_user'),
_("You don't have the right to create a user."),
can,
_("You don't have the right to create a user.") if not can else None,
('users.add_user',)
)
@ -1259,9 +1274,10 @@ class Club(User):
if OptionalUser.get_cached_value('all_can_create_club'):
return True, None, None
else:
can = user_request.has_perm('users.add_user')
return (
user_request.has_perm('users.add_user'),
_("You don't have the right to create a club."),
can,
_("You don't have the right to create a club.") if not can else None,
('users.add_user',)
)