mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-28 01:43:46 +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.,
|
||||
# 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 import settings
|
||||
from re2o.views import form
|
||||
from re2o.utils import (
|
||||
SortTable,
|
||||
from re2o.utils import SortTable
|
||||
from re2o.acl import (
|
||||
can_create,
|
||||
can_edit,
|
||||
can_delete,
|
||||
|
|
|
@ -21,3 +21,4 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 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_has_access,
|
||||
all_adherent,
|
||||
)
|
||||
from re2o.acl import (
|
||||
can_view_all,
|
||||
can_view_app,
|
||||
can_edit_history,
|
||||
|
|
|
@ -21,3 +21,4 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 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,
|
||||
filter_active_interfaces,
|
||||
SortTable,
|
||||
)
|
||||
from re2o.acl import (
|
||||
can_create,
|
||||
can_edit,
|
||||
can_delete,
|
||||
|
@ -219,7 +221,7 @@ def generate_ipv4_mbf_param( form, is_type_tt ):
|
|||
@can_create(Machine)
|
||||
@can_edit(User)
|
||||
def new_machine(request, user, userid):
|
||||
""" Fonction de creation d'une machine. Cree l'objet machine,
|
||||
""" Fonction de creation d'une machine. Cree l'objet machine,
|
||||
le sous objet interface et l'objet domain à partir de model forms.
|
||||
Trop complexe, devrait être simplifié"""
|
||||
|
||||
|
@ -568,7 +570,7 @@ def add_mx(request):
|
|||
@login_required
|
||||
@can_edit(Mx)
|
||||
def edit_mx(request, mx_instance, mxid):
|
||||
|
||||
|
||||
mx = MxForm(request.POST or None, instance=mx_instance)
|
||||
if mx.is_valid():
|
||||
with transaction.atomic(), reversion.create_revision():
|
||||
|
@ -746,7 +748,7 @@ def add_alias(request, interface, interfaceid):
|
|||
reversion.set_comment("Création")
|
||||
messages.success(request, "Cet alias a été ajouté")
|
||||
return redirect(reverse(
|
||||
'machines:index-alias',
|
||||
'machines:index-alias',
|
||||
kwargs={'interfaceid':str(interfaceid)}
|
||||
))
|
||||
return form({'aliasform': alias}, 'machines/machine.html', request)
|
||||
|
@ -763,7 +765,7 @@ def edit_alias(request, domain_instance, domainid):
|
|||
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in alias.changed_data))
|
||||
messages.success(request, "Alias modifié")
|
||||
return redirect(reverse(
|
||||
'machines:index-alias',
|
||||
'machines:index-alias',
|
||||
kwargs={'interfaceid':str(domain_instance.cname.interface_parent.id)}
|
||||
))
|
||||
return form({'aliasform': alias}, 'machines/machine.html', request)
|
||||
|
@ -783,7 +785,7 @@ def del_alias(request, interface, interfaceid):
|
|||
except ProtectedError:
|
||||
messages.error(request, "Erreur l'alias suivant %s ne peut être supprimé" % alias_del)
|
||||
return redirect(reverse(
|
||||
'machines:index-alias',
|
||||
'machines:index-alias',
|
||||
kwargs={'interfaceid':str(interfaceid)}
|
||||
))
|
||||
return form({'aliasform': alias}, 'machines/machine.html', request)
|
||||
|
|
|
@ -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 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 .models import Service, OptionalUser, OptionalMachine, AssoOption
|
||||
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
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
# 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 Maël Kervella
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
|
|
@ -48,7 +48,7 @@ an instance of a model (either Model.can_xxx or instance.can_xxx)
|
|||
|
||||
**Example**:
|
||||
{% 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 %}
|
||||
<p>Why can't I create a little machine for this guy ? :(</p>
|
||||
{% 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
|
||||
|
||||
"""
|
||||
import sys
|
||||
|
||||
from django import template
|
||||
from django.template.base import Node, NodeList
|
||||
|
||||
from re2o.utils import APP_VIEWING_RIGHT
|
||||
|
||||
import cotisations.models as cotisations
|
||||
import machines.models as machines
|
||||
import preferences.models as preferences
|
||||
import topologie.models as topologie
|
||||
import users.models as users
|
||||
import cotisations
|
||||
import machines
|
||||
import preferences
|
||||
import topologie
|
||||
import users
|
||||
|
||||
register = template.Library()
|
||||
|
||||
MODEL_NAME = {
|
||||
# cotisations
|
||||
'Facture' : cotisations.Facture,
|
||||
'Vente' : cotisations.Vente,
|
||||
'Article' : cotisations.Article,
|
||||
'Banque' : cotisations.Banque,
|
||||
'Paiement' : cotisations.Paiement,
|
||||
'Cotisation' : cotisations.Cotisation,
|
||||
'Facture' : cotisations.models.Facture,
|
||||
'Vente' : cotisations.models.Vente,
|
||||
'Article' : cotisations.models.Article,
|
||||
'Banque' : cotisations.models.Banque,
|
||||
'Paiement' : cotisations.models.Paiement,
|
||||
'Cotisation' : cotisations.models.Cotisation,
|
||||
# machines
|
||||
'Machine' : machines.Machine,
|
||||
'MachineType' : machines.MachineType,
|
||||
'IpType' : machines.IpType,
|
||||
'Vlan' : machines.Vlan,
|
||||
'Nas' : machines.Nas,
|
||||
'SOA' : machines.SOA,
|
||||
'Extension' : machines.Extension,
|
||||
'Mx' : machines.Mx,
|
||||
'Ns' : machines.Ns,
|
||||
'Txt' : machines.Txt,
|
||||
'Srv' : machines.Srv,
|
||||
'Interface' : machines.Interface,
|
||||
'Domain' : machines.Domain,
|
||||
'IpList' : machines.IpList,
|
||||
'Service' : machines.Service,
|
||||
'Service_link' : machines.Service_link,
|
||||
'OuverturePortList' : machines.OuverturePortList,
|
||||
'OuverturePort' : machines.OuverturePort,
|
||||
'Machine' : machines.models.Machine,
|
||||
'MachineType' : machines.models.MachineType,
|
||||
'IpType' : machines.models.IpType,
|
||||
'Vlan' : machines.models.Vlan,
|
||||
'Nas' : machines.models.Nas,
|
||||
'SOA' : machines.models.SOA,
|
||||
'Extension' : machines.models.Extension,
|
||||
'Mx' : machines.models.Mx,
|
||||
'Ns' : machines.models.Ns,
|
||||
'Txt' : machines.models.Txt,
|
||||
'Srv' : machines.models.Srv,
|
||||
'Interface' : machines.models.Interface,
|
||||
'Domain' : machines.models.Domain,
|
||||
'IpList' : machines.models.IpList,
|
||||
'Service' : machines.models.Service,
|
||||
'Service_link' : machines.models.Service_link,
|
||||
'OuverturePortList' : machines.models.OuverturePortList,
|
||||
'OuverturePort' : machines.models.OuverturePort,
|
||||
# preferences
|
||||
'OptionalUser': preferences.OptionalUser,
|
||||
'OptionalMachine': preferences.OptionalMachine,
|
||||
'OptionalTopologie': preferences.OptionalTopologie,
|
||||
'GeneralOption': preferences.GeneralOption,
|
||||
'Service': preferences.Service,
|
||||
'AssoOption': preferences.AssoOption,
|
||||
'MailMessageOption': preferences.MailMessageOption,
|
||||
'OptionalUser': preferences.models.OptionalUser,
|
||||
'OptionalMachine': preferences.models.OptionalMachine,
|
||||
'OptionalTopologie': preferences.models.OptionalTopologie,
|
||||
'GeneralOption': preferences.models.GeneralOption,
|
||||
'Service': preferences.models.Service,
|
||||
'AssoOption': preferences.models.AssoOption,
|
||||
'MailMessageOption': preferences.models.MailMessageOption,
|
||||
# topologie
|
||||
'Stack' : topologie.Stack,
|
||||
'Switch' : topologie.Switch,
|
||||
'ModelSwitch' : topologie.ModelSwitch,
|
||||
'ConstructorSwitch' : topologie.ConstructorSwitch,
|
||||
'Port' : topologie.Port,
|
||||
'Room' : topologie.Room,
|
||||
'Stack' : topologie.models.Stack,
|
||||
'Switch' : topologie.models.Switch,
|
||||
'ModelSwitch' : topologie.models.ModelSwitch,
|
||||
'ConstructorSwitch' : topologie.models.ConstructorSwitch,
|
||||
'Port' : topologie.models.Port,
|
||||
'Room' : topologie.models.Room,
|
||||
# users
|
||||
'User' : users.User,
|
||||
'Adherent' : users.Adherent,
|
||||
'Club' : users.Club,
|
||||
'ServiceUser' : users.ServiceUser,
|
||||
'Right' : users.Right,
|
||||
'School' : users.School,
|
||||
'ListRight' : users.ListRight,
|
||||
'Ban' : users.Ban,
|
||||
'Whitelist' : users.Whitelist,
|
||||
'User' : users.models.User,
|
||||
'Adherent' : users.models.Adherent,
|
||||
'Club' : users.models.Club,
|
||||
'ServiceUser' : users.models.ServiceUser,
|
||||
'Right' : users.models.Right,
|
||||
'School' : users.models.School,
|
||||
'ListRight' : users.models.ListRight,
|
||||
'Ban' : users.models.Ban,
|
||||
'Whitelist' : users.models.Whitelist,
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,21 +180,9 @@ def get_callback(tag_name, obj=None):
|
|||
if tag_name == 'cannot_view_all':
|
||||
return acl_fct(obj.can_view_all, True)
|
||||
if tag_name == 'can_view_app':
|
||||
return acl_fct(
|
||||
lambda user:(
|
||||
user.has_perms((APP_VIEWING_RIGHT[obj],)),
|
||||
"Vous ne pouvez pas voir cette application."
|
||||
),
|
||||
False
|
||||
)
|
||||
return acl_fct(sys.modules[obj].can_view, False)
|
||||
if tag_name == 'cannot_view_app':
|
||||
return acl_fct(
|
||||
lambda user:(
|
||||
user.has_perms((APP_VIEWING_RIGHT[obj],)),
|
||||
"Vous ne pouvez pas voir cette application."
|
||||
),
|
||||
True
|
||||
)
|
||||
return acl_fct(sys.modules[obj].can_view, True)
|
||||
if tag_name == 'can_edit_history':
|
||||
return acl_fct(lambda user:(user.has_perms(('admin',)),None),False)
|
||||
if tag_name == 'cannot_edit_history':
|
||||
|
@ -252,7 +239,7 @@ def acl_app_filter(parser, token):
|
|||
"%r tag require 1 argument : the application"
|
||||
% token.contents.split()[0]
|
||||
)
|
||||
if not app_name in APP_VIEWING_RIGHT.keys():
|
||||
if not app_name in sys.modules.keys():
|
||||
raise template.TemplateSyntaxError(
|
||||
"%r is not a registered application for acl."
|
||||
% app_name
|
||||
|
|
208
re2o/utils.py
208
re2o/utils.py
|
@ -50,214 +50,6 @@ from preferences.models import Service
|
|||
|
||||
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):
|
||||
""" 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.,
|
||||
# 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.,
|
||||
# 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
|
||||
)
|
||||
from users.views import form
|
||||
from re2o.utils import (
|
||||
SortTable,
|
||||
from re2o.utils import SortTable
|
||||
from re2o.acl import (
|
||||
can_create,
|
||||
can_edit,
|
||||
can_delete,
|
||||
|
|
|
@ -21,3 +21,4 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 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 (
|
||||
all_has_access,
|
||||
SortTable,
|
||||
)
|
||||
from re2o.acl import (
|
||||
can_create,
|
||||
can_edit,
|
||||
can_delete_set,
|
||||
|
|
Loading…
Reference in a new issue