Integrate django-scopes (#1319)

* Install django-scopes

* Fix tests.api

* Update tasks and cronjobs

* Fix remaining tests

* Remove unused import

* Fix tests after rebase

* Disable scopes for get_Events_with_any_permission

* Disable scopes for a management command
This commit is contained in:
Raphael Michel
2019-06-17 10:46:55 +02:00
committed by GitHub
parent b1db5dbb3e
commit d85ddb5bda
130 changed files with 6253 additions and 4509 deletions

View File

@@ -7,6 +7,7 @@ from pretix.base.models import (
CachedFile, Event, OrderPosition, cachedfile_name,
)
from pretix.base.services.orders import OrderError
from pretix.base.services.tasks import EventTask
from pretix.celery_app import app
from .exporters import render_pdf
@@ -14,8 +15,8 @@ from .exporters import render_pdf
logger = logging.getLogger(__name__)
@app.task(throws=(OrderError,))
def badges_create_pdf(fileid: int, event: int, positions: List[int]) -> int:
@app.task(base=EventTask, throws=(OrderError,))
def badges_create_pdf(event: int, fileid: int, positions: List[int]) -> int:
file = CachedFile.objects.get(id=fileid)
event = Event.objects.get(id=event)

View File

@@ -223,7 +223,7 @@ class OrderPrintDo(EventPermissionRequiredMixin, AsyncAction, View):
else:
positions = [p.pk for p in order.positions.all()]
return self.do(
str(cf.id),
self.request.event.pk,
str(cf.id),
positions,
)

View File

@@ -9,6 +9,7 @@ from django.db import transaction
from django.db.models import Q
from django.utils.formats import date_format
from django.utils.translation import ugettext, ugettext_noop
from django_scopes import scope, scopes_disabled
from pretix.base.i18n import language
from pretix.base.models import (
@@ -194,51 +195,53 @@ def _get_unknown_transactions(job: BankImportJob, data: list, event: Event=None,
@app.task(base=TransactionAwareTask, bind=True, max_retries=5, default_retry_delay=1)
def process_banktransfers(self, job: int, data: list) -> None:
with language("en"): # We'll translate error messages at display time
job = BankImportJob.objects.get(pk=job)
job.state = BankImportJob.STATE_RUNNING
job.save()
prefixes = []
with scopes_disabled():
job = BankImportJob.objects.get(pk=job)
with scope(organizer=job.organizer or job.event.organizer):
job.state = BankImportJob.STATE_RUNNING
job.save()
prefixes = []
try:
# Delete left-over transactions from a failed run before so they can reimported
BankTransaction.objects.filter(state=BankTransaction.STATE_UNCHECKED, **job.owner_kwargs).delete()
transactions = _get_unknown_transactions(job, data, **job.owner_kwargs)
code_len = settings.ENTROPY['order_code']
if job.event:
pattern = re.compile(job.event.slug.upper() + r"[ \-_]*([A-Z0-9]{%s})" % code_len)
else:
if not prefixes:
prefixes = [e.slug.upper().replace(".", r"\.").replace("-", r"[\- ]*")
for e in job.organizer.events.all()]
pattern = re.compile("(%s)[ \\-_]*([A-Z0-9]{%s})" % ("|".join(prefixes), code_len))
for trans in transactions:
match = pattern.search(trans.reference.replace(" ", "").replace("\n", "").upper())
if match:
if job.event:
code = match.group(1)
_handle_transaction(trans, code, event=job.event)
else:
slug = match.group(1)
code = match.group(2)
_handle_transaction(trans, code, organizer=job.organizer, slug=slug)
else:
trans.state = BankTransaction.STATE_NOMATCH
trans.save()
except LockTimeoutException:
try:
self.retry()
except MaxRetriesExceededError:
logger.exception('Maximum number of retries exceeded for task.')
# Delete left-over transactions from a failed run before so they can reimported
BankTransaction.objects.filter(state=BankTransaction.STATE_UNCHECKED, **job.owner_kwargs).delete()
transactions = _get_unknown_transactions(job, data, **job.owner_kwargs)
code_len = settings.ENTROPY['order_code']
if job.event:
pattern = re.compile(job.event.slug.upper() + r"[ \-_]*([A-Z0-9]{%s})" % code_len)
else:
if not prefixes:
prefixes = [e.slug.upper().replace(".", r"\.").replace("-", r"[\- ]*")
for e in job.organizer.events.all()]
pattern = re.compile("(%s)[ \\-_]*([A-Z0-9]{%s})" % ("|".join(prefixes), code_len))
for trans in transactions:
match = pattern.search(trans.reference.replace(" ", "").replace("\n", "").upper())
if match:
if job.event:
code = match.group(1)
_handle_transaction(trans, code, event=job.event)
else:
slug = match.group(1)
code = match.group(2)
_handle_transaction(trans, code, organizer=job.organizer, slug=slug)
else:
trans.state = BankTransaction.STATE_NOMATCH
trans.save()
except LockTimeoutException:
try:
self.retry()
except MaxRetriesExceededError:
logger.exception('Maximum number of retries exceeded for task.')
job.state = BankImportJob.STATE_ERROR
job.save()
except Exception as e:
job.state = BankImportJob.STATE_ERROR
job.save()
except Exception as e:
job.state = BankImportJob.STATE_ERROR
job.save()
raise e
else:
job.state = BankImportJob.STATE_COMPLETED
job.save()
raise e
else:
job.state = BankImportJob.STATE_COMPLETED
job.save()

View File

@@ -13,6 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django_scopes import scopes_disabled
from paypalrestsdk.openid_connect import Tokeninfo
from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota
@@ -133,6 +134,7 @@ def abort(request, *args, **kwargs):
@csrf_exempt
@require_POST
@scopes_disabled()
def webhook(request, *args, **kwargs):
event_body = request.body.decode('utf-8').strip()
event_json = json.loads(event_body)

View File

@@ -1,6 +1,9 @@
from django import forms
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django_scopes.forms import (
SafeModelChoiceField, SafeModelMultipleChoiceField,
)
from pretix.control.forms.widgets import Select2
from pretix.plugins.pretixdroid.models import AppConfiguration
@@ -16,6 +19,10 @@ class AppConfigurationForm(forms.ModelForm):
}),
'app': forms.RadioSelect
}
field_classes = {
'items': SafeModelMultipleChoiceField,
'list': SafeModelChoiceField,
}
def __init__(self, **kwargs):
self.event = kwargs.pop('event')

