forked from DGNum/gestioCOF
Merge branch 'dodo/limit-history-acces' into 'master'
Limit kfet history access See merge request klub-dev-ens/gestioCOF!487
This commit is contained in:
commit
778637d60e
8 changed files with 100 additions and 7 deletions
|
@ -23,6 +23,10 @@ adhérents ni des cotisations.
|
||||||
|
|
||||||
## Version ??? - dans un futur proche
|
## 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
|
## Version 0.9 - 06/02/2020
|
||||||
|
|
||||||
### COF / BdA
|
### COF / BdA
|
||||||
|
|
|
@ -5,6 +5,7 @@ Surcharge les settings définis dans common.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
from .common import * # NOQA
|
from .common import * # NOQA
|
||||||
from .common import (
|
from .common import (
|
||||||
|
@ -202,3 +203,15 @@ MAIL_DATA = {
|
||||||
"REPLYTO": "BdA-Revente <bda-revente@ens.fr>",
|
"REPLYTO": "BdA-Revente <bda-revente@ens.fr>",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# 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)
|
||||||
|
|
|
@ -2,6 +2,7 @@ from datetime import timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
@ -484,7 +485,15 @@ class KFetConfigForm(ConfigForm):
|
||||||
|
|
||||||
|
|
||||||
class FilterHistoryForm(forms.Form):
|
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)
|
end = forms.DateTimeField(label=_("À"), widget=DateTimeWidget, required=False)
|
||||||
checkout = forms.ModelChoiceField(
|
checkout = forms.ModelChoiceField(
|
||||||
label=_("Caisse"),
|
label=_("Caisse"),
|
||||||
|
|
36
kfet/migrations/0074_auto_20210219_1337.py
Normal file
36
kfet/migrations/0074_auto_20210219_1337.py
Normal file
|
@ -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"),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -89,6 +89,7 @@ class Account(models.Model):
|
||||||
("can_force_close", "Fermer manuellement la K-Fêt"),
|
("can_force_close", "Fermer manuellement la K-Fêt"),
|
||||||
("see_config", "Voir la configuration K-Fêt"),
|
("see_config", "Voir la configuration K-Fêt"),
|
||||||
("change_config", "Modifier 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):
|
def __str__(self):
|
||||||
|
|
|
@ -62,6 +62,7 @@ $(document).ready(function() {
|
||||||
format : 'YYYY-MM-DD HH:mm',
|
format : 'YYYY-MM-DD HH:mm',
|
||||||
stepping : 5,
|
stepping : 5,
|
||||||
locale : 'fr',
|
locale : 'fr',
|
||||||
|
minDate : '{{ history_limit }}',
|
||||||
showTodayButton: true,
|
showTodayButton: true,
|
||||||
widgetPositioning: {
|
widgetPositioning: {
|
||||||
horizontal: "left",
|
horizontal: "left",
|
||||||
|
|
|
@ -4219,8 +4219,8 @@ class HistoryJSONViewTests(ViewTestCaseMixin, TestCase):
|
||||||
url_name = "kfet.history.json"
|
url_name = "kfet.history.json"
|
||||||
url_expected = "/k-fet/history.json"
|
url_expected = "/k-fet/history.json"
|
||||||
|
|
||||||
auth_user = "user"
|
auth_user = "team"
|
||||||
auth_forbidden = [None, "noaccount"]
|
auth_forbidden = [None, "user", "noaccount"]
|
||||||
|
|
||||||
def test_ok(self):
|
def test_ok(self):
|
||||||
r = self.client.post(self.url)
|
r = self.client.post(self.url)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import heapq
|
import heapq
|
||||||
import statistics
|
import statistics
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import List
|
from typing import List
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
|
@ -1410,6 +1411,18 @@ def cancel_operations(request):
|
||||||
return JsonResponse(data)
|
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
|
@login_required
|
||||||
def history_json(request):
|
def history_json(request):
|
||||||
# Récupération des paramètres
|
# Récupération des paramètres
|
||||||
|
@ -1468,6 +1481,9 @@ def history_json(request):
|
||||||
.order_by("at")
|
.order_by("at")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# limite l'accès à l'historique plus vieux que settings.KFET_HISTORY_DATE_LIMIT
|
||||||
|
limit_date = True
|
||||||
|
|
||||||
# Application des filtres
|
# Application des filtres
|
||||||
if start:
|
if start:
|
||||||
opegroups = opegroups.filter(at__gte=start)
|
opegroups = opegroups.filter(at__gte=start)
|
||||||
|
@ -1484,9 +1500,18 @@ def history_json(request):
|
||||||
transfergroups = TransferGroup.objects.none()
|
transfergroups = TransferGroup.objects.none()
|
||||||
if account:
|
if account:
|
||||||
opegroups = opegroups.filter(on_acc=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
|
# Un non-membre de l'équipe n'a que accès à son historique
|
||||||
if not request.user.has_perm("kfet.is_team"):
|
elif not request.user.has_perm("kfet.is_team"):
|
||||||
opegroups = opegroups.filter(on_acc=request.user.profile.account_kfet)
|
# 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
|
# Construction de la réponse
|
||||||
history_groups = []
|
history_groups = []
|
||||||
|
@ -1576,7 +1601,11 @@ def kpsul_articles_data(request):
|
||||||
|
|
||||||
@teamkfet_required
|
@teamkfet_required
|
||||||
def history(request):
|
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)
|
return render(request, "kfet/history.html", data)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue