mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 11:23:10 +00:00
ACL dans un fichier dédié dans chaque application.
This commit is contained in:
parent
8fbcecd3ea
commit
dc38c32ad4
24 changed files with 592 additions and 291 deletions
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
cotisations/acl.py
Normal file
39
cotisations/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
""".acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -43,8 +43,8 @@ from users.models import User
|
||||||
from re2o.settings import LOGO_PATH
|
from re2o.settings import LOGO_PATH
|
||||||
from re2o import settings
|
from re2o import settings
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from re2o.utils import (
|
from re2o.utils import SortTable
|
||||||
SortTable,
|
from re2o.acl import (
|
||||||
can_create,
|
can_create,
|
||||||
can_edit,
|
can_edit,
|
||||||
can_delete,
|
can_delete,
|
||||||
|
|
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
logs/acl.py
Normal file
39
logs/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""logs.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -98,6 +98,8 @@ from re2o.utils import (
|
||||||
all_baned,
|
all_baned,
|
||||||
all_has_access,
|
all_has_access,
|
||||||
all_adherent,
|
all_adherent,
|
||||||
|
)
|
||||||
|
from re2o.acl import (
|
||||||
can_view_all,
|
can_view_all,
|
||||||
can_view_app,
|
can_view_app,
|
||||||
can_edit_history,
|
can_edit_history,
|
||||||
|
|
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
machines/acl.py
Normal file
39
machines/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""machines.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -124,6 +124,8 @@ from re2o.utils import (
|
||||||
all_has_access,
|
all_has_access,
|
||||||
filter_active_interfaces,
|
filter_active_interfaces,
|
||||||
SortTable,
|
SortTable,
|
||||||
|
)
|
||||||
|
from re2o.acl import (
|
||||||
can_create,
|
can_create,
|
||||||
can_edit,
|
can_edit,
|
||||||
can_delete,
|
can_delete,
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
from .acl import *
|
39
preferences/acl.py
Normal file
39
preferences/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""preferences.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -42,7 +42,7 @@ from reversion.models import Version
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
|
|
||||||
from re2o.views import form
|
from re2o.views import form
|
||||||
from re2o.utils import can_create, can_edit, can_delete_set, can_view_all
|
from re2o.acl import can_create, can_edit, can_delete_set, can_view_all
|
||||||
from .forms import ServiceForm, DelServiceForm
|
from .forms import ServiceForm, DelServiceForm
|
||||||
from .models import Service, OptionalUser, OptionalMachine, AssoOption
|
from .models import Service, OptionalUser, OptionalMachine, AssoOption
|
||||||
from .models import MailMessageOption, GeneralOption, OptionalTopologie
|
from .models import MailMessageOption, GeneralOption, OptionalTopologie
|
||||||
|
|
235
re2o/acl.py
Normal file
235
re2o/acl.py
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""Handles ACL for re2o.
|
||||||
|
|
||||||
|
Here are defined some decorators that can be used in views to handle ACL.
|
||||||
|
"""
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
import cotisations, logs, machines, preferences, search, topologie, users
|
||||||
|
|
||||||
|
|
||||||
|
def can_create(model):
|
||||||
|
"""Decorator to check if an user can create a model.
|
||||||
|
It assumes that a valid user exists in the request and that the model has a
|
||||||
|
method can_create(user) which returns true if the user can create this kind
|
||||||
|
of models.
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
can, msg = model.can_create(request.user, *args, **kwargs)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_edit(model, *field_list):
|
||||||
|
"""Decorator to check if an user can edit a model.
|
||||||
|
It tries to get an instance of the model, using
|
||||||
|
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
||||||
|
method `can_edit(user)` which returns `true` if the user can edit this
|
||||||
|
kind of models.
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
instance = model.get_instance(*args, **kwargs)
|
||||||
|
except model.DoesNotExist:
|
||||||
|
messages.error(request, u"Entrée inexistante")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
can, msg = instance.can_edit(request.user)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
for field in field_list:
|
||||||
|
can_create = getattr(model, 'can_change_' + field)
|
||||||
|
can, msg = can_create(instance, request.user, *args, **kwargs)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, instance, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_change(model, *field_list):
|
||||||
|
"""Decorator to check if an user can edit a field of a model class.
|
||||||
|
Difference with can_edit : take a class and not an instance
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
for field in field_list:
|
||||||
|
can_create = getattr(model, 'can_change_' + field)
|
||||||
|
can, msg = can_create(request.user, *args, **kwargs)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_delete(model):
|
||||||
|
"""Decorator to check if an user can delete a model.
|
||||||
|
It tries to get an instance of the model, using
|
||||||
|
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
||||||
|
method `can_delete(user)` which returns `true` if the user can delete this
|
||||||
|
kind of models.
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
instance = model.get_instance(*args, **kwargs)
|
||||||
|
except model.DoesNotExist:
|
||||||
|
messages.error(request, u"Entrée inexistante")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
can, msg = instance.can_delete(request.user)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, instance, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_delete_set(model):
|
||||||
|
"""Decorator which returns a list of detable models by request user.
|
||||||
|
If none of them, return an error"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
all_objects = model.objects.all()
|
||||||
|
instances_id = []
|
||||||
|
for instance in all_objects:
|
||||||
|
can, msg = instance.can_delete(request.user)
|
||||||
|
if can:
|
||||||
|
instances_id.append(instance.id)
|
||||||
|
instances = model.objects.filter(id__in=instances_id)
|
||||||
|
if not instances:
|
||||||
|
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, instances, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_view(model):
|
||||||
|
"""Decorator to check if an user can view a model.
|
||||||
|
It tries to get an instance of the model, using
|
||||||
|
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
||||||
|
method `can_view(user)` which returns `true` if the user can view this
|
||||||
|
kind of models.
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
instance = model.get_instance(*args, **kwargs)
|
||||||
|
except model.DoesNotExist:
|
||||||
|
messages.error(request, u"Entrée inexistante")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
can, msg = instance.can_view(request.user)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, instance, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_view_all(model):
|
||||||
|
"""Decorator to check if an user can view a class of model.
|
||||||
|
"""
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
can, msg = model.can_view_all(request.user)
|
||||||
|
if not can:
|
||||||
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return view(request, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_view_app(app_name):
|
||||||
|
"""Decorator to check if an user can view an application.
|
||||||
|
"""
|
||||||
|
assert app_name in sys.modules.keys()
|
||||||
|
def decorator(view):
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
app = sys.modules[app_name]
|
||||||
|
can,msg = app.can_view(request.user)
|
||||||
|
if can:
|
||||||
|
return view(request, *args, **kwargs)
|
||||||
|
messages.error(request, msg)
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def can_edit_history(view):
|
||||||
|
"""Decorator to check if an user can edit history."""
|
||||||
|
def wrapper(request, *args, **kwargs):
|
||||||
|
if request.user.has_perms(('admin',)):
|
||||||
|
return view(request, *args, **kwargs)
|
||||||
|
messages.error(
|
||||||
|
request,
|
||||||
|
"Vous ne pouvez pas éditer l'historique."
|
||||||
|
)
|
||||||
|
return redirect(reverse('users:profil',
|
||||||
|
kwargs={'userid':str(request.user.id)}
|
||||||
|
))
|
||||||
|
return wrapper
|
||||||
|
|
|
@ -48,7 +48,7 @@ an instance of a model (either Model.can_xxx or instance.can_xxx)
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
{% can_create Machine targeted_user %}
|
{% can_create Machine targeted_user %}
|
||||||
<p>I'm authorized to create new machines for this guy \\o/</p>
|
<p>I'm authorized to create new machines.models.for this guy \\o/</p>
|
||||||
{% acl_else %}
|
{% acl_else %}
|
||||||
<p>Why can't I create a little machine for this guy ? :(</p>
|
<p>Why can't I create a little machine for this guy ? :(</p>
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
|
@ -70,72 +70,71 @@ an instance of a model (either Model.can_xxx or instance.can_xxx)
|
||||||
the acl function exists in the model definition
|
the acl function exists in the model definition
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.template.base import Node, NodeList
|
from django.template.base import Node, NodeList
|
||||||
|
|
||||||
from re2o.utils import APP_VIEWING_RIGHT
|
import cotisations
|
||||||
|
import machines
|
||||||
import cotisations.models as cotisations
|
import preferences
|
||||||
import machines.models as machines
|
import topologie
|
||||||
import preferences.models as preferences
|
import users
|
||||||
import topologie.models as topologie
|
|
||||||
import users.models as users
|
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
MODEL_NAME = {
|
MODEL_NAME = {
|
||||||
# cotisations
|
# cotisations
|
||||||
'Facture' : cotisations.Facture,
|
'Facture' : cotisations.models.Facture,
|
||||||
'Vente' : cotisations.Vente,
|
'Vente' : cotisations.models.Vente,
|
||||||
'Article' : cotisations.Article,
|
'Article' : cotisations.models.Article,
|
||||||
'Banque' : cotisations.Banque,
|
'Banque' : cotisations.models.Banque,
|
||||||
'Paiement' : cotisations.Paiement,
|
'Paiement' : cotisations.models.Paiement,
|
||||||
'Cotisation' : cotisations.Cotisation,
|
'Cotisation' : cotisations.models.Cotisation,
|
||||||
# machines
|
# machines
|
||||||
'Machine' : machines.Machine,
|
'Machine' : machines.models.Machine,
|
||||||
'MachineType' : machines.MachineType,
|
'MachineType' : machines.models.MachineType,
|
||||||
'IpType' : machines.IpType,
|
'IpType' : machines.models.IpType,
|
||||||
'Vlan' : machines.Vlan,
|
'Vlan' : machines.models.Vlan,
|
||||||
'Nas' : machines.Nas,
|
'Nas' : machines.models.Nas,
|
||||||
'SOA' : machines.SOA,
|
'SOA' : machines.models.SOA,
|
||||||
'Extension' : machines.Extension,
|
'Extension' : machines.models.Extension,
|
||||||
'Mx' : machines.Mx,
|
'Mx' : machines.models.Mx,
|
||||||
'Ns' : machines.Ns,
|
'Ns' : machines.models.Ns,
|
||||||
'Txt' : machines.Txt,
|
'Txt' : machines.models.Txt,
|
||||||
'Srv' : machines.Srv,
|
'Srv' : machines.models.Srv,
|
||||||
'Interface' : machines.Interface,
|
'Interface' : machines.models.Interface,
|
||||||
'Domain' : machines.Domain,
|
'Domain' : machines.models.Domain,
|
||||||
'IpList' : machines.IpList,
|
'IpList' : machines.models.IpList,
|
||||||
'Service' : machines.Service,
|
'Service' : machines.models.Service,
|
||||||
'Service_link' : machines.Service_link,
|
'Service_link' : machines.models.Service_link,
|
||||||
'OuverturePortList' : machines.OuverturePortList,
|
'OuverturePortList' : machines.models.OuverturePortList,
|
||||||
'OuverturePort' : machines.OuverturePort,
|
'OuverturePort' : machines.models.OuverturePort,
|
||||||
# preferences
|
# preferences
|
||||||
'OptionalUser': preferences.OptionalUser,
|
'OptionalUser': preferences.models.OptionalUser,
|
||||||
'OptionalMachine': preferences.OptionalMachine,
|
'OptionalMachine': preferences.models.OptionalMachine,
|
||||||
'OptionalTopologie': preferences.OptionalTopologie,
|
'OptionalTopologie': preferences.models.OptionalTopologie,
|
||||||
'GeneralOption': preferences.GeneralOption,
|
'GeneralOption': preferences.models.GeneralOption,
|
||||||
'Service': preferences.Service,
|
'Service': preferences.models.Service,
|
||||||
'AssoOption': preferences.AssoOption,
|
'AssoOption': preferences.models.AssoOption,
|
||||||
'MailMessageOption': preferences.MailMessageOption,
|
'MailMessageOption': preferences.models.MailMessageOption,
|
||||||
# topologie
|
# topologie
|
||||||
'Stack' : topologie.Stack,
|
'Stack' : topologie.models.Stack,
|
||||||
'Switch' : topologie.Switch,
|
'Switch' : topologie.models.Switch,
|
||||||
'ModelSwitch' : topologie.ModelSwitch,
|
'ModelSwitch' : topologie.models.ModelSwitch,
|
||||||
'ConstructorSwitch' : topologie.ConstructorSwitch,
|
'ConstructorSwitch' : topologie.models.ConstructorSwitch,
|
||||||
'Port' : topologie.Port,
|
'Port' : topologie.models.Port,
|
||||||
'Room' : topologie.Room,
|
'Room' : topologie.models.Room,
|
||||||
# users
|
# users
|
||||||
'User' : users.User,
|
'User' : users.models.User,
|
||||||
'Adherent' : users.Adherent,
|
'Adherent' : users.models.Adherent,
|
||||||
'Club' : users.Club,
|
'Club' : users.models.Club,
|
||||||
'ServiceUser' : users.ServiceUser,
|
'ServiceUser' : users.models.ServiceUser,
|
||||||
'Right' : users.Right,
|
'Right' : users.models.Right,
|
||||||
'School' : users.School,
|
'School' : users.models.School,
|
||||||
'ListRight' : users.ListRight,
|
'ListRight' : users.models.ListRight,
|
||||||
'Ban' : users.Ban,
|
'Ban' : users.models.Ban,
|
||||||
'Whitelist' : users.Whitelist,
|
'Whitelist' : users.models.Whitelist,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,21 +180,9 @@ def get_callback(tag_name, obj=None):
|
||||||
if tag_name == 'cannot_view_all':
|
if tag_name == 'cannot_view_all':
|
||||||
return acl_fct(obj.can_view_all, True)
|
return acl_fct(obj.can_view_all, True)
|
||||||
if tag_name == 'can_view_app':
|
if tag_name == 'can_view_app':
|
||||||
return acl_fct(
|
return acl_fct(sys.modules[obj].can_view, False)
|
||||||
lambda user:(
|
|
||||||
user.has_perms((APP_VIEWING_RIGHT[obj],)),
|
|
||||||
"Vous ne pouvez pas voir cette application."
|
|
||||||
),
|
|
||||||
False
|
|
||||||
)
|
|
||||||
if tag_name == 'cannot_view_app':
|
if tag_name == 'cannot_view_app':
|
||||||
return acl_fct(
|
return acl_fct(sys.modules[obj].can_view, True)
|
||||||
lambda user:(
|
|
||||||
user.has_perms((APP_VIEWING_RIGHT[obj],)),
|
|
||||||
"Vous ne pouvez pas voir cette application."
|
|
||||||
),
|
|
||||||
True
|
|
||||||
)
|
|
||||||
if tag_name == 'can_edit_history':
|
if tag_name == 'can_edit_history':
|
||||||
return acl_fct(lambda user:(user.has_perms(('admin',)),None),False)
|
return acl_fct(lambda user:(user.has_perms(('admin',)),None),False)
|
||||||
if tag_name == 'cannot_edit_history':
|
if tag_name == 'cannot_edit_history':
|
||||||
|
@ -252,7 +239,7 @@ def acl_app_filter(parser, token):
|
||||||
"%r tag require 1 argument : the application"
|
"%r tag require 1 argument : the application"
|
||||||
% token.contents.split()[0]
|
% token.contents.split()[0]
|
||||||
)
|
)
|
||||||
if not app_name in APP_VIEWING_RIGHT.keys():
|
if not app_name in sys.modules.keys():
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r is not a registered application for acl."
|
"%r is not a registered application for acl."
|
||||||
% app_name
|
% app_name
|
||||||
|
|
208
re2o/utils.py
208
re2o/utils.py
|
@ -50,214 +50,6 @@ from preferences.models import Service
|
||||||
|
|
||||||
DT_NOW = timezone.now()
|
DT_NOW = timezone.now()
|
||||||
|
|
||||||
def can_create(model):
|
|
||||||
"""Decorator to check if an user can create a model.
|
|
||||||
It assumes that a valid user exists in the request and that the model has a
|
|
||||||
method can_create(user) which returns true if the user can create this kind
|
|
||||||
of models.
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
can, msg = model.can_create(request.user, *args, **kwargs)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_edit(model, *field_list):
|
|
||||||
"""Decorator to check if an user can edit a model.
|
|
||||||
It tries to get an instance of the model, using
|
|
||||||
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
|
||||||
method `can_edit(user)` which returns `true` if the user can edit this
|
|
||||||
kind of models.
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
instance = model.get_instance(*args, **kwargs)
|
|
||||||
except model.DoesNotExist:
|
|
||||||
messages.error(request, u"Entrée inexistante")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
can, msg = instance.can_edit(request.user)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
for field in field_list:
|
|
||||||
can_create = getattr(model, 'can_change_' + field)
|
|
||||||
can, msg = can_create(instance, request.user, *args, **kwargs)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, instance, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_change(model, *field_list):
|
|
||||||
"""Decorator to check if an user can edit a field of a model class.
|
|
||||||
Difference with can_edit : take a class and not an instance
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
for field in field_list:
|
|
||||||
can_create = getattr(model, 'can_change_' + field)
|
|
||||||
can, msg = can_create(None, request.user, *args, **kwargs)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_delete(model):
|
|
||||||
"""Decorator to check if an user can delete a model.
|
|
||||||
It tries to get an instance of the model, using
|
|
||||||
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
|
||||||
method `can_delete(user)` which returns `true` if the user can delete this
|
|
||||||
kind of models.
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
instance = model.get_instance(*args, **kwargs)
|
|
||||||
except model.DoesNotExist:
|
|
||||||
messages.error(request, u"Entrée inexistante")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
can, msg = instance.can_delete(request.user)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, instance, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_delete_set(model):
|
|
||||||
"""Decorator which returns a list of detable models by request user.
|
|
||||||
If none of them, return an error"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
all_objects = model.objects.all()
|
|
||||||
instances_id = []
|
|
||||||
for instance in all_objects:
|
|
||||||
can, msg = instance.can_delete(request.user)
|
|
||||||
if can:
|
|
||||||
instances_id.append(instance.id)
|
|
||||||
instances = model.objects.filter(id__in=instances_id)
|
|
||||||
if not instances:
|
|
||||||
messages.error(request, "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, instances, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_view(model):
|
|
||||||
"""Decorator to check if an user can view a model.
|
|
||||||
It tries to get an instance of the model, using
|
|
||||||
`model.get_instance(*args, **kwargs)` and assumes that the model has a
|
|
||||||
method `can_view(user)` which returns `true` if the user can view this
|
|
||||||
kind of models.
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
instance = model.get_instance(*args, **kwargs)
|
|
||||||
except model.DoesNotExist:
|
|
||||||
messages.error(request, u"Entrée inexistante")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
can, msg = instance.can_view(request.user)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, instance, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_view_all(model):
|
|
||||||
"""Decorator to check if an user can view a class of model.
|
|
||||||
"""
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
can, msg = model.can_view_all(request.user)
|
|
||||||
if not can:
|
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return view(request, *args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
APP_VIEWING_RIGHT = {
|
|
||||||
'cotisations' : 'cableur',
|
|
||||||
'logs' : 'cableur',
|
|
||||||
'machines' : 'cableur',
|
|
||||||
'preferences' : 'cableur',
|
|
||||||
'search' : 'cableur',
|
|
||||||
'topologie' : 'cableur',
|
|
||||||
'users' : 'cableur',
|
|
||||||
}
|
|
||||||
|
|
||||||
def can_view_app(app_name):
|
|
||||||
"""Decorator to check if an user can view an application.
|
|
||||||
"""
|
|
||||||
assert app_name in APP_VIEWING_RIGHT.keys()
|
|
||||||
def decorator(view):
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
if request.user.has_perms((APP_VIEWING_RIGHT[app_name],)):
|
|
||||||
return view(request, *args, **kwargs)
|
|
||||||
messages.error(
|
|
||||||
request,
|
|
||||||
msg or "Vous ne pouvez pas accéder à l'application " + app_name
|
|
||||||
)
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return wrapper
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def can_edit_history(view):
|
|
||||||
"""Decorator to check if an user can edit history."""
|
|
||||||
def wrapper(request, *args, **kwargs):
|
|
||||||
if request.user.has_perms(('admin',)):
|
|
||||||
return view(request, *args, **kwargs)
|
|
||||||
messages.error(
|
|
||||||
request,
|
|
||||||
"Vous ne pouvez pas éditer l'historique."
|
|
||||||
)
|
|
||||||
return redirect(reverse('users:profil',
|
|
||||||
kwargs={'userid':str(request.user.id)}
|
|
||||||
))
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
def all_adherent(search_time=DT_NOW):
|
def all_adherent(search_time=DT_NOW):
|
||||||
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
|
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
|
||||||
|
|
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
search/acl.py
Normal file
39
search/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""search.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
topologie/acl.py
Normal file
39
topologie/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""topologie.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -65,8 +65,8 @@ from topologie.forms import (
|
||||||
CreatePortsForm
|
CreatePortsForm
|
||||||
)
|
)
|
||||||
from users.views import form
|
from users.views import form
|
||||||
from re2o.utils import (
|
from re2o.utils import SortTable
|
||||||
SortTable,
|
from re2o.acl import (
|
||||||
can_create,
|
can_create,
|
||||||
can_edit,
|
can_edit,
|
||||||
can_delete,
|
can_delete,
|
||||||
|
|
|
@ -21,3 +21,4 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from .acl import *
|
||||||
|
|
39
users/acl.py
Normal file
39
users/acl.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
# quelques clics.
|
||||||
|
#
|
||||||
|
# Copyright © 2017 Gabriel Détraz
|
||||||
|
# Copyright © 2017 Goulven Kermarec
|
||||||
|
# Copyright © 2017 Augustin Lemesle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""users.acl
|
||||||
|
|
||||||
|
Here are defined some functions to check acl on the application.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def can_view(user):
|
||||||
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user: The user who wants to view the application.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A couple (allowed, msg) where allowed is a boolean which is True if
|
||||||
|
viewing is granted and msg is a message (can be None).
|
||||||
|
"""
|
||||||
|
can = user.has_perms(('cableur',))
|
||||||
|
return can, None if can else "Vous ne pouvez pas voir cette application."
|
|
@ -93,6 +93,8 @@ from re2o.views import form
|
||||||
from re2o.utils import (
|
from re2o.utils import (
|
||||||
all_has_access,
|
all_has_access,
|
||||||
SortTable,
|
SortTable,
|
||||||
|
)
|
||||||
|
from re2o.acl import (
|
||||||
can_create,
|
can_create,
|
||||||
can_edit,
|
can_edit,
|
||||||
can_delete_set,
|
can_delete_set,
|
||||||
|
|
Loading…
Reference in a new issue