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

ACL dans un fichier dédié dans chaque application.

This commit is contained in:
LEVY-FALK Hugo 2017-12-29 01:51:24 +01:00 committed by root
parent 8fbcecd3ea
commit dc38c32ad4
24 changed files with 592 additions and 291 deletions

View file

@ -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
View 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."

View file

@ -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,

View file

@ -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
View 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."

View file

@ -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,

View file

@ -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
View 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."

View file

@ -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,

View file

@ -0,0 +1,2 @@
from .acl import *

39
preferences/acl.py Normal file
View 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."

View file

@ -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
View 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

View file

@ -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

View file

@ -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

View file

@ -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
View 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."

View file

@ -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
View 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."

View file

@ -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,

View file

@ -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
View 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."

View file

@ -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,