From 4b7393b5e4fad40738f383e027207b2e65156fa8 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:17:06 +0200 Subject: [PATCH 01/15] Add views to get IP / MAC history --- logs/forms.py | 57 ++++++ logs/models.py | 169 ++++++++++++++++++ logs/templates/logs/machine_history.html | 59 ++++++ .../logs/search_machine_history.html | 48 +++++ logs/views.py | 25 +++ 5 files changed, 358 insertions(+) create mode 100644 logs/forms.py create mode 100644 logs/models.py create mode 100644 logs/templates/logs/machine_history.html create mode 100644 logs/templates/logs/search_machine_history.html diff --git a/logs/forms.py b/logs/forms.py new file mode 100644 index 00000000..9e2b98a6 --- /dev/null +++ b/logs/forms.py @@ -0,0 +1,57 @@ +# 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 © 2020 Jean-Romain Garnier +# +# 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. + +"""The forms used by the search app""" + +from django import forms +from django.forms import Form +from django.utils.translation import ugettext_lazy as _ +from re2o.base import get_input_formats_help_text + +CHOICES_TYPE = ( + ("ip", _("IPv4")), + ("mac", _("MAC")), +) + + +class MachineHistoryForm(Form): + """The form for a simple search""" + + q = forms.CharField( + label=_("Search"), + max_length=100, + ) + t = forms.CharField( + label=_("Search type"), + widget=forms.Select, + choices=CHOICES_TYPE, + initial=0, + ) + s = forms.DateField(required=False, label=_("Start date")) + e = forms.DateField(required=False, label=_("End date")) + + def __init__(self, *args, **kwargs): + super(MachineHistoryForm, self).__init__(*args, **kwargs) + self.fields["s"].help_text = get_input_formats_help_text( + self.fields["s"].input_formats + ) + self.fields["e"].help_text = get_input_formats_help_text( + self.fields["e"].input_formats + ) diff --git a/logs/models.py b/logs/models.py new file mode 100644 index 00000000..906fc020 --- /dev/null +++ b/logs/models.py @@ -0,0 +1,169 @@ +# -*- 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 © 2020 Jean-Romain Garnier +# +# 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.models +The models definitions for the Machines app +""" +from reversion.models import Version +from machines.models import IpList +from machines.models import Interface +from machines.models import Machine +from users.models import User + + +class HistoryEvent: + def __init__(self, user: User, machine: Version, interface: Version, start=None, end=None): + self.user = user + self.machine = machine + self.interface = interface + self.ipv4 = IpList.objects.get(id=interface.field_dict["ipv4_id"]).ipv4 + self.mac = self.interface.field_dict["mac_address"] + self.start_date = start + self.end_date = end + self.comment = interface.revision.get_comment() or None + + def is_similar(self, elt2): + return ( + elt2 is not None + and self.user.id == elt2.user.id + and self.ipv4 == elt2.ipv4 + and self.machine.field_dict["id"] == elt2.machine.field_dict["id"] + and self.interface.field_dict["id"] == elt2.interface.field_dict["id"] + ) + + def __repr__(self): + return "{} ({} - ): from {} to {} ({})".format( + self.machine, + self.mac, + self.ipv4, + self.start_date, + self.end_date, + self.comment or "No comment" + ) + + +class MachineHistory: + def __init__(self): + self.events = [] + self.__last_evt = None + + def get(self, search, params): + self.start = params.get("s", None) + self.end = params.get("e", None) + search_type = params.get("t", 0) + + self.events = [] + if search_type == "ip": + return self.__get_by_ip(search) + elif search_type == "mac": + return self.__get_by_mac(search) + + return None + + def __add_revision(self, user: User, machine: Version, interface: Version): + evt = HistoryEvent(user, machine, interface) + evt.start_date = interface.revision.date_created + + # Try not to recreate events if unnecessary + if evt.is_similar(self.__last_evt): + return + + # Mark the end of validity of the last element + if self.__last_evt and not self.__last_evt.end_date: + self.__last_evt.end_date = evt.start_date + + # If the event ends before the given date, remove it + if self.start and evt.start_date < self.start: + self.__last_evt = None + self.events.pop() + + # Make sure the new event starts before the given end date + if self.end and evt.start_date > self.end: + return + + # Save the new element + self.events.append(evt) + self.__last_evt = evt + + def __get_interfaces_for_ip(self, ip: str): + """ + Returns an iterable object with the Version objects + of Interfaces with the given IP + """ + # TODO: Deleted IpList + ip_id = IpList.objects.get(ipv4=ip).id + return filter( + lambda x: x.field_dict["ipv4_id"] == ip_id, + Version.objects.get_for_model(Interface).order_by("revision__date_created") + ) + + def __get_interfaces_for_mac(self, mac: str): + """ + Returns an iterable object with the Version objects + of Interfaces with the given MAC + """ + # TODO: What if IpList was deleted? + return filter( + lambda x: str(x.field_dict["mac_address"]) == mac, + Version.objects.get_for_model(Interface).order_by("revision__date_created") + ) + + def __get_machines_for_interface(self, interface: Version): + """ + Returns an iterable object with the Verison objects + of Machines to which the given interface was attributed + """ + machine_id = interface.field_dict["machine_id"] + return filter( + lambda x: x.field_dict["id"] == machine_id, + Version.objects.get_for_model(Machine).order_by("revision__date_created") + ) + + def __get_user_for_machine(self, machine: Version): + """ + Returns the user to which the given machine belongs + """ + # TODO: What if user was deleted? + user_id = machine.field_dict["user_id"] + return User.objects.get(id=user_id) + + def __get_by_ip(self, ip: str): + interfaces = self.__get_interfaces_for_ip(ip) + + for interface in interfaces: + machines = self.__get_machines_for_interface(interface) + + for machine in machines: + user = self.__get_user_for_machine(machine) + self.__add_revision(user, machine, interface) + + return self.events + + def __get_by_mac(self, mac: str): + interfaces = self.__get_interfaces_for_mac(mac) + + for interface in interfaces: + machines = self.__get_machines_for_interface(interface) + + for machine in machines: + user = self.__get_user_for_machine(machine) + self.__add_revision(user, machine, interface) + + return self.events diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html new file mode 100644 index 00000000..01d6c7e7 --- /dev/null +++ b/logs/templates/logs/machine_history.html @@ -0,0 +1,59 @@ +{% extends 'log/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 © 2020 Jean-Romain Garnier + +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 i18n %} + +{% block title %}{% trans "Search results" %}{% endblock %} + +{% block content %} + {% if events %} + + + + + + + + + + + + {% for event in events %} + + + + + + + + + {% endfor %} +
UserIPv4MACStart dateEnd dateComment
{{ event.user.pseudo }}{{ event.ipv4 }}{{ event.mac }}{{ event.start_date }}{{ event.end_date }}{{ event.comment }}
+ {% else %} +