View File

@@ -17,6 +17,7 @@ from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView, View
from django_scopes import scope, scopes_disabled
from pretix.base.models import Checkin, Event, Order, OrderPosition
from pretix.base.models.event import SubEvent
@@ -124,34 +125,35 @@ class ConfigView(EventPermissionRequiredMixin, TemplateView):
class ApiView(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, **kwargs):
try:
self.event = Event.objects.get(
slug=self.kwargs['event'],
organizer__slug=self.kwargs['organizer']
)
except Event.DoesNotExist:
return HttpResponseNotFound('Unknown event')
with scopes_disabled():
try:
self.event = Event.objects.get(
slug=self.kwargs['event'],
organizer__slug=self.kwargs['organizer']
)
except Event.DoesNotExist:
return HttpResponseNotFound('Unknown event')
with scope(organizer=self.event.organizer):
try:
self.config = self.event.appconfiguration_set.get(key=request.GET.get("key", "-unset-"))
except AppConfiguration.DoesNotExist:
return HttpResponseForbidden('Invalid key')
try:
self.config = self.event.appconfiguration_set.get(key=request.GET.get("key", "-unset-"))
except AppConfiguration.DoesNotExist:
return HttpResponseForbidden('Invalid key')
self.subevent = None
if self.event.has_subevents:
if self.config.list.subevent:
self.subevent = self.config.list.subevent
if 'subevent' in kwargs and kwargs['subevent'] != str(self.subevent.pk):
return HttpResponseForbidden('Invalid subevent selected.')
elif 'subevent' in kwargs:
self.subevent = get_object_or_404(SubEvent, event=self.event, pk=kwargs['subevent'])
self.subevent = None
if self.event.has_subevents:
if self.config.list.subevent:
self.subevent = self.config.list.subevent
if 'subevent' in kwargs and kwargs['subevent'] != str(self.subevent.pk):
return HttpResponseForbidden('Invalid subevent selected.')
elif 'subevent' in kwargs:
self.subevent = get_object_or_404(SubEvent, event=self.event, pk=kwargs['subevent'])
else:
return HttpResponseForbidden('No subevent selected.')
else:
return HttpResponseForbidden('No subevent selected.')
else:
if 'subevent' in kwargs:
return HttpResponseForbidden('Subevents not enabled.')
if 'subevent' in kwargs:
return HttpResponseForbidden('Subevents not enabled.')
return super().dispatch(request, **kwargs)
return super().dispatch(request, **kwargs)
class ApiRedeemView(ApiView):

