Ajout de groupes et raffinement des permissions

This commit is contained in:
Jean-Marie Favreau 2024-04-01 11:51:00 +02:00
parent 0b67454824
commit 7b51236f06
12 changed files with 161 additions and 18 deletions

View File

@ -516,7 +516,7 @@ msgstr ""
#: agenda_culturel/views.py:350 #: agenda_culturel/views.py:350
msgid "Your message has been sent successfully." msgid "Your message has been sent successfully."
msgstr "L'événement a été supprimé avec succès" msgstr "Votre message a été envoyé avec succès."
#: agenda_culturel/views.py:358 #: agenda_culturel/views.py:358
msgid "The contact message properties has been successfully modified." msgid "The contact message properties has been successfully modified."

View File

@ -0,0 +1,29 @@
# Generated by Django 4.2.7 on 2024-03-31 16:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('agenda_culturel', '0036_auto_20240331_1421'),
]
operations = [
migrations.AlterModelOptions(
name='batchimportation',
options={'permissions': [('run_batchimportation', 'Can run a batch importation')]},
),
migrations.AlterModelOptions(
name='categorisationrule',
options={'permissions': [('apply_categorisationrules', 'Apply a categorisation rule')]},
),
migrations.AlterModelOptions(
name='event',
options={'permissions': [('set_duplicated_event', 'Can set an event as duplicated')], 'verbose_name': 'Event', 'verbose_name_plural': 'Events'},
),
migrations.AlterModelOptions(
name='recurrentimport',
options={'permissions': [('run_recurrentimport', 'Can run a recurrent import')]},
),
]

View File

@ -0,0 +1,45 @@
# Generated by Django 4.2.7 on 2024-03-31 16:15
from django.db import migrations
from django.contrib.auth.management import create_permissions
from django.contrib.auth.models import Group, Permission
def update_groups_permissions(apps, schema_editor):
# first add a missing role
user_roles = ["Moderator"]
for name in user_roles:
Group.objects.create(name=name)
all_perms = Permission.objects.all()
# set permissions for moderators
moderator_perms = [i for i in all_perms if i.content_type.app_label == 'agenda_culturel' and i.content_type.model in ['event', 'duplicatedevents']]
Group.objects.get(name="Moderator").permissions.add(*moderator_perms)
read_mod_perms = [i for i in moderator_perms if i.codename.startswith('view_')]
# set permissions for automation managers
automanager_perms = [i for i in all_perms if i.content_type.app_label == 'agenda_culturel' and i.content_type.model in ['batchimportation', 'recurrentimport', 'categorisationrule']]
Group.objects.get(name="Automation Manager").permissions.add(*automanager_perms)
Group.objects.get(name="Automation Manager").permissions.add(*read_mod_perms)
# set permissions for receptionists
receptionist_perms = [i for i in all_perms if i.content_type.app_label == 'agenda_culturel' and i.content_type.model in ['contactmessage']]
Group.objects.get(name="Receptionist").permissions.add(*receptionist_perms)
Group.objects.get(name="Receptionist").permissions.add(*read_mod_perms)
class Migration(migrations.Migration):
dependencies = [
('agenda_culturel', '0037_alter_batchimportation_options_and_more'),
]
operations = [
migrations.RunPython(update_groups_permissions),
]

View File

