views.py 36.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 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.

23
# App de gestion des machines pour re2o
Dalahro's avatar
Dalahro committed
24
# Gabriel Détraz, Augustin Lemesle
25
# Gplv2
Dalahro's avatar
Dalahro committed
26
from django.http import HttpResponse
27
from django.shortcuts import render, redirect
28 29
from django.shortcuts import get_object_or_404
from django.template.context_processors import csrf
30
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
31 32
from django.template import Context, RequestContext, loader
from django.contrib import messages
33
from django.contrib.auth.decorators import login_required, permission_required
34
from django.db.models import ProtectedError
35
from django.forms import ValidationError
36
from django.db import transaction
Dalahro's avatar
Dalahro committed
37 38
from django.contrib.auth import authenticate, login
from django.views.decorators.csrf import csrf_exempt
39

Dalahro's avatar
Dalahro committed
40
from rest_framework.renderers import JSONRenderer
chirac's avatar
chirac committed
41
from machines.serializers import InterfaceSerializer, TypeSerializer, DomainSerializer, MxSerializer, ExtensionSerializer, NsSerializer
42
from reversion import revisions as reversion
root's avatar
root committed
43
from reversion.models import Version
Dalahro's avatar
Dalahro committed
44

45
import re
46
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
47
from .forms import IpTypeForm, DelIpTypeForm, AliasForm, DelAliasForm, NsForm, DelNsForm, MxForm, DelMxForm
chirac's avatar
chirac committed
48
from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain
49
from users.models import User
50
from re2o.settings import PAGINATION_NUMBER, PAGINATION_LARGE_NUMBER, MAX_INTERFACES, MAX_ALIAS
51

chirac's avatar
chirac committed
52
def full_domain_validator(request, domain):
53 54
    """ Validation du nom de domaine, extensions dans type de machine, prefixe pas plus long que 63 caractères """
    HOSTNAME_LABEL_PATTERN = re.compile("(?!-)[A-Z\d-]+(?<!-)$", re.IGNORECASE)
chirac's avatar
chirac committed
55
    dns = domain.name.lower()
chirac's avatar
chirac committed
56
    if len(dns) > 63:
57 58 59
        messages.error(request,
                "Le nom de domaine %s est trop long (maximum de 63 caractères)." % dns)
        return False
chirac's avatar
chirac committed
60
    if not HOSTNAME_LABEL_PATTERN.match(dns):
61 62 63 64 65
        messages.error(request,
                "Ce nom de domaine %s contient des carractères interdits." % dns)
        return False
    return True

66
def unassign_ips(user):
67
    machines = user.user_interfaces()
68
    for machine in machines:
69 70 71 72 73
        unassign_ipv4(machine)
    return

def assign_ips(user):
    """ Assign une ipv4 aux machines d'un user """
74
    machines = user.user_interfaces()
75 76 77
    for machine in machines:
        if not machine.ipv4:
            interface = assign_ipv4(machine)
78 79 80
            with transaction.atomic(), reversion.create_revision():
                reversion.set_comment("Assignation ipv4")
                interface.save()
81 82
    return

83
def free_ip(type):
84
    """ Renvoie la liste des ip disponibles """
85 86 87 88
    if not type.need_infra:
        return IpList.objects.filter(interface__isnull=True).filter(ip_type=type).filter(need_infra=False)
    else:
        return IpList.objects.filter(interface__isnull=True).filter(ip_type=type)
89 90 91

def assign_ipv4(interface):
    """ Assigne une ip à l'interface """
92
    free_ips = free_ip(interface.type.ip_type)
93 94 95 96
    if free_ips:
        interface.ipv4 = free_ips[0]
    return interface

97 98
def unassign_ipv4(interface):
    interface.ipv4 = None
99 100 101
    with transaction.atomic(), reversion.create_revision():
        reversion.set_comment("Désassignation ipv4")
        interface.save()
102

103 104 105
def form(ctx, template, request):
    c = ctx
    c.update(csrf(request))
106
    return render(request, template, c)
107

chirac's avatar
chirac committed
108
@login_required
109 110 111 112 113 114
def new_machine(request, userid):
    try:
        user = User.objects.get(pk=userid)
    except User.DoesNotExist:
        messages.error(request, u"Utilisateur inexistant" )
        return redirect("/machines/")
115 116 117 118 119 120 121
    if not request.user.has_perms(('cableur',)):
        if user != request.user:
            messages.error(request, "Vous ne pouvez pas ajouter une machine à un autre user que vous sans droit")
            return redirect("/users/profil/" + str(request.user.id))
        if user.user_interfaces().count() >= MAX_INTERFACES:
            messages.error(request, "Vous avez atteint le maximum d'interfaces autorisées que vous pouvez créer vous même (%s) " % MAX_INTERFACES)
            return redirect("/users/profil/" + str(request.user.id))
122
    machine = NewMachineForm(request.POST or None)
123
    interface = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',))) 
Dalahro's avatar
Dalahro committed
124
    nb_machine = Interface.objects.filter(machine__user=userid).count()
Dalahro's avatar
Dalahro committed
125
    domain = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',)), name_user=user.surname, nb_machine=nb_machine)
126
    try:
127
        if machine.is_valid() and interface.is_valid() and domain.is_valid():
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
            new_machine = machine.save(commit=False)
            new_machine.user = user
            new_interface = interface.save(commit=False)
            new_domain = domain.save(commit=False)
            if full_domain_validator(request, new_domain):
                with transaction.atomic(), reversion.create_revision():
                    new_machine.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                new_interface.machine = new_machine
                if free_ip(new_interface.type.ip_type) and not new_interface.ipv4:
                    new_interface = assign_ipv4(new_interface)
                elif not new_interface.ipv4:
                    messages.error(request, u"Il n'y a plus d'ip disponibles")
                with transaction.atomic(), reversion.create_revision():
                    new_interface.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                new_domain.interface_parent = new_interface
                with transaction.atomic(), reversion.create_revision():
                    new_domain.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                messages.success(request, "La machine a été crée")
                return redirect("/users/profil/" + str(user.id))
    except TypeError:
        messages.error(request, u"Adresse mac invalide")
chirac's avatar
chirac committed
155
    return form({'machineform': machine, 'interfaceform': interface, 'domainform': domain}, 'machines/machine.html', request)
156

chirac's avatar
chirac committed
157
@login_required
158
def edit_interface(request, interfaceid):
159 160 161 162 163
    try:
        interface = Interface.objects.get(pk=interfaceid)
    except Interface.DoesNotExist:
        messages.error(request, u"Interface inexistante" )
        return redirect("/machines")
164
    if not request.user.has_perms(('infra',)):
165
        if not request.user.has_perms(('cableur',)) and interface.machine.user != request.user:
166 167 168
            messages.error(request, "Vous ne pouvez pas éditer une machine d'un autre user que vous sans droit")
            return redirect("/users/profil/" + str(request.user.id))
        machine_form = BaseEditMachineForm(request.POST or None, instance=interface.machine)
169
        interface_form = BaseEditInterfaceForm(request.POST or None, instance=interface, infra=False)
170 171
    else:
        machine_form = EditMachineForm(request.POST or None, instance=interface.machine)
chirac's avatar
chirac committed
172
        interface_form = EditInterfaceForm(request.POST or None, instance=interface)
chirac's avatar
chirac committed
173
    domain_form = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',)), instance=interface.domain)
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
    try:
        if machine_form.is_valid() and interface_form.is_valid() and domain_form.is_valid():
            new_interface = interface_form.save(commit=False)
            new_machine = machine_form.save(commit=False)
            new_domain = domain_form.save(commit=False)
            if full_domain_validator(request, new_domain):
                with transaction.atomic(), reversion.create_revision():
                    new_machine.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machine_form.changed_data))
                if free_ip(new_interface.type.ip_type) and not new_interface.ipv4:
                    new_interface = assign_ipv4(new_interface)
                with transaction.atomic(), reversion.create_revision():
                    new_interface.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in interface_form.changed_data))
                with transaction.atomic(), reversion.create_revision():
                    new_domain.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in domain_form.changed_data))
                messages.success(request, "La machine a été modifiée")
                return redirect("/users/profil/" + str(interface.machine.user.id))
    except TypeError:
        messages.error(request, u"Adresse mac invalide")
chirac's avatar
chirac committed
198
    return form({'machineform': machine_form, 'interfaceform': interface_form, 'domainform': domain_form}, 'machines/machine.html', request)
199

200 201 202 203 204 205 206 207 208 209
@login_required
def del_machine(request, machineid):
    try:
        machine = Machine.objects.get(pk=machineid)
    except Machine.DoesNotExist:
        messages.error(request, u"Machine inexistante" )
        return redirect("/machines")
    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")
210
            return redirect("/users/profil/" + str(machine.user.id))
211
    if request.method == "POST":
212 213 214
        with transaction.atomic(), reversion.create_revision():
            machine.delete()
            reversion.set_user(request.user)
215
        messages.success(request, "La machine a été détruite")
216
        return redirect("/users/profil/" + str(machine.user.id))
217
    return form({'objet': machine, 'objet_name': 'machine'}, 'machines/delete.html', request)
218

chirac's avatar
chirac committed
219
@login_required
220 221 222 223 224 225
def new_interface(request, machineid):
    try:
        machine = Machine.objects.get(pk=machineid)
    except Machine.DoesNotExist:
        messages.error(request, u"Machine inexistante" )
        return redirect("/machines")
226
    if not request.user.has_perms(('cableur',)):
227
        if machine.user != request.user:
228 229
            messages.error(request, "Vous ne pouvez pas ajouter une interface à une machine d'un autre user que vous sans droit")
            return redirect("/users/profil/" + str(request.user.id))
230 231 232
        if machine.user.user_interfaces().count() >= MAX_INTERFACES:
            messages.error(request, "Vous avez atteint le maximum d'interfaces autorisées que vous pouvez créer vous même (%s) " % MAX_INTERFACES)
            return redirect("/users/profil/" + str(request.user.id))
233
    interface_form = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',)))
chirac's avatar
chirac committed
234
    domain_form = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',)))
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
    try:
        if interface_form.is_valid() and domain_form.is_valid():
            new_interface = interface_form.save(commit=False)
            new_interface.machine = machine
            new_domain = domain_form.save(commit=False)
            if full_domain_validator(request, new_domain):
                if free_ip(new_interface.type.ip_type) and not new_interface.ipv4:
                    new_interface = assign_ipv4(new_interface)
                elif not new_interface.ipv4:
                    messages.error(request, u"Il n'y a plus d'ip disponibles")
                with transaction.atomic(), reversion.create_revision():
                    new_interface.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                new_domain.interface_parent = new_interface
                with transaction.atomic(), reversion.create_revision():
                    new_domain.save()
                    reversion.set_user(request.user)
                    reversion.set_comment("Création")
                messages.success(request, "L'interface a été ajoutée")
                return redirect("/users/profil/" + str(machine.user.id))
    except TypeError:
        messages.error(request, u"Adresse mac invalide")
chirac's avatar
chirac committed
258
    return form({'interfaceform': interface_form, 'domainform': domain_form}, 'machines/machine.html', request)
259

260 261 262 263 264 265 266 267 268 269 270
@login_required
def del_interface(request, interfaceid):
    try:
        interface = Interface.objects.get(pk=interfaceid)
    except Interface.DoesNotExist:
        messages.error(request, u"Interface inexistante" )
        return redirect("/machines")
    if not request.user.has_perms(('cableur',)):
        if 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("/users/profil/" + str(request.user.id))
271
    if request.method == "POST":
272
        machine = interface.machine
273 274
        with transaction.atomic(), reversion.create_revision():
            interface.delete()
275 276
            if not machine.interface_set.all():
               machine.delete()
277
            reversion.set_user(request.user)
278 279 280
        messages.success(request, "L'interface a été détruite")
        return redirect("/users/profil/" + str(request.user.id))
    return form({'objet': interface, 'objet_name': 'interface'}, 'machines/delete.html', request)
