8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-27 07:02:26 +00:00

Merge branch '213-helpful-acl-messages' into 'dev'

Resolve "When refusing access due to missing permission, also indicate which groups would have granted the required permission"

See merge request federez/re2o!432
This commit is contained in:
Maxime Bombar 2019-09-09 16:21:57 +02:00
commit 9f800a6c02
17 changed files with 698 additions and 339 deletions

View file

@ -33,7 +33,7 @@ from django.utils.translation import ugettext as _
def _create_api_permission():
"""Creates the 'use_api' permission if not created.
The 'use_api' is a fake permission in the sense it is not associated with an
existing model and this ensure the permission is created every time this file
is imported.
@ -70,6 +70,7 @@ def can_view(user):
'app_label': settings.API_CONTENT_TYPE_APP_LABEL,
'codename': settings.API_PERMISSION_CODENAME
}
can = user.has_perm('%(app_label)s.%(codename)s' % kwargs)
permission = '%(app_label)s.%(codename)s' % kwargs
can = user.has_perm(permission)
return can, None if can else _("You don't have the right to see this"
" application.")
" application."), (permission,)

View file

@ -40,7 +40,11 @@ def can_view(user):
"""
can = user.has_module_perms('cotisations')
if can:
return can, None
return can, None, ('cotisations',)
else:
return can, _("You don't have the right to view this application.")
return (
can,
_("You don't have the right to view this application."),
('cotisations',)
)

View file

@ -169,44 +169,78 @@ class Facture(BaseInvoice):
return self.vente_set.all()
def can_edit(self, user_request, *args, **kwargs):
user_can, _, permissions = self.user.can_edit(
user_request, *args, **kwargs)
if not user_request.has_perm('cotisations.change_facture'):
return False, _("You don't have the right to edit an invoice.")
return (
False,
_("You don't have the right to edit an invoice."),
('cotisations.change_facture',)
)
elif not user_request.has_perm('cotisations.change_all_facture') and \
not self.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to edit this user's "
"invoices.")
not user_can:
return (
False,
_("You don't have the right to edit this user's invoices."),
('cotisations.change_all_facture',) + permissions
)
elif not user_request.has_perm('cotisations.change_all_facture') and \
(self.control or not self.valid):
return False, _("You don't have the right to edit an invoice "
"already controlled or invalidated.")
return (
False,
_("You don't have the right to edit an invoice "
"already controlled or invalidated."),
('cotisations.change_all_facture',)
)
else:
return True, None
return True, None, None
def can_delete(self, user_request, *args, **kwargs):
user_can, _, permissions = self.user.can_edit(
user_request, *args, **kwargs)
if not user_request.has_perm('cotisations.delete_facture'):
return False, _("You don't have the right to delete an invoice.")
return (
False,
_("You don't have the right to delete an invoice."),
('cotisations.delete_facture',)
)
elif not user_request.has_perm('cotisations.change_all_facture') and \
not self.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to delete this user's "
"invoices.")
not user_can:
return (
False,
_("You don't have the right to delete this user's invoices."),
('cotisations.change_all_facture',) + permissions
)
elif not user_request.has_perm('cotisations.change_all_facture') and \
(self.control or not self.valid):
return False, _("You don't have the right to delete an invoice "
"already controlled or invalidated.")
return (
False,
_("You don't have the right to delete an invoice "
"already controlled or invalidated."),
('cotisations.change_all_facture',)
)
else:
return True, None
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
if not user_request.has_perm('cotisations.view_facture'):
if self.user != user_request:
return False, _("You don't have the right to view someone else's "
"invoices history.")
return (
False,
_("You don't have the right to view someone else's "
"invoices history."),
('cotisations.view_facture',)
)
elif not self.valid:
return False, _("The invoice has been invalidated.")
return (
False,
_("The invoice has been invalidated."),
('cotisations.view_facture',)
)
else:
return True, None
return True, None, None
else:
return True, None
return True, None, None
@staticmethod
def can_change_control(user_request, *_args, **_kwargs):
@ -214,7 +248,8 @@ class Facture(BaseInvoice):
this invoice """
return (
user_request.has_perm('cotisations.change_facture_control'),
_("You don't have the right to edit the \"controlled\" state.")
_("You don't have the right to edit the \"controlled\" state."),
('cotisations.change_facture_control',)
)
@staticmethod
@ -226,12 +261,12 @@ class Facture(BaseInvoice):
an invoice or if the `options.allow_self_subscription` is set.
"""
if user_request.has_perm('cotisations.add_facture'):
return True, None
return True, None, None
if len(Paiement.find_allowed_payments(user_request)) <= 0:
return False, _("There are no payment method which you can use.")
return False, _("There are no payment method which you can use."), ('cotisations.add_facture',)
if len(Article.find_allowed_articles(user_request, user_request)) <= 0:
return False, _("There are no article that you can buy.")
return True, None
return False, _("There are no article that you can buy."), ('cotisations.add_facture',)
return True, None, None
def __init__(self, *args, **kwargs):
super(Facture, self).__init__(*args, **kwargs)
@ -360,12 +395,18 @@ class CostEstimate(CustomInvoice):
def can_delete(self, user_request, *args, **kwargs):
if not user_request.has_perm('cotisations.delete_costestimate'):
return False, _("You don't have the right "
"to delete a cost estimate.")
return (
False,
_("You don't have the right to delete a cost estimate."),
('cotisations.delete_costestimate',)
)
if self.final_invoice is not None:
return False, _("The cost estimate has an "
"invoice and can't be deleted.")
return True, None
return (
False,
_("The cost estimate has an invoice and can't be deleted."),
None
)
return True, None, None
# TODO : change Vente to Purchase
@ -505,40 +546,66 @@ class Vente(RevMixin, AclMixin, models.Model):
super(Vente, self).save(*args, **kwargs)
def can_edit(self, user_request, *args, **kwargs):
user_can, _, permissions = self.facture.user.can_edit(
user_request, *args, **kwargs
)
if not user_request.has_perm('cotisations.change_vente'):
return False, _("You don't have the right to edit the purchases.")
elif (not user_request.has_perm('cotisations.change_all_facture') and
not self.facture.user.can_edit(
user_request, *args, **kwargs
)[0]):
return False, _("You don't have the right to edit this user's "
"purchases.")
return (
False,
_("You don't have the right to edit the purchases."),
('cotisations.change_vente',)
)
elif not (
user_request.has_perm('cotisations.change_all_facture') or
user_can):
return (
False,
_("You don't have the right to edit this user's purchases."),
('cotisations.change_all_facture',) + permissions
)
elif (not user_request.has_perm('cotisations.change_all_vente') and
(self.facture.control or not self.facture.valid)):
return False, _("You don't have the right to edit a purchase "
"already controlled or invalidated.")
return (
False,
_("You don't have the right to edit a purchase "
"already controlled or invalidated."),
('cotisations.change_all_vente',)
)
else:
return True, None
return True, None, None
def can_delete(self, user_request, *args, **kwargs):
user_can, _, permissions = self.facture.user.can_edit(
user_request, *args, **kwargs)
if not user_request.has_perm('cotisations.delete_vente'):
return False, _("You don't have the right to delete a purchase.")
if not self.facture.user.can_edit(user_request, *args, **kwargs)[0]:
return False, _("You don't have the right to delete this user's "
"purchases.")
return (
False,
_("You don't have the right to delete a purchase."),
('cotisations.delete_vente',)
)
if not user_can:
return (
False,
_("You don't have the right to delete this user's purchases."),
permissions
)
if self.facture.control or not self.facture.valid:
return False, _("You don't have the right to delete a purchase "
"already controlled or invalidated.")
"already controlled or invalidated."), None
else:
return True, None
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
if (not user_request.has_perm('cotisations.view_vente') and
self.facture.user != user_request):
return False, _("You don't have the right to view someone "
"else's purchase history.")
return (
False,
_("You don't have the right to view someone "
"else's purchase history."),
('cotisations.view_vente',)
)
else:
return True, None
return True, None, None
def __str__(self):
return str(self.name) + ' ' + str(self.facture)
@ -683,7 +750,8 @@ class Article(RevMixin, AclMixin, models.Model):
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.")
_("You can't buy this article."),
('cotisations.buy_every_article', 'cotisations.add_facture')
)
@classmethod
@ -838,7 +906,8 @@ class Paiement(RevMixin, AclMixin, models.Model):
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.")
_("You can't use this payment method."),
('cotisations.use_every_payment', 'cotisations.add_facture')
)
@classmethod
@ -907,32 +976,51 @@ class Cotisation(RevMixin, AclMixin, models.Model):
def can_edit(self, user_request, *_args, **_kwargs):
if not user_request.has_perm('cotisations.change_cotisation'):
return False, _("You don't have the right to edit a subscription.")
return (
False,
_("You don't have the right to edit a subscription."),
('cotisations.change_cotisation',)
)
elif not user_request.has_perm('cotisations.change_all_cotisation') \
and (self.vente.facture.control or
not self.vente.facture.valid):
return False, _("You don't have the right to edit a subscription "
"already controlled or invalidated.")
return (
False,
_("You don't have the right to edit a subscription "
"already controlled or invalidated."),
('cotisations.change_all_cotisation',)
)
else:
return True, None
return True, None, None
def can_delete(self, user_request, *_args, **_kwargs):
if not user_request.has_perm('cotisations.delete_cotisation'):
return False, _("You don't have the right to delete a "
"subscription.")
return (
False,
_("You don't have the right to delete a subscription."),
('cotisations.delete_cotisation',)
)
if self.vente.facture.control or not self.vente.facture.valid:
return False, _("You don't have the right to delete a subscription "
"already controlled or invalidated.")
return (
False,
_("You don't have the right to delete a subscription "
"already controlled or invalidated."),
None
)
else:
return True, None
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
if not user_request.has_perm('cotisations.view_cotisation') and\
self.vente.facture.user != user_request:
return False, _("You don't have the right to view someone else's "
"subscription history.")
return (
False,
_("You don't have the right to view someone else's "
"subscription history."),
('cotisations.view_cotisation',)
)
else:
return True, None
return True, None, None
def __str__(self):
return str(self.vente)

