From 9b32290964c9e176bf0054e60653e5244522f4e0 Mon Sep 17 00:00:00 2001
From: PCoder <purple.coder@yahoo.co.uk>
Date: Sat, 13 Apr 2019 23:52:41 +0200
Subject: [PATCH] Add webhook app and create_webhook management command

---
 dynamicweb/settings/base.py                   |  3 ++
 webhook/__init__.py                           |  0
 webhook/management/commands/create_webhook.py | 49 +++++++++++++++++++
 webhook/models.py                             |  3 ++
 webhook/views.py                              | 36 ++++++++++++++
 5 files changed, 91 insertions(+)
 create mode 100644 webhook/__init__.py
 create mode 100644 webhook/management/commands/create_webhook.py
 create mode 100644 webhook/models.py
 create mode 100644 webhook/views.py

diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py
index a770018f..45018f13 100644
--- a/dynamicweb/settings/base.py
+++ b/dynamicweb/settings/base.py
@@ -153,6 +153,7 @@ INSTALLED_APPS = (
     'rest_framework',
     'opennebula_api',
     'django_celery_results',
+    'webhook',
 )
 
 MIDDLEWARE_CLASSES = (
@@ -719,6 +720,8 @@ X_FRAME_OPTIONS = ('SAMEORIGIN' if X_FRAME_OPTIONS_ALLOW_FROM_URI is None else
                        X_FRAME_OPTIONS_ALLOW_FROM_URI.strip()
                    ))
 
+INVOICE_WEBHOOK_SECRET = env('INVOICE_WEBHOOK_SECRET')
+
 DEBUG = bool_env('DEBUG')
 
 if DEBUG:
diff --git a/webhook/__init__.py b/webhook/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/webhook/management/commands/create_webhook.py b/webhook/management/commands/create_webhook.py
new file mode 100644
index 00000000..23960297
--- /dev/null
+++ b/webhook/management/commands/create_webhook.py
@@ -0,0 +1,49 @@
+import logging
+import stripe
+
+from django.core.management.base import BaseCommand
+
+logger = logging.getLogger(__name__)
+
+
+class Command(BaseCommand):
+    help = '''creates webhook with the supplied arguments and returns the 
+    webhook secret
+    '''
+
+    def add_arguments(self, parser):
+        parser.add_argument(
+            '--webhook_endpoint',
+            help="The url of the webhook endpoint that accepts the events "
+                 "from stripe",
+            dest="webhook_endpoint"
+        )
+        parser.add_argument('--events_csv', dest="events_csv")
+
+    def handle(self, *args, **options):
+        wep_exists = False
+        try:
+            we_list = stripe.WebhookEndpoint.list(limit=100)
+            for wep in we_list.data:
+                if set(wep.enabled_events) == set(options['events_csv'].split(",")):
+                    if wep.url == options['webhook_endpoint']:
+                        logger.debug("We have this webhook already")
+                        wep_exists = True
+                        break
+            if wep_exists is False:
+                logger.debug(
+                    "No webhook exists for {} at {}. Creatting a new endpoint "
+                    "now".format(
+                        options['webhook_endpoint'], options['events_csv']
+                    )
+                )
+                wep = stripe.WebhookEndpoint.create(
+                    url=options['webhook_endpoint'],
+                    enabled_events=options['events_csv'].split(",")
+                )
+                self.stdout.write(
+                    self.style.SUCCESS('Creation successful. '
+                                       'webhook_secret = %s' % wep.secret)
+                )
+        except Exception as e:
+            print(" *** Error occurred. Details {}".format(str(e)))
diff --git a/webhook/models.py b/webhook/models.py
new file mode 100644
index 00000000..d49766e4
--- /dev/null
+++ b/webhook/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
\ No newline at end of file
diff --git a/webhook/views.py b/webhook/views.py
new file mode 100644
index 00000000..19587e69
--- /dev/null
+++ b/webhook/views.py
@@ -0,0 +1,36 @@
+import logging
+import stripe
+
+# Create your views here.
+from django.conf import settings
+from django.http import HttpResponse
+from django.views.decorators.csrf import csrf_exempt
+from django.views.decorators.http import require_POST
+
+logger = logging.getLogger(__name__)
+
+
+@require_POST
+@csrf_exempt
+def handle_invoice_webhook(request):
+    payload = request.body
+    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
+    event = None
+
+    try:
+        event = stripe.Webhook.construct_event(
+            payload, sig_header, settings.INVOICE_WEBHOOK_SECRET
+        )
+    except ValueError as e:
+        logger.error("Invalid payload details = " + str(e))
+        # Invalid payload
+        return HttpResponse(status=400)
+    except stripe.error.SignatureVerificationError as e:
+        logger.error("SignatureVerificationError details = " + str(e))
+        # Invalid signature
+        return HttpResponse(status=400)
+
+    # Do something with event
+    logger.debug("Passed invoice signature verification")
+
+    return HttpResponse(status=200)
\ No newline at end of file