{% trans "No result" %}

+ {% endif %} +
+
+
+{% endblock %} diff --git a/logs/templates/logs/search_machine_history.html b/logs/templates/logs/search_machine_history.html new file mode 100644 index 00000000..3baf563d --- /dev/null +++ b/logs/templates/logs/search_machine_history.html @@ -0,0 +1,48 @@ +{% extends 'logs/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 © 2020 Jean-Romain Garnier + +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 i18n %} + +{% block title %}{% trans "Search" %}{% endblock %} + +{% block content %} + +
+ {% bootstrap_field history_form.q %} + {% bootstrap_form_errors history_form.t %} + {% if history_form.s %} + {% bootstrap_field history_form.s %} + {% endif %} + {% if history_form.e %} + {% bootstrap_field history_form.e %} + {% endif %} + {% trans "Search" as tr_search %} + {% bootstrap_button tr_search button_type="submit" icon="search" %} +
+
+
+
+
+
+{% endblock %} diff --git a/logs/views.py b/logs/views.py index 78971d18..08ac0c9f 100644 --- a/logs/views.py +++ b/logs/views.py @@ -101,6 +101,9 @@ from re2o.utils import ( from re2o.base import re2o_paginator, SortTable from re2o.acl import can_view_all, can_view_app, can_edit_history +from .models import MachineHistory +from .forms import MachineHistoryForm + @login_required @can_view_app("logs") @@ -478,6 +481,28 @@ def stats_actions(request): return render(request, "logs/stats_users.html", {"stats_list": stats}) +@login_required +@can_view_app("users") +def search_machine_history(request): + """Vue qui permet de rechercher l'historique des machines ayant utilisé + une IP ou une adresse MAC""" + history_form = MachineHistoryForm(request.GET or None) + if history_form.is_valid(): + history = MachineHistory() + return render( + request, + "logs/machine_history.html", + { + "events": + history.get( + history_form.cleaned_data.get("q", ""), + history_form.cleaned_data + ) + }, + ) + return render(request, "logs/search_machine_history.html", {"history_form": history_form}) + + def history(request, application, object_name, object_id): """Render history for a model. From c4634191f5fb59da5cf1e487979428acfe81d133 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 16:32:56 +0000 Subject: [PATCH 02/15] Fix machine history views --- logs/forms.py | 4 +- logs/templates/logs/machine_history.html | 2 +- .../logs/search_machine_history.html | 10 ++-- logs/urls.py | 1 + logs/views.py | 2 +- test.py | 50 +++++++++++++++++++ 6 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 test.py diff --git a/logs/forms.py b/logs/forms.py index 9e2b98a6..f51dbef7 100644 --- a/logs/forms.py +++ b/logs/forms.py @@ -40,9 +40,7 @@ class MachineHistoryForm(Form): ) t = forms.CharField( label=_("Search type"), - widget=forms.Select, - choices=CHOICES_TYPE, - initial=0, + widget=forms.Select(choices=CHOICES_TYPE) ) s = forms.DateField(required=False, label=_("Start date")) e = forms.DateField(required=False, label=_("End date")) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index 01d6c7e7..50efbcf5 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -1,4 +1,4 @@ -{% extends 'log/sidebar.html' %} +{% extends 'logs/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 diff --git a/logs/templates/logs/search_machine_history.html b/logs/templates/logs/search_machine_history.html index 3baf563d..07c9f68c 100644 --- a/logs/templates/logs/search_machine_history.html +++ b/logs/templates/logs/search_machine_history.html @@ -24,19 +24,17 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} {% load i18n %} -{% block title %}{% trans "Search" %}{% endblock %} +{% block title %}{% trans "Search machine history" %}{% endblock %} {% block content %}
+

{% trans "Search machine history" %}

+ {% bootstrap_field history_form.q %} - {% bootstrap_form_errors history_form.t %} - {% if history_form.s %} + {% bootstrap_field history_form.t %} {% bootstrap_field history_form.s %} - {% endif %} - {% if history_form.e %} {% bootstrap_field history_form.e %} - {% endif %} {% trans "Search" as tr_search %} {% bootstrap_button tr_search button_type="submit" icon="search" %}
diff --git a/logs/urls.py b/logs/urls.py index 8fa0f469..eced2a83 100644 --- a/logs/urls.py +++ b/logs/urls.py @@ -46,4 +46,5 @@ urlpatterns = [ views.history, name="history", ), + url(r"^stats_search_machine/$", views.stats_search_machine_history, name="stats-search-machine"), ] diff --git a/logs/views.py b/logs/views.py index 08ac0c9f..ca75e48f 100644 --- a/logs/views.py +++ b/logs/views.py @@ -483,7 +483,7 @@ def stats_actions(request): @login_required @can_view_app("users") -def search_machine_history(request): +def stats_search_machine_history(request): """Vue qui permet de rechercher l'historique des machines ayant utilisé une IP ou une adresse MAC""" history_form = MachineHistoryForm(request.GET or None) diff --git a/test.py b/test.py new file mode 100644 index 00000000..7b777609 --- /dev/null +++ b/test.py @@ -0,0 +1,50 @@ +from reversion.models import Version +from machines.models import IpList +from machines.models import Interface +from machines.models import Machine +from users.models import User + + +def get_interfaces_with_ip(ip): + """ + Get all the interfaces that, at some point, had the given ip + """ + # TODO: What if IpList was deleted? + ip_id = IpList.objects.get(ipv4=ip).id + interfaces = Version.objects.get_for_model(Interface) + interfaces = filter(lambda x: x.field_dict["ipv4_id"] == ip_id, interfaces) + return interfaces + + +def get_machine_with_interface(interface): + """ + Get the machine which contained the given interface, even if deleted + """ + machine_id = interface.field_dict["machine_id"] + machines = Version.objects.get_for_model(Machine) + machines = filter(lambda x: x.field_dict["id"] == machine_id, machines) + return machines[0] + + +def get_user_with_machine(machine): + """ + """ + user_id = machine.field_dict["user_id"] + user = User.objects.filter(id=user_id) + return user[0] + + +interfaces = get_interfaces_with_ip("10.0.0.0") + +output_dict = {} +for interface in interfaces: + mac = interface.field_dict["mac_address"] + machine = get_machine_with_interface(interface) + user = get_user_with_machine(machine) + output_dict[mac] = { + "machine": machine.field_dict["name"], + "user": user + } + +print(output_dict) + From 451923be3e9744e350dd250504daa300f89632f4 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:39:05 +0200 Subject: [PATCH 03/15] Add comments to logs/models.py --- logs/models.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/logs/models.py b/logs/models.py index 906fc020..59466405 100644 --- a/logs/models.py +++ b/logs/models.py @@ -40,6 +40,9 @@ class HistoryEvent: self.comment = interface.revision.get_comment() or None def is_similar(self, elt2): + """ + Checks whether two events are similar enough to be merged + """ return ( elt2 is not None and self.user.id == elt2.user.id @@ -78,10 +81,13 @@ class MachineHistory: return None def __add_revision(self, user: User, machine: Version, interface: Version): + """ + Add a new revision to the chronological order + """ evt = HistoryEvent(user, machine, interface) evt.start_date = interface.revision.date_created - # Try not to recreate events if unnecessary + # Try not to recreate events if it's unnecessary if evt.is_similar(self.__last_evt): return @@ -107,8 +113,12 @@ class MachineHistory: Returns an iterable object with the Version objects of Interfaces with the given IP """ - # TODO: Deleted IpList - ip_id = IpList.objects.get(ipv4=ip).id + # TODO: What if ip list was deleted? + try: + ip_id = IpList.objects.get(ipv4=ip).id + except IpList.DoesNotExist: + return [] + return filter( lambda x: x.field_dict["ipv4_id"] == ip_id, Version.objects.get_for_model(Interface).order_by("revision__date_created") @@ -119,7 +129,6 @@ class MachineHistory: Returns an iterable object with the Version objects of Interfaces with the given MAC """ - # TODO: What if IpList was deleted? return filter( lambda x: str(x.field_dict["mac_address"]) == mac, Version.objects.get_for_model(Interface).order_by("revision__date_created") From c662fa64d84e8465b7edb8b5935b064522ef5777 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:41:59 +0200 Subject: [PATCH 04/15] Improve machine history results view --- logs/templates/logs/machine_history.html | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index 50efbcf5..4af9bf16 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -31,17 +31,21 @@ with this program; if not, write to the Free Software Foundation, Inc., - - - - - - + + + + + + {% for event in events %} - + From f051d5c09c6219ff6c96c94c8bf28aaf42a13e6e Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:43:13 +0200 Subject: [PATCH 05/15] Tweak machine history results view --- logs/templates/logs/machine_history.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index 4af9bf16..c2ad7368 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., - + @@ -43,7 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., From e76a215579841a20715f8b2043b87caf44a33a68 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:45:43 +0200 Subject: [PATCH 06/15] Handle empty dates in machine history results view --- logs/templates/logs/machine_history.html | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index c2ad7368..e1c510ed 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -48,8 +48,20 @@ with this program; if not, write to the Free Software Foundation, Inc., - - + + {% endfor %} From 830f6341dfb6b6d92eb61701b2745d14674b4723 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:47:21 +0200 Subject: [PATCH 07/15] Add link to machine history view --- logs/templates/logs/sidebar.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/logs/templates/logs/sidebar.html b/logs/templates/logs/sidebar.html index 7f7d6cbf..a44da9e3 100644 --- a/logs/templates/logs/sidebar.html +++ b/logs/templates/logs/sidebar.html @@ -52,6 +52,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Users" %} + + + {% trans "Machine history" %} + {% acl_end %} {% endblock %} From 6678c15c2c0368ed6db21738b0268462eb591661 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:51:11 +0200 Subject: [PATCH 08/15] Fix date compare in machine history view --- logs/models.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/logs/models.py b/logs/models.py index 59466405..0c70c739 100644 --- a/logs/models.py +++ b/logs/models.py @@ -22,6 +22,8 @@ The models definitions for the Machines app """ from reversion.models import Version +from datetime import datetime + from machines.models import IpList from machines.models import Interface from machines.models import Machine @@ -72,6 +74,21 @@ class MachineHistory: self.end = params.get("e", None) search_type = params.get("t", 0) + # Convert dates to datetime objects + if self.start: + self.start = datetime.datetime( + self.start.year, + self.start.month, + self.start.day + ) + + if self.end: + self.end = datetime.datetime( + self.end.year, + self.end.month, + self.end.day + ) + self.events = [] if search_type == "ip": return self.__get_by_ip(search) From 69666e1c9126eba53a5b882f2fb8527830d20e8f Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 18:52:58 +0200 Subject: [PATCH 09/15] Handle dates more gracefuly in machine history view --- logs/models.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/logs/models.py b/logs/models.py index 0c70c739..f54b8365 100644 --- a/logs/models.py +++ b/logs/models.py @@ -22,7 +22,6 @@ The models definitions for the Machines app """ from reversion.models import Version -from datetime import datetime from machines.models import IpList from machines.models import Interface @@ -74,21 +73,6 @@ class MachineHistory: self.end = params.get("e", None) search_type = params.get("t", 0) - # Convert dates to datetime objects - if self.start: - self.start = datetime.datetime( - self.start.year, - self.start.month, - self.start.day - ) - - if self.end: - self.end = datetime.datetime( - self.end.year, - self.end.month, - self.end.day - ) - self.events = [] if search_type == "ip": return self.__get_by_ip(search) @@ -113,12 +97,12 @@ class MachineHistory: self.__last_evt.end_date = evt.start_date # If the event ends before the given date, remove it - if self.start and evt.start_date < self.start: + if self.start and evt.start_date.date() < self.start: self.__last_evt = None self.events.pop() # Make sure the new event starts before the given end date - if self.end and evt.start_date > self.end: + if self.end and evt.start_date.date() > self.end: return # Save the new element From 41723adc8946a3a586d0c47752520336ef2fb8be Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 16:55:59 +0000 Subject: [PATCH 10/15] Fix date check in machine history display --- logs/templates/logs/machine_history.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index e1c510ed..93e1817a 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -56,7 +56,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% endfor %}
UserIPv4MACStart dateEnd dateComment{% trans "User" %}{% trans "User" %}{% trans "MAC address" %}{% trans "Start date" %}{% trans "End date" %}{% trans "Comment" %}
{{ event.user.pseudo }} + + {{ event.user }} + + {{ event.ipv4 }} {{ event.mac }} {{ event.start_date }}
{% trans "User" %}{% trans "User" %}{% trans "IPv4" %} {% trans "MAC address" %} {% trans "Start date" %} {% trans "End date" %}
- {{ event.user }} + {{ event.user }} {{ event.ipv4 }}{{ event.ipv4 }} {{ event.mac }}{{ event.start_date }}{{ event.end_date }} + {% if event.start_date %} + {{ event.start_date }} + {% else %} + {% trans "Unknown" %} + {% endif %} + + {% if event.start_date %} + {{ event.end_date }} + {% else %} + {% trans "Now" %} + {% endif %} + {{ event.comment }}
- {% if event.start_date %} + {% if event.end_date %} {{ event.end_date }} {% else %} {% trans "Now" %} From 91cee11297ebdf260d757130362fc822a8062c37 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 17:02:33 +0000 Subject: [PATCH 11/15] Add missing translations in logs --- api/locale/fr/LC_MESSAGES/django.po | 2 +- cotisations/locale/fr/LC_MESSAGES/django.po | 2 +- logs/forms.py | 2 +- logs/locale/fr/LC_MESSAGES/django.po | 126 ++++++++++++++------ machines/locale/fr/LC_MESSAGES/django.po | 2 +- multi_op/locale/fr/LC_MESSAGES/django.po | 2 +- preferences/locale/fr/LC_MESSAGES/django.po | 2 +- re2o/locale/fr/LC_MESSAGES/django.po | 2 +- search/locale/fr/LC_MESSAGES/django.po | 2 +- templates/locale/fr/LC_MESSAGES/django.po | 2 +- tickets/locale/fr/LC_MESSAGES/django.po | 2 +- topologie/locale/fr/LC_MESSAGES/django.po | 2 +- users/locale/fr/LC_MESSAGES/django.po | 5 +- 13 files changed, 103 insertions(+), 50 deletions(-) diff --git a/api/locale/fr/LC_MESSAGES/django.po b/api/locale/fr/LC_MESSAGES/django.po index 8040325f..3c08e4e5 100644 --- a/api/locale/fr/LC_MESSAGES/django.po +++ b/api/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2019-01-07 01:37+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/cotisations/locale/fr/LC_MESSAGES/django.po b/cotisations/locale/fr/LC_MESSAGES/django.po index ef9b3fa5..aca2607b 100644 --- a/cotisations/locale/fr/LC_MESSAGES/django.po +++ b/cotisations/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language: fr_FR\n" diff --git a/logs/forms.py b/logs/forms.py index f51dbef7..3182ef17 100644 --- a/logs/forms.py +++ b/logs/forms.py @@ -27,7 +27,7 @@ from re2o.base import get_input_formats_help_text CHOICES_TYPE = ( ("ip", _("IPv4")), - ("mac", _("MAC")), + ("mac", _("MAC address")), ) diff --git a/logs/locale/fr/LC_MESSAGES/django.po b/logs/locale/fr/LC_MESSAGES/django.po index 88f515fd..bb8dc944 100644 --- a/logs/locale/fr/LC_MESSAGES/django.po +++ b/logs/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-23 16:01+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -34,6 +34,30 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." +#: logs/forms.py:29 logs/templates/logs/machine_history.html:35 +msgid "IPv4" +msgstr "IPv4" + +#: logs/forms.py:30 logs/templates/logs/machine_history.html:36 +msgid "MAC address" +msgstr "Adresse MAC" + +#: logs/forms.py:38 logs/templates/logs/search_machine_history.html:38 +msgid "Search" +msgstr "Rechercher" + +#: logs/forms.py:42 +msgid "Search type" +msgstr "Type de recherche" + +#: logs/forms.py:45 logs/templates/logs/machine_history.html:37 +msgid "Start date" +msgstr "Date de début" + +#: logs/forms.py:46 logs/templates/logs/machine_history.html:38 +msgid "End date" +msgstr "Date de fin" + #: logs/templates/logs/aff_stats_logs.html:36 msgid "Edited object" msgstr "Objet modifié" @@ -52,6 +76,7 @@ msgid "Date of editing" msgstr "Date de modification" #: logs/templates/logs/aff_stats_logs.html:42 +#: logs/templates/logs/machine_history.html:39 msgid "Comment" msgstr "Commentaire" @@ -159,10 +184,35 @@ msgid "Statistics" msgstr "Statistiques" #: logs/templates/logs/index.html:32 logs/templates/logs/stats_logs.html:32 -#: logs/views.py:418 +#: logs/views.py:421 msgid "Actions performed" msgstr "Actions effectuées" +#: logs/templates/logs/machine_history.html:27 +msgid "Search results" +msgstr "Résultats de la recherche" + +#: logs/templates/logs/machine_history.html:34 +msgid "User" +msgstr "Utilisateur" + +#: logs/templates/logs/machine_history.html:55 +msgid "Unknown" +msgstr "Inconnu(e)" + +#: logs/templates/logs/machine_history.html:62 +msgid "Now" +msgstr "Maintenant" + +#: logs/templates/logs/machine_history.html:70 +msgid "No result" +msgstr "Aucun résultat" + +#: logs/templates/logs/search_machine_history.html:27 +#: logs/templates/logs/search_machine_history.html:32 +msgid "Search machine history" +msgstr "Rechercher l'historique des machines" + #: logs/templates/logs/sidebar.html:33 msgid "Summary" msgstr "Résumé" @@ -187,6 +237,10 @@ msgstr "Actions de câblage" msgid "Users" msgstr "Utilisateurs" +#: logs/templates/logs/sidebar.html:57 +msgid "Machine history" +msgstr "Historique des machines" + #: logs/templates/logs/stats_general.html:32 msgid "General statistics" msgstr "Statistiques générales" @@ -199,138 +253,138 @@ msgstr "Statistiques sur la base de données" msgid "Statistics about users" msgstr "Statistiques sur les utilisateurs" -#: logs/views.py:175 +#: logs/views.py:178 msgid "Nonexistent revision." msgstr "Révision inexistante." -#: logs/views.py:178 +#: logs/views.py:181 msgid "The action was deleted." msgstr "L'action a été supprimée." -#: logs/views.py:219 +#: logs/views.py:222 msgid "Category" msgstr "Catégorie" -#: logs/views.py:220 +#: logs/views.py:223 msgid "Number of users (members and clubs)" msgstr "Nombre d'utilisateurs (adhérents et clubs)" -#: logs/views.py:221 +#: logs/views.py:224 msgid "Number of members" msgstr "Nombre d'adhérents" -#: logs/views.py:222 +#: logs/views.py:225 msgid "Number of clubs" msgstr "Nombre de clubs" -#: logs/views.py:226 +#: logs/views.py:229 msgid "Activated users" msgstr "Utilisateurs activés" -#: logs/views.py:232 +#: logs/views.py:235 msgid "Disabled users" msgstr "Utilisateurs désactivés" -#: logs/views.py:238 +#: logs/views.py:241 msgid "Archived users" msgstr "Utilisateurs archivés" -#: logs/views.py:244 +#: logs/views.py:247 msgid "Fully archived users" msgstr "Utilisateurs complètement archivés" -#: logs/views.py:254 +#: logs/views.py:257 msgid "Not yet active users" msgstr "Utilisateurs pas encore actifs" -#: logs/views.py:264 +#: logs/views.py:267 msgid "Contributing members" msgstr "Adhérents cotisants" -#: logs/views.py:270 +#: logs/views.py:273 msgid "Users benefiting from a connection" msgstr "Utilisateurs bénéficiant d'une connexion" -#: logs/views.py:276 +#: logs/views.py:279 msgid "Banned users" msgstr "Utilisateurs bannis" -#: logs/views.py:282 +#: logs/views.py:285 msgid "Users benefiting from a free connection" msgstr "Utilisateurs bénéficiant d'une connexion gratuite" -#: logs/views.py:288 +#: logs/views.py:291 msgid "Users with a confirmed email" msgstr "Utilisateurs ayant un mail confirmé" -#: logs/views.py:294 +#: logs/views.py:297 msgid "Users with an unconfirmed email" msgstr "Utilisateurs ayant un mail non confirmé" -#: logs/views.py:300 +#: logs/views.py:303 msgid "Users pending email confirmation" msgstr "Utilisateurs en attente de confirmation du mail" -#: logs/views.py:306 +#: logs/views.py:309 msgid "Active interfaces (with access to the network)" msgstr "Interfaces actives (ayant accès au réseau)" -#: logs/views.py:320 +#: logs/views.py:323 msgid "Active interfaces assigned IPv4" msgstr "Interfaces actives assignées IPv4" -#: logs/views.py:337 +#: logs/views.py:340 msgid "IP range" msgstr "Plage d'IP" -#: logs/views.py:338 +#: logs/views.py:341 msgid "VLAN" msgstr "VLAN" -#: logs/views.py:339 +#: logs/views.py:342 msgid "Total number of IP addresses" msgstr "Nombre total d'adresses IP" -#: logs/views.py:340 +#: logs/views.py:343 msgid "Number of assigned IP addresses" msgstr "Nombre d'adresses IP assignées" -#: logs/views.py:341 +#: logs/views.py:344 msgid "Number of IP address assigned to an activated machine" msgstr "Nombre d'adresses IP assignées à une machine activée" -#: logs/views.py:342 +#: logs/views.py:345 msgid "Number of unassigned IP addresses" msgstr "Nombre d'adresses IP non assignées" -#: logs/views.py:357 +#: logs/views.py:360 msgid "Users (members and clubs)" msgstr "Utilisateurs (adhérents et clubs)" -#: logs/views.py:403 +#: logs/views.py:406 msgid "Topology" msgstr "Topologie" -#: logs/views.py:419 +#: logs/views.py:422 msgid "Number of actions" msgstr "Nombre d'actions" -#: logs/views.py:444 +#: logs/views.py:447 msgid "rights" msgstr "droits" -#: logs/views.py:473 +#: logs/views.py:476 msgid "actions" msgstr "actions" -#: logs/views.py:504 +#: logs/views.py:529 msgid "No model found." msgstr "Aucun modèle trouvé." -#: logs/views.py:510 +#: logs/views.py:535 msgid "Nonexistent entry." msgstr "Entrée inexistante." -#: logs/views.py:517 +#: logs/views.py:542 msgid "You don't have the right to access this menu." msgstr "Vous n'avez pas le droit d'accéder à ce menu." diff --git a/machines/locale/fr/LC_MESSAGES/django.po b/machines/locale/fr/LC_MESSAGES/django.po index e5f8dfc9..f1726d25 100644 --- a/machines/locale/fr/LC_MESSAGES/django.po +++ b/machines/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 22:29+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-23 16:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/multi_op/locale/fr/LC_MESSAGES/django.po b/multi_op/locale/fr/LC_MESSAGES/django.po index e60cb464..14c22e92 100644 --- a/multi_op/locale/fr/LC_MESSAGES/django.po +++ b/multi_op/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2019-11-16 00:22+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/preferences/locale/fr/LC_MESSAGES/django.po b/preferences/locale/fr/LC_MESSAGES/django.po index e90c1e2a..c655e7a3 100644 --- a/preferences/locale/fr/LC_MESSAGES/django.po +++ b/preferences/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-24 15:54+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/re2o/locale/fr/LC_MESSAGES/django.po b/re2o/locale/fr/LC_MESSAGES/django.po index 84b4bd34..92498917 100644 --- a/re2o/locale/fr/LC_MESSAGES/django.po +++ b/re2o/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/search/locale/fr/LC_MESSAGES/django.po b/search/locale/fr/LC_MESSAGES/django.po index 2e18a0a2..0c644ed6 100644 --- a/search/locale/fr/LC_MESSAGES/django.po +++ b/search/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-24 20:10+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/templates/locale/fr/LC_MESSAGES/django.po b/templates/locale/fr/LC_MESSAGES/django.po index ad8e9968..89d40143 100644 --- a/templates/locale/fr/LC_MESSAGES/django.po +++ b/templates/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/tickets/locale/fr/LC_MESSAGES/django.po b/tickets/locale/fr/LC_MESSAGES/django.po index df651ec7..fbb7cbc2 100644 --- a/tickets/locale/fr/LC_MESSAGES/django.po +++ b/tickets/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2019-11-16 00:35+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/topologie/locale/fr/LC_MESSAGES/django.po b/topologie/locale/fr/LC_MESSAGES/django.po index b5f45bff..a637304c 100644 --- a/topologie/locale/fr/LC_MESSAGES/django.po +++ b/topologie/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-25 14:53+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/users/locale/fr/LC_MESSAGES/django.po b/users/locale/fr/LC_MESSAGES/django.po index edae2c02..6ce34b36 100644 --- a/users/locale/fr/LC_MESSAGES/django.po +++ b/users/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-21 21:38+0200\n" +"POT-Creation-Date: 2020-04-22 19:00+0200\n" "PO-Revision-Date: 2018-06-27 23:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -492,8 +492,7 @@ msgstr "Le champ mail ne peut pas ^êêtre vide" #: users/models.py:1344 msgid "You can't use a {} address as an external contact address." -msgstr "" -"Vous ne pouvez pas utiliser une adresse {} pour votre adresse externe." +msgstr "Vous ne pouvez pas utiliser une adresse {} pour votre adresse externe." #: users/models.py:1371 msgid "member" From 01236373aa85ad2564b0f55fdcc0cbdb99387a47 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 19:10:10 +0200 Subject: [PATCH 12/15] Add pagination for machine history results --- logs/templates/logs/machine_history.html | 1 + logs/views.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/logs/templates/logs/machine_history.html b/logs/templates/logs/machine_history.html index 93e1817a..5aea5e9d 100644 --- a/logs/templates/logs/machine_history.html +++ b/logs/templates/logs/machine_history.html @@ -66,6 +66,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
+ {% include 'pagination.html' with list=events %} {% else %}

{% trans "No result" %}

{% endif %} diff --git a/logs/views.py b/logs/views.py index ca75e48f..7e6df54a 100644 --- a/logs/views.py +++ b/logs/views.py @@ -489,16 +489,19 @@ def stats_search_machine_history(request): history_form = MachineHistoryForm(request.GET or None) if history_form.is_valid(): history = MachineHistory() + events = history.get( + history_form.cleaned_data.get("q", ""), + history_form.cleaned_data + ) + max_result = GeneralOption.get_cached_value("search_display_page") + re2o_paginator(request, + events, + max_result) + return render( request, "logs/machine_history.html", - { - "events": - history.get( - history_form.cleaned_data.get("q", ""), - history_form.cleaned_data - ) - }, + { "events": events }, ) return render(request, "logs/search_machine_history.html", {"history_form": history_form}) From a5b67300c9da27c566df406ec34443a542dd9648 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 17:14:49 +0000 Subject: [PATCH 13/15] Fix number of results in pagination for machine history --- logs/views.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/logs/views.py b/logs/views.py index 7e6df54a..2ee1b0c7 100644 --- a/logs/views.py +++ b/logs/views.py @@ -493,10 +493,12 @@ def stats_search_machine_history(request): history_form.cleaned_data.get("q", ""), history_form.cleaned_data ) - max_result = GeneralOption.get_cached_value("search_display_page") - re2o_paginator(request, - events, - max_result) + max_result = GeneralOption.get_cached_value("pagination_number") + events = re2o_paginator( + request, + events, + max_result + ) return render( request, From 5639d438660d0571fa170818d3d0bd9519cecb4e Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 19:48:30 +0200 Subject: [PATCH 14/15] Remove unused file --- test.py | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 test.py diff --git a/test.py b/test.py deleted file mode 100644 index 7b777609..00000000 --- a/test.py +++ /dev/null @@ -1,50 +0,0 @@ -from reversion.models import Version -from machines.models import IpList -from machines.models import Interface -from machines.models import Machine -from users.models import User - - -def get_interfaces_with_ip(ip): - """ - Get all the interfaces that, at some point, had the given ip - """ - # TODO: What if IpList was deleted? - ip_id = IpList.objects.get(ipv4=ip).id - interfaces = Version.objects.get_for_model(Interface) - interfaces = filter(lambda x: x.field_dict["ipv4_id"] == ip_id, interfaces) - return interfaces - - -def get_machine_with_interface(interface): - """ - Get the machine which contained the given interface, even if deleted - """ - machine_id = interface.field_dict["machine_id"] - machines = Version.objects.get_for_model(Machine) - machines = filter(lambda x: x.field_dict["id"] == machine_id, machines) - return machines[0] - - -def get_user_with_machine(machine): - """ - """ - user_id = machine.field_dict["user_id"] - user = User.objects.filter(id=user_id) - return user[0] - - -interfaces = get_interfaces_with_ip("10.0.0.0") - -output_dict = {} -for interface in interfaces: - mac = interface.field_dict["mac_address"] - machine = get_machine_with_interface(interface) - user = get_user_with_machine(machine) - output_dict[mac] = { - "machine": machine.field_dict["name"], - "user": user - } - -print(output_dict) - From 17f0691957e3a0d96a877d9ae873457cfa1a7492 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Wed, 22 Apr 2020 23:23:12 +0200 Subject: [PATCH 15/15] Fix comments for machine history view and model --- logs/models.py | 62 ++++++++++++++++++++++++++++++++++++-------------- logs/views.py | 4 ++-- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/logs/models.py b/logs/models.py index f54b8365..343a33cb 100644 --- a/logs/models.py +++ b/logs/models.py @@ -18,8 +18,8 @@ # 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.models -The models definitions for the Machines app +"""logs.models +The models definitions for the logs app """ from reversion.models import Version @@ -30,7 +30,14 @@ from users.models import User class HistoryEvent: - def __init__(self, user: User, machine: Version, interface: Version, start=None, end=None): + def __init__(self, user, machine, interface, start=None, end=None): + """ + :param user: User, The user owning the maching at the time of the event + :param machine: Version, the machine version related to the interface + :param interface: Version, the interface targeted by this event + :param start: datetime, the date at which this version was created + :param end: datetime, the date at which this version was replace by a new one + """ self.user = user self.machine = machine self.interface = interface @@ -43,6 +50,7 @@ class HistoryEvent: def is_similar(self, elt2): """ Checks whether two events are similar enough to be merged + :return: bool """ return ( elt2 is not None @@ -69,6 +77,11 @@ class MachineHistory: self.__last_evt = None def get(self, search, params): + """ + :param search: ip or mac to lookup + :param params: dict built by the search view + :return: list or None, a list of HistoryEvent + """ self.start = params.get("s", None) self.end = params.get("e", None) search_type = params.get("t", 0) @@ -81,9 +94,12 @@ class MachineHistory: return None - def __add_revision(self, user: User, machine: Version, interface: Version): + def __add_revision(self, user, machine, interface): """ Add a new revision to the chronological order + :param user: User, The user owning the maching at the time of the event + :param machine: Version, the machine version related to the interface + :param interface: Version, the interface targeted by this event """ evt = HistoryEvent(user, machine, interface) evt.start_date = interface.revision.date_created @@ -109,10 +125,11 @@ class MachineHistory: self.events.append(evt) self.__last_evt = evt - def __get_interfaces_for_ip(self, ip: str): + def __get_interfaces_for_ip(self, ip): """ - Returns an iterable object with the Version objects - of Interfaces with the given IP + :param ip: str + :return: An iterable object with the Version objects + of Interfaces with the given IP """ # TODO: What if ip list was deleted? try: @@ -125,20 +142,22 @@ class MachineHistory: Version.objects.get_for_model(Interface).order_by("revision__date_created") ) - def __get_interfaces_for_mac(self, mac: str): + def __get_interfaces_for_mac(self, mac): """ - Returns an iterable object with the Version objects - of Interfaces with the given MAC + :param mac: str + :return: An iterable object with the Version objects + of Interfaces with the given MAC address """ return filter( lambda x: str(x.field_dict["mac_address"]) == mac, Version.objects.get_for_model(Interface).order_by("revision__date_created") ) - def __get_machines_for_interface(self, interface: Version): + def __get_machines_for_interface(self, interface): """ - Returns an iterable object with the Verison objects - of Machines to which the given interface was attributed + :param interface: Version, the interface for which to find the machines + :return: An iterable object with the Version objects of Machine to + which the given interface was attributed """ machine_id = interface.field_dict["machine_id"] return filter( @@ -146,15 +165,20 @@ class MachineHistory: Version.objects.get_for_model(Machine).order_by("revision__date_created") ) - def __get_user_for_machine(self, machine: Version): + def __get_user_for_machine(self, machine): """ - Returns the user to which the given machine belongs + :param machine: Version, the machine of which the owner must be found + :return: The user to which the given machine belongs """ # TODO: What if user was deleted? user_id = machine.field_dict["user_id"] return User.objects.get(id=user_id) - def __get_by_ip(self, ip: str): + def __get_by_ip(self, ip): + """ + :param ip: str, The IP to lookup + :returns: list, a list of HistoryEvent + """ interfaces = self.__get_interfaces_for_ip(ip) for interface in interfaces: @@ -166,7 +190,11 @@ class MachineHistory: return self.events - def __get_by_mac(self, mac: str): + def __get_by_mac(self, mac): + """ + :param mac: str, The MAC address to lookup + :returns: list, a list of HistoryEvent + """ interfaces = self.__get_interfaces_for_mac(mac) for interface in interfaces: diff --git a/logs/views.py b/logs/views.py index 2ee1b0c7..85ba35cf 100644 --- a/logs/views.py +++ b/logs/views.py @@ -484,8 +484,8 @@ def stats_actions(request): @login_required @can_view_app("users") def stats_search_machine_history(request): - """Vue qui permet de rechercher l'historique des machines ayant utilisé - une IP ou une adresse MAC""" + """View which displays the history of machines with the given + une IP or MAC adresse""" history_form = MachineHistoryForm(request.GET or None) if history_form.is_valid(): history = MachineHistory()