From 3a93095437ba8b433f9b108234fc2879d8d763f5 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO <ynerant@crans.org> Date: Sat, 19 Jun 2021 12:22:08 +0200 Subject: [PATCH] Clean code --- billing/models/payment_methods.py | 1 + billing/views/note_kfet.py | 105 ++++++++++++++++++++---------- constellation/settings.py | 1 + 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/billing/models/payment_methods.py b/billing/models/payment_methods.py index 7394ce6..56450e4 100644 --- a/billing/models/payment_methods.py +++ b/billing/models/payment_methods.py @@ -57,6 +57,7 @@ class NoteKfetPaymentMethod(PaymentMethod): def get_payment_url(self, invoice, request=None): scheme = request.scheme if request else "https" host = request.get_host() if request else Site.objects.first().domain + # Go to the authorization link of the Note Kfet return settings.NOTE_KFET_URL + "o/authorize/?client_id=" + settings.NOTE_KFET_CLIENT_ID \ + "&response_type=code&scope=" + settings.NOTE_KFET_SCOPES + "&state=" + str(invoice.pk) \ + f"&redirect_uri={scheme}://{host}{reverse_lazy('billing:note_auth')}" diff --git a/billing/views/note_kfet.py b/billing/views/note_kfet.py index 0026976..b214565 100644 --- a/billing/views/note_kfet.py +++ b/billing/views/note_kfet.py @@ -1,6 +1,7 @@ import requests from django.conf import settings from django.contrib import messages +from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import RedirectView @@ -8,23 +9,41 @@ from django.views.generic import RedirectView from ..models import Invoice -class NoteKfetAuthorizeView(RedirectView): +class NoteKfetAuthorizeView(LoginRequiredMixin, RedirectView): + """ + This view is called after an authorization from the Note Kfet. + Constellation requests an authorization to create a transaction. + When the user gave the authorization, it is redirected here. + + With the grant token, we get an access token, then we can query + the API to create the transaction. + """ + url = reverse_lazy('index') def get(self, request, *args, **kwargs): + if 'error' in request.GET: + messages.error(request, _("Error:") + " " + request.GET['error']) + return super().get(request, *args, **kwargs) + if 'code' not in request.GET or 'state' not in request.GET: messages.error(request, _("Bad request")) return super().get(request, *args, **kwargs) invoice_id = request.GET['state'] + qs = Invoice.objects.filter(pk=invoice_id) + # Don't validate invoices from other users + if not request.user.has_perm('billing.change_invoice'): + qs = qs.filter(target=request.user) if not Invoice.objects.filter(pk=invoice_id).exists(): messages.error(request, _("Bad request")) return super().get(request, *args, **kwargs) - invoice = Invoice.objects.get(pk=invoice_id) + invoice = qs.get() code = request.GET['code'] + # Generate access token response = requests.post(settings.NOTE_KFET_URL + "o/token/", data={ 'client_id': settings.NOTE_KFET_CLIENT_ID, 'client_secret': settings.NOTE_KFET_CLIENT_SECRET, @@ -33,38 +52,56 @@ class NoteKfetAuthorizeView(RedirectView): }) resp_json = response.json() - if 'error' not in resp_json: - resp_json = response.json() - access_token = resp_json['access_token'] - - note = requests.get(settings.NOTE_KFET_URL + "api/note/note/", - headers={"Authorization": f"Bearer {access_token}"}).json()['results'][0] - - response = requests.post( - settings.NOTE_KFET_URL + "api/note/transaction/transaction/", - json={ - 'source_alias': note['name'], - 'destination_alias': 'Crans', - 'quantity': 1, - 'amount': invoice.price, - 'reason': f'Facture n°{invoice.id}', - 'valid': True, - 'polymorphic_ctype': 26, - 'source': note['id'], - 'destination': 2088, - 'resourcetype': 'Transaction', - - }, - headers={"Authorization": f"Bearer {access_token}"}, - ) - - if response.status_code == 201: - messages.success(request, _("Payment succeed!")) - invoice.valid = True - invoice.save() - else: - messages.error(request, _("Error:") + " " + str(response.json())) - else: + if 'error' in resp_json: messages.error(request, _("Error:") + " " + str(resp_json)) + return super().get(request, *args, **kwargs) + + resp_json = response.json() + access_token = resp_json['access_token'] + + # Get user note id + response = requests.get(settings.NOTE_KFET_URL + "api/note/note/", + headers={"Authorization": f"Bearer {access_token}"}) + + if response.status_code != 200: + messages.error(request, _("Error:") + " " + str(response.json())) + return super().get(request, *args, **kwargs) + + note = response.json()['results'][0] + + # Get Transaction polymorphic ctype + response = requests.get(settings.NOTE_KFET_URL + "api/models/?app_label=note&model=transaction", + headers={"Authorization": f"Bearer {access_token}"}) + if response.status_code != 200: + messages.error(request, _("Error:") + " " + str(response.json())) + return super().get(request, *args, **kwargs) + polymorphic_ctype_id = response.json()['results'][0]['id'] + + # Create transaction + response = requests.post( + settings.NOTE_KFET_URL + "api/note/transaction/transaction/", + json={ + 'source_alias': note['name'], + 'destination_alias': 'Crans', + 'quantity': 1, + 'amount': invoice.price, + 'reason': f'Facture n°{invoice.id}', + 'valid': True, + 'polymorphic_ctype': polymorphic_ctype_id, + 'source': note['id'], + 'destination': settings.NOTE_KFET_CLUB_NOTE_ID, + 'resourcetype': 'Transaction', + + }, + headers={"Authorization": f"Bearer {access_token}"}, + ) + + if response.status_code == 201: + messages.success(request, _("Payment succeed!")) + # Validate invoice + invoice.valid = True + invoice.save() + else: + messages.error(request, _("Error:") + " " + str(response.json())) return super().get(request, *args, **kwargs) diff --git a/constellation/settings.py b/constellation/settings.py index 4f31b9c..04087fa 100644 --- a/constellation/settings.py +++ b/constellation/settings.py @@ -251,6 +251,7 @@ NOTE_KFET_URL = "https://note.crans.org/" NOTE_KFET_CLIENT_ID = "CHANGEME" NOTE_KFET_CLIENT_SECRET = "CHANGEME" NOTE_KFET_SCOPES = "3_1 17_1" # View own note, create transaction from our own note +NOTE_KFET_CLUB_NOTE_ID = 2088 # WARNING: this is the note ID, not the club ID. try: from .settings_local import * # noqa: F401, F403& -- GitLab