281

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
@login_required
@permission_required('infra')
def add_iptype(request):
    iptype = IpTypeForm(request.POST or None)
    if iptype.is_valid():
        with transaction.atomic(), reversion.create_revision():
            iptype.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Ce type d'ip a été ajouté")
        return redirect("/machines/index_iptype")
    return form({'machineform': iptype, 'interfaceform': None}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def edit_iptype(request, iptypeid):
    try:
        iptype_instance = IpType.objects.get(pk=iptypeid)
    except IpType.DoesNotExist:
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_iptype/")
    iptype = IpTypeForm(request.POST or None, instance=iptype_instance)
    if iptype.is_valid():
        with transaction.atomic(), reversion.create_revision():
            iptype.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in iptype.changed_data))
        messages.success(request, "Type d'ip modifié")
        return redirect("/machines/index_iptype/")
    return form({'machineform': iptype}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def del_iptype(request):
    iptype = DelIpTypeForm(request.POST or None)
    if iptype.is_valid():
        iptype_dels = iptype.cleaned_data['iptypes']
        for iptype_del in iptype_dels:
            try:
                with transaction.atomic(), reversion.create_revision():
                    iptype_del.delete()
                    reversion.set_user(request.user)
                messages.success(request, "Le type d'ip a été supprimé")
            except ProtectedError:
                messages.error(request, "Le type d'ip %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % iptype_del)
        return redirect("/machines/index_iptype")
    return form({'machineform': iptype, 'interfaceform': None}, 'machines/machine.html', request)

chirac's avatar
chirac committed
330
@login_required
331
@permission_required('infra')
332 333 334
def add_machinetype(request):
    machinetype = MachineTypeForm(request.POST or None)
    if machinetype.is_valid():
335 336 337 338
        with transaction.atomic(), reversion.create_revision():
            machinetype.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
339
        messages.success(request, "Ce type de machine a été ajouté")
340
        return redirect("/machines/index_machinetype")
341 342
    return form({'machineform': machinetype, 'interfaceform': None}, 'machines/machine.html', request)

chirac's avatar
chirac committed
343
@login_required
344
@permission_required('infra')
345 346 347 348 349 350 351 352
def edit_machinetype(request, machinetypeid):
    try:
        machinetype_instance = MachineType.objects.get(pk=machinetypeid)
    except MachineType.DoesNotExist:
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_machinetype/")
    machinetype = MachineTypeForm(request.POST or None, instance=machinetype_instance)
    if machinetype.is_valid():
353 354 355 356
        with transaction.atomic(), reversion.create_revision():
            machinetype.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in machinetype.changed_data))
357 358 359 360
        messages.success(request, "Type de machine modifié")
        return redirect("/machines/index_machinetype/")
    return form({'machineform': machinetype}, 'machines/machine.html', request)

chirac's avatar
chirac committed
361
@login_required
362
@permission_required('infra')
363 364 365 366 367 368
def del_machinetype(request):
    machinetype = DelMachineTypeForm(request.POST or None)
    if machinetype.is_valid():
        machinetype_dels = machinetype.cleaned_data['machinetypes']
        for machinetype_del in machinetype_dels:
            try:
369 370 371
                with transaction.atomic(), reversion.create_revision():
                    machinetype_del.delete()
                    reversion.set_user(request.user)
372 373 374
                messages.success(request, "Le type de machine a été supprimé")
            except ProtectedError:
                messages.error(request, "Le type de machine %s est affectée à au moins une machine, vous ne pouvez pas le supprimer" % machinetype_del)
375
        return redirect("/machines/index_machinetype")
376 377
    return form({'machineform': machinetype, 'interfaceform': None}, 'machines/machine.html', request)

378
@login_required
379
@permission_required('infra')
380 381 382
def add_extension(request):
    extension = ExtensionForm(request.POST or None)
    if extension.is_valid():
383 384 385 386
        with transaction.atomic(), reversion.create_revision():
            extension.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
387 388 389 390 391
        messages.success(request, "Cette extension a été ajoutée")
        return redirect("/machines/index_extension")
    return form({'machineform': extension, 'interfaceform': None}, 'machines/machine.html', request)

@login_required
392
@permission_required('infra')
393 394 395 396 397 398 399 400
def edit_extension(request, extensionid):
    try:
        extension_instance = Extension.objects.get(pk=extensionid)
    except Extension.DoesNotExist:
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_extension/")
    extension = ExtensionForm(request.POST or None, instance=extension_instance)
    if extension.is_valid():
401 402 403 404
        with transaction.atomic(), reversion.create_revision():
            extension.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in extension.changed_data))
405 406 407 408 409
        messages.success(request, "Extension modifiée")
        return redirect("/machines/index_extension/")
    return form({'machineform': extension}, 'machines/machine.html', request)

