diff --git a/combo/apps/lingo/models.py b/combo/apps/lingo/models.py index 3998266a..07def1de 100644 --- a/combo/apps/lingo/models.py +++ b/combo/apps/lingo/models.py @@ -622,22 +622,25 @@ class LingoRecentTransactionsCell(CellBase): def is_enabled(cls): return Regie.objects.exists() + def get_transactions_queryset(self, context): + user = context['request'].user + # list transactions : + # * paid by the user + # * or linked to a BasketItem of the user + return ( + Transaction.objects + .filter(models.Q(user=user) | models.Q(items__user=user)) + .filter(start_date__gte=timezone.now() - datetime.timedelta(days=7)) + ) + def is_relevant(self, context): if not (getattr(context['request'], 'user', None) and context['request'].user.is_authenticated): return False - return ( - Transaction.objects.filter( - user=context['request'].user, - start_date__gte=timezone.now()-datetime.timedelta(days=7)) - .exists()) + return self.get_transactions_queryset(context).exists() def render(self, context): - recent_transactions_template = template.loader.get_template( - 'lingo/combo/recent_transactions.html') - context['transactions'] = Transaction.objects.filter( - user=context['request'].user, - start_date__gte=timezone.now()-datetime.timedelta(days=7) - ).order_by('-start_date') + recent_transactions_template = template.loader.get_template('lingo/combo/recent_transactions.html') + context['transactions'] = self.get_transactions_queryset(context).distinct().order_by('-start_date') return recent_transactions_template.render(context) diff --git a/combo/apps/lingo/templates/lingo/combo/recent_transactions.html b/combo/apps/lingo/templates/lingo/combo/recent_transactions.html index 6c6a6e4a..af8de2d1 100644 --- a/combo/apps/lingo/templates/lingo/combo/recent_transactions.html +++ b/combo/apps/lingo/templates/lingo/combo/recent_transactions.html @@ -9,7 +9,7 @@ {% else %} diff --git a/combo/apps/lingo/views.py b/combo/apps/lingo/views.py index 07e5c0ac..71cbf27f 100644 --- a/combo/apps/lingo/views.py +++ b/combo/apps/lingo/views.py @@ -518,9 +518,6 @@ class BasketItemPayView(PayMixin, View): if regie.extra_fees_ws_url: return HttpResponseForbidden(_('No item payment allowed as extra fees set.')) - if item.user and item.user != request.user: - return HttpResponseForbidden(_('Wrong item: payment not allowed.')) - if not next_url: next_url = item.source_url diff --git a/tests/test_lingo_payment.py b/tests/test_lingo_payment.py index 86c83732..3f12ac9f 100644 --- a/tests/test_lingo_payment.py +++ b/tests/test_lingo_payment.py @@ -519,13 +519,15 @@ def test_pay_single_basket_item(app, key, regie, user_name_id, john_doe): resp = app.post_json(url, params=data) # check that an unpaid item exists in basket assert BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=True).exists() - payment_url = resp.json['payment_url'] - resp = app.get(payment_url, status=403) - assert 'Wrong item: payment not allowed.' in resp.text + payment_data = resp.json + payment_url = payment_data['payment_url'] + # check that payment is possible unconnected + app.get(payment_url, status=302) + + # and connected with another user (john.doe != admin) login(app, username='john.doe', password='john.doe') - resp = app.get(payment_url, status=403) - assert 'Wrong item: payment not allowed.' in resp.text + app.get(payment_url, status=302) # forbid payment to regie with extra_fees_ws_url regie.extra_fees_ws_url = 'http://example.com/extra-fees' @@ -538,7 +540,9 @@ def test_pay_single_basket_item(app, key, regie, user_name_id, john_doe): regie.extra_fees_ws_url = '' regie.save() + assert not Transaction.objects.filter(user__username='admin', status=0).exists() resp = app.get(payment_url, params={'next_url': 'http://example.net/form/id/'}) + assert Transaction.objects.filter(user__username='admin', status=0).exists() # make sure the redirection is done to the payment backend assert resp.location.startswith('http://dummy-payment.demo.entrouvert.com/') @@ -554,6 +558,48 @@ def test_pay_single_basket_item(app, key, regie, user_name_id, john_doe): item = BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=False).first() # check that user is redirected to the item payment status view assert_payment_status(resp.location, transaction_id=item.transaction_set.last().pk) + assert Transaction.objects.filter(user__username='admin', status=eopayment.PAID).exists() + + +def test_pay_single_basket_item_another_user(app, key, regie, user_name_id, john_doe): + page = Page(title='xxx', slug='index', template_name='standard') + page.save() + cell = LingoBasketCell(page=page, placeholder='content', order=0) + cell.save() + + amount = 12 + data = {'amount': amount, + 'display_name': 'test amount', + 'url': 'http://example.com'} + url = '%s?NameId=%s&orig=wcs' % (reverse('api-add-basket-item'), user_name_id) + url = sign_url(url, key) + resp = app.post_json(url, params=data) + # check that an unpaid item exists in basket + assert BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=True).exists() + payment_url = resp.json['payment_url'] + + # and connected with another user (john.doe != admin) + login(app, username='john.doe', password='john.doe') + + assert not Transaction.objects.filter(user__username='john.doe', status=0).exists() + resp = app.get(payment_url, params={'next_url': 'http://example.net/form/id/'}) + assert Transaction.objects.filter(user__username='john.doe', status=0).exists() + + # make sure the redirection is done to the payment backend + assert resp.location.startswith('http://dummy-payment.demo.entrouvert.com/') + qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query) + assert qs['amount'] == ['12.00'] + # simulate successful payment response from dummy backend + data = {'transaction_id': qs['transaction_id'][0], 'ok': True, + 'amount': qs['amount'][0], 'signed': True} + # simulate payment service redirecting the user to /lingo/return/... (eopayment + # dummy module put that URL in return_url query string parameter). + resp = app.get(qs['return_url'][0], params=data) + # check that item is paid + item = BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=False).first() + # check that user is redirected to the item payment status view + assert_payment_status(resp.location, transaction_id=item.transaction_set.last().pk) + assert Transaction.objects.filter(user__username='john.doe', status=eopayment.PAID).exists() def test_pay_multiple_regies(app, key, regie, user_name_id):