@ -237,6 +237,7 @@ class Event(models.Model):
class Meta: class Meta:
verbose_name = _('Event') verbose_name = _('Event')
verbose_name_plural = _('Events') verbose_name_plural = _('Events')
permissions = [("set_duplicated_event", "Can set an event as duplicated")]
def get_all_tags(): def get_all_tags():
try: try:
@ -737,6 +738,10 @@ class ContactMessage(models.Model):
class RecurrentImport(models.Model): class RecurrentImport(models.Model):
class Meta:
permissions = [("run_recurrentimport", "Can run a recurrent import")]
class PROCESSOR(models.TextChoices): class PROCESSOR(models.TextChoices):
ICAL = "ical", _("ical") ICAL = "ical", _("ical")
ICALNOBUSY = "icalnobusy", _("ical no busy") ICALNOBUSY = "icalnobusy", _("ical no busy")
@ -781,6 +786,9 @@ class BatchImportation(models.Model):
SUCCESS = "success", _("Success") SUCCESS = "success", _("Success")
FAILED = "failed", _("Failed") FAILED = "failed", _("Failed")
class Meta:
permissions = [("run_batchimportation", "Can run a batch importation")]
created_date = models.DateTimeField(auto_now_add=True) created_date = models.DateTimeField(auto_now_add=True)
@ -810,6 +818,10 @@ class CategorisationRule(models.Model):
title_contains = models.CharField(verbose_name=_('Contained in the title'), help_text=_('Text contained in the event title'), max_length=512, blank=True, null=True) title_contains = models.CharField(verbose_name=_('Contained in the title'), help_text=_('Text contained in the event title'), max_length=512, blank=True, null=True)
title_exact = models.BooleanField(verbose_name=_('Exact title extract'), help_text=_("If checked, the extract will be searched for in the title using the exact form (capitals, accents)."), default=False) title_exact = models.BooleanField(verbose_name=_('Exact title extract'), help_text=_("If checked, the extract will be searched for in the title using the exact form (capitals, accents)."), default=False)
class Meta:
permissions = [("apply_categorisationrules", "Apply a categorisation rule")]
# on applique toutes les règles, de la première à la dernière # on applique toutes les règles, de la première à la dernière
def apply_rules(event): def apply_rules(event):
rules = CategorisationRule.objects.all().order_by("weight", "pk") rules = CategorisationRule.objects.all().order_by("weight", "pk")

View File

@ -27,12 +27,14 @@
<li>{{ e.start_day }}{% if e.start_time %} à {{ e.start_time }}{% endif %}&nbsp;: <a href="{{ e.get_absolute_url }}">{{ e.title }}</a> créé le {{ e.created_date }}</li> <li>{{ e.start_day }}{% if e.start_time %} à {{ e.start_time }}{% endif %}&nbsp;: <a href="{{ e.get_absolute_url }}">{{ e.title }}</a> créé le {{ e.created_date }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% if perms.agenda_culturel.change_duplicatedevents %}
<footer class="infos-and-buttons"> <footer class="infos-and-buttons">
<div class="infos"></div> <div class="infos"></div>
<div class="buttons"> <div class="buttons">
<a role="button" href="{% url 'fix_duplicate' obj.pk %}">Corriger {% picto_from_name "tool" %}</a> <a role="button" href="{% url 'fix_duplicate' obj.pk %}">Corriger {% picto_from_name "tool" %}</a>
</div> </div>
</footer> </footer>
{% endif %}
</article> </article>
{% endwith %} {% endwith %}
{% endfor %} {% endfor %}

View File

@ -46,10 +46,16 @@
</a> </a>
</li> </li>
<li> <li>
{% if user.is_authenticated %} {% if perms.agenda_culturel.change_event %}
{% show_badges_events "bottom" %} {% show_badges_events "bottom" %}
{% endif %}
{% if perms.agenda_culturel.change_duplicatedevents %}
{% show_badge_duplicated "bottom" %} {% show_badge_duplicated "bottom" %}
{% endif %}
{% if perms.agenda_culturel.view_contactmessage %}
{% show_badge_contactmessages "bottom" %} {% show_badge_contactmessages "bottom" %}
{% endif %}
{% if user.is_authenticated %}
{{ user.username }} @ {{ user.username }} @
{% endif %} {% endif %}
<a href="{% url 'home' %}" aria-label="Retour accueil">Pommes de lune</a> <a href="{% url 'home' %}" aria-label="Retour accueil">Pommes de lune</a>

View File