@login_required
410
@permission_required('infra')
411 412 413 414 415 416
def del_extension(request):
    extension = DelExtensionForm(request.POST or None)
    if extension.is_valid():
        extension_dels = extension.cleaned_data['extensions']
        for extension_del in extension_dels:
            try:
417 418 419
                with transaction.atomic(), reversion.create_revision():
                    extension_del.delete()
                    reversion.set_user(request.user)
420 421 422 423 424 425
                messages.success(request, "L'extension a été supprimée")
            except ProtectedError:
                messages.error(request, "L'extension %s est affectée à au moins un type de machine, vous ne pouvez pas la supprimer" % extension_del)
        return redirect("/machines/index_extension")
    return form({'machineform': extension, 'interfaceform': None}, 'machines/machine.html', request)

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
@login_required
@permission_required('infra')
def add_mx(request):
    mx = MxForm(request.POST or None)
    if mx.is_valid():
        with transaction.atomic(), reversion.create_revision():
            mx.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Cet enregistrement mx a été ajouté")
        return redirect("/machines/index_extension")
    return form({'machineform': mx, 'interfaceform': None}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def edit_mx(request, mxid):
    try:
        mx_instance = Mx.objects.get(pk=mxid)
    except Mx.DoesNotExist:
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_extension/")
    mx = MxForm(request.POST or None, instance=mx_instance)
    if mx.is_valid():
        with transaction.atomic(), reversion.create_revision():
            mx.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in mx.changed_data))
        messages.success(request, "Mx modifié")
        return redirect("/machines/index_extension/")
    return form({'machineform': mx}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def del_mx(request):
    mx = DelMxForm(request.POST or None)
    if mx.is_valid():
        mx_dels = mx.cleaned_data['mx']
        for mx_del in mx_dels:
            try:
                with transaction.atomic(), reversion.create_revision():
                    mx_del.delete()
                    reversion.set_user(request.user)
                messages.success(request, "L'mx a été supprimée")
            except ProtectedError:
                messages.error(request, "Erreur le Mx suivant %s ne peut être supprimé" % mx_del)
        return redirect("/machines/index_extension")
    return form({'machineform': mx, 'interfaceform': None}, 'machines/machine.html', request)

474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
@login_required
@permission_required('infra')
def add_ns(request):
    ns = NsForm(request.POST or None)
    if ns.is_valid():
        with transaction.atomic(), reversion.create_revision():
            ns.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Cet enregistrement ns a été ajouté")
        return redirect("/machines/index_extension")
    return form({'machineform': ns, 'interfaceform': None}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def edit_ns(request, nsid):
    try:
        ns_instance = Ns.objects.get(pk=nsid)
    except Ns.DoesNotExist:
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_extension/")
    ns = NsForm(request.POST or None, instance=ns_instance)
    if ns.is_valid():
        with transaction.atomic(), reversion.create_revision():
            ns.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in ns.changed_data))
        messages.success(request, "Ns modifié")
        return redirect("/machines/index_extension/")
    return form({'machineform': ns}, 'machines/machine.html', request)

@login_required
@permission_required('infra')
def del_ns(request):
    ns = DelNsForm(request.POST or None)
    if ns.is_valid():
        ns_dels = ns.cleaned_data['ns']
        for ns_del in ns_dels:
            try:
                with transaction.atomic(), reversion.create_revision():
                    ns_del.delete()
                    reversion.set_user(request.user)
                messages.success(request, "Le ns a été supprimée")
            except ProtectedError:
                messages.error(request, "Erreur le Ns suivant %s ne peut être supprimé" % ns_del)
        return redirect("/machines/index_extension")
    return form({'machineform': ns, 'interfaceform': None}, 'machines/machine.html', request)

522 523 524 525 526 527 528
@login_required
def add_alias(request, interfaceid):
    try:
        interface = Interface.objects.get(pk=interfaceid)
    except Interface.DoesNotExist:
        messages.error(request, u"Interface inexistante" )
        return redirect("/machines")
529 530 531 532
    if not request.user.has_perms(('cableur',)):
        if interface.machine.user != request.user:
            messages.error(request, "Vous ne pouvez pas ajouter un alias à une machine d'un autre user que vous sans droit")
            return redirect("/users/profil/" + str(request.user.id))
chirac's avatar
chirac committed
533
        if Domain.objects.filter(cname__in=Domain.objects.filter(interface_parent__in=interface.machine.user.user_interfaces())).count() >= MAX_ALIAS:
534 535
            messages.error(request, "Vous avez atteint le maximum d'alias autorisées que vous pouvez créer vous même (%s) " % MAX_ALIAS)
            return redirect("/users/profil/" + str(request.user.id))
536
    alias = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',)))
537 538
    if alias.is_valid():
        alias = alias.save(commit=False)
chirac's avatar
chirac committed
539
        alias.cname = interface.domain
540 541 542 543 544 545 546 547 548 549 550
        with transaction.atomic(), reversion.create_revision():
            alias.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Cet alias a été ajouté")
        return redirect("/machines/index_alias/" + str(interfaceid))
    return form({'machineform': alias, 'interfaceform': None}, 'machines/machine.html', request)

@login_required
def edit_alias(request, aliasid):
    try:
chirac's avatar
chirac committed
551 552
        alias_instance = Domain.objects.get(pk=aliasid)
    except Domain.DoesNotExist:
553 554
        messages.error(request, u"Entrée inexistante" )
        return redirect("/machines/index_extension/")
chirac's avatar
chirac committed
555
    if not request.user.has_perms(('cableur',)) and alias_instance.cname.interface_parent.machine.user != request.user:
556 557
        messages.error(request, "Vous ne pouvez pas ajouter un alias à une machine d'un autre user que vous sans droit")
        return redirect("/users/profil/" + str(request.user.id))
558
    alias = AliasForm(request.POST or None, instance=alias_instance, infra=request.user.has_perms(('infra',)))
559 560 561 562 563 564
    if alias.is_valid():
        with transaction.atomic(), reversion.create_revision():
            alias_instance = alias.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in alias.changed_data))
        messages.success(request, "Alias modifié")
chirac's avatar
chirac committed
565
        return redirect("/machines/index_alias/" + str(alias_instance.cname.interface_parent.id))
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
    return form({'machineform': alias}, 'machines/machine.html', request)

@login_required
def del_alias(request, interfaceid):
    try:
        interface = Interface.objects.get(pk=interfaceid)
    except Interface.DoesNotExist:
        messages.error(request, u"Interface inexistante" )
        return redirect("/machines")
    if not request.user.has_perms(('cableur',)) and interface.machine.user != request.user:
        messages.error(request, "Vous ne pouvez pas ajouter un alias à une machine d'un autre user que vous sans droit")
        return redirect("/users/profil/" + str(request.user.id))
    alias = DelAliasForm(request.POST or None, interface=interface)
    if alias.is_valid():
        alias_dels = alias.cleaned_data['alias']
        for alias_del in alias_dels:
            try:
                with transaction.atomic(), reversion.create_revision():
                    alias_del.delete()
                    reversion.set_user(request.user)
                messages.success(request, "L'alias %s a été supprimé" % alias_del)
            except ProtectedError:
                messages.error(request, "Erreur l'alias suivant %s ne peut être supprimé" % alias_del)
        return redirect("/machines/index_alias/" + str(interfaceid))
    return form({'machineform': alias, 'interfaceform': None}, 'machines/machine.html', request)

chirac's avatar
chirac committed
592
@login_required
chirac's avatar
chirac committed
593
@permission_required('cableur')
594
def index(request):
595
    machines_list = Machine.objects.order_by('pk')
chirac's avatar
chirac committed
596
    paginator = Paginator(machines_list, PAGINATION_LARGE_NUMBER)
597 598 599 600 601 602 603 604 605
    page = request.GET.get('page')
    try:
        machines_list = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        machines_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        machines_list = paginator.page(paginator.num_pages)
606
    return render(request, 'machines/index.html', {'machines_list': machines_list})
607

608 609 610 611 612 613
@login_required
@permission_required('cableur')
def index_iptype(request):
    iptype_list = IpType.objects.order_by('type')
    return render(request, 'machines/index_iptype.html', {'iptype_list':iptype_list})

chirac's avatar
chirac committed
614
@login_required
chirac's avatar
chirac committed
615
@permission_required('cableur')
616 617
def index_machinetype(request):
    machinetype_list = MachineType.objects.order_by('type')