View file

@ -39,6 +39,10 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('admin')
return can, None if can else _("You don't have the right to view this"
" application.")
return (
can,
None if can else _("You don't have the right to view this"
" application."),
'admin'
)

View file

@ -39,5 +39,10 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('machines')
return can, None if can else _("You don't have the right to view this"
" application.")
return (
can,
None if can else _("You don't have the right to view this"
" application."),
('machines',)
)

View file

@ -105,8 +105,11 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
A tuple with a boolean stating if edition is allowed and an
explanation message.
"""
return (user_request.has_perm('machines.change_machine_user'),
_("You don't have the right to change the machine's user."))
return (
user_request.has_perm('machines.change_machine_user'),
_("You don't have the right to change the machine's user."),
('machines.change_machine_user',)
)
@staticmethod
def can_view_all(user_request, *_args, **_kwargs):
@ -115,9 +118,12 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison de l'échec le cas échéant"""
if not user_request.has_perm('machines.view_machine'):
return False, _("You don't have the right to view all the"
" machines.")
return True, None
return (
False,
_("You don't have the right to view all the machines."),
('machines.view_machine',)
)
return True, None, None
@staticmethod
def can_create(user_request, userid, *_args, **_kwargs):
@ -129,7 +135,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
try:
user = users.models.User.objects.get(pk=userid)
except users.models.User.DoesNotExist:
return False, _("Nonexistent user.")
return False, _("Nonexistent user."), None
max_lambdauser_interfaces = (preferences.models.OptionalMachine
.get_cached_value(
'max_lambdauser_interfaces'
@ -137,15 +143,23 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
if not user_request.has_perm('machines.add_machine'):
if not (preferences.models.OptionalMachine
.get_cached_value('create_machine')):
return False, (_("You don't have the right to add a machine."))
return (
False,
_("You don't have the right to add a machine."),
('machines.add_machine',)
)
if user != user_request:
return False, (_("You don't have the right to add a machine"
" to another user."))
return (
False,
_("You don't have the right to add a machine"
" to another user."),
('machines.add_machine',)
)
if user.user_interfaces().count() >= max_lambdauser_interfaces:
return False, (_("You reached the maximum number of interfaces"
return False, _("You reached the maximum number of interfaces"
" that you are allowed to create yourself"
" (%s)." % max_lambdauser_interfaces))
return True, None
" (%s)." % max_lambdauser_interfaces), None
return True, None, None
def can_edit(self, user_request, *args, **kwargs):
"""Vérifie qu'on peut bien éditer cette instance particulière (soit
@ -154,16 +168,22 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison le cas échéant"""
if self.user != user_request:
if (not user_request.has_perm('machines.change_interface') or
not self.user.can_edit(
self.user,
user_request,
*args,
**kwargs
)[0]):
return False, (_("You don't have the right to edit a machine"
" of another user."))
return True, None
can_user, _, permissions = self.user.can_edit(
self.user,
user_request,
*args,
**kwargs
)
if not (
user_request.has_perm('machines.change_interface') and
can_user):
return (
False,
_("You don't have the right to edit a machine"
" of another user."),
('machines.change_interface',) + permissions
)
return True, None, None
def can_delete(self, user_request, *args, **kwargs):
"""Vérifie qu'on peut bien supprimer cette instance particulière (soit
@ -172,16 +192,22 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
:param user_request: instance user qui fait l'edition
:return: True ou False avec la raison de l'échec le cas échéant"""
if self.user != user_request:
if (not user_request.has_perm('machines.change_interface') or
not self.user.can_edit(
self.user,
user_request,
*args,
**kwargs
)[0]):
return False, _("You don't have the right to delete a machine"
" of another user.")
return True, None
can_user, _, permissions = self.user.can_edit(
self.user,
user_request,
*args,
**kwargs
)
if not (
user_request.has_perm('machines.change_interface') and
can_user):
return (
False,
_("You don't have the right to delete a machine"
" of another user."),
('machines.change_interface',) + permissions
)
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien voir cette instance particulière (soit
@ -191,9 +217,13 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
:return: True ou False avec la raison de l'échec le cas échéant"""
if (not user_request.has_perm('machines.view_machine') and
self.user != user_request):
return False, _("You don't have the right to view other machines"
" than yours.")
return True, None
return (
False,
_("You don't have the right to view other machines"
" than yours."),
('machines.view_machine',)
)
return True, None, None
@cached_property
def short_name(self):
@ -285,9 +315,12 @@ class MachineType(RevMixin, AclMixin, models.Model):
message is acces is not allowed.
"""
if not user_request.has_perm('machines.use_all_machinetype'):
return False, (_("You don't have the right to use all machine"
" types."))
return True, None
return (
False,
_("You don't have the right to use all machine types."),
('machines.use_all_machinetype',)
)
return True, None, None
def __str__(self):
return self.name
@ -528,7 +561,11 @@ class IpType(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"""
return user_request.has_perm('machines.use_all_iptype'), None
return (
user_request.has_perm('machines.use_all_iptype'),
None,
('machines.use_all_iptype',)
)
def __str__(self):
return self.name
@ -766,7 +803,11 @@ 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"""
return user_request.has_perm('machines.use_all_extension'), None
return (
user_request.has_perm('machines.use_all_extension'),
_("You cannot use all extensions."),
('machines.use_all_extension',)
)
def __str__(self):
return self.name
@ -1222,31 +1263,42 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
try:
machine = Machine.objects.get(pk=machineid)
except Machine.DoesNotExist:
return False, _("Nonexistent machine.")
return False, _("Nonexistent machine."), None
if not user_request.has_perm('machines.add_interface'):
if not (preferences.models.OptionalMachine
.get_cached_value('create_machine')):
return False, _("You can't add a machine.")
return False, _("You can't add a machine."), ('machines.add_interface',)
max_lambdauser_interfaces = (preferences.models.OptionalMachine
.get_cached_value(
'max_lambdauser_interfaces'
))
if machine.user != user_request:
return False, _("You don't have the right to add an interface"
" to a machine of another user.")
return (
False,
_("You don't have the right to add an interface"
" to a machine of another user."),
('machines.add_interface',)
)
if (machine.user.user_interfaces().count() >=
max_lambdauser_interfaces):
return False, (_("You reached the maximum number of interfaces"
" that you are allowed to create yourself"
" (%s)." % max_lambdauser_interfaces))
return True, None
return (
False,
_("You reached the maximum number of interfaces"
" that you are allowed to create yourself"
" (%s)." % max_lambdauser_interfaces),
('machines.add_interface',)
)
return True, None, None
@staticmethod
def can_change_machine(user_request, *_args, **_kwargs):
"""Check if a user can change the machine associated with an
Interface object """
return (user_request.has_perm('machines.change_interface_machine'),
_("Permission required to edit the machine."))
return (
user_request.has_perm('machines.change_interface_machine'),
_("Permission required to edit the machine."),
('machines.change_interface_machine',)
)
def can_edit(self, user_request, *args, **kwargs):
"""Verifie que l'user a les bons droits infra pour editer
@ -1255,15 +1307,21 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
if self.machine.user != user_request:
if (not user_request.has_perm('machines.change_interface') or
not self.machine.user.can_edit(
user_request,
*args,
**kwargs
)[0]):
return False, _("You don't have the right to edit a machine of"
" another user.")
return True, None
can_user, _, permissions = self.machine.user.can_edit(
user_request,
*args,
**kwargs
)
if not (
user_request.has_perm('machines.change_interface') and
can_user ):
return (
False,
_("You don't have the right to edit a machine of"
" another user."),
('machines.change_interface',) + permissions
)
return True, None, None
def can_delete(self, user_request, *args, **kwargs):
"""Verifie que l'user a les bons droits delete object pour del
@ -1272,15 +1330,21 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
if self.machine.user != user_request:
if (not user_request.has_perm('machines.change_interface') or
not self.machine.user.can_edit(
user_request,
*args,
**kwargs
)[0]):
return False, _("You don't have the right to edit a machine of"
" another user.")
return True, None
can_user, _, permissions = self.machine.user.can_edit(
user_request,
*args,
**kwargs
)
if not (
user_request.has_perm('machines.change_interface') and
can_user):
return (
False,
_("You don't have the right to edit a machine of"
" another user."),
('machines.change_interface',) + permissions
)
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien voir cette instance particulière avec
@ -1290,9 +1354,12 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:return: True ou False avec la raison de l'échec le cas échéant"""
if (not user_request.has_perm('machines.view_interface') and
self.machine.user != user_request):
return False, _("You don't have the right to view machines other"
" than yours.")
return True, None
return (
False,
_("You don't have the right to view machines other than yours."),
('machines.view_interface',)
)
return True, None, None
def __init__(self, *args, **kwargs):
super(Interface, self).__init__(*args, **kwargs)
@ -1340,19 +1407,26 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
try:
interface = Interface.objects.get(pk=interfaceid)
except Interface.DoesNotExist:
return False, _("Nonexistent interface.")
return False, _("Nonexistent interface."), None
if not user_request.has_perm('machines.add_ipv6list'):
if interface.machine.user != user_request:
return False, _("You don't have the right to add an alias to a"
" machine of another user.")
return True, None
return (
False,
_("You don't have the right to add an alias to a"
" machine of another user."),
('machines.add_ipv6list',)
)
return True, None, None
@staticmethod
def can_change_slaac_ip(user_request, *_args, **_kwargs):
""" Check if a user can change the slaac value """
return (user_request.has_perm('machines.change_ipv6list_slaac_ip'),
_("Permission required to change the SLAAC value of an IPv6"
" address"))
return (
user_request.has_perm('machines.change_ipv6list_slaac_ip'),
_("Permission required to change the SLAAC value of an IPv6"
" address"),
('machines.change_ipv6list_slaac_ip',)
)
def can_edit(self, user_request, *args, **kwargs):
"""Verifie que l'user a les bons droits infra pour editer
@ -1361,15 +1435,21 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
if self.interface.machine.user != user_request:
if (not user_request.has_perm('machines.change_ipv6list') or
not self.interface.machine.user.can_edit(
user_request,
*args,
**kwargs
)[0]):
return False, _("You don't have the right to edit a machine of"
" another user.")
return True, None
can_user, _, permissions = self.interface.machine.user.can_edit(
user_request,
*args,
**kwargs
)
if not (
user_request.has_perm('machines.change_ipv6list') and
can_user):
return (
False,
_("You don't have the right to edit a machine of"
" another user."),
('machines.change_ipv6list',)
)
return True, None, None
def can_delete(self, user_request, *args, **kwargs):
"""Verifie que l'user a les bons droits delete object pour del
@ -1378,15 +1458,20 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
if self.interface.machine.user != user_request:
if (not user_request.has_perm('machines.change_ipv6list') or
not self.interface.machine.user.can_edit(
user_request,
*args,
**kwargs
)[0]):
return False, _("You don't have the right to edit a machine of"
" another user.")
return True, None
can_user, _, permissions = self.interface.machine.user.can_edit(
user_request,
*args,
**kwargs
)
if not (user_request.has_perm('machines.change_ipv6list') and
can_user):
return (
False,
_("You don't have the right to edit a machine of"
" another user."),
('machines.change_ipv6list',) + permissions
)
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien voir cette instance particulière avec
@ -1396,9 +1481,12 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
:return: True ou False avec la raison de l'échec le cas échéant"""
if (not user_request.has_perm('machines.view_ipv6list') and
self.interface.machine.user != user_request):
return False, _("You don't have the right to view machines other"
" than yours.")
return True, None
return (
False,
_("You don't have the right to view machines other than yours."),
('machines.view_ipv6list',)
)
return True, None, None
def __init__(self, *args, **kwargs):
super(Ipv6List, self).__init__(*args, **kwargs)
@ -1554,25 +1642,33 @@ class Domain(RevMixin, AclMixin, models.Model):
try:
interface = Interface.objects.get(pk=interfaceid)
except Interface.DoesNotExist:
return False, _("Nonexistent interface.")
return False, _("Nonexistent interface."), None
if not user_request.has_perm('machines.add_domain'):
max_lambdauser_aliases = (preferences.models.OptionalMachine
.get_cached_value(
'max_lambdauser_aliases'
))
if interface.machine.user != user_request:
return False, _("You don't have the right to add an alias to a"
" machine of another user.")
return (
False,
_("You don't have the right to add an alias to a"
" machine of another user."),
('machines.add_domain',)
)
if Domain.objects.filter(
cname__in=Domain.objects.filter(
interface_parent__in=(interface.machine.user
.user_interfaces())
)
).count() >= max_lambdauser_aliases:
return False, _("You reached the maximum number of alias that"
" you are allowed to create yourself (%s). "
% max_lambdauser_aliases)
return True, None
return (
False,
_("You reached the maximum number of alias that"
" you are allowed to create yourself (%s). "
% max_lambdauser_aliases),
('machines.add_domain',)
)
return True, None, None
def can_edit(self, user_request, *_args, **_kwargs):
"""Verifie que l'user a les bons droits pour editer
@ -1582,9 +1678,13 @@ class Domain(RevMixin, AclMixin, models.Model):
:return: soit True, soit False avec la raison de l'échec"""
if (not user_request.has_perm('machines.change_domain') and
self.get_source_interface.machine.user != user_request):
return False, _("You don't have the right to edit an alias of a"
" machine of another user.")
return True, None
return (
False,
_("You don't have the right to edit an alias of a"
" machine of another user."),
('machines.change_domain',)
)
return True, None, None
def can_delete(self, user_request, *_args, **_kwargs):
"""Verifie que l'user a les bons droits delete object pour del
@ -1594,9 +1694,13 @@ class Domain(RevMixin, AclMixin, models.Model):
:return: soit True, soit False avec la raison de l'échec"""
if (not user_request.has_perm('machines.delete_domain') and
self.get_source_interface.machine.user != user_request):
return False, _("You don't have the right to delete an alias of a"
" machine of another user.")
return True, None
return (
False,
_("You don't have the right to delete an alias of a"
" machine of another user."),
('machines.delete_domain',)
)
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
"""Vérifie qu'on peut bien voir cette instance particulière avec
@ -1606,9 +1710,12 @@ class Domain(RevMixin, AclMixin, models.Model):
:return: True ou False avec la raison de l'échec le cas échéant"""
if (not user_request.has_perm('machines.view_domain') and
self.get_source_interface.machine.user != user_request):
return False, _("You don't have the right to view machines other"
" than yours.")
return True, None
return (
False,
_("You don't have the right to view machines other than yours."),
('machines.view_domain',)
)
return True, None, None
def __str__(self):
return str(self.name) + str(self.extension)
@ -1840,11 +1947,14 @@ class OuverturePortList(RevMixin, AclMixin, models.Model):
:param user_request: Utilisateur qui fait la requête
:return: soit True, soit False avec la raison de l'échec"""
if not user_request.has_perm('machines.delete_ouvertureportlist'):
return False, _("You don't have the right to delete a ports"
" opening list.")
return (
False,
_("You don't have the right to delete a ports opening list."),
('machines.delete_ouvertureportlist',)
)
if self.interface_set.all():
return False, _("This ports opening list is used.")
return True, None
return False, _("This ports opening list is used."), None
return True, None, None
def __str__(self):
return self.name

View file

@ -39,6 +39,10 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('preferences')
return can, None if can else _("You don't have the right to view this"
" application.")
return (
can,
None if can else _("You don't have the right to view this"
" application."),
('preferences',)
)

View file

@ -43,7 +43,7 @@ from reversion import revisions as reversion
from importlib import import_module
from re2o.settings_local import OPTIONNAL_APPS_RE2O
from re2o.views import form
from re2o.acl import can_create, can_edit, can_delete_set, can_view_all, can_delete
from re2o.acl import can_create, can_edit, can_delete_set, can_view_all, can_delete, acl_error_message
from .forms import MailContactForm, DelMailContactForm
from .forms import (
@ -130,10 +130,9 @@ def edit_options(request, section):
return redirect(reverse('preferences:display-options'))
options_instance, _created = model.objects.get_or_create()
can, msg = options_instance.can_edit(request.user)
can, msg, permissions = options_instance.can_edit(request.user)
if not can:
messages.error(request, msg or _("You don't have the right to edit"
" this option."))
messages.error(request, acl_error_message(msg, permissions))
return redirect(reverse('index'))
options = form_instance(
request.POST or None,

View file

@ -36,6 +36,28 @@ from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import ugettext as _
from re2o.utils import get_group_having_permission
def acl_error_message(msg, permissions):
"""Create an error message for msg and permissions."""
groups = ", ".join([
g.name for g in get_group_having_permission(*permissions)
])
message = msg or _("You don't have the right to edit"
" this option.")
if groups:
return message + _(
" You need to be a member of one of those"
" groups : %s"
) % groups
else:
return message + " No group have the %s permission(s) !" % " or ".join([
",".join(permissions[:-1]),
permissions[-1]]
if len(permissions) > 2 else permissions
)
def acl_base_decorator(method_name, *targets, on_instance=True):
"""Base decorator for acl. It checks if the `request.user` has the
@ -53,9 +75,10 @@ def acl_base_decorator(method_name, *targets, on_instance=True):
then no error will be triggered, the decorator will act as if
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)` with `can` being a boolean stating whether the
access is granted and `reason` a message to be displayed if `can`
equals `False` (can be `None`)
`(can, reason, permissions)` with `can` being a boolean stating
whether the access is granted, `reason` a message to be
displayed if `can` equals `False` (can be `None`) and `permissions`
a list of permissions needed for access (can be `None`).
*targets: The targets. Targets are specified like a sequence of models
and fields names. As an example
```
@ -139,7 +162,7 @@ ModelC)
target = target.get_instance(*args, **kwargs)
instances.append(target)
except target.DoesNotExist:
yield False, _("Nonexistent entry.")
yield False, _("Nonexistent entry."), []
return
if hasattr(target, method_name):
can_fct = getattr(target, method_name)
@ -148,11 +171,12 @@ ModelC)
can_change_fct = getattr(target, 'can_change_' + field)
yield can_change_fct(request.user, *args, **kwargs)
error_messages = [
x[1] for x in chain.from_iterable(
process_target(x[0], x[1]) for x in group_targets()
) if not x[0]
]
error_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))
if error_messages:
for msg in error_messages:
messages.error(

View file

@ -69,7 +69,7 @@ class FieldPermissionModelMixin:
# Try to find a user setting that qualifies them for permission.
for perm in checks:
if callable(perm):
result, _reason = perm(user_request=user)
result, _reason, _permissions = perm(user_request=user)
if result is not None:
return result
else:

View file

@ -104,12 +104,12 @@ class AclMixin(object):
un 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()
return (
user_request.has_perm(
cls.get_modulename() + '.add_' + cls.get_classname()
),
(_("You don't have the right to create a %s object.")
% cls.get_classname())
user_request.has_perm(permission),
_("You don't have the right to create a %s object.")
% cls.get_classname(),
(permission,)
)
def can_edit(self, user_request, *_args, **_kwargs):
@ -118,12 +118,12 @@ class AclMixin(object):
:param self: Instance à editer
: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()
return (
user_request.has_perm(
self.get_modulename() + '.change_' + self.get_classname()
),
(_("You don't have the right to edit a %s object.")
% self.get_classname())
user_request.has_perm(permission),
_("You don't have the right to edit a %s object.")
% self.get_classname(),
(permission,)
)
def can_delete(self, user_request, *_args, **_kwargs):
@ -132,12 +132,12 @@ class AclMixin(object):
:param self: Instance à delete
: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()
return (
user_request.has_perm(
self.get_modulename() + '.delete_' + self.get_classname()
),
(_("You don't have the right to delete a %s object.")
% self.get_classname())
user_request.has_perm(permission),
_("You don't have the right to delete a %s object.")
% self.get_classname(),
(permission,)
)
@classmethod
@ -146,12 +146,12 @@ class AclMixin(object):
droit particulier view objet correspondant
: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()
return (
user_request.has_perm(
cls.get_modulename() + '.view_' + cls.get_classname()
),
(_("You don't have the right to view every %s object.")
% cls.get_classname())
user_request.has_perm(permission),
_("You don't have the right to view every %s object.")
% cls.get_classname(),
(permission,)
)
def can_view(self, user_request, *_args, **_kwargs):
@ -160,11 +160,11 @@ class AclMixin(object):
:param self: instance à voir
: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()
return (
user_request.has_perm(
self.get_modulename() + '.view_' + self.get_classname()
),
(_("You don't have the right to view a %s object.")
% self.get_classname())
user_request.has_perm(permission),
_("You don't have the right to view a %s object.")
% self.get_classname(),
(permission,)
)

View file

@ -147,6 +147,7 @@ def get_callback(tag_name, obj=None):
return acl_fct(
lambda x: (
not any(not sys.modules[o].can_view(x)[0] for o in obj),
None,
None
),
False
@ -155,28 +156,29 @@ def get_callback(tag_name, obj=None):
return acl_fct(
lambda x: (
not any(not sys.modules[o].can_view(x)[0] for o in obj),
None,
None
),
True
)
if tag_name == 'can_edit_history':
return acl_fct(
lambda user: (user.has_perm('admin.change_logentry'), None),
lambda user: (user.has_perm('admin.change_logentry'), None, None),
False
)
if tag_name == 'cannot_edit_history':
return acl_fct(
lambda user: (user.has_perm('admin.change_logentry'), None),
lambda user: (user.has_perm('admin.change_logentry'), None, None),
True
)
if tag_name == 'can_view_any_app':
return acl_fct(
lambda x: (any(sys.modules[o].can_view(x)[0] for o in obj), None),
lambda x: (any(sys.modules[o].can_view(x)[0] for o in obj), None, None),
False
)
if tag_name == 'cannot_view_any_app':
return acl_fct(
lambda x: (any(sys.modules[o].can_view(x)[0] for o in obj), None),
lambda x: (any(sys.modules[o].can_view(x)[0] for o in obj), None, None),
True
)
@ -194,8 +196,8 @@ def acl_fct(callback, reverse):
def acl_fct_reverse(user, *args, **kwargs):
"""The cannot_xxx checker callback"""
can, msg = callback(user, *args, **kwargs)
return not can, msg
can, msg, permissions = callback(user, *args, **kwargs)
return not can, msg, permissions
return acl_fct_reverse if reverse else acl_fct_normal
@ -217,7 +219,7 @@ def acl_history_filter(parser, token):
assert token.contents == 'acl_end'
return AclNode(callback, oknodes, konodes)
return AclNode(tag_name, callback, oknodes, konodes)
@register.tag('can_view_any_app')
@ -254,7 +256,7 @@ def acl_app_filter(parser, token):
assert token.contents == 'acl_end'
return AclNode(callback, oknodes, konodes)
return AclNode(tag_name, callback, oknodes, konodes)
@register.tag('can_change')
@ -264,7 +266,7 @@ def acl_change_filter(parser, token):
try:
tag_content = token.split_contents()
# tag_name = tag_content[0]
tag_name = tag_content[0]
model_name = tag_content[1]
field_name = tag_content[2]
args = tag_content[3:]
@ -291,7 +293,7 @@ def acl_change_filter(parser, token):
# {% can_create_end %}
assert token.contents == 'acl_end'
return AclNode(callback, oknodes, konodes, *args)
return AclNode(tag_name, callback, oknodes, konodes, *args)
@register.tag('can_create')
@ -333,7 +335,7 @@ def acl_model_filter(parser, token):
# {% can_create_end %}
assert token.contents == 'acl_end'
return AclNode(callback, oknodes, konodes, *args)
return AclNode(tag_name, callback, oknodes, konodes, *args)
@register.tag('can_edit')
@ -377,7 +379,8 @@ class AclNode(Node):
"""A node for the compiled ACL block when acl callback doesn't require
context."""
def __init__(self, callback, oknodes, konodes, *args):
def __init__(self, tag_name, callback, oknodes, konodes, *args):
self.tag_name = tag_name
self.callback = callback
self.oknodes = oknodes
self.konodes = konodes
@ -388,11 +391,14 @@ class AclNode(Node):
if context['user'].is_anonymous():
can = False
else:
can, _ = self.callback(context['user'], *(resolved_args))
can, _, _ = self.callback(context['user'], *(resolved_args))
if can:
return self.oknodes.render(context)
return self.konodes.render(context)
def __repr__(self):
return '<AclNode %s>' % self.tag_name
class AclInstanceNode(Node):
"""A node for the compiled ACL block when acl is based on instance"""
@ -410,7 +416,10 @@ class AclInstanceNode(Node):
if context['user'].is_anonymous():
can = False
else:
can, _ = callback(context['user'], *(resolved_args))
can, _, _ = callback(context['user'], *(resolved_args))
if can:
return self.oknodes.render(context)
return self.konodes.render(context)
def __repr__(self):
return '<AclInstanceNode %s>' % self.tag_name

View file

@ -38,12 +38,23 @@ from __future__ import unicode_literals
from django.utils import timezone
from django.db.models import Q
from django.contrib.auth.models import Permission
from cotisations.models import Cotisation, Facture, Vente
from machines.models import Interface, Machine
from users.models import Adherent, User, Ban, Whitelist
from preferences.models import AssoOption
def get_group_having_permission(*permission_name):
"""Returns every group having the permission `permission_name`
"""
groups = set()
for name in permission_name:
app_label, codename = name.split('.')
permission = Permission.objects.get(content_type__app_label=app_label, codename=codename)
groups = groups.union(permission.group_set.all())
return groups
def all_adherent(search_time=None, including_asso=True):
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
qu'une seule requete sql

View file

@ -17,7 +17,7 @@ class Ticket(AclMixin, models.Model):
"""Model of a ticket"""
user = models.ForeignKey(
'users.User',
'users.User',
on_delete=models.CASCADE,
related_name="tickets",
blank=True,
@ -35,7 +35,7 @@ class Ticket(AclMixin, models.Model):
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(
help_text = _("An email address to get back to you"),
max_length=100,
max_length=100,
null=True)
solved = models.BooleanField(default=False)
@ -67,26 +67,31 @@ class Ticket(AclMixin, models.Model):
GeneralOption.get_cached_value('email_from'),
[to_addr],
fail_silently = False)
def can_view(self, user_request, *_args, **_kwargs):
""" Check that the user has the right to view the ticket
or that it is the author"""
if (not user_request.has_perm('tickets.view_ticket') and self.user != user_request):
return False, _("You don't have the right to view other tickets than yours.")
return (
False,
_("You don't have the right to view other tickets than yours."),
('tickets.view_ticket',)
)
else:
return True, None
return True, None, None
@staticmethod
def can_view_all(user_request, *_args, **_kwargs):
""" Check that the user has access to the list of all tickets"""
return(
user_request.has_perm('tickets.view_tickets'),
_("You don't have the right to view the list of tickets.")
_("You don't have the right to view the list of tickets."),
('tickets.view_tickets',)
)
def can_create(user_request,*_args, **_kwargs):
""" Authorise all users to open tickets """
return True,None
return True, None, None
@receiver(post_save, sender=Ticket)
def ticket_post_save(**kwargs):

View file

@ -39,6 +39,10 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('topologie')
return can, None if can else _("You don't have the right to view this"
" application.")
return (
can,
None if can else _("You don't have the right to view this"
" application."),
('topologie',)
)

View file

@ -38,6 +38,10 @@ def can_view(user):
viewing is granted and msg is a message (can be None).
"""
can = user.has_module_perms('users')
return can, None if can else _("You don't have the right to view this"
" application.")
return (
can,
None if can else _("You don't have the right to view this"
" application."),
('users',)
)

View file

@ -864,29 +864,38 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
if (self == user_request or
user_request.has_perm('users.change_user') or
user_request.adherent in self.club.administrators.all()):
return True, None
return True, None, None
else:
return False, _("You don't have the right to edit this club.")
return False, _("You don't have the right to edit this club."), ('users.change_user',)
else:
if self == user_request:
return True, None
return True, None, None
elif user_request.has_perm('users.change_all_users'):
return True, None
return True, None, None
elif user_request.has_perm('users.change_user'):
if self.groups.filter(listright__critical=True):
return False, (_("User with critical rights, can't be"
" edited."))
return (
False,
_("User with critical rights, can't be edited. "),
('users.change_all_users',)
)
elif self == AssoOption.get_cached_value('utilisateur_asso'):
return False, (_("Impossible to edit the organisation's"
" user without the 'change_all_users'"
" right."))
return (
False,
_("Impossible to edit the organisation's"
" user without the 'change_all_users' right."),
('users.change_all_users', )
)
else:
return True, None
return True, None, None
elif user_request.has_perm('users.change_all_users'):
return True, None
return True, None, None
else:
return False, (_("You don't have the right to edit another"
" user."))
return (
False,
_("You don't have the right to edit another user."),
('users.change_user', 'users.change_all_users')
)
def can_change_password(self, user_request, *_args, **_kwargs):
"""Check if a user can change a user's password
@ -901,27 +910,34 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
if (self == user_request or
user_request.has_perm('users.change_user_password') or
user_request.adherent in self.club.administrators.all()):
return True, None
return True, None, None
else:
return False, _("You don't have the right to edit this club.")
return (
False,
_("You don't have the right to edit this club."),
('users.change_user_password',)
)
else:
if (self == user_request or
user_request.has_perm('users.change_user_groups')):
# Peut éditer les groupes d'un user,
# c'est un privilège élevé, True
return True, None
return True, None, None
elif (user_request.has_perm('users.change_user') and
not self.groups.all()):
return True, None
return True, None, None
else:
return False, (_("You don't have the right to edit another"
" user."))
return (
False,
_("You don't have the right to edit another user."),
('users.change_user_groups', 'users.change_user')
)
def check_selfpasswd(self, user_request, *_args, **_kwargs):
""" Returns (True, None) if user_request is self, else returns
(False, None)
""" Returns (True, None, None) if user_request is self, else returns
(False, None, None)
"""
return user_request == self, None
return user_request == self, None, None
def can_change_room(self, user_request, *_args, **_kwargs):
""" Check if a user can change a room
@ -932,9 +948,13 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_room'))
or user_request.has_perm('users.change_user')):
return False, _("Permission required to change the room.")
return (
False,
_("Permission required to change the room."),
('users.change_user',)
)
else:
return True, None
return True, None, None
@staticmethod
def can_change_state(user_request, *_args, **_kwargs):
@ -946,7 +966,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.has_perm('users.change_user_state'),
_("Permission required to change the state.")
_("Permission required to change the state."),
('users.change_user_state',)
)
def can_change_shell(self, user_request, *_args, **_kwargs):
@ -958,9 +979,13 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
if not ((self.pk == user_request.pk and OptionalUser.get_cached_value('self_change_shell'))
or user_request.has_perm('users.change_user_shell')):
return False, _("Permission required to change the shell.")
return (
False,
_("Permission required to change the shell."),
('users.change_user_shell',)
)
else:
return True, None
return True, None, None
@staticmethod
def can_change_local_email_redirect(user_request, *_args, **_kwargs):
@ -972,7 +997,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
OptionalUser.get_cached_value('local_email_accounts_enabled'),
_("Local email accounts must be enabled.")
_("Local email accounts must be enabled."),
None
)
@staticmethod
@ -985,7 +1011,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
OptionalUser.get_cached_value('local_email_accounts_enabled'),
_("Local email accounts must be enabled.")
_("Local email accounts must be enabled."),
None
)
@staticmethod
@ -998,7 +1025,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.has_perm('users.change_user_force'),
_("Permission required to force the move.")
_("Permission required to force the move."),
('users.change_user_force',)
)
@staticmethod
@ -1011,7 +1039,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.has_perm('users.change_user_groups'),
_("Permission required to edit the user's groups of rights.")
_("Permission required to edit the user's groups of rights."),
('users.change_user_groups')
)
@staticmethod
@ -1023,7 +1052,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.is_superuser,
_("'superuser' right required to edit the superuser flag.")
_("'superuser' right required to edit the superuser flag."),
[]
)
def can_view(self, user_request, *_args, **_kwargs):
@ -1039,16 +1069,23 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
user_request.has_perm('users.view_user') or
user_request.adherent in self.club.administrators.all() or
user_request.adherent in self.club.members.all()):
return True, None
return True, None, None
else:
return False, _("You don't have the right to view this club.")
return (
False,
_("You don't have the right to view this club."),
('users.view_user',)
)
else:
if (self == user_request or
user_request.has_perm('users.view_user')):
return True, None
return True, None, None
else:
return False, (_("You don't have the right to view another"
" user."))
return (
False,
_("You don't have the right to view another user."),
('users.view_user',)
)
@staticmethod
def can_view_all(user_request, *_args, **_kwargs):
@ -1060,7 +1097,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.has_perm('users.view_user'),
_("You don't have the right to view the list of users.")
_("You don't have the right to view the list of users."),
('users.view_user',)
)
def can_delete(self, user_request, *_args, **_kwargs):
@ -1073,7 +1111,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
"""
return (
user_request.has_perm('users.delete_user'),
_("You don't have the right to delete this user.")
_("You don't have the right to delete this user."),
('users.delete_user',)
)
def __init__(self, *args, **kwargs):
@ -1160,15 +1199,16 @@ class Adherent(User):
"""
if (not user_request.is_authenticated and
not OptionalUser.get_cached_value('self_adhesion')):
return False, None
return False, _("Self adhesion is disabled."), None
else:
if (OptionalUser.get_cached_value('all_can_create_adherent') or
OptionalUser.get_cached_value('self_adhesion')):
return True, None
return True, None, None
else:
return (
user_request.has_perm('users.add_user'),
_("You don't have the right to create a user.")
_("You don't have the right to create a user."),
('users.add_user',)
)
def clean(self, *args, **kwargs):
@ -1216,14 +1256,15 @@ class Club(User):
an user or if the `options.all_can_create` is set.
"""
if not user_request.is_authenticated:
return False, None
return False, _("You must be authenticated."), None
else:
if OptionalUser.get_cached_value('all_can_create_club'):
return True, None
return True, None, None
else:
return (
user_request.has_perm('users.add_user'),
_("You don't have the right to create a club.")
_("You don't have the right to create a club."),
('users.add_user',)
)
@staticmethod
@ -1235,13 +1276,17 @@ class Club(User):
message.
"""
if user_request.has_perm('users.view_user'):
return True, None
return True, None, None
if (hasattr(user_request, 'is_class_adherent') and
user_request.is_class_adherent):
if (user_request.adherent.club_administrator.all() or
user_request.adherent.club_members.all()):
return True, None
return False, _("You don't have the right to view the list of users.")
return True, None, None
return (
False,
_("You don't have the right to view the list of users."),
('users.view_user',)
)
@classmethod
def get_instance(cls, clubid, *_args, **_kwargs):
@ -1553,10 +1598,13 @@ class Ban(RevMixin, AclMixin, models.Model):
"""
if (not user_request.has_perm('users.view_ban') and
self.user != user_request):
return False, (_("You don't have the right to view bans other"
" than yours."))
return (
False,
_("You don't have the right to view bans other than yours."),
('users.view_ban',)
)
else:
return True, None
return True, None, None
def __str__(self):
return str(self.user) + ' ' + str(self.raison)
@ -1620,10 +1668,13 @@ class Whitelist(RevMixin, AclMixin, models.Model):
"""
if (not user_request.has_perm('users.view_whitelist') and
self.user != user_request):
return False, (_("You don't have the right to view whitelists"
" other than yours."))
return (
False,
_("You don't have the right to view whitelists other than yours."),
('users.view_whitelist',)
)
else:
return True, None
return True, None, None
def __str__(self):
return str(self.user) + ' ' + str(self.raison)
@ -1892,17 +1943,29 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
a local email account.
"""
if user_request.has_perm('users.add_emailaddress'):
return True, None
return True, None, None
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
return False, _("The local email accounts are not enabled.")
if int(user_request.id) != int(userid):
return False, _("You don't have the right to add a local email"
" account to another user.")
elif user_request.email_address.count() >= OptionalUser.get_cached_value('max_email_address'):
return False, _("You reached the limit of {} local email accounts.").format(
OptionalUser.get_cached_value('max_email_address')
return (
False,
_("The local email accounts are not enabled."),
None
)
return True, None
if int(user_request.id) != int(userid):
return (
False,
_("You don't have the right to add a local email"
" account to another user."),
('users.add_emailaddress',)
)
elif user_request.email_address.count() >= OptionalUser.get_cached_value('max_email_address'):
return (
False,
_("You reached the limit of {} local email accounts.").format(
OptionalUser.get_cached_value('max_email_address')
),
None
)
return True, None, None
def can_view(self, user_request, *_args, **_kwargs):
"""Check if a user can view the local email account
@ -1915,13 +1978,21 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
the local email account.
"""
if user_request.has_perm('users.view_emailaddress'):
return True, None
return True, None, None
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
return False, _("The local email accounts are not enabled.")
return (
False,
_("The local email accounts are not enabled."),
None
)
if user_request == self.user:
return True, None
return False, _("You don't have the right to edit another user's local"
" email account.")
return True, None, None
return (
False,
_("You don't have the right to edit another user's local"
" email account."),
('users.view_emailaddress',)
)
def can_delete(self, user_request, *_args, **_kwargs):
"""Check if a user can delete the alias
@ -1934,16 +2005,24 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
the local email account.
"""
if self.local_part == self.user.pseudo.lower():
return False, _("You can't delete a local email account whose"
" local part is the same as the username.")
return (
False,
_("You can't delete a local email account whose"
" local part is the same as the username."),
None
)
if user_request.has_perm('users.delete_emailaddress'):
return True, None
return True, None, None
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
return False, _("The local email accounts are not enabled.")
return False, _("The local email accounts are not enabled."), None
if user_request == self.user:
return True, None
return False, _("You don't have the right to delete another user's"
" local email account")
return True, None, None
return (
False,
_("You don't have the right to delete another user's"
" local email account"),
('users.delete_emailaddress',)
)
def can_edit(self, user_request, *_args, **_kwargs):
"""Check if a user can edit the alias
@ -1956,16 +2035,24 @@ class EMailAddress(RevMixin, AclMixin, models.Model):
the local email account.
"""
if self.local_part == self.user.pseudo.lower():
return False, _("You can't edit a local email account whose local"
" part is the same as the username.")
return (
False,
_("You can't edit a local email account whose local"
" part is the same as the username."),
None
)
if user_request.has_perm('users.change_emailaddress'):
return True, None
return True, None, None
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
return False, _("The local email accounts are not enabled.")
return False, _("The local email accounts are not enabled."), None
if user_request == self.user:
return True, None
return False, _("You don't have the right to edit another user's local"
" email account.")
return True, None, None
return (
False,
_("You don't have the right to edit another user's local"
" email account."),
('users.change_emailaddress',)
)
def clean(self, *args, **kwargs):
self.local_part = self.local_part.lower()