mirror of
https://github.com/inventree/InvenTree.git
synced 2025-05-03 13:58:47 +00:00
hmac verification
This commit is contained in:
parent
5bf9561984
commit
68ca672937
@ -6,6 +6,9 @@ Provides a JSON API for common components.
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
import base64
|
||||||
from secrets import compare_digest
|
from secrets import compare_digest
|
||||||
|
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
@ -75,6 +78,7 @@ class WebhookView(CsrfExemptMixin, APIView):
|
|||||||
# To be overridden
|
# To be overridden
|
||||||
def init(self, request, *args, **kwargs):
|
def init(self, request, *args, **kwargs):
|
||||||
self.token = ''
|
self.token = ''
|
||||||
|
self.secret = ''
|
||||||
self.verify = self.VERIFICATION_METHOD
|
self.verify = self.VERIFICATION_METHOD
|
||||||
|
|
||||||
def get_webhook(self, endpoint):
|
def get_webhook(self, endpoint):
|
||||||
@ -90,6 +94,10 @@ class WebhookView(CsrfExemptMixin, APIView):
|
|||||||
self.token = self.webhook.token
|
self.token = self.webhook.token
|
||||||
self.verify = VerificationMethod.TOKEN
|
self.verify = VerificationMethod.TOKEN
|
||||||
# TODO make a object-setting
|
# TODO make a object-setting
|
||||||
|
if self.webhook.secret:
|
||||||
|
self.secret = self.webhook.secret
|
||||||
|
self.verify = VerificationMethod.HMAC
|
||||||
|
# TODO make a object-setting
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def validate_token(self, payload, headers):
|
def validate_token(self, payload, headers):
|
||||||
@ -106,6 +114,10 @@ class WebhookView(CsrfExemptMixin, APIView):
|
|||||||
|
|
||||||
# hmac token
|
# hmac token
|
||||||
elif self.verify == VerificationMethod.HMAC:
|
elif self.verify == VerificationMethod.HMAC:
|
||||||
|
digest = hmac.new(self.secret, payload.encode('utf-8'), 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
|
return True
|
||||||
|
|
||||||
|
18
InvenTree/common/migrations/0013_auto_20210912_1443.py
Normal file
18
InvenTree/common/migrations/0013_auto_20210912_1443.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.4 on 2021-09-12 14:43
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0012_webhookendpoint'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhookendpoint',
|
||||||
|
name='secret',
|
||||||
|
field=models.CharField(blank=True, help_text='Shared secret for HMAC', max_length=255, null=True, verbose_name='Secret'),
|
||||||
|
),
|
||||||
|
]
|
@ -1177,6 +1177,7 @@ class WebhookEndpoint(models.Model):
|
|||||||
active: Is this webhook active?,
|
active: Is this webhook active?,
|
||||||
user: User associated with webhook,
|
user: User associated with webhook,
|
||||||
token: Token for sending a webhook,
|
token: Token for sending a webhook,
|
||||||
|
secret: Shared secret for HMAC verification,
|
||||||
"""
|
"""
|
||||||
|
|
||||||
endpoint_id = models.CharField(
|
endpoint_id = models.CharField(
|
||||||
@ -1215,3 +1216,10 @@ class WebhookEndpoint(models.Model):
|
|||||||
help_text=_('Token for access'),
|
help_text=_('Token for access'),
|
||||||
default=uuid.uuid4,
|
default=uuid.uuid4,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
secret = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
blank=True, null=True,
|
||||||
|
verbose_name=_('Secret'),
|
||||||
|
help_text=_('Shared secret for HMAC'),
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user