From fdee69cd6981496e16a9592313d80d6d05a651be Mon Sep 17 00:00:00 2001 From: Martin Gross Date: Wed, 8 Jun 2022 12:59:30 +0200 Subject: [PATCH] PPv2: Revert ISU Return-Retry; Add access token cache invalidation on ISU return --- .../paypal2/client/core/paypal_http_client.py | 8 ++++++-- src/pretix/plugins/paypal2/views.py | 18 ++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/pretix/plugins/paypal2/client/core/paypal_http_client.py b/src/pretix/plugins/paypal2/client/core/paypal_http_client.py index 1e78f55f9..b4812203c 100644 --- a/src/pretix/plugins/paypal2/client/core/paypal_http_client.py +++ b/src/pretix/plugins/paypal2/client/core/paypal_http_client.py @@ -29,12 +29,16 @@ from paypalcheckoutsdk.core import ( class PayPalHttpClient(VendorPayPalHttpClient): def __call__(self, request): - # First we get all the items that make up the current credentials and create a hash to detect changes + # Cached access tokens are not updated by PayPal to include new Merchants that granted access rights since + # the access token was generated. Therefor we increment the cycle count and by that invalidate the cached + # token and pull a new one. + incr = cache.get('pretix_paypal_token_hash_cycle', default=0) + # Then we get all the items that make up the current credentials and create a hash to detect changes checksum = hashlib.sha256(''.join([ self.environment.base_url, self.environment.client_id, self.environment.client_secret ]).encode()).hexdigest() - cache_key_hash = f'pretix_paypal_token_hash_{checksum}' + cache_key_hash = f'pretix_paypal_token_hash_{checksum}_{incr}' token_hash = cache.get(cache_key_hash) if token_hash: diff --git a/src/pretix/plugins/paypal2/views.py b/src/pretix/plugins/paypal2/views.py index 4cc8fc50d..b9f825db4 100644 --- a/src/pretix/plugins/paypal2/views.py +++ b/src/pretix/plugins/paypal2/views.py @@ -38,6 +38,7 @@ from decimal import Decimal from django.contrib import messages from django.core import signing +from django.core.cache import cache from django.db.models import Sum from django.http import ( Http404, HttpResponse, HttpResponseBadRequest, JsonResponse, @@ -201,6 +202,11 @@ def isu_return(request, *args, **kwargs): event = get_object_or_404(Event, pk=request.session['payment_paypal_isu_event']) + # Cached access tokens are not updated by PayPal to include new Merchants that granted access rights since + # the access token was generated. Therefor we increment the cycle count and by that invalidate the cached + # token and pull a new one. + cache.incr('pretix_paypal_token_hash_cycle') + gs = GlobalSettingsObject() prov = Paypal(event) prov.init_api() @@ -212,16 +218,8 @@ def isu_return(request, *args, **kwargs): ) response = prov.client.execute(req) except IOError as e: - retry = request.GET.get('retry', 0) - retry = int(retry) - if retry < 3: - params = request.GET.copy() - params['retry'] = retry + 1 - logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}; Retrying.'.format(str(e))) - return redirect('{}?{}'.format(request.path, params.urlencode())) - else: - messages.error(request, _('An error occurred during connecting with PayPal, please try again.')) - logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}'.format(str(e))) + messages.error(request, _('An error occurred during connecting with PayPal, please try again.')) + logger.exception('PayPal PartnersMerchantIntegrationsGetRequest: {}'.format(str(e))) else: params = ['merchant_id', 'tracking_id', 'payments_receivable', 'primary_email_confirmed'] if not any(k in response.result for k in params):