diff --git a/machines/models.py b/machines/models.py index 3a98dcab..f2118e84 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1179,10 +1179,8 @@ class Interface(models.Model): :param self: Instance interface à editer :param user_request: Utilisateur qui fait la requête :return: soit True, soit False avec la raison de l'échec""" - if not user_request.has_perms(('infra',)) and \ - not user_request.has_perms(('cableur',)) and \ - self.machine.user != user_request: - return False, u"Vous ne pouvez pas éditer une machine\ + if not user_request.has_perms(('cableur',)) and self.machine.user != user_request: + return False, u"Vous ne pouvez pas éditer une machine\ d'un autre user que vous sans droit" return True, None @@ -1202,6 +1200,9 @@ class Interface(models.Model): droit particulier cableur correspondant :param user_request: instance user qui fait l'edition :return: True ou False avec la raison de l'échec le cas échéant""" + if not user_request.has_perms(('cableur',)): + return False, u"Vous n'avez pas le droit de voir des machines autre\ + que les vôtres" return True, None def can_view(self, user_request, *args, **kwargs): @@ -1210,7 +1211,7 @@ class Interface(models.Model): :param self: instance interface à voir :param user_request: instance user qui fait l'edition :return: True ou False avec la raison de l'échec le cas échéant""" - if user_request.has_perms(('cableur',)) and self.machine.user != user_request: + if not user_request.has_perms(('cableur',)) and self.machine.user != user_request: return False, u"Vous n'avez pas le droit de voir des machines autre\ que les vôtres" return True, None @@ -1314,6 +1315,18 @@ class Domain(models.Model): self.full_clean() super(Domain, self).save(*args, **kwargs) + @cached_property + def get_source_interface(self): + """Renvoie l'interface source : + - l'interface reliée si c'est un A + - si c'est un cname, suit le cname jusqu'à atteindre le A + et renvoie l'interface parente + Fonction récursive""" + if self.interface_parent: + return self.interface_parent + else: + return self.cname.get_parent_interface() + def get_instance(domainid, *args, **kwargs): """Récupère une instance :param domainid: Instance id à trouver @@ -1352,10 +1365,8 @@ class Domain(models.Model): :param self: Instance domain à editer :param user_request: Utilisateur qui fait la requête :return: soit True, soit False avec la raison de l'échec""" - if not user_request.has_perms(('cableur',)) and ( - self.cname is None or \ - self.cname.interface_parent.machine.user != user_request - ): + if not user_request.has_perms(('cableur',)) and\ + self.get_source_interface.machine.user != user_request: return False, u"Vous ne pouvez pas ajouter un alias à une machine\ d'un autre user que vous sans droit" return True, None @@ -1366,7 +1377,8 @@ class Domain(models.Model): :param self: Instance domain à del :param user_request: Utilisateur qui fait la requête :return: soit True, soit False avec la raison de l'échec""" - if not user_request.has_perms(('cableur',)) and self.machine.user != user_request: + if not user_request.has_perms(('cableur',)) and\ + self.get_source_interface.machine.user != user_request: return False, u"Vous ne pouvez pas supprimer un alias à une machine\ d'un autre user que vous sans droit" return True, None @@ -1387,7 +1399,8 @@ class Domain(models.Model): :param self: instance domain à voir :param user_request: instance user qui fait l'edition :return: True ou False avec la raison de l'échec le cas échéant""" - if user_request.has_perms(('cableur',)) and self.machine.user != user_request: + if not user_request.has_perms(('cableur',)) and\ + self.get_source_interface.machine.user != user_request: return False, u"Vous n'avez pas le droit de voir des machines autre\ que les vôtres" return True, None diff --git a/machines/urls.py b/machines/urls.py index 1bece2f6..3c437f22 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -107,6 +107,6 @@ urlpatterns = [ url(r'^edit_portlist/(?P[0-9]+)$', views.edit_portlist, name='edit-portlist'), url(r'^del_portlist/(?P[0-9]+)$', views.del_portlist, name='del-portlist'), url(r'^add_portlist/$', views.add_portlist, name='add-portlist'), - url(r'^port_config/(?P[0-9]+)$', views.configure_ports, name='port-config'), + url(r'^port_config/(?P[0-9]+)$', views.configure_ports, name='port-config'), ] diff --git a/machines/views.py b/machines/views.py index 1a47ebce..fc12427a 100644 --- a/machines/views.py +++ b/machines/views.py @@ -128,6 +128,7 @@ from re2o.utils import ( can_edit, can_delete, can_view, + can_view_all, can_delete_set, ) from re2o.views import form @@ -304,20 +305,9 @@ def edit_interface(request, interface_instance, interfaceid): return form({'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form, 'i_mbf_param': i_mbf_param}, 'machines/machine.html', request) @login_required -def del_machine(request, machineid): +@can_delete(Machine) +def del_machine(request, machine, machineid): """ Supprime une machine, interfaces en mode cascade""" - try: - machine = Machine.objects.get(pk=machineid) - except Machine.DoesNotExist: - messages.error(request, u"Machine inexistante" ) - return redirect(reverse('machines:index')) - if not request.user.has_perms(('cableur',)): - if machine.user != request.user: - messages.error(request, "Vous ne pouvez pas éditer une machine d'un autre user que vous sans droit") - return redirect(reverse( - 'users:profil', - kwargs={'userid':str(machine.user.id)} - )) if request.method == "POST": with transaction.atomic(), reversion.create_revision(): machine.delete() @@ -935,7 +925,7 @@ def del_nas(request, instances): return form({'nasform': nas}, 'machines/machine.html', request) @login_required -@permission_required('cableur') +@can_view_all(Machine) def index(request): options, created = GeneralOption.objects.get_or_create() pagination_large_number = options.pagination_large_number @@ -959,31 +949,36 @@ def index(request): return render(request, 'machines/index.html', {'machines_list': machines_list}) @login_required -@permission_required('cableur') +@can_view_all(IpType) def index_iptype(request): iptype_list = IpType.objects.select_related('extension').select_related('vlan').order_by('type') return render(request, 'machines/index_iptype.html', {'iptype_list':iptype_list}) @login_required -@permission_required('cableur') +@can_view_all(Vlan) def index_vlan(request): vlan_list = Vlan.objects.prefetch_related('iptype_set').order_by('vlan_id') return render(request, 'machines/index_vlan.html', {'vlan_list':vlan_list}) @login_required -@permission_required('cableur') +@can_view_all(MachineType) def index_machinetype(request): machinetype_list = MachineType.objects.select_related('ip_type').order_by('type') return render(request, 'machines/index_machinetype.html', {'machinetype_list':machinetype_list}) @login_required -@permission_required('cableur') +@can_view_all(Nas) def index_nas(request): nas_list = Nas.objects.select_related('machine_type').select_related('nas_type').order_by('name') return render(request, 'machines/index_nas.html', {'nas_list':nas_list}) @login_required -@permission_required('cableur') +@can_view_all(SOA) +@can_view_all(Mx) +@can_view_all(Ns) +@can_view_all(Txt) +@can_view_all(Srv) +@can_view_all(Extension) def index_extension(request): extension_list = Extension.objects.select_related('origin').select_related('soa').order_by('name') soa_list = SOA.objects.order_by('name') @@ -994,23 +989,13 @@ def index_extension(request): return render(request, 'machines/index_extension.html', {'extension_list':extension_list, 'soa_list': soa_list, 'mx_list': mx_list, 'ns_list': ns_list, 'txt_list' : txt_list, 'srv_list': srv_list}) @login_required -def index_alias(request, interfaceid): - try: - interface = Interface.objects.get(pk=interfaceid) - except Interface.DoesNotExist: - messages.error(request, u"Interface inexistante" ) - return redirect(reverse('machines:index')) - if not request.user.has_perms(('cableur',)) and interface.machine.user != request.user: - messages.error(request, "Vous ne pouvez pas éditer une machine d'un autre user que vous sans droit") - return redirect(reverse( - 'users:profil', - kwargs={'userid':str(request.user.id)} - )) +@can_edit(Interface) +def index_alias(request, interface, interfaceid): alias_list = Domain.objects.filter(cname=Domain.objects.filter(interface_parent=interface)).order_by('name') return render(request, 'machines/index_alias.html', {'alias_list':alias_list, 'interface_id': interfaceid}) @login_required -@permission_required('cableur') +@can_view_all(Service) def index_service(request): service_list = Service.objects.prefetch_related('service_link_set__server__domain__extension').all() servers_list = Service_link.objects.select_related('server__domain__extension').select_related('service').all() @@ -1140,7 +1125,7 @@ def history(request, object, id): @login_required -@permission_required('cableur') +@can_view_all(OuverturePortList) def index_portlist(request): port_list = OuverturePortList.objects.prefetch_related('ouvertureport_set')\ .prefetch_related('interface_set__domain__extension')\ @@ -1211,13 +1196,9 @@ def add_portlist(request): return form({'machineform' : port_list}, 'machines/machine.html', request) @login_required -@permission_required('cableur') -def configure_ports(request, pk): - try: - interface_instance = Interface.objects.get(pk=pk) - except Interface.DoesNotExist: - messages.error(request, u"Interface inexistante" ) - return redirect(reverse('machines:index')) +@can_create(OuverturePort) +@can_edit(Interface) +def configure_ports(request, interface_instance, interfaceid): if not interface_instance.may_have_port_open(): messages.error(request, "Attention, l'ipv4 n'est pas publique, l'ouverture n'aura pas d'effet en v4") interface = EditOuverturePortConfigForm(request.POST or None, instance=interface_instance) diff --git a/re2o/utils.py b/re2o/utils.py index 9c76d16e..47a94ee7 100644 --- a/re2o/utils.py +++ b/re2o/utils.py @@ -172,6 +172,22 @@ def can_view(model): 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 all_adherent(search_time=DT_NOW): """ Fonction renvoyant tous les users adherents. Optimisee pour n'est qu'une seule requete sql