diff --git a/CHANGELOG.md b/CHANGELOG.md index b2573983..79eb297b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ adhérents ni des cotisations. ## Version ??? - dans un futur proche +### K-Fêt + +- L'accès à l'historique est maintenant limité à 7 jours pour raison de confidentialité. Les chefs/trez peuvent disposer d'une permission supplémentaire pour accèder à jusqu'à 30 jours en cas de problème de compta. L'accès à son historique personnel n'est pas limité. Les durées sont configurables dans `settings/cof_prod.py`. + ## Version 0.9 - 06/02/2020 ### COF / BdA diff --git a/gestioasso/settings/cof_prod.py b/gestioasso/settings/cof_prod.py index d85e84c5..3104e5b0 100644 --- a/gestioasso/settings/cof_prod.py +++ b/gestioasso/settings/cof_prod.py @@ -5,6 +5,7 @@ Surcharge les settings définis dans common.py """ import os +from datetime import timedelta from .common import * # NOQA from .common import ( @@ -202,3 +203,15 @@ MAIL_DATA = { "REPLYTO": "BdA-Revente ", }, } + +# --- +# kfet history limits +# --- + +# L'historique n'est accesible que d'aujourd'hui +# à aujourd'hui - KFET_HISTORY_DATE_LIMIT +KFET_HISTORY_DATE_LIMIT = timedelta(days=7) + +# Limite plus longue pour les chefs/trez +# (qui ont la permission kfet.access_old_history) +KFET_HISTORY_LONG_DATE_LIMIT = timedelta(days=30) diff --git a/kfet/forms.py b/kfet/forms.py index bc98a8ce..f93ff068 100644 --- a/kfet/forms.py +++ b/kfet/forms.py @@ -2,6 +2,7 @@ from datetime import timedelta from decimal import Decimal from django import forms +from django.conf import settings from django.contrib.auth.models import User from django.core import validators from django.core.exceptions import ValidationError @@ -484,7 +485,15 @@ class KFetConfigForm(ConfigForm): class FilterHistoryForm(forms.Form): - start = forms.DateTimeField(label=_("De"), widget=DateTimeWidget, required=False) + start = forms.DateTimeField( + label=_("De"), + widget=DateTimeWidget, + required=False, + help_text="Limité à {} jours ({} pour les chefs/trez)".format( + settings.KFET_HISTORY_DATE_LIMIT.days, + settings.KFET_HISTORY_LONG_DATE_LIMIT.days, + ), + ) end = forms.DateTimeField(label=_("À"), widget=DateTimeWidget, required=False) checkout = forms.ModelChoiceField( label=_("Caisse"), diff --git a/kfet/migrations/0074_auto_20210219_1337.py b/kfet/migrations/0074_auto_20210219_1337.py new file mode 100644 index 00000000..7b4127d8 --- /dev/null +++ b/kfet/migrations/0074_auto_20210219_1337.py @@ -0,0 +1,36 @@ +# Generated by Django 2.2.17 on 2021-02-19 12:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("kfet", "0073_2021"), + ] + + operations = [ + migrations.AlterModelOptions( + name="account", + options={ + "permissions": ( + ("is_team", "Is part of the team"), + ("manage_perms", "Gérer les permissions K-Fêt"), + ("manage_addcosts", "Gérer les majorations"), + ("edit_balance_account", "Modifier la balance d'un compte"), + ( + "change_account_password", + "Modifier le mot de passe d'une personne de l'équipe", + ), + ( + "special_add_account", + "Créer un compte avec une balance initiale", + ), + ("can_force_close", "Fermer manuellement la K-Fêt"), + ("see_config", "Voir la configuration K-Fêt"), + ("change_config", "Modifier la configuration K-Fêt"), + ("access_old_history", "Peut accéder à l'historique plus ancien"), + ) + }, + ), + ] diff --git a/kfet/models.py b/kfet/models.py index 2eacf06f..622c0ac9 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -89,6 +89,7 @@ class Account(models.Model): ("can_force_close", "Fermer manuellement la K-Fêt"), ("see_config", "Voir la configuration K-Fêt"), ("change_config", "Modifier la configuration K-Fêt"), + ("access_old_history", "Peut accéder à l'historique plus ancien"), ) def __str__(self): diff --git a/kfet/templates/kfet/history.html b/kfet/templates/kfet/history.html index c3ebc8b0..03f9bbdf 100644 --- a/kfet/templates/kfet/history.html +++ b/kfet/templates/kfet/history.html @@ -62,6 +62,7 @@ $(document).ready(function() { format : 'YYYY-MM-DD HH:mm', stepping : 5, locale : 'fr', + minDate : '{{ history_limit }}', showTodayButton: true, widgetPositioning: { horizontal: "left", diff --git a/kfet/tests/test_views.py b/kfet/tests/test_views.py index 7d395e7e..40b9ef77 100644 --- a/kfet/tests/test_views.py +++ b/kfet/tests/test_views.py @@ -4219,8 +4219,8 @@ class HistoryJSONViewTests(ViewTestCaseMixin, TestCase): url_name = "kfet.history.json" url_expected = "/k-fet/history.json" - auth_user = "user" - auth_forbidden = [None, "noaccount"] + auth_user = "team" + auth_forbidden = [None, "user", "noaccount"] def test_ok(self): r = self.client.post(self.url) diff --git a/kfet/views.py b/kfet/views.py index c50fb33e..0fe99ea4 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -1,11 +1,12 @@ import heapq import statistics from collections import defaultdict -from datetime import timedelta +from datetime import datetime, timedelta from decimal import Decimal from typing import List from urllib.parse import urlencode +from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.mixins import PermissionRequiredMixin @@ -1410,6 +1411,18 @@ def cancel_operations(request): return JsonResponse(data) +def get_history_limit(user) -> datetime: + """returns the earliest date the given user can view history + according to his/her permissions""" + now = timezone.now() + if user.has_perm("kfet.access_old_history"): + return now - settings.KFET_HISTORY_LONG_DATE_LIMIT + if user.has_perm("kfet.is_team"): + return now - settings.KFET_HISTORY_LONG_DATE_LIMIT + # should not happen - future earliest date + return now + timedelta(days=1) + + @login_required def history_json(request): # Récupération des paramètres @@ -1468,6 +1481,9 @@ def history_json(request): .order_by("at") ) + # limite l'accès à l'historique plus vieux que settings.KFET_HISTORY_DATE_LIMIT + limit_date = True + # Application des filtres if start: opegroups = opegroups.filter(at__gte=start) @@ -1484,9 +1500,18 @@ def history_json(request): transfergroups = TransferGroup.objects.none() if account: opegroups = opegroups.filter(on_acc=account) + if account.user == request.user: + limit_date = False # pas de limite de date sur son propre historique # Un non-membre de l'équipe n'a que accès à son historique - if not request.user.has_perm("kfet.is_team"): - opegroups = opegroups.filter(on_acc=request.user.profile.account_kfet) + elif not request.user.has_perm("kfet.is_team"): + # un non membre de la kfet doit avoir le champ account + # pré-rempli, cette requête est douteuse + return JsonResponse({}, status=403) + if limit_date: + # limiter l'accès à l'historique ancien pour confidentialité + earliest_date = get_history_limit(request.user) + opegroups = opegroups.filter(at__gte=earliest_date) + transfergroups = transfergroups.filter(at__gte=earliest_date) # Construction de la réponse history_groups = [] @@ -1576,7 +1601,11 @@ def kpsul_articles_data(request): @teamkfet_required def history(request): - data = {"filter_form": FilterHistoryForm()} + history_limit = get_history_limit(request.user) + data = { + "filter_form": FilterHistoryForm(), + "history_limit": history_limit.strftime("%Y-%m-%d %H:%M"), + } return render(request, "kfet/history.html", data)