@ -9,31 +9,48 @@
<h3>Événements</h3> <h3>Événements</h3>
<nav> <nav>
<ul> <ul>
{% if perms.agenda_culturel.change_event %}
<li><a {% if current == "moderation" %}class="selected" {% endif %}href="{% url 'moderation' %}">Derniers événements soumis</a>{% show_badges_events "left" %}</li> <li><a {% if current == "moderation" %}class="selected" {% endif %}href="{% url 'moderation' %}">Derniers événements soumis</a>{% show_badges_events "left" %}</li>
{% endif %}
{% if perms.agenda_culturel.change_duplicatedevents %}
<li><a {% if current == "duplicates" %}class="selected" {% endif %}href="{% url 'duplicates' %}">Gestion des doublons</a>{% show_badge_duplicated "left" %}</li> <li><a {% if current == "duplicates" %}class="selected" {% endif %}href="{% url 'duplicates' %}">Gestion des doublons</a>{% show_badge_duplicated "left" %}</li>
{% endif %}
<li><a {% if current == "tags" %}class="selected" {% endif %}href="{% url 'view_all_tags' %}">Consulter les étiquettes</a></li> <li><a {% if current == "tags" %}class="selected" {% endif %}href="{% url 'view_all_tags' %}">Consulter les étiquettes</a></li>
</ul> </ul>
</nav> </nav>
{% if perms.agenda_culturel.view_batchimportation or perms.agenda_culturel.view_recurrentimport or perms.agenda_culturel.view_categorisationrule%}
<h3>Traitements automatiques</h3> <h3>Traitements automatiques</h3>
<nav> <nav>
<ul> <ul>
{% if perms.agenda_culturel.view_batchimportation %}
<li><a {% if current == "imports" %}class="selected" {% endif %}href="{% url 'imports' %}">Historiques des importations</a></li> <li><a {% if current == "imports" %}class="selected" {% endif %}href="{% url 'imports' %}">Historiques des importations</a></li>
{% endif %}
{% if perms.agenda_culturel.view_recurrentimport %}
<li><a {% if current == "rimports" %}class="selected" {% endif %}href="{% url 'recurrent_imports' %}">Importations récurrentes</a></li> <li><a {% if current == "rimports" %}class="selected" {% endif %}href="{% url 'recurrent_imports' %}">Importations récurrentes</a></li>
{% endif %}
{% if perms.agenda_culturel.view_categorisationrule %}
<li><a {% if current == "catrules" %}class="selected" {% endif %}href="{% url 'categorisation_rules' %}">Règles de catégorisation</a></li> <li><a {% if current == "catrules" %}class="selected" {% endif %}href="{% url 'categorisation_rules' %}">Règles de catégorisation</a></li>
{% endif %}
</ul> </ul>
</nav> </nav>
{% endif %}
{% if perms.agenda_culturel.view_contactmessage %}
<h3>Messages</h3> <h3>Messages</h3>
<nav> <nav>
<ul> <ul>
<li><a {% if current == "contactmessages" %}class="selected" {% endif %}href="{% url 'contactmessages' %}">Messages de contact</a>{% show_badge_contactmessages "left" %}</li> <li><a {% if current == "contactmessages" %}class="selected" {% endif %}href="{% url 'contactmessages' %}">Messages de contact</a>{% show_badge_contactmessages "left" %}</li>
</ul> </ul>
</nav> </nav>
{% endif %}
{% if user.is_staff %}
<h3>Configuration interne</h3> <h3>Configuration interne</h3>
<nav> <nav>
<ul> <ul>
<li><a href="{% url 'admin:index' %}">Administration de django</a></li> <li><a href="{% url 'admin:index' %}">Administration de django</a></li>
</ul> </ul>
</nav> </nav>
{% endif %}
</article> </article>
<article> <article>
<p>Vous êtes connecté(e) en tant que {{ user }}.</p> <p>Vous êtes connecté(e) en tant que {{ user }}.</p>

View File

@ -37,7 +37,7 @@
{% if event.description_hl %}{{ event.description_hl | safe }} [...]{% else %}{% if event.description %}{{ event.description |truncatewords:60 }}{% else %}<em>pas de description</em>{% endif %}{% endif %} {% if event.description_hl %}{{ event.description_hl | safe }} [...]{% else %}{% if event.description %}{{ event.description |truncatewords:60 }}{% else %}<em>pas de description</em>{% endif %}{% endif %}
</div> </div>
{% if user.is_authenticated %} {% if perms.agenda_culturel.change_event %}
<footer> <footer>
<div class="buttons"> <div class="buttons">
{% include "agenda_culturel/edit-buttons-inc.html" with event=event %} {% include "agenda_culturel/edit-buttons-inc.html" with event=event %}

View File

@ -77,7 +77,7 @@
</p> </p>
{% endif %} {% endif %}
</div> </div>
{% if user.is_authenticated %} {% if perms.agenda_culturel.change_event %}
<div class="buttons"> <div class="buttons">
{% include "agenda_culturel/edit-buttons-inc.html" with event=event %} {% include "agenda_culturel/edit-buttons-inc.html" with event=event %}
<a href="{{ event.get_absolute_url }}" role="button">Voir l'événement <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <a href="{{ event.get_absolute_url }}" role="button">Voir l'événement <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">