618
    return render(request, 'machines/index_machinetype.html', {'machinetype_list':machinetype_list})
619 620

@login_required
chirac's avatar
chirac committed
621
@permission_required('cableur')
622 623
def index_extension(request):
    extension_list = Extension.objects.order_by('name')
624 625 626
    mx_list = Mx.objects.order_by('zone')
    ns_list = Ns.objects.order_by('zone')
    return render(request, 'machines/index_extension.html', {'extension_list':extension_list, 'mx_list': mx_list, 'ns_list': ns_list})
Dalahro's avatar
Dalahro committed
627

628 629 630 631 632 633 634 635 636 637
@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("/machines")
    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("/users/profil/" + str(request.user.id))
chirac's avatar
chirac committed
638
    alias_list = Domain.objects.filter(cname=Domain.objects.filter(interface_parent=interface)).order_by('name')
639 640
    return render(request, 'machines/index_alias.html', {'alias_list':alias_list, 'interface_id': interfaceid})

641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
@login_required
def history(request, object, id):
    if object == 'machine':
        try:
             object_instance = Machine.objects.get(pk=id)
        except Machine.DoesNotExist:
             messages.error(request, "Machine inexistante")
             return redirect("/machines/")
        if not request.user.has_perms(('cableur',)) and object_instance.user != request.user:
             messages.error(request, "Vous ne pouvez pas afficher l'historique d'une machine d'un autre user que vous sans droit cableur")
             return redirect("/users/profil/" + str(request.user.id))
    elif object == 'interface':
        try:
             object_instance = Interface.objects.get(pk=id)
        except Interface.DoesNotExist:
             messages.error(request, "Interface inexistante")
             return redirect("/machines/")
        if not request.user.has_perms(('cableur',)) and object_instance.machine.user != request.user:
             messages.error(request, "Vous ne pouvez pas afficher l'historique d'une interface d'un autre user que vous sans droit cableur")
             return redirect("/users/profil/" + str(request.user.id))
661 662
    elif object == 'alias':
        try:
chirac's avatar
chirac committed
663 664
             object_instance = Domain.objects.get(pk=id)
        except Domain.DoesNotExist:
665 666
             messages.error(request, "Alias inexistant")
             return redirect("/machines/")
chirac's avatar
chirac committed
667
        if not request.user.has_perms(('cableur',)) and object_instance.cname.interface_parent.machine.user != request.user:
668 669
             messages.error(request, "Vous ne pouvez pas afficher l'historique d'un alias d'un autre user que vous sans droit cableur")
             return redirect("/users/profil/" + str(request.user.id))
670 671 672 673 674 675
    elif object == 'machinetype' and request.user.has_perms(('cableur',)):
        try:
             object_instance = MachineType.objects.get(pk=id)
        except MachineType.DoesNotExist:
             messages.error(request, "Type de machine inexistant")
             return redirect("/machines/")
676 677 678 679 680 681
    elif object == 'iptype' and request.user.has_perms(('cableur',)):
        try:
             object_instance = IpType.objects.get(pk=id)
        except IpType.DoesNotExist:
             messages.error(request, "Type d'ip inexistant")
             return redirect("/machines/")
682 683 684 685 686 687
    elif object == 'extension' and request.user.has_perms(('cableur',)):
        try:
             object_instance = Extension.objects.get(pk=id)
        except Extension.DoesNotExist:
             messages.error(request, "Extension inexistante")
             return redirect("/machines/")
688 689 690 691 692 693
    elif object == 'mx' and request.user.has_perms(('cableur',)):
        try:
             object_instance = Mx.objects.get(pk=id)
        except Mx.DoesNotExist:
             messages.error(request, "Mx inexistant")
             return redirect("/machines/")
694 695 696 697 698 699
    elif object == 'ns' and request.user.has_perms(('cableur',)):
        try:
             object_instance = Ns.objects.get(pk=id)
        except Ns.DoesNotExist:
             messages.error(request, "Ns inexistant")
             return redirect("/machines/")
700 701 702
    else:
        messages.error(request, "Objet  inconnu")
        return redirect("/machines/")
root's avatar
root committed
703
    reversions = Version.objects.get_for_object(object_instance)
chirac's avatar
chirac committed
704 705 706 707 708 709 710 711 712 713
    paginator = Paginator(reversions, PAGINATION_NUMBER)
    page = request.GET.get('page')
    try:
        reversions = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        reversions = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        reversions = paginator.page(paginator.num_pages)
714 715 716
    return render(request, 're2o/history.html', {'reversions': reversions, 'object': object_instance})


Dalahro's avatar
Dalahro committed
717 718 719 720
""" Framework Rest """

class JSONResponse(HttpResponse):
    def __init__(self, data, **kwargs):
Dalahro's avatar
Dalahro committed
721
        content = JSONRenderer().render(data)
Dalahro's avatar
Dalahro committed
722 723 724
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

Dalahro's avatar
Dalahro committed
725 726 727
@csrf_exempt
@login_required
@permission_required('serveur')
Gabriel Detraz's avatar
Gabriel Detraz committed
728
def mac_ip_list(request):
Gabriel Detraz's avatar
Gabriel Detraz committed
729 730
    interf = Interface.objects.select_related('ipv4').select_related('domain__extension').all()
    interfaces = list(filter(
731
        lambda interface: interface.ipv4 and interface.is_active,
Gabriel Detraz's avatar
Gabriel Detraz committed
732 733
        interf
        ))
Gabriel Detraz's avatar
Gabriel Detraz committed
734
    seria = InterfaceSerializer(interfaces, many=True)
Dalahro's avatar
Dalahro committed
735
    return seria.data
Dalahro's avatar
Dalahro committed
736

737 738 739
@csrf_exempt
@login_required
@permission_required('serveur')
740
def alias(request):
chirac's avatar
chirac committed
741 742
    alias = Domain.objects.filter(interface_parent=None).filter(cname=Domain.objects.filter(interface_parent__in=Interface.objects.exclude(ipv4=None)))
    seria = DomainSerializer(alias, many=True)
743 744 745 746 747 748
    return JSONResponse(seria.data)

@csrf_exempt
@login_required
@permission_required('serveur')
def corresp(request):
749 750
    type = IpType.objects.all()
    seria = TypeSerializer(type, many=True)
751
    return JSONResponse(seria.data)
752

753 754 755 756 757 758 759 760 761 762 763 764
@csrf_exempt
@login_required
@permission_required('serveur')
def mx(request):
    mx = Mx.objects.all()
    seria = MxSerializer(mx, many=True)
    return JSONResponse(seria.data)

@csrf_exempt
@login_required
@permission_required('serveur')
def ns(request):
Gabriel Detraz's avatar
Gabriel Detraz committed
765
    ns = Ns.objects.exclude(ns__in=Domain.objects.filter(interface_parent__in=Interface.objects.filter(ipv4=None)))
766 767 768
    seria = NsSerializer(ns, many=True)
    return JSONResponse(seria.data)

769 770 771 772 773 774 775 776
@csrf_exempt
@login_required
@permission_required('serveur')
def zones(request):
    zones = Extension.objects.all()
    seria = ExtensionSerializer(zones, many=True)
    return JSONResponse(seria.data)

Dalahro's avatar
Dalahro committed
777 778 779
@csrf_exempt
@login_required
@permission_required('serveur')
Dalahro's avatar
Dalahro committed
780
def mac_ip(request):
Gabriel Detraz's avatar
Gabriel Detraz committed
781
    seria = mac_ip_list(request)
Dalahro's avatar
Dalahro committed
782
    return JSONResponse(seria)
Dalahro's avatar
Dalahro committed
783

Dalahro's avatar
Dalahro committed
784 785 786
@csrf_exempt
@login_required
@permission_required('serveur')
Dalahro's avatar
Dalahro committed
787
def mac_ip_dns(request):
Gabriel Detraz's avatar
Gabriel Detraz committed
788
    seria = mac_ip_list(request)
Dalahro's avatar
Dalahro committed
789
    return JSONResponse(seria)
Dalahro's avatar
Dalahro committed
790

Dalahro's avatar
Dalahro committed
791 792 793 794 795
@csrf_exempt
def login_user(request):
    user = authenticate(username=request.POST['username'], password=request.POST['password'])
    login(request, user)
    return HttpResponse("Logged In")