mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
helpful acl messages structure
This commit is contained in:
parent
0f063bd187
commit
eaf9609024
2 changed files with 42 additions and 9 deletions
40
re2o/acl.py
40
re2o/acl.py
|
@ -36,6 +36,22 @@ from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from re2o.utils import get_group_having_permission
|
||||||
|
|
||||||
|
|
||||||
|
def group_list(permissions):
|
||||||
|
"""Create a string listing every groups having one of the given
|
||||||
|
`permissions`."""
|
||||||
|
if permissions:
|
||||||
|
return ", ".join([
|
||||||
|
g.name for g in get_group_having_permission(*permissions)
|
||||||
|
]) or "No group have the %s permission(s) !" % " or ".join([
|
||||||
|
",".join(permissions[:-1]),
|
||||||
|
permissions[-1]] if len(permissions) > 2 else permissions
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def acl_base_decorator(method_name, *targets, on_instance=True):
|
def acl_base_decorator(method_name, *targets, on_instance=True):
|
||||||
"""Base decorator for acl. It checks if the `request.user` has the
|
"""Base decorator for acl. It checks if the `request.user` has the
|
||||||
|
@ -53,9 +69,10 @@ def acl_base_decorator(method_name, *targets, on_instance=True):
|
||||||
then no error will be triggered, the decorator will act as if
|
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
|
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
|
fields only. If the method exists, it has to return a 2-tuple
|
||||||
`(can, reason)` with `can` being a boolean stating whether the
|
`(can, reason, permissions)` with `can` being a boolean stating
|
||||||
access is granted and `reason` a message to be displayed if `can`
|
whether the access is granted, `reason` a message to be
|
||||||
equals `False` (can be `None`)
|
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
|
*targets: The targets. Targets are specified like a sequence of models
|
||||||
and fields names. As an example
|
and fields names. As an example
|
||||||
```
|
```
|
||||||
|
@ -139,7 +156,7 @@ ModelC)
|
||||||
target = target.get_instance(*args, **kwargs)
|
target = target.get_instance(*args, **kwargs)
|
||||||
instances.append(target)
|
instances.append(target)
|
||||||
except target.DoesNotExist:
|
except target.DoesNotExist:
|
||||||
yield False, _("Nonexistent entry.")
|
yield False, _("Nonexistent entry."), []
|
||||||
return
|
return
|
||||||
if hasattr(target, method_name):
|
if hasattr(target, method_name):
|
||||||
can_fct = getattr(target, method_name)
|
can_fct = getattr(target, method_name)
|
||||||
|
@ -148,11 +165,16 @@ ModelC)
|
||||||
can_change_fct = getattr(target, 'can_change_' + field)
|
can_change_fct = getattr(target, 'can_change_' + field)
|
||||||
yield can_change_fct(request.user, *args, **kwargs)
|
yield can_change_fct(request.user, *args, **kwargs)
|
||||||
|
|
||||||
error_messages = [
|
error_messages = []
|
||||||
x[1] for x in chain.from_iterable(
|
for target, fields in group_targets():
|
||||||
process_target(x[0], x[1]) for x in group_targets()
|
for can, msg, permissions in process_target(target, fields):
|
||||||
) if not x[0]
|
if not can:
|
||||||
]
|
error_messages.append(
|
||||||
|
msg + _(
|
||||||
|
" You need to be a member of one of those"
|
||||||
|
" groups : %s"
|
||||||
|
) % group_list(permissions)
|
||||||
|
)
|
||||||
if error_messages:
|
if error_messages:
|
||||||
for msg in error_messages:
|
for msg in error_messages:
|
||||||
messages.error(
|
messages.error(
|
||||||
|
|
|
@ -38,12 +38,23 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
from cotisations.models import Cotisation, Facture, Vente
|
from cotisations.models import Cotisation, Facture, Vente
|
||||||
from machines.models import Interface, Machine
|
from machines.models import Interface, Machine
|
||||||
from users.models import Adherent, User, Ban, Whitelist
|
from users.models import Adherent, User, Ban, Whitelist
|
||||||
from preferences.models import AssoOption
|
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):
|
def all_adherent(search_time=None, including_asso=True):
|
||||||
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
|
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
|
||||||
qu'une seule requete sql
|
qu'une seule requete sql
|
||||||
|
|
Loading…
Reference in a new issue