2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-03 20:20:58 +00:00

move webhook receiver logic

This commit is contained in:
Matthias
2021-10-18 22:39:08 +02:00
parent 20bb2d438e
commit b36a1d47e1
3 changed files with 90 additions and 89 deletions

View File

@ -10,6 +10,10 @@ import os
import decimal
import math
import uuid
import hmac
import hashlib
import base64
from secrets import compare_digest
from django.db import models, transaction
from django.contrib.auth.models import User, Group
@ -20,6 +24,8 @@ from djmoney.settings import CURRENCY_CHOICES
from djmoney.contrib.exchange.models import convert_money
from djmoney.contrib.exchange.exceptions import MissingRate
from rest_framework.exceptions import PermissionDenied
from django.utils.translation import ugettext_lazy as _
from django.core.validators import MinValueValidator, URLValidator
from django.core.exceptions import ValidationError
@ -1248,6 +1254,12 @@ class ColorTheme(models.Model):
return False
class VerificationMethod:
NONE = 0
TOKEN = 1
HMAC = 2
class WebhookEndpoint(models.Model):
""" Defines a Webhook entdpoint
@ -1260,6 +1272,13 @@ class WebhookEndpoint(models.Model):
secret: Shared secret for HMAC verification,
"""
# Token
TOKEN_NAME = "Token"
VERIFICATION_METHOD = VerificationMethod.NONE
MESSAGE_OK = "Message was received."
MESSAGE_TOKEN_ERROR = "Incorrect token in header."
endpoint_id = models.CharField(
max_length=255,
verbose_name=_('Endpoint'),
@ -1304,6 +1323,61 @@ class WebhookEndpoint(models.Model):
help_text=_('Shared secret for HMAC'),
)
# To be overridden
def init(self, request, *args, **kwargs):
self.verify = self.VERIFICATION_METHOD
def process_webhook(self):
if self.token:
self.token = self.token
self.verify = VerificationMethod.TOKEN
# TODO make a object-setting
if self.secret:
self.secret = self.secret
self.verify = VerificationMethod.HMAC
# TODO make a object-setting
return True
def validate_token(self, payload, headers, request):
token = headers.get(self.TOKEN_NAME, "")
# no token
if self.verify == VerificationMethod.NONE:
pass
# static token
elif self.verify == VerificationMethod.TOKEN:
if not compare_digest(token, self.token):
raise PermissionDenied(self.MESSAGE_TOKEN_ERROR)
# hmac token
elif self.verify == VerificationMethod.HMAC:
digest = hmac.new(self.secret.encode('utf-8'), request.body, hashlib.sha256).digest()
computed_hmac = base64.b64encode(digest)
if not hmac.compare_digest(computed_hmac, token.encode('utf-8')):
raise PermissionDenied(self.MESSAGE_TOKEN_ERROR)
return True
def save_data(self, payload, headers=None, request=None):
return WebhookMessage.objects.create(
# host=request.host,
# TODO fix
header=headers,
body=payload,
endpoint=self,
)
def process_payload(self, message, payload=None, headers=None):
return True
def get_result(self, payload, headers=None, request=None):
context = {}
context['data'] = {'message': self.MESSAGE_OK}
context['status'] = 200
return context
class WebhookMessage(models.Model):
""" Defines a webhook message