mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Pluggable permissions (#5728)
* Data model draft * Refactor query and assignment usages of old permissions * Backend UI * API serializer * Big string replace * Docs, tests and fixes for teams api * Update docs for device auth * Eliminate old names * Make tests pass * Use new permissions, remove inconsistencies * Add test for translations * Show plugin permissions * Add permission for seating plans * Fix plugin activation * Fix failing test * Refactor to permission groups * Update doc/api/resources/devices.rst Co-authored-by: luelista <weller@rami.io> * Update doc/api/resources/events.rst Co-authored-by: luelista <weller@rami.io> * Update src/pretix/api/serializers/organizer.py Co-authored-by: luelista <weller@rami.io> * Fix typo * Fix python version compat * Replacement after rebase * Add proper permission handling for exports * Docs for exporters * Runtime linting of permission names * Fix typos * Show export page even without orders permission * More legacy compat * Do not strongly validate before plugins are loaded * Rebase migration * Add permission for outgoing mails * Review notes * Update doc/api/resources/teams.rst Co-authored-by: Richard Schreiber <schreiber@pretix.eu> * Clean up logic around exporters * Review and failures * Fix migration leading to forbidden combination * Handle permissions on event copying * Remove print-statements * Make test clearer * Review feedback * Add AnyPermissionOf * migration safety --------- Co-authored-by: luelista <weller@rami.io> Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
This commit is contained in:
@@ -108,7 +108,7 @@ class RuleViewSet(viewsets.ModelViewSet):
|
||||
filter_backends = (DjangoFilterBackend, TotalOrderingFilter)
|
||||
ordering = ("id",)
|
||||
ordering_fields = ("id",)
|
||||
permission = "can_change_event_settings"
|
||||
permission = "event.settings.general:write"
|
||||
|
||||
def get_queryset(self):
|
||||
return AutoCheckinRule.objects.filter(event=self.request.event)
|
||||
|
||||
@@ -39,7 +39,7 @@ from pretix.plugins.autocheckin.models import AutoCheckinRule
|
||||
def nav_event_receiver(sender, request, **kwargs):
|
||||
url = request.resolver_match
|
||||
if not request.user.has_event_permission(
|
||||
request.organizer, request.event, "can_change_event_settings", request=request
|
||||
request.organizer, request.event, "event.settings.general:write", request=request
|
||||
):
|
||||
return []
|
||||
return [
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:autocheckin:edit" organizer=request.event.organizer.slug event=request.event.slug rule=r.id %}" class="btn btn-default btn-sm"><i class="fa fa-edit"></i></a>
|
||||
<a href="{% url "plugins:autocheckin:add" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ r.id }}"
|
||||
class="btn btn-default btn-sm" title="{% trans "Clone" %}" data-toggle="tooltip"><i class="fa fa-copy"></i></a>
|
||||
|
||||
@@ -35,7 +35,7 @@ from pretix.plugins.autocheckin.models import AutoCheckinRule
|
||||
|
||||
|
||||
class IndexView(EventPermissionRequiredMixin, ListView):
|
||||
permission = "can_change_event_settings"
|
||||
permission = "event.settings.general:write"
|
||||
template_name = "pretixplugins/autocheckin/index.html"
|
||||
paginate_by = 50
|
||||
context_object_name = "rules"
|
||||
@@ -70,7 +70,7 @@ class IndexView(EventPermissionRequiredMixin, ListView):
|
||||
|
||||
class RuleAddView(EventPermissionRequiredMixin, CreateView):
|
||||
template_name = "pretixplugins/autocheckin/add.html"
|
||||
permission = "can_change_event_settings"
|
||||
permission = "event.settings.general:write"
|
||||
form_class = AutoCheckinRuleForm
|
||||
model = AutoCheckinRule
|
||||
|
||||
@@ -140,7 +140,7 @@ class RuleEditView(EventPermissionRequiredMixin, UpdateView):
|
||||
model = AutoCheckinRule
|
||||
form_class = AutoCheckinRuleForm
|
||||
template_name = "pretixplugins/autocheckin/edit.html"
|
||||
permission = "can_change_event_settings"
|
||||
permission = "event.settings.general:write"
|
||||
|
||||
def get_object(self, queryset=None) -> AutoCheckinRule:
|
||||
return get_object_or_404(
|
||||
@@ -178,7 +178,7 @@ class RuleEditView(EventPermissionRequiredMixin, UpdateView):
|
||||
|
||||
class RuleDeleteView(EventPermissionRequiredMixin, DeleteView):
|
||||
model = AutoCheckinRule
|
||||
permission = "can_change_event_settings"
|
||||
permission = "event.settings.general:write"
|
||||
template_name = "pretixplugins/autocheckin/delete.html"
|
||||
context_object_name = "rule"
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ from pretix.plugins.badges.models import BadgeItem, BadgeLayout
|
||||
def control_nav_import(sender, request=None, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
p = (
|
||||
request.user.has_event_permission(request.organizer, request.event, 'can_change_settings', request)
|
||||
or request.user.has_event_permission(request.organizer, request.event, 'can_view_orders', request)
|
||||
request.user.has_event_permission(request.organizer, request.event, 'event.settings.general:write', request)
|
||||
or request.user.has_event_permission(request.organizer, request.event, 'event.orders:read', request)
|
||||
)
|
||||
if not p:
|
||||
return []
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:badges: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 badge layout" %}
|
||||
</a>
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:badges:add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new badge layout" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
@@ -40,7 +40,7 @@
|
||||
{% for l in layouts %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<strong><a href="{% url "plugins:badges:edit" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}">
|
||||
{{ l.name }}
|
||||
</a></strong>
|
||||
@@ -54,7 +54,7 @@
|
||||
<span class="fa fa-check"></span>
|
||||
{% trans "Default" %}
|
||||
</span>
|
||||
{% elif "can_change_event_settings" in request.eventpermset %}
|
||||
{% elif "event.settings.general:write" in request.eventpermset %}
|
||||
<form class="form-inline" method="post"
|
||||
action="{% url "plugins:badges:default" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}"
|
||||
>
|
||||
@@ -66,7 +66,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:badges:edit" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}" class="btn btn-default btn-sm"><i class="fa fa-edit"></i></a>
|
||||
<a href="{% url "plugins:badges:add" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ l.id }}"
|
||||
class="btn btn-default btn-sm" title="{% trans "Clone" %}" data-toggle="tooltip"><i class="fa fa-copy"></i></a>
|
||||
|
||||
@@ -52,6 +52,7 @@ from pretix.helpers.models import modelcopy
|
||||
from pretix.plugins.badges.forms import BadgeLayoutForm
|
||||
from pretix.plugins.badges.tasks import badges_create_pdf
|
||||
|
||||
from ...base.permissions import AnyPermissionOf
|
||||
from ...helpers.compat import CompatDeleteView
|
||||
from .models import BadgeLayout
|
||||
from .templates import TEMPLATES
|
||||
@@ -59,7 +60,7 @@ from .templates import TEMPLATES
|
||||
|
||||
class LayoutListView(EventPermissionRequiredMixin, ListView):
|
||||
model = BadgeLayout
|
||||
permission = ('can_change_event_settings', 'can_view_orders')
|
||||
permission = AnyPermissionOf('event.settings.general:write', 'event.orders:read')
|
||||
template_name = 'pretixplugins/badges/index.html'
|
||||
context_object_name = 'layouts'
|
||||
|
||||
@@ -71,7 +72,7 @@ class LayoutCreate(EventPermissionRequiredMixin, CreateView):
|
||||
model = BadgeLayout
|
||||
form_class = BadgeLayoutForm
|
||||
template_name = 'pretixplugins/badges/edit.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'layout'
|
||||
success_url = '/ignored'
|
||||
|
||||
@@ -139,7 +140,7 @@ class LayoutCreate(EventPermissionRequiredMixin, CreateView):
|
||||
|
||||
class LayoutSetDefault(EventPermissionRequiredMixin, DetailView):
|
||||
model = BadgeLayout
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get_object(self, queryset=None) -> BadgeLayout:
|
||||
try:
|
||||
@@ -171,7 +172,7 @@ class LayoutSetDefault(EventPermissionRequiredMixin, DetailView):
|
||||
class LayoutDelete(EventPermissionRequiredMixin, CompatDeleteView):
|
||||
model = BadgeLayout
|
||||
template_name = 'pretixplugins/badges/delete.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'layout'
|
||||
|
||||
def get_object(self, queryset=None) -> BadgeLayout:
|
||||
@@ -269,7 +270,7 @@ class LayoutEditorView(BaseEditorView):
|
||||
|
||||
class OrderPrintDo(EventPermissionRequiredMixin, AsyncAction, View):
|
||||
task = badges_create_pdf
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
known_errortypes = ['OrderError', 'ExportError']
|
||||
|
||||
def get_success_message(self, value):
|
||||
|
||||
@@ -97,7 +97,6 @@ class BankImportJobViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
|
||||
queryset = BankImportJob.objects.none()
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = JobFilter
|
||||
permission = 'can_view_orders'
|
||||
|
||||
def get_queryset(self):
|
||||
return BankImportJob.objects.filter(organizer=self.request.organizer)
|
||||
@@ -105,9 +104,30 @@ class BankImportJobViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
|
||||
def perform_create(self, serializer):
|
||||
return serializer.save()
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
perm_holder = (request.auth if isinstance(request.auth, (Device, TeamAPIToken)) else request.user)
|
||||
has_any_event_perm = perm_holder.get_events_with_permission(
|
||||
"event.orders:read", request=request
|
||||
).filter(organizer=request.organizer).exists()
|
||||
if not has_any_event_perm:
|
||||
raise PermissionDenied('Invalid set of permissions')
|
||||
return super().retrieve(request, *args, **kwargs)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
perm_holder = (request.auth if isinstance(request.auth, (Device, TeamAPIToken)) else request.user)
|
||||
has_any_event_perm = perm_holder.get_events_with_permission(
|
||||
"event.orders:read", request=request
|
||||
).filter(organizer=request.organizer).exists()
|
||||
if not has_any_event_perm:
|
||||
raise PermissionDenied('Invalid set of permissions')
|
||||
return super().list(request, *args, **kwargs)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
perm_holder = (request.auth if isinstance(request.auth, (Device, TeamAPIToken)) else request.user)
|
||||
if not perm_holder.has_organizer_permission(request.organizer, 'can_change_orders'):
|
||||
has_any_event_perm = perm_holder.get_events_with_permission(
|
||||
"event.orders:write", request=request
|
||||
).filter(organizer=request.organizer).exists()
|
||||
if not has_any_event_perm:
|
||||
raise PermissionDenied('Invalid set of permissions')
|
||||
|
||||
if BankImportJob.objects.filter(Q(organizer=request.organizer)).filter(
|
||||
|
||||
@@ -41,7 +41,7 @@ def register_payment_provider(sender, **kwargs):
|
||||
@receiver(nav_event, dispatch_uid="payment_banktransfer_nav")
|
||||
def control_nav_import(sender, request=None, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_orders', request=request):
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'event.orders:write', request=request):
|
||||
return []
|
||||
return [
|
||||
{
|
||||
@@ -76,7 +76,10 @@ def control_nav_import(sender, request=None, **kwargs):
|
||||
@receiver(nav_organizer, dispatch_uid="payment_banktransfer_organav")
|
||||
def control_nav_orga_import(sender, request=None, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
if not request.user.has_organizer_permission(request.organizer, 'can_change_orders', request=request):
|
||||
has_any_event_perm = request.user.get_events_with_permission(
|
||||
"event.orders:write", request=request
|
||||
).filter(organizer=request.organizer).exists()
|
||||
if not has_any_event_perm:
|
||||
return []
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ from typing import Set
|
||||
|
||||
from django import forms
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db import transaction
|
||||
from django.db.models import Count, Q, QuerySet
|
||||
from django.http import FileResponse, JsonResponse
|
||||
@@ -58,11 +59,10 @@ from localflavor.generic.forms import BICFormField, IBANFormField
|
||||
|
||||
from pretix.base.forms.widgets import DatePickerWidget
|
||||
from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota
|
||||
from pretix.base.models.organizer import TeamQuerySet
|
||||
from pretix.base.settings import SettingsSandbox
|
||||
from pretix.base.templatetags.money import money_filter
|
||||
from pretix.control.permissions import (
|
||||
EventPermissionRequiredMixin, OrganizerPermissionRequiredMixin,
|
||||
)
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.views.organizer import OrganizerDetailViewMixin
|
||||
from pretix.helpers.json import CustomJSONEncoder
|
||||
from pretix.plugins.banktransfer import camtimport, csvimport, mt940import
|
||||
@@ -79,7 +79,7 @@ logger = logging.getLogger('pretix.plugins.banktransfer')
|
||||
|
||||
|
||||
class ActionView(View):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
def _discard(self, trans):
|
||||
trans.state = BankTransaction.STATE_DISCARDED
|
||||
@@ -279,7 +279,7 @@ class ActionView(View):
|
||||
|
||||
class JobDetailView(DetailView):
|
||||
template_name = 'pretixplugins/banktransfer/job_detail.html'
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
context_objectname = 'job'
|
||||
|
||||
def redirect_form(self):
|
||||
@@ -368,7 +368,7 @@ class BankTransactionFilterForm(forms.Form):
|
||||
|
||||
class ImportView(ListView):
|
||||
template_name = 'pretixplugins/banktransfer/import_form.html'
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
context_object_name = 'transactions_unhandled'
|
||||
paginate_by = 30
|
||||
|
||||
@@ -625,44 +625,54 @@ class ImportView(ListView):
|
||||
|
||||
class OrganizerBanktransferView:
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
has_any_event_perm = request.user.get_events_with_permission(
|
||||
"event.orders:write", request=request
|
||||
).filter(organizer=request.organizer).exists()
|
||||
if not has_any_event_perm:
|
||||
raise PermissionDenied()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class EventImportView(EventPermissionRequiredMixin, ImportView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
|
||||
class OrganizerImportView(OrganizerBanktransferView, OrganizerPermissionRequiredMixin, OrganizerDetailViewMixin,
|
||||
class OrganizerImportView(OrganizerBanktransferView, OrganizerDetailViewMixin,
|
||||
ImportView):
|
||||
permission = 'can_change_orders'
|
||||
pass
|
||||
|
||||
|
||||
class EventJobDetailView(EventPermissionRequiredMixin, JobDetailView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
|
||||
class OrganizerJobDetailView(OrganizerBanktransferView, OrganizerPermissionRequiredMixin, OrganizerDetailViewMixin,
|
||||
class OrganizerJobDetailView(OrganizerBanktransferView, OrganizerDetailViewMixin,
|
||||
JobDetailView):
|
||||
permission = 'can_change_orders'
|
||||
pass
|
||||
|
||||
|
||||
class EventActionView(EventPermissionRequiredMixin, ActionView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
|
||||
class OrganizerActionView(OrganizerBanktransferView, OrganizerPermissionRequiredMixin, OrganizerDetailViewMixin,
|
||||
class OrganizerActionView(OrganizerBanktransferView, OrganizerDetailViewMixin,
|
||||
ActionView):
|
||||
permission = 'can_change_orders'
|
||||
|
||||
def order_qs(self):
|
||||
all = self.request.user.teams.filter(organizer=self.request.organizer, can_change_orders=True,
|
||||
can_view_orders=True, all_events=True).exists()
|
||||
all = self.request.user.teams.filter(
|
||||
TeamQuerySet.event_permission_q("event.orders:read"),
|
||||
TeamQuerySet.event_permission_q("event.orders:write"),
|
||||
all_events=True,
|
||||
organizer=self.request.organizer,
|
||||
).exists()
|
||||
if self.request.user.has_active_staff_session(self.request.session.session_key) or all:
|
||||
return Order.objects.filter(event__organizer=self.request.organizer)
|
||||
else:
|
||||
return Order.objects.filter(
|
||||
event_id__in=self.request.user.teams.filter(
|
||||
organizer=self.request.organizer, can_change_orders=True, can_view_orders=True
|
||||
TeamQuerySet.event_permission_q("event.orders:read"),
|
||||
TeamQuerySet.event_permission_q("event.orders:write"),
|
||||
organizer=self.request.organizer,
|
||||
).values_list('limit_events__id', flat=True)
|
||||
)
|
||||
|
||||
@@ -755,7 +765,7 @@ class RefundExportListView(ListView):
|
||||
|
||||
|
||||
class EventRefundExportListView(EventPermissionRequiredMixin, RefundExportListView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('plugins:banktransfer:refunds.list', kwargs={
|
||||
@@ -777,8 +787,7 @@ class EventRefundExportListView(EventPermissionRequiredMixin, RefundExportListVi
|
||||
)
|
||||
|
||||
|
||||
class OrganizerRefundExportListView(OrganizerPermissionRequiredMixin, RefundExportListView):
|
||||
permission = 'can_change_orders'
|
||||
class OrganizerRefundExportListView(OrganizerBanktransferView, RefundExportListView):
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('plugins:banktransfer:refunds.list', kwargs={
|
||||
@@ -811,7 +820,7 @@ class DownloadRefundExportView(DetailView):
|
||||
|
||||
|
||||
class EventDownloadRefundExportView(EventPermissionRequiredMixin, DownloadRefundExportView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
return get_object_or_404(
|
||||
@@ -821,8 +830,7 @@ class EventDownloadRefundExportView(EventPermissionRequiredMixin, DownloadRefund
|
||||
)
|
||||
|
||||
|
||||
class OrganizerDownloadRefundExportView(OrganizerPermissionRequiredMixin, OrganizerDetailViewMixin, DownloadRefundExportView):
|
||||
permission = 'can_change_orders'
|
||||
class OrganizerDownloadRefundExportView(OrganizerBanktransferView, OrganizerDetailViewMixin, DownloadRefundExportView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
return get_object_or_404(
|
||||
@@ -850,9 +858,9 @@ class SepaXMLExportView(SingleObjectMixin, FormView):
|
||||
template_name = 'pretixplugins/banktransfer/sepa_export.html'
|
||||
context_object_name = "export"
|
||||
|
||||
def setup(self, request, *args, **kwargs):
|
||||
super().setup(request, *args, **kwargs)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.object: RefundExport = self.get_object()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
self.object.downloaded = True
|
||||
@@ -869,7 +877,7 @@ class SepaXMLExportView(SingleObjectMixin, FormView):
|
||||
|
||||
|
||||
class EventSepaXMLExportView(EventPermissionRequiredMixin, SepaXMLExportView):
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
return get_object_or_404(
|
||||
@@ -884,8 +892,7 @@ class EventSepaXMLExportView(EventPermissionRequiredMixin, SepaXMLExportView):
|
||||
return form
|
||||
|
||||
|
||||
class OrganizerSepaXMLExportView(OrganizerPermissionRequiredMixin, OrganizerDetailViewMixin, SepaXMLExportView):
|
||||
permission = 'can_change_orders'
|
||||
class OrganizerSepaXMLExportView(OrganizerBanktransferView, OrganizerDetailViewMixin, SepaXMLExportView):
|
||||
|
||||
def get_object(self, *args, **kwargs):
|
||||
return get_object_or_404(
|
||||
|
||||
@@ -246,7 +246,7 @@ def webhook(request, *args, **kwargs):
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
@event_permission_required('can_change_event_settings')
|
||||
@event_permission_required('event.settings.general:write')
|
||||
@require_POST
|
||||
def oauth_disconnect(request, **kwargs):
|
||||
del request.event.settings.payment_paypal_connect_refresh_token
|
||||
|
||||
@@ -216,7 +216,7 @@ class PayView(PaypalOrderView, TemplateView):
|
||||
|
||||
|
||||
@scopes_disabled()
|
||||
@event_permission_required('can_change_event_settings')
|
||||
@event_permission_required('event.settings.general:write')
|
||||
def isu_return(request, *args, **kwargs):
|
||||
getparams = ['merchantId', 'merchantIdInPayPal', 'permissionsGranted', 'accountStatus', 'consentStatus', 'productIntentID', 'isEmailConfirmed']
|
||||
sessionparams = ['payment_paypal_isu_event', 'payment_paypal_isu_tracking_id']
|
||||
@@ -526,7 +526,7 @@ def webhook(request, *args, **kwargs):
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
@event_permission_required('can_change_event_settings')
|
||||
@event_permission_required('event.settings.general:write')
|
||||
@require_POST
|
||||
def isu_disconnect(request, **kwargs):
|
||||
del request.event.settings.payment_paypal_connect_refresh_token
|
||||
|
||||
@@ -83,7 +83,7 @@ def check_against_prefix_list(u, allowlist):
|
||||
@receiver(nav_event_settings, dispatch_uid='returnurl_nav')
|
||||
def navbar_info(sender, request, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_event_settings',
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'event.settings.general:write',
|
||||
request=request):
|
||||
return []
|
||||
return [{
|
||||
|
||||
@@ -48,7 +48,7 @@ class ReturnSettings(EventSettingsViewMixin, EventSettingsFormView):
|
||||
model = Event
|
||||
form_class = ReturnSettingsForm
|
||||
template_name = 'returnurl/settings.html'
|
||||
permission = 'can_change_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get_success_url(self) -> str:
|
||||
return reverse('plugins:returnurl:settings', kwargs={
|
||||
|
||||
@@ -113,7 +113,7 @@ class RuleViewSet(viewsets.ModelViewSet):
|
||||
filterset_class = RuleFilter
|
||||
ordering = ('id',)
|
||||
ordering_fields = ('id',)
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get_queryset(self):
|
||||
return Rule.objects.filter(event=self.request.event)
|
||||
|
||||
@@ -79,7 +79,7 @@ def scheduled_mail_create(sender, **kwargs):
|
||||
@receiver(nav_event, dispatch_uid="sendmail_nav")
|
||||
def control_nav_import(sender, request=None, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'can_change_orders', request=request):
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'event.orders:write', request=request):
|
||||
return []
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ logger = logging.getLogger('pretix.plugins.sendmail')
|
||||
|
||||
class IndexView(EventPermissionRequiredMixin, TemplateView):
|
||||
template_name = 'pretixplugins/sendmail/index.html'
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
from .signals import sendmail_view_classes
|
||||
@@ -94,7 +94,7 @@ class IndexView(EventPermissionRequiredMixin, TemplateView):
|
||||
class BaseSenderView(EventPermissionRequiredMixin, FormView):
|
||||
# These parameters usually SHOULD NOT be overridden
|
||||
template_name = 'pretixplugins/sendmail/send_form.html'
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
|
||||
# These parameters MUST be overridden by subclasses
|
||||
form_fragment_name = None
|
||||
@@ -523,7 +523,7 @@ class WaitinglistSendView(BaseSenderView):
|
||||
|
||||
class EmailHistoryView(EventPermissionRequiredMixin, ListView):
|
||||
template_name = 'pretixplugins/sendmail/history.html'
|
||||
permission = 'can_change_orders'
|
||||
permission = 'event.orders:write'
|
||||
model = LogEntry
|
||||
context_object_name = 'logs'
|
||||
paginate_by = 5
|
||||
@@ -571,7 +571,7 @@ class EmailHistoryView(EventPermissionRequiredMixin, ListView):
|
||||
|
||||
class CreateRule(EventPermissionRequiredMixin, CreateView):
|
||||
template_name = 'pretixplugins/sendmail/rule_create.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
form_class = forms.RuleForm
|
||||
|
||||
model = Rule
|
||||
@@ -621,7 +621,7 @@ class UpdateRule(EventPermissionRequiredMixin, UpdateView):
|
||||
model = Rule
|
||||
form_class = forms.RuleForm
|
||||
template_name = 'pretixplugins/sendmail/rule_update.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get_object(self, queryset=None) -> Rule:
|
||||
return get_object_or_404(
|
||||
@@ -701,7 +701,7 @@ class ListRules(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
|
||||
class DeleteRule(EventPermissionRequiredMixin, DeleteView):
|
||||
model = Rule
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
template_name = 'pretixplugins/sendmail/rule_delete.html'
|
||||
context_object_name = 'rule'
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ from pretix.control.signals import nav_event
|
||||
@receiver(nav_event, dispatch_uid="statistics_nav")
|
||||
def control_nav_import(sender, request=None, **kwargs):
|
||||
url = resolve(request.path_info)
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'can_view_orders', request=request):
|
||||
if not request.user.has_event_permission(request.organizer, request.event, 'event.orders:read', request=request):
|
||||
return []
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ from pretix.plugins.statistics.signals import clear_cache
|
||||
|
||||
class IndexView(EventPermissionRequiredMixin, ChartContainingView, TemplateView):
|
||||
template_name = 'pretixplugins/statistics/index.html'
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
|
||||
@@ -473,7 +473,7 @@ def paymentintent_webhook(event, event_json, paymentintent_id, rso):
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
@event_permission_required('can_change_event_settings')
|
||||
@event_permission_required('event.settings.general:write')
|
||||
def oauth_disconnect(request, **kwargs):
|
||||
if request.method != "POST":
|
||||
return render(request, 'pretixplugins/stripe/oauth_disconnect.html', {})
|
||||
@@ -671,7 +671,7 @@ class ScaReturnView(StripeOrderView, View):
|
||||
|
||||
class OrganizerSettingsFormView(DecoupleMixin, OrganizerDetailViewMixin, AdministratorPermissionRequiredMixin, FormView):
|
||||
model = Organizer
|
||||
permission = 'can_change_organizer_settings'
|
||||
permission = 'organizer.settings.general:write'
|
||||
form_class = OrganizerStripeSettingsForm
|
||||
template_name = 'pretixplugins/stripe/organizer_stripe.html'
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ class RenderJobSerializer(serializers.Serializer):
|
||||
|
||||
|
||||
class TicketRendererViewSet(viewsets.ViewSet):
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
|
||||
def get_serializer_kwargs(self):
|
||||
return {}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:ticketoutputpdf: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 layout" %}
|
||||
</a>
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:ticketoutputpdf:add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new layout" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
@@ -38,7 +38,7 @@
|
||||
{% for l in layouts %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<strong><a href="{% url "plugins:ticketoutputpdf:edit" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}">
|
||||
{{ l.name }}
|
||||
</a></strong>
|
||||
@@ -52,7 +52,7 @@
|
||||
<span class="fa fa-check"></span>
|
||||
{% trans "Default" %}
|
||||
</span>
|
||||
{% elif "can_change_event_settings" in request.eventpermset %}
|
||||
{% elif "event.settings.general:write" in request.eventpermset %}
|
||||
<form class="form-inline" method="post"
|
||||
action="{% url "plugins:ticketoutputpdf:default" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}">
|
||||
{% csrf_token %}
|
||||
@@ -63,7 +63,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
{% if "can_change_event_settings" in request.eventpermset %}
|
||||
{% if "event.settings.general:write" in request.eventpermset %}
|
||||
<a href="{% url "plugins:ticketoutputpdf:edit" organizer=request.event.organizer.slug event=request.event.slug layout=l.id %}" class="btn btn-default btn-sm"><i class="fa fa-edit"></i></a>
|
||||
<a href="{% url "plugins:ticketoutputpdf:add" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ l.id }}"
|
||||
class="btn btn-default btn-sm" title="{% trans "Clone" %}" data-toggle="tooltip"><i class="fa fa-copy"></i></a>
|
||||
|
||||
@@ -95,7 +95,7 @@ class EditorView(BaseEditorView):
|
||||
|
||||
class LayoutListView(EventPermissionRequiredMixin, ListView):
|
||||
model = TicketLayout
|
||||
permission = ('can_change_event_settings')
|
||||
permission = 'event.settings.general:write'
|
||||
template_name = 'pretixplugins/ticketoutputpdf/index.html'
|
||||
context_object_name = 'layouts'
|
||||
|
||||
@@ -107,7 +107,7 @@ class LayoutCreate(EventPermissionRequiredMixin, CreateView):
|
||||
model = TicketLayout
|
||||
form_class = TicketLayoutForm
|
||||
template_name = 'pretixplugins/ticketoutputpdf/edit.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'layout'
|
||||
success_url = '/ignored'
|
||||
|
||||
@@ -157,7 +157,7 @@ class LayoutCreate(EventPermissionRequiredMixin, CreateView):
|
||||
|
||||
class LayoutSetDefault(EventPermissionRequiredMixin, DetailView):
|
||||
model = TicketLayout
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get_object(self, queryset=None) -> TicketLayout:
|
||||
try:
|
||||
@@ -186,7 +186,7 @@ class LayoutSetDefault(EventPermissionRequiredMixin, DetailView):
|
||||
class LayoutDelete(EventPermissionRequiredMixin, CompatDeleteView):
|
||||
model = TicketLayout
|
||||
template_name = 'pretixplugins/ticketoutputpdf/delete.html'
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
context_object_name = 'layout'
|
||||
|
||||
def get_object(self, queryset=None) -> TicketLayout:
|
||||
@@ -218,7 +218,7 @@ class LayoutDelete(EventPermissionRequiredMixin, CompatDeleteView):
|
||||
|
||||
|
||||
class LayoutGetDefault(EventPermissionRequiredMixin, View):
|
||||
permission = 'can_change_event_settings'
|
||||
permission = 'event.settings.general:write'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
layout = self.request.event.ticket_layouts.get_or_create(
|
||||
@@ -304,7 +304,7 @@ class LayoutEditorView(BaseEditorView):
|
||||
|
||||
class OrderPrintDo(EventPermissionRequiredMixin, AsyncAction, View):
|
||||
task = tickets_create_pdf
|
||||
permission = 'can_view_orders'
|
||||
permission = 'event.orders:read'
|
||||
known_errortypes = ['OrderError', 'ExportError']
|
||||
|
||||
def get_success_message(self, value):
|
||||
|
||||
@@ -30,7 +30,7 @@ from pretix.control.signals import nav_event
|
||||
@receiver(nav_event, dispatch_uid='webcheckin_nav_event')
|
||||
def navbar_entry(sender, request, **kwargs):
|
||||
url = request.resolver_match
|
||||
if not request.user.has_event_permission(request.organizer, request.event, ('can_change_orders', 'can_checkin_orders'), request=request):
|
||||
if not request.user.has_event_permission(request.organizer, request.event, ('event.orders:write', 'event.orders:checkin'), request=request):
|
||||
return []
|
||||
return [{
|
||||
'label': mark_safe(_('Web Check-in') + ' <span class="label label-success">beta</span>'),
|
||||
|
||||
@@ -21,12 +21,13 @@
|
||||
#
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from pretix.base.permissions import AnyPermissionOf
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.helpers.countries import CachedCountries
|
||||
|
||||
|
||||
class IndexView(EventPermissionRequiredMixin, TemplateView):
|
||||
permission = ('can_change_orders', 'can_checkin_orders')
|
||||
permission = AnyPermissionOf('event.orders:write', 'event.orders:checkin')
|
||||
template_name = 'pretixplugins/webcheckin/index.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user