View File

@ -56,7 +56,7 @@
<p><em>À notre connaissance, cet événement n'est pas référencé autre part sur internet.</em></p> <p><em>À notre connaissance, cet événement n'est pas référencé autre part sur internet.</em></p>
{% endif %} {% endif %}
</div> </div>
{% if user.is_authenticated %} {% if perms.agenda_culturel.change_event %}
<div class="buttons"> <div class="buttons">
{% include "agenda_culturel/edit-buttons-inc.html" with event=event %} {% include "agenda_culturel/edit-buttons-inc.html" with event=event %}
<a href="{{ event.get_absolute_url }}" role="button">Voir l'événement <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <a href="{{ event.get_absolute_url }}" role="button">Voir l'événement <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">

View File

@ -67,7 +67,7 @@
{% endif %} {% endif %}
</p> </p>
</div> </div>
{% if user.is_authenticated %} {% if perms.agenda_culturel.change_event %}
<div class="buttons"> <div class="buttons">
{% include "agenda_culturel/edit-buttons-inc.html" with event=event %} {% include "agenda_culturel/edit-buttons-inc.html" with event=event %}
</div> </div>

View File

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, FormView from django.views.generic import ListView, DetailView, FormView
from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin, PermissionRequiredMixin
from django.http import QueryDict from django.http import QueryDict
from django import forms from django import forms
from django.contrib.postgres.search import SearchQuery, SearchHeadline from django.contrib.postgres.search import SearchQuery, SearchHeadline
@ -24,7 +24,7 @@ from django.utils.translation import gettext_lazy as _
from django.utils.translation import activate, get_language_info from django.utils.translation import activate, get_language_info
import django_filters import django_filters
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib import messages from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
@ -208,6 +208,7 @@ def tag_list(request):
class StaticContentCreateView(LoginRequiredMixin, CreateView): class StaticContentCreateView(LoginRequiredMixin, CreateView):
model = StaticContent model = StaticContent
fields = ['text'] fields = ['text']
permission_required = ("agenda_culturel.add_staticcontent")
def form_valid(self, form): def form_valid(self, form):
form.instance.name = self.request.GET["name"] form.instance.name = self.request.GET["name"]
@ -215,14 +216,16 @@ class StaticContentCreateView(LoginRequiredMixin, CreateView):
return super().form_valid(form) return super().form_valid(form)
class StaticContentUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class StaticContentUpdateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = StaticContent model = StaticContent
permission_required = ("agenda_culturel.change_staticcontent")
fields = ['text'] fields = ['text']
success_message = _('The static content has been successfully updated.') success_message = _('The static content has been successfully updated.')
class EventUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class EventUpdateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = Event model = Event
permission_required = ("agenda_culturel.changes_event")
form_class = EventForm form_class = EventForm
success_message = _('The event has been successfully modified.') success_message = _('The event has been successfully modified.')
@ -232,8 +235,9 @@ class EventUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
return kwargs return kwargs
class EventDeleteView(SuccessMessageMixin, LoginRequiredMixin, DeleteView): class EventDeleteView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, DeleteView):
model = Event model = Event
permission_required = ("agenda_culturel.delete_event")
success_url = reverse_lazy('moderation') success_url = reverse_lazy('moderation')
success_message = _('The event has been successfully deleted.') success_message = _('The event has been successfully deleted.')
@ -256,6 +260,7 @@ class EventDetailView(UserPassesTestMixin, DetailView):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.change_event')
def change_status_event(request, pk, status): def change_status_event(request, pk, status):
event = get_object_or_404(Event, pk=pk) event = get_object_or_404(Event, pk=pk)
@ -368,8 +373,9 @@ class ContactMessageCreateView(SuccessMessageMixin, CreateView):
success_message = _('Your message has been sent successfully.') success_message = _('Your message has been sent successfully.')
class ContactMessageUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class ContactMessageUpdateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = ContactMessage model = ContactMessage
permission_required = ("agenda_culturel.change_contactmessage")
template_name = "agenda_culturel/contactmessage_moderation_form.html" template_name = "agenda_culturel/contactmessage_moderation_form.html"
fields = ('closed', 'comments') fields = ('closed', 'comments')
@ -396,6 +402,7 @@ class ContactMessagesFilterAdmin(django_filters.FilterSet):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_event')
def moderation(request): def moderation(request):
filter = EventFilterAdmin(request.GET, queryset=Event.objects.all().order_by("-created_date")) filter = EventFilterAdmin(request.GET, queryset=Event.objects.all().order_by("-created_date"))
paginator = Paginator(filter.qs, 10) paginator = Paginator(filter.qs, 10)
@ -411,6 +418,7 @@ def moderation(request):
return render(request, 'agenda_culturel/moderation.html', {'filter': filter, 'paginator_filter': response} ) return render(request, 'agenda_culturel/moderation.html', {'filter': filter, 'paginator_filter': response} )
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_contactmessage')
def contactmessages(request): def contactmessages(request):
filter = ContactMessagesFilterAdmin(request.GET, queryset=ContactMessage.objects.all().order_by("-date")) filter = ContactMessagesFilterAdmin(request.GET, queryset=ContactMessage.objects.all().order_by("-date"))
paginator = Paginator(filter.qs, 10) paginator = Paginator(filter.qs, 10)
@ -518,6 +526,7 @@ def event_search_full(request):
######################### #########################
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_batchimportation')
def imports(request): def imports(request):
paginator = Paginator(BatchImportation.objects.all().order_by("-created_date"), 10) paginator = Paginator(BatchImportation.objects.all().order_by("-created_date"), 10)
page = request.GET.get('page') page = request.GET.get('page')
@ -533,6 +542,8 @@ def imports(request):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.add_batchimportation')
@permission_required('agenda_culturel.run_batchimportation')
def add_import(request): def add_import(request):
form = BatchImportationForm() form = BatchImportationForm()
@ -550,6 +561,8 @@ def add_import(request):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_batchimportation')
@permission_required('agenda_culturel.run_batchimportation')
def cancel_import(request, pk): def cancel_import(request, pk):
import_process = get_object_or_404(BatchImportation, pk=pk) import_process = get_object_or_404(BatchImportation, pk=pk)
@ -570,6 +583,7 @@ def cancel_import(request, pk):
######################### #########################
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_recurrentimport')
def recurrent_imports(request): def recurrent_imports(request):
paginator = Paginator(RecurrentImport.objects.all().order_by("-pk"), 10) paginator = Paginator(RecurrentImport.objects.all().order_by("-pk"), 10)
page = request.GET.get('page') page = request.GET.get('page')
@ -584,25 +598,30 @@ def recurrent_imports(request):
return render(request, 'agenda_culturel/rimports.html', {'paginator_filter': response} ) return render(request, 'agenda_culturel/rimports.html', {'paginator_filter': response} )
class RecurrentImportCreateView(LoginRequiredMixin, CreateView): class RecurrentImportCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = RecurrentImport model = RecurrentImport
permission_required = ("agenda_culturel.create_recurrentimport")
success_url = reverse_lazy('recurrent_imports') success_url = reverse_lazy('recurrent_imports')
form_class = RecurrentImportForm form_class = RecurrentImportForm
class RecurrentImportUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class RecurrentImportUpdateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = RecurrentImport model = RecurrentImport
permission_required = ("agenda_culturel.change_recurrentimport")
form_class = RecurrentImportForm form_class = RecurrentImportForm
success_message = _('The recurrent import has been successfully modified.') success_message = _('The recurrent import has been successfully modified.')
class RecurrentImportDeleteView(SuccessMessageMixin, LoginRequiredMixin, DeleteView): class RecurrentImportDeleteView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, DeleteView):
model = RecurrentImport model = RecurrentImport
permission_required = ("agenda_culturel.delete_recurrentimport")
success_url = reverse_lazy('recurrent_imports') success_url = reverse_lazy('recurrent_imports')
success_message = _('The recurrent import has been successfully deleted.') success_message = _('The recurrent import has been successfully deleted.')
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_recurrentimport')
@permission_required('agenda_culturel.view_batchimportation')
def view_rimport(request, pk): def view_rimport(request, pk):
obj = get_object_or_404(RecurrentImport, pk=pk) obj = get_object_or_404(RecurrentImport, pk=pk)
paginator = Paginator(BatchImportation.objects.filter(recurrentImport=pk).order_by("-created_date"), 10) paginator = Paginator(BatchImportation.objects.filter(recurrentImport=pk).order_by("-created_date"), 10)
@ -620,6 +639,8 @@ def view_rimport(request, pk):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_recurrentimport')
@permission_required('agenda_culturel.run_recurrentimport')
def run_rimport(request, pk): def run_rimport(request, pk):
rimport = get_object_or_404(RecurrentImport, pk=pk) rimport = get_object_or_404(RecurrentImport, pk=pk)
@ -644,6 +665,8 @@ class DuplicatedEventsDetailView(LoginRequiredMixin, DetailView):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.change_event')
@permission_required('agenda_culturel.change_duplicatedevents')
def merge_duplicate(request, pk): def merge_duplicate(request, pk):
edup = get_object_or_404(DuplicatedEvents, pk=pk) edup = get_object_or_404(DuplicatedEvents, pk=pk)
form = MergeDuplicates(duplicates=edup) form = MergeDuplicates(duplicates=edup)
@ -694,6 +717,8 @@ def merge_duplicate(request, pk):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.change_event')
@permission_required('agenda_culturel.change_duplicatedevents')
def fix_duplicate(request, pk): def fix_duplicate(request, pk):
edup = get_object_or_404(DuplicatedEvents, pk=pk) edup = get_object_or_404(DuplicatedEvents, pk=pk)
@ -760,6 +785,7 @@ class DuplicatedEventsUpdateView(LoginRequiredMixin, UpdateView):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_duplicatedevents')
def duplicates(request): def duplicates(request):
paginator = Paginator(DuplicatedEvents.objects.all(), 10) paginator = Paginator(DuplicatedEvents.objects.all(), 10)
page = request.GET.get('page') page = request.GET.get('page')
@ -803,6 +829,7 @@ def set_duplicate(request, year, month, day, pk):
######################### #########################
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.view_categorisationrule')
def categorisation_rules(request): def categorisation_rules(request):
paginator = Paginator(CategorisationRule.objects.all().order_by("weight", "pk"), 10) paginator = Paginator(CategorisationRule.objects.all().order_by("weight", "pk"), 10)
page = request.GET.get('page') page = request.GET.get('page')
@ -816,25 +843,30 @@ def categorisation_rules(request):
return render(request, 'agenda_culturel/categorisation_rules.html', {'paginator_filter': response} ) return render(request, 'agenda_culturel/categorisation_rules.html', {'paginator_filter': response} )
class CategorisationRuleCreateView(LoginRequiredMixin, CreateView): class CategorisationRuleCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = CategorisationRule model = CategorisationRule
permission_required = ("agenda_culturel.add_categorisationrule")
success_url = reverse_lazy('categorisation_rules') success_url = reverse_lazy('categorisation_rules')
form_class = CategorisationRuleImportForm form_class = CategorisationRuleImportForm
class CategorisationRuleUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class CategorisationRuleUpdateView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
model = CategorisationRule model = CategorisationRule
permission_required = ("agenda_culturel.change_categorisationrule")
form_class = CategorisationRuleImportForm form_class = CategorisationRuleImportForm
success_url = reverse_lazy('categorisation_rules') success_url = reverse_lazy('categorisation_rules')
success_message = _('The categorisation rule has been successfully modified.') success_message = _('The categorisation rule has been successfully modified.')
class CategorisationRuleDeleteView(SuccessMessageMixin, LoginRequiredMixin, DeleteView): class CategorisationRuleDeleteView(SuccessMessageMixin, PermissionRequiredMixin, LoginRequiredMixin, DeleteView):
model = CategorisationRule model = CategorisationRule
permission_required = ("agenda_culturel.delete_categorisationrule")
success_url = reverse_lazy('categorisation_rules') success_url = reverse_lazy('categorisation_rules')
success_message = _('The categorisation rule has been successfully deleted.') success_message = _('The categorisation rule has been successfully deleted.')
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required('agenda_culturel.change_event')
@permission_required('agenda_culturel.apply_categorisationrule')
def apply_categorisation_rules(request): def apply_categorisation_rules(request):
nb = 0 nb = 0