Commit a84e8b55 authored by chirac's avatar chirac

Merge branch 'fix_65_history' into 'master'

fix #65, gestion propre de l'historique.

Closes #65

See merge request federez/re2o!186
parents f6a152f0 c7bf2958
...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load acl %} {% load acl %}
{% load i18n %} {% load i18n %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
...@@ -46,14 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -46,14 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ article.type_user }}</td> <td>{{ article.type_user }}</td>
<td>{{ article.available_for_everyone }}</td> <td>{{ article.available_for_everyone }}</td>
<td class="text-right"> <td class="text-right">
{% can_edit article %} {% can_edit article %}
<a class="btn btn-primary btn-sm" role="button" title="{% trans "Edit" %}" href="{% url 'cotisations:edit-article' article.id %}"> <a class="btn btn-primary btn-sm" role="button" title="{% trans "Edit" %}" href="{% url 'cotisations:edit-article' article.id %}">
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
</a> </a>
{% acl_end %} {% acl_end %}
<a class="btn btn-info btn-sm" role="button" title="{% trans "Historique" %}" href="{% url 'cotisations:history' 'article' article.id %}"> {% history_button article %}
<i class="fa fa-history"></i>
</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load acl %} {% load acl %}
{% load i18n %} {% load i18n %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
...@@ -36,14 +37,12 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -36,14 +37,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr> <tr>
<td>{{ banque.name }}</td> <td>{{ banque.name }}</td>
<td class="text-right"> <td class="text-right">
{% can_edit banque %} {% can_edit banque %}
<a class="btn btn-primary btn-sm" role="button" title="{% trans "Edit" %}" href="{% url 'cotisations:edit-banque' banque.id %}"> <a class="btn btn-primary btn-sm" role="button" title="{% trans "Edit" %}" href="{% url 'cotisations:edit-banque' banque.id %}">
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
</a> </a>
{% acl_end %} {% acl_end %}
<a class="btn btn-info btn-sm" role="button" title="{% trans "Historique" %}" href="{% url 'cotisations:history' 'banque' banque.id %}"> {% history_button banque %}
<i class="fa fa-history"></i>
</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load acl %} {% load acl %}
{% load i18n %} {% load i18n %}
{% load logs_extra %}
<div class="table-responsive"> <div class="table-responsive">
{% if facture_list.paginator %} {% if facture_list.paginator %}
...@@ -86,9 +87,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -86,9 +87,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</li> </li>
{% acl_end %} {% acl_end %}
<li> <li>
<a href="{% url 'cotisations:history' 'facture' facture.id %}"> {% history_button facture text=True html_class=False%}
<i class="fa fa-history"></i> {% trans "Historique" %}
</a>
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load acl %} {% load acl %}
{% load i18n %} {% load i18n %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
...@@ -47,9 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -47,9 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<i class="fa fa-edit"></i> <i class="fa fa-edit"></i>
</a> </a>
{% acl_end %} {% acl_end %}
<a class="btn btn-info btn-sm" role="button" title="{% trans "Historique" %}" href="{% url 'cotisations:history' 'paiement' paiement.id %}"> {% history_button paiement %}
<i class="fa fa-history"></i>
</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -27,7 +27,6 @@ from __future__ import unicode_literals ...@@ -27,7 +27,6 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
import re2o
from . import views from . import views
from . import payment_methods from . import payment_methods
...@@ -122,12 +121,6 @@ urlpatterns = [ ...@@ -122,12 +121,6 @@ urlpatterns = [
views.index_paiement, views.index_paiement,
name='index-paiement' name='index-paiement'
), ),
url(
r'history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
re2o.views.history,
name='history',
kwargs={'application': 'cotisations'},
),
url( url(
r'^control/$', r'^control/$',
views.control, views.control,
......
...@@ -33,3 +33,23 @@ register = template.Library() ...@@ -33,3 +33,23 @@ register = template.Library()
def classname(obj): def classname(obj):
""" Returns the object class name """ """ Returns the object class name """
return obj.__class__.__name__ return obj.__class__.__name__
@register.inclusion_tag('buttons/history.html')
def history_button(instance, text=False, html_class=True):
"""Creates the correct history button for an instance.
Args:
instance: The instance of which you want to get history buttons.
text: Flag stating if a 'History' text should be displayed.
html_class: Flag stating if the link should have the html classes
allowing it to be displayed as a button.
"""
return {
'application': instance._meta.app_label,
'name': instance._meta.model_name,
'id': instance.id,
'text': text,
'class': html_class,
}
...@@ -39,4 +39,9 @@ urlpatterns = [ ...@@ -39,4 +39,9 @@ urlpatterns = [
url(r'^stats_models/$', views.stats_models, name='stats-models'), url(r'^stats_models/$', views.stats_models, name='stats-models'),
url(r'^stats_users/$', views.stats_users, name='stats-users'), url(r'^stats_users/$', views.stats_users, name='stats-users'),
url(r'^stats_actions/$', views.stats_actions, name='stats-actions'), url(r'^stats_actions/$', views.stats_actions, name='stats-actions'),
url(
r'(?P<application>\w+)/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
views.history,
name='history',
),
] ]
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
# se veut agnostique au réseau considéré, de manière à être installable en # se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics. # quelques clics.
# #
# Copyright © 2017 Gabriel Détraz # Copyright © 2018 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec # Copyright © 2018 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle # Copyright © 2018 Augustin Lemesle
# Copyright © 2018 Hugo Levy-Falk
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
...@@ -36,12 +37,16 @@ nombre d'objets par models, nombre d'actions par user, etc ...@@ -36,12 +37,16 @@ nombre d'objets par models, nombre d'actions par user, etc
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from itertools import chain
from django.urls import reverse from django.urls import reverse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Count, Max, F from django.http import Http404
from django.db.models import Count
from django.apps import apps
from django.utils.translation import ugettext as _
from reversion.models import Revision from reversion.models import Revision
from reversion.models import Version, ContentType from reversion.models import Version, ContentType
...@@ -142,7 +147,7 @@ def index(request): ...@@ -142,7 +147,7 @@ def index(request):
'comment': version.revision.comment, 'comment': version.revision.comment,
'datetime': version.revision.date_created.strftime( 'datetime': version.revision.date_created.strftime(
'%d/%m/%y %H:%M:%S' '%d/%m/%y %H:%M:%S'
), ),
'username': 'username':
version.revision.user.get_username() version.revision.user.get_username()
if version.revision.user else '?', if version.revision.user else '?',
...@@ -173,7 +178,7 @@ def stats_logs(request): ...@@ -173,7 +178,7 @@ def stats_logs(request):
revisions = re2o_paginator(request, revisions, pagination_number) revisions = re2o_paginator(request, revisions, pagination_number)
return render(request, 'logs/stats_logs.html', { return render(request, 'logs/stats_logs.html', {
'revisions_list': revisions 'revisions_list': revisions
}) })
@login_required @login_required
...@@ -191,7 +196,7 @@ def revert_action(request, revision_id): ...@@ -191,7 +196,7 @@ def revert_action(request, revision_id):
return form({ return form({
'objet': revision, 'objet': revision,
'objet_name': revision.__class__.__name__ 'objet_name': revision.__class__.__name__
}, 'logs/delete.html', request) }, 'logs/delete.html', request)
@login_required @login_required
...@@ -453,3 +458,58 @@ def stats_actions(request): ...@@ -453,3 +458,58 @@ def stats_actions(request):
}, },
} }
return render(request, 'logs/stats_users.html', {'stats_list': stats}) return render(request, 'logs/stats_users.html', {'stats_list': stats})
def history(request, application, object_name, object_id):
"""Render history for a model.
The model is determined using the `HISTORY_BIND` dictionnary if none is
found, raises a Http404. The view checks if the user is allowed to see the
history using the `can_view` method of the model.
Args:
request: The request sent by the user.
application: Name of the application.
object_name: Name of the model.
object_id: Id of the object you want to acces history.
Returns:
The rendered page of history if access is granted, else the user is
redirected to their profile page, with an error message.
Raises:
Http404: This kind of models doesn't have history.
"""
try:
model = apps.get_model(application, object_name)
except LookupError:
raise Http404(_("No model found."))
object_name_id = object_name + 'id'
kwargs = {object_name_id: object_id}
try:
instance = model.get_instance(**kwargs)
except model.DoesNotExist:
messages.error(request, _("No entry found."))
return redirect(reverse(
'users:profil',
kwargs={'userid': str(request.user.id)}
))
can, msg = instance.can_view(request.user)
if not can:
messages.error(request, msg or _("You cannot acces to this menu"))
return redirect(reverse(
'users:profil',
kwargs={'userid': str(request.user.id)}
))
pagination_number = GeneralOption.get_cached_value('pagination_number')
reversions = Version.objects.get_for_object(instance)
if hasattr(instance, 'linked_objects'):
for related_object in chain(instance.linked_objects()):
reversions = (reversions |
Version.objects.get_for_object(related_object))
reversions = re2o_paginator(request, reversions, pagination_number)
return render(
request,
're2o/history.html',
{'reversions': reversions, 'object': instance}
)
...@@ -23,24 +23,25 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,24 +23,25 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr>
<th>Alias</th>
<th></th>
</tr>
</thead>
{% for alias in alias_list %}
<tr> <tr>
<td>{{ alias }}</td> <th>Alias</th>
<td class="text-right"> <th></th>
{% can_edit alias %}
{% include 'buttons/edit.html' with href='machines:edit-alias' id=alias.id %}
{% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='domain' id=alias.id %}
</td>
</tr> </tr>
{% endfor %} </thead>
</table> {% for alias in alias_list %}
<tr>
<td>{{ alias }}</td>
<td class="text-right">
{% can_edit alias %}
{% include 'buttons/edit.html' with href='machines:edit-alias' id=alias.id %}
{% acl_end %}
{% history_button alias %}
</td>
</tr>
{% endfor %}
</table>
...@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped"> <table class="table table-striped">
...@@ -30,28 +31,28 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -30,28 +31,28 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr> <tr>
<th>Extension</th> <th>Extension</th>
<th>Droit infra pour utiliser ?</th> <th>Droit infra pour utiliser ?</th>
<th>Enregistrement SOA</th> <th>Enregistrement SOA</th>
<th>Enregistrement A origin</th> <th>Enregistrement A origin</th>
{% if ipv6_enabled %} {% if ipv6_enabled %}
<th>Enregistrement AAAA origin</th> <th>Enregistrement AAAA origin</th>
{% endif %} {% endif %}
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
{% for extension in extension_list %} {% for extension in extension_list %}
<tr> <tr>
<td>{{ extension.name }}</td> <td>{{ extension.name }}</td>
<td>{{ extension.need_infra }}</td> <td>{{ extension.need_infra }}</td>
<td>{{ extension.soa}}</td> <td>{{ extension.soa}}</td>
<td>{{ extension.origin }}</td> <td>{{ extension.origin }}</td>
{% if ipv6_enabled %} {% if ipv6_enabled %}
<td>{{ extension.origin_v6 }}</td> <td>{{ extension.origin_v6 }}</td>
{% endif %} {% endif %}
<td class="text-right"> <td class="text-right">
{% can_edit extension %} {% can_edit extension %}
{% include 'buttons/edit.html' with href='machines:edit-extension' id=extension.id %} {% include 'buttons/edit.html' with href='machines:edit-extension' id=extension.id %}
{% acl_end %} {% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='extension' id=extension.id %} {% history_button extension %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
...@@ -31,10 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -31,10 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th>Extension</th> <th>Extension</th>
<th>Nécessite l'autorisation infra</th> <th>Nécessite l'autorisation infra</th>
<th>Plage ipv4</th> <th>Plage ipv4</th>
<th>Préfixe v6</th> <th>Préfixe v6</th>
<th>Sur vlan</th> <th>Sur vlan</th>
<th>Ouverture ports par défault</th> <th>Ouverture ports par défault</th>
<th></th> <th></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
...@@ -43,15 +44,15 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -43,15 +44,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ type.type }}</td> <td>{{ type.type }}</td>
<td>{{ type.extension }}</td> <td>{{ type.extension }}</td>
<td>{{ type.need_infra }}</td> <td>{{ type.need_infra }}</td>
<td>{{ type.domaine_ip_start }}-{{ type.domaine_ip_stop }}</td> <td>{{ type.domaine_ip_start }}-{{ type.domaine_ip_stop }}</td>
<td>{{ type.prefix_v6 }}</td> <td>{{ type.prefix_v6 }}</td>
<td>{{ type.vlan }}</td> <td>{{ type.vlan }}</td>
<td>{{ type.ouverture_ports }}</td> <td>{{ type.ouverture_ports }}</td>
<td class="text-right"> <td class="text-right">
{% can_edit type %} {% can_edit type %}
{% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %} {% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %}
{% acl_end %} {% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='iptype' id=type.id %} {% history_button type %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -23,29 +23,30 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,29 +23,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr>
<th>Ipv6</th>
<th>Slaac</th>
<th></th>
</tr>
</thead>
{% for ipv6 in ipv6_list %}
<tr> <tr>
<td>{{ ipv6.ipv6 }}</td> <th>Ipv6</th>
<td>{{ ipv6.slaac_ip }}</td> <th>Slaac</th>
<td class="text-right"> <th></th>
{% can_edit ipv6 %}
{% include 'buttons/edit.html' with href='machines:edit-ipv6list' id=ipv6.id %}
{% acl_end %}
{% can_delete ipv6 %}
{% include 'buttons/suppr.html' with href='machines:del-ipv6list' id=ipv6.id %}
{% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='ipv6list' id=ipv6.id %}
</td>
</tr> </tr>
{% endfor %} </thead>
</table> {% for ipv6 in ipv6_list %}
<tr>
<td>{{ ipv6.ipv6 }}</td>
<td>{{ ipv6.slaac_ip }}</td>
<td class="text-right">
{% can_edit ipv6 %}
{% include 'buttons/edit.html' with href='machines:edit-ipv6list' id=ipv6.id %}
{% acl_end %}
{% can_delete ipv6 %}
{% include 'buttons/suppr.html' with href='machines:del-ipv6list' id=ipv6.id %}
{% acl_end %}
{% history_button ipv6 %}
</td>
</tr>
{% endfor %}
</table>
...@@ -23,26 +23,27 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,26 +23,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr>
<th>Type de machine</th>
<th>Type d'ip correspondant</th>
<th></th>
</tr>
</thead>
{% for type in machinetype_list %}
<tr> <tr>
<td>{{ type.type }}</td> <th>Type de machine</th>
<td>{{ type.ip_type }}</td> <th>Type d'ip correspondant</th>
<td class="text-right"> <th></th>
{% can_edit type %}
{% include 'buttons/edit.html' with href='machines:edit-machinetype' id=type.id %}
{% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='machinetype' id=type.id %}
</td>
</tr> </tr>
{% endfor %} </thead>
</table> {% for type in machinetype_list %}
<tr>
<td>{{ type.type }}</td>
<td>{{ type.ip_type }}</td>
<td class="text-right">
{% can_edit type %}
{% include 'buttons/edit.html' with href='machines:edit-machinetype' id=type.id %}
{% acl_end %}
{% history_button type %}
</td>
</tr>
{% endfor %}
</table>
...@@ -23,30 +23,31 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,30 +23,31 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr>
<th>Zone concernée</th>
<th>Priorité</th>
<th>Enregistrement</th>
<th></th>
<th></th>
</tr>
</thead>
{% for mx in mx_list %}
<tr> <tr>
<td>{{ mx.zone }}</td> <th>Zone concernée</th>
<td>{{ mx.priority }}</td> <th>Priorité</th>
<td>{{ mx.name }}</td> <th>Enregistrement</th>
<td class="text-right"> <th></th>
<th></th>
</tr>
</thead>
{% for mx in mx_list %}
<tr>
<td>{{ mx.zone }}</td>
<td>{{ mx.priority }}</td>
<td>{{ mx.name }}</td>
<td class="text-right">
{% can_edit mx %} {% can_edit mx %}
{% include 'buttons/edit.html' with href='machines:edit-mx' id=mx.id %} {% include 'buttons/edit.html' with href='machines:edit-mx' id=mx.id %}
{% acl_end %} {% acl_end %}
{% include 'buttons/history.html' with href='machines:history' name='mx' id=mx.id %} {% history_button mx %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
...@@ -23,32 +23,33 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -23,32 +23,33 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %} {% endcomment %}
{% load acl %} {% load acl %}
{% load logs_extra %}
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr>
<th>Nom</th>
<th>Type du nas</th>
<th>Type de machine reliées au nas</th>
<th>Mode d'accès</th>
<th>Autocapture mac</th>
<th></th>
</tr>
</thead>
{% for nas in nas_list %}
<tr> <tr>
<td>{{ nas.name }}</td> <th>Nom</th>
<td>{{ nas.nas_type }}</td> <th>Type du nas</th>
<td>{{ nas.machine_type }}</td> <th>Type de machine reliées au nas</th>
<td>{{ nas.port_access_mode }}</td> <th>Mode d'accès</th>
<td>{{ nas.autocapture_mac }}</td> <th>Autocapture mac</th>
<td class="text-right"> <th></th>
</tr>
</thead>
{% for nas in nas_list %}
<tr>
<td>{{ nas.name }}</td>
<td>{{ nas.nas_type }}</td>