diff --git a/machines/admin.py b/machines/admin.py index eb765748..168d84a3 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -43,7 +43,9 @@ from .models import ( Service, OuverturePort, Ipv6List, - OuverturePortList + OuverturePortList, + SshFingerprint, + SshFprAlgo, ) @@ -141,6 +143,15 @@ class ServiceAdmin(VersionAdmin): list_display = ('service_type', 'min_time_regen', 'regular_time_regen') +class SshFprAlgoAdmin(VersionAdmin): + """ Admin view of a SshFprAlgo object """ + pass + + +class SshFingerprintAdmin(VersionAdmin): + """ Admin view of a SshFprAlgo object """ + pass + admin.site.register(Machine, MachineAdmin) admin.site.register(MachineType, MachineTypeAdmin) admin.site.register(IpType, IpTypeAdmin) @@ -160,3 +171,5 @@ admin.site.register(Ipv6List, Ipv6ListAdmin) admin.site.register(Nas, NasAdmin) admin.site.register(OuverturePort, OuverturePortAdmin) admin.site.register(OuverturePortList, OuverturePortListAdmin) +admin.site.register(SshFprAlgo, SshFprAlgoAdmin) +admin.site.register(SshFingerprint, SshFingerprintAdmin) diff --git a/machines/forms.py b/machines/forms.py index 36cd64f8..869ad058 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -60,6 +60,8 @@ from .models import ( IpType, OuverturePortList, Ipv6List, + SshFingerprint, + SshFprAlgo ) @@ -595,3 +597,33 @@ class EditOuverturePortListForm(FormRevMixin, ModelForm): prefix=prefix, **kwargs ) + + +class SshFingerprintForm(FormRevMixin, ModelForm): + """Edition d'une sshfingerprint""" + class Meta: + model = SshFingerprint + exclude = ('machine',) + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(SshFingerprintForm, self).__init__( + *args, + prefix=prefix, + **kwargs + ) + + +class SshFprAlgoForm(FormRevMixin, ModelForm): + """Edition de la liste des algo pour sshfpr""" + class Meta: + model = SshFprAlgo + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(SshFprAlgoForm, self).__init__( + *args, + prefix=prefix, + **kwargs + ) diff --git a/machines/migrations/0084_auto_20180623_1651.py b/machines/migrations/0084_auto_20180623_1651.py new file mode 100644 index 00000000..443c89ad --- /dev/null +++ b/machines/migrations/0084_auto_20180623_1651.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-06-23 14:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0083_role'), + ] + + operations = [ + migrations.CreateModel( + name='SshFingerprint', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('hash_entry', models.TextField(max_length=512)), + ('comment', models.CharField(blank=True, max_length=255, null=True)), + ], + options={ + 'permissions': (('view_sshfingerprint', 'Peut voir un objet sshfingerprint'),), + }, + bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model), + ), + migrations.CreateModel( + name='SshFprAlgo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField(max_length=256)), + ], + options={ + 'permissions': (('view_sshfpralgo', 'Peut voir un algo de chiffrement'),), + }, + bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model), + ), + migrations.AddField( + model_name='sshfingerprint', + name='algo', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='machines.SshFprAlgo'), + ), + migrations.AddField( + model_name='sshfingerprint', + name='machine', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.Machine'), + ), + ] diff --git a/machines/models.py b/machines/models.py index 590e3997..ba72ebb6 100644 --- a/machines/models.py +++ b/machines/models.py @@ -200,6 +200,52 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model): def __str__(self): return str(self.user) + ' - ' + str(self.id) + ' - ' + str(self.name) +class SshFingerprint(RevMixin, AclMixin, models.Model): + """Hash de la clef ssh d'une machine""" + + PRETTY_NAME = "Fingerprint ssh" + + machine = models.ForeignKey('Machine', on_delete=models.CASCADE) + hash_entry = models.TextField(max_length=512) + algo = models.ForeignKey('SshFprAlgo', on_delete=models.PROTECT) + comment = models.CharField( + max_length=255, + null=True, + blank=True + ) + + class Meta: + permissions = ( + ("view_sshfingerprint", "Peut voir un objet sshfingerprint"), + ) + + def can_view(self, user_request, *_args, **_kwargs): + return self.machine.can_view(user_request, *_args, **_kwargs) + + def can_edit(self, user_request, *args, **kwargs): + return self.machine.can_edit(user_request, *args, **kwargs) + + def can_delete(self, user_request, *args, **kwargs): + return self.machine.can_delete(user_request, *args, **kwargs) + + def __str__(self): + return str(self.algo) + ' ' + str(self.hash_entry) + ' ' + str(self.comment) + + +class SshFprAlgo(RevMixin, AclMixin, models.Model): + """Un aglorithme de création de la fingerprint ssh""" + PRETTY_NAME = "Algo de clef ssh" + + name = models.TextField(max_length=256) + + class Meta: + permissions = ( + ("view_sshfpralgo", "Peut voir un algo de chiffrement"), + ) + + def __str__(self): + return str(self.name) + class MachineType(RevMixin, AclMixin, models.Model): """ Type de machine, relié à un type d'ip, affecté aux interfaces""" diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index 0acababc..5db5e836 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -119,6 +119,13 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} + {% can_create SshFingerprint interface.machine.id %} +
  • + + Gerer les fingerprint ssh + +
  • + {% acl_end %} {% can_create OuverturePortList %}
  • diff --git a/machines/templates/machines/aff_sshfingerprint.html b/machines/templates/machines/aff_sshfingerprint.html new file mode 100644 index 00000000..33e7d7ad --- /dev/null +++ b/machines/templates/machines/aff_sshfingerprint.html @@ -0,0 +1,51 @@ +{% comment %} +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 © 2018 Gabriel Détraz + +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. +{% endcomment %} + +{% load acl %} + + + + + + + + + + + {% for sshfpr in sshfingerprint_list %} + + + + + + + {% endfor %} +
    Entrée du hashAlgorithme utiliséCommentaire
    {{ sshfpr.hash_entry }}{{ sshfpr.algo }}{{ sshfpr.comment }} + {% can_edit sshfpr %} + {% include 'buttons/edit.html' with href='machines:edit-sshfingerprint' id=sshfpr.id %} + {% acl_end %} + {% can_delete sshfpr %} + {% include 'buttons/suppr.html' with href='machines:del-sshfingerprint' id=sshfpr.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='machines:history' name='sshfingerprint' id=sshfpr.id %} +
    + diff --git a/machines/templates/machines/index_sshfingerprint.html b/machines/templates/machines/index_sshfingerprint.html new file mode 100644 index 00000000..eba872c0 --- /dev/null +++ b/machines/templates/machines/index_sshfingerprint.html @@ -0,0 +1,39 @@ +{% extends "machines/sidebar.html" %} +{% comment %} +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 © 2018 Gabriel Détraz + +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. +{% endcomment %} + +{% load bootstrap3 %} +{% load acl %} + +{% block title %}Machines{% endblock %} + +{% block content %} +

    Liste des fingerprint ssh

    + {% can_create SshFingerprint machine_id %} +
    Ajouter une fingerprint ssh + {% acl_end %} + {% include "machines/aff_sshfingerprint.html" with sshfingerprint_list=sshfingerprint_list %} +
    +
    +
    +{% endblock %} + diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index 0c5a478a..71caa705 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -78,6 +78,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if ipv6form %} {% bootstrap_form_errors ipv6form %} {% endif %} +{% if sshfingerprintform %} + {% bootstrap_form_errors sshfingerprintform %} +{% endif %} + +
    {% csrf_token %} @@ -153,6 +158,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,

    Ipv6

    {% bootstrap_form ipv6form %} {% endif %} + {% if sshfingerprintform %} +

    SshFingerprint

    + {% bootstrap_form sshfingerprintform %} + {% endif %} {% bootstrap_button action_name button_type="submit" icon="star" %}

    diff --git a/machines/urls.py b/machines/urls.py index bf3d63d8..8f58373a 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -107,6 +107,18 @@ urlpatterns = [ url(r'^index_ipv6/(?P[0-9]+)$', views.index_ipv6, name='index-ipv6'), + url(r'^new_sshfingerprint/(?P[0-9]+)$', + views.new_sshfingerprint, + name='new-sshfingerprint'), + url(r'^edit_sshfingerprint/(?P[0-9]+)$', + views.edit_sshfingerprint, + name='edit-sshfingerprint'), + url(r'^del_sshfingerprint/(?P[0-9]+)$', + views.del_sshfingerprint, + name='del-sshfingerprint'), + url(r'^index_sshfingerprint/(?P[0-9]+)$', + views.index_sshfingerprint, + name='index-sshfingerprint'), url(r'^add_service/$', views.add_service, name='add-service'), url(r'^edit_service/(?P[0-9]+)$', views.edit_service, diff --git a/machines/views.py b/machines/views.py index 71484952..91cbf0fc 100644 --- a/machines/views.py +++ b/machines/views.py @@ -108,7 +108,9 @@ from .forms import ( DelSrvForm, Ipv6ListForm, EditOuverturePortListForm, - EditOuverturePortConfigForm + EditOuverturePortConfigForm, + SshFingerprintForm, + SshFprAlgoForm, ) from .models import ( IpType, @@ -130,6 +132,8 @@ from .models import ( OuverturePortList, OuverturePort, Ipv6List, + SshFingerprint, + SshFprAlgo, ) @@ -460,6 +464,72 @@ def del_ipv6list(request, ipv6list, **_kwargs): ) +@login_required +@can_create(SshFingerprint) +@can_edit(Machine) +def new_sshfingerprint(request, machine, **_kwargs): + """Nouvelle sshfingerprint""" + sshfingerprint_instance = SshFingerprint(machine=machine) + sshfingerprint = SshFingerprintForm( + request.POST or None, + instance=sshfingerprint_instance + ) + if sshfingerprint.is_valid(): + sshfingerprint.save() + messages.success(request, "Fingerprint ssh ajoutée") + return redirect(reverse( + 'machines:index-sshfingerprint', + kwargs={'machine': str(machine.id)} + )) + return form( + {'sshfingerprintform': sshfingerprint, 'action_name': 'Créer'}, + 'machines/machine.html', + request + ) + + +@login_required +@can_edit(SshFingerprint) +def edit_sshfingerprint(request, sshfingerprint_instance, **_kwargs): + """Edition d'une sshfingerprint""" + sshfingerprint = SshFingerprintForm( + request.POST or None, + instance=sshfingerprint_instance + ) + if sshfingerprint.is_valid(): + if sshfingerprint.changed_data: + sshfingerprint.save() + messages.success(request, "Ipv6 modifiée") + return redirect(reverse( + 'machines:index-sshfingerprint', + kwargs={'machineid': str(sshfingerprint_instance.machine.id)} + )) + return form( + {'sshfingerprintform': sshfingerprint, 'action_name': 'Editer'}, + 'machines/machine.html', + request + ) + + +@login_required +@can_delete(SshFingerprint) +def del_sshfingerprint(request, sshfingerprint, **_kwargs): + """ Supprime une sshfingerprint""" + if request.method == "POST": + machineid = sshfingerprint.machine.id + sshfingerprint.delete() + messages.success(request, "La sshfingerprint a été détruite") + return redirect(reverse( + 'machines:index-sshfingerprint', + kwargs={'machineid': str(machineid)} + )) + return form( + {'objet': sshfingerprint, 'objet_name': 'sshfingerprint'}, + 'machines/delete.html', + request + ) + + @login_required @can_create(IpType) def add_iptype(request): @@ -1388,7 +1458,31 @@ def index_alias(request, interface, interfaceid): @login_required -@can_edit(Interface) +@can_edit(Machine) +def index_sshfingerprint(request, machine, machineid): + """ View used to display the list of existing IPv6 of an interface """ + sshfingerprint_list = SshFingerprint.objects.filter(machine=machine) + return render( + request, + 'machines/index_sshfingerprint.html', + {'sshfingerprint_list': sshfingerprint_list, 'machine_id': machineid} + ) + + +@login_required +@can_view_all(SshFprAlgo) +def index_sshfpralgo(request): + """ View used to display the list of existing sshfrpalgo""" + sshfpralgo_list = SshFprAlgo.objects.all() + return render( + request, + 'machines/index_sshfpralgo.html', + {'sshfpralgo_list': sshfpralgo_list} + ) + + +@login_required +@can_view_all(Interface) def index_ipv6(request, interface, interfaceid): """ View used to display the list of existing IPv6 of an interface """ ipv6_list = Ipv6List.objects.filter(interface=interface)