View File

@@ -5,15 +5,14 @@ from i18nfield.strings import LazyI18nString
from pretix.base.i18n import language
from pretix.base.models import Event, InvoiceAddress, Order, User
from pretix.base.services.mail import SendMailException, mail
from pretix.base.services.tasks import ProfiledTask
from pretix.base.services.tasks import ProfiledEventTask
from pretix.celery_app import app
from pretix.multidomain.urlreverse import build_absolute_uri
@app.task(base=ProfiledTask)
def send_mails(event: int, user: int, subject: dict, message: dict, orders: list, items: list, recipients: str) -> None:
@app.task(base=ProfiledEventTask)
def send_mails(event: Event, user: int, subject: dict, message: dict, orders: list, items: list, recipients: str) -> None:
failures = []
event = Event.objects.get(pk=event)
user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=orders, event=event)
subject = LazyI18nString(subject)

View File

@@ -1,5 +1,6 @@
import stripe
from django.core.management.base import BaseCommand
from django_scopes import scopes_disabled
from pretix.base.models import Event
from pretix.base.settings import GlobalSettingsObject
@@ -8,6 +9,7 @@ from pretix.base.settings import GlobalSettingsObject
class Command(BaseCommand):
help = "Detect country for Stripe Connect accounts connected with pretix 2.0 (required for payment request buttons)"
@scopes_disabled()
def handle(self, *args, **options):
cache = {}
gs = GlobalSettingsObject()

View File

@@ -5,6 +5,7 @@ import stripe
from django.conf import settings
from pretix.base.models import Event
from pretix.base.services.tasks import EventTask
from pretix.celery_app import app
from pretix.multidomain.urlreverse import get_domain
from pretix.plugins.stripe.models import RegisteredApplePayDomain
@@ -27,7 +28,7 @@ def get_stripe_account_key(prov):
return prov.settings.publishable_key
@app.task(max_retries=5, default_retry_delay=1)
@app.task(base=EventTask, max_retries=5, default_retry_delay=1)
def stripe_verify_domain(event_id, domain):
from pretix.plugins.stripe.payment import StripeCC
event = Event.objects.get(pk=event_id)

View File

@@ -17,6 +17,7 @@ from django.views import View
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django_scopes import scopes_disabled
from pretix.base.models import Event, Order, OrderPayment, Quota
from pretix.base.payment import PaymentException
@@ -140,6 +141,7 @@ def oauth_return(request, *args, **kwargs):
@csrf_exempt
@require_POST
@scopes_disabled()
def webhook(request, *args, **kwargs):
event_json = json.loads(request.body.decode('utf-8'))