Fix voucher and order views for users with read-only permissions (#3594)

This commit is contained in:
Raphael Michel
2023-09-14 17:37:48 +02:00
committed by GitHub
parent 7d8a788361
commit 56803e3d65
5 changed files with 103 additions and 77 deletions

View File

@@ -122,10 +122,12 @@
<table class="table table-condensed table-hover table-orders">
<thead>
<tr>
<th>
<label aria-label="{% trans "select all rows for batch-operation" %}"
class="batch-select-label"><input type="checkbox" data-toggle-table/></label>
</th>
{% if "can_change_orders" in request.eventpermset %}
<th>
<label aria-label="{% trans "select all rows for batch-operation" %}"
class="batch-select-label"><input type="checkbox" data-toggle-table/></label>
</th>
{% endif %}
<th>{% trans "Order code" %}
<a href="?{% url_replace request 'ordering' '-code' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'code' %}"><i class="fa fa-caret-up"></i></a>
@@ -152,7 +154,7 @@
<a href="?{% url_replace request 'ordering' 'status' %}"><i class="fa fa-caret-up"></i></a>
</th>
</tr>
{% if page_obj.paginator.num_pages > 1 %}
{% if page_obj.paginator.num_pages > 1 and "can_change_orders" in request.eventpermset %}
<tr class="table-select-all warning hidden">
<td>
<input type="checkbox" name="__ALL" id="__all"
@@ -169,12 +171,14 @@
<tbody>
{% for o in orders %}
<tr>
<td>
<label aria-label="{% trans "select row for batch-operation" %}"
class="batch-select-label"><input type="checkbox" name="order"
class="batch-select-checkbox"
value="{{ o.pk }}"/></label>
</td>
{% if "can_change_orders" in request.eventpermset %}
<td>
<label aria-label="{% trans "select row for batch-operation" %}"
class="batch-select-label"><input type="checkbox" name="order"
class="batch-select-checkbox"
value="{{ o.pk }}"/></label>
</td>
{% endif %}
<td>
<strong>
<a
@@ -272,47 +276,49 @@
{% endif %}
</table>
</div>
<div class="batch-select-actions">
<div class="btn-group dropup">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
{% trans "Select action" %}
</button>
<ul class="dropdown-menu">
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.approve" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-thumbs-up fa-fw text-green"></i>
{% trans "Approve" %}
</button>
</li>
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.deny" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-thumbs-down fa-fw text-danger"></i>
{% trans "Deny" %}
</button>
</li>
{% if not request.event.settings.payment_term_expire_automatically %}
{% if "can_change_orders" in request.eventpermset %}
<div class="batch-select-actions">
<div class="btn-group dropup">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
{% trans "Select action" %}
</button>
<ul class="dropdown-menu">
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.expire" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-times fa-fw"></i>
{% trans "Mark as expired if overdue" %}
formaction="{% url "control:event.orders.bulk.approve" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-thumbs-up fa-fw text-green"></i>
{% trans "Approve" %}
</button>
</li>
{% endif %}
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.delete" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-trash fa-fw text-danger"></i>
{% trans "Delete (test mode only)" %}
</button>
</li>
</ul>
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.deny" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-thumbs-down fa-fw text-danger"></i>
{% trans "Deny" %}
</button>
</li>
{% if not request.event.settings.payment_term_expire_automatically %}
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.expire" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-times fa-fw"></i>
{% trans "Mark as expired if overdue" %}
</button>
</li>
{% endif %}
<li>
<button type="submit" class="btn"
formaction="{% url "control:event.orders.bulk.delete" organizer=request.organizer.slug event=request.event.slug %}">
<i class="fa fa-trash fa-fw text-danger"></i>
{% trans "Delete (test mode only)" %}
</button>
</li>
</ul>
</div>
</div>
</div>
{% endif %}
</form>
{% include "pretixcontrol/pagination.html" %}
{% endif %}

View File

@@ -114,10 +114,12 @@
</div>
</div>
</div>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
</div>
{% if "can_change_vouchers" in request.eventpermset %}
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
</div>
{% endif %}
</form>
{% endblock %}

View File

@@ -72,18 +72,22 @@
{% endif %}
</p>
<a href="{% url "control:event.vouchers.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create a new voucher" %}</a>
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create multiple new vouchers" %}</a>
{% if "can_change_vouchers" in request.eventpermset %}
<a href="{% url "control:event.vouchers.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create a new voucher" %}</a>
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create multiple new vouchers" %}</a>
{% endif %}
</div>
{% else %}
<p>
<a href="{% url "control:event.vouchers.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new voucher" %}</a>
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i>
{% trans "Create multiple new vouchers" %}</a>
{% if "can_change_vouchers" in request.eventpermset %}
<a href="{% url "control:event.vouchers.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new voucher" %}</a>
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i>
{% trans "Create multiple new vouchers" %}</a>
{% endif %}
<a href="?{% url_replace request "download" "yes" %}"
class="btn btn-default"><i class="fa fa-download"></i>
{% trans "Download list" %}</a>
@@ -94,13 +98,13 @@
<table class="table table-hover table-quotas">
<thead>
<tr>
<th>
{% if "can_change_vouchers" in request.eventpermset %}
{% if "can_change_vouchers" in request.eventpermset %}
<th>
<label aria-label="{% trans "select all rows for batch-operation" %}" class="batch-select-label">
<input type="checkbox" data-toggle-table />
</label>
{% endif %}
</th>
</th>
{% endif %}
<th>
{% trans "Voucher code" %}
<a href="?{% url_replace request 'ordering' '-code' %}"><i class="fa fa-caret-down"></i></a>
@@ -139,13 +143,13 @@
<tbody>
{% for v in vouchers %}
<tr>
<td>
{% if "can_change_vouchers" in request.eventpermset %}
{% if "can_change_vouchers" in request.eventpermset %}
<td>
<label aria-label="{% trans "select row for batch-operation" %}" class="batch-select-label">
<input type="checkbox" name="voucher" class="batch-select-checkbox" value="{{ v.pk }}"/>
</label>
{% endif %}
</td>
</td>
{% endif %}
<td>
{% if not v.is_active %}<del>{% endif %}
<strong><a href="{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}">{{ v.code }}</a></strong>
@@ -186,11 +190,13 @@
</td>
{% endif %}
<td class="text-right flip">
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ v.id }}"
class="btn btn-sm btn-default" title="{% trans "Use as a template for new vouchers" %}" data-toggle="tooltip">
<span class="fa fa-copy"></span>
</a>
<a href="{% url "control:event.voucher.delete" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
{% if "can_change_vouchers" in request.eventpermset %}
<a href="{% url "control:event.vouchers.bulk" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ v.id }}"
class="btn btn-sm btn-default" title="{% trans "Use as a template for new vouchers" %}" data-toggle="tooltip">
<span class="fa fa-copy"></span>
</a>
<a href="{% url "control:event.voucher.delete" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
{% endif %}
</td>
</tr>
{% endfor %}

View File

@@ -40,7 +40,7 @@ import bleach
from defusedcsv import csv
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.exceptions import PermissionDenied, ValidationError
from django.db import connection, transaction
from django.db.models import Exists, OuterRef, Sum
from django.http import (
@@ -269,7 +269,7 @@ class VoucherDelete(EventPermissionRequiredMixin, CompatDeleteView):
class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
model = Voucher
template_name = 'pretixcontrol/vouchers/detail.html'
permission = 'can_change_vouchers'
permission = ('can_change_vouchers', 'can_view_vouchers')
context_object_name = 'voucher'
def form_invalid(self, form):
@@ -283,6 +283,14 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
form_class = response
return form_class
def get_form(self, form_class=None):
form = super().get_form(form_class)
if not self.request.user.has_event_permission(self.request.organizer, self.request.event, 'can_change_vouchers',
request=self.request):
for f in form.fields.values():
f.disabled = True
return form
def get_object(self, queryset=None) -> VoucherForm:
url = resolve(self.request.path_info)
try:
@@ -304,6 +312,9 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
@transaction.atomic
def post(self, request, *args, **kwargs):
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_vouchers',
request=request):
raise PermissionDenied()
return super().post(request, *args, **kwargs)
def get_success_url(self) -> str: