lingo: allow item payment by any user (#41837)

This commit is contained in:
Benjamin Dauvergne 2020-06-22 17:40:56 +02:00
parent 236fa3557a
commit 832b8188fb
4 changed files with 66 additions and 20 deletions

View File

@ -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)

View File

@ -9,7 +9,7 @@
<ul>
{% for item in transaction.items.all %}
<li>{{ item.subject }}: {{ item.amount }} €</label>
{% if item.source_url %}(<a href="{{ item.source_url}}">{% trans 'open' %}</a>){% endif %}</li>
{% if item.source_url and item.user == request.user %}(<a href="{{ item.source_url}}">{% trans 'open' %}</a>){% endif %}</li>
{% endfor %}
</ul>
{% else %}

View File

@ -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

View File

@ -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):