webhooks.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import hashlib
  2. import hmac
  3. from django.contrib.contenttypes.models import ContentType
  4. from django.utils import timezone
  5. from extras.models import Webhook
  6. from utilities.api import get_serializer_for_model
  7. from .choices import *
  8. from .constants import *
  9. def generate_signature(request_body, secret):
  10. """
  11. Return a cryptographic signature that can be used to verify the authenticity of webhook data.
  12. """
  13. hmac_prep = hmac.new(
  14. key=secret.encode('utf8'),
  15. msg=request_body.encode('utf8'),
  16. digestmod=hashlib.sha512
  17. )
  18. return hmac_prep.hexdigest()
  19. def enqueue_webhooks(instance, user, request_id, action):
  20. """
  21. Find Webhook(s) assigned to this instance + action and enqueue them
  22. to be processed
  23. """
  24. obj_type = ContentType.objects.get_for_model(instance.__class__)
  25. webhook_models = ContentType.objects.filter(WEBHOOK_MODELS)
  26. if obj_type not in webhook_models:
  27. return
  28. # Retrieve any applicable Webhooks
  29. action_flag = {
  30. ObjectChangeActionChoices.ACTION_CREATE: 'type_create',
  31. ObjectChangeActionChoices.ACTION_UPDATE: 'type_update',
  32. ObjectChangeActionChoices.ACTION_DELETE: 'type_delete',
  33. }[action]
  34. webhooks = Webhook.objects.filter(obj_type=obj_type, enabled=True, **{action_flag: True})
  35. if webhooks.exists():
  36. # Get the Model's API serializer class and serialize the object
  37. serializer_class = get_serializer_for_model(instance.__class__)
  38. serializer_context = {
  39. 'request': None,
  40. }
  41. serializer = serializer_class(instance, context=serializer_context)
  42. # We must only import django_rq if the Webhooks feature is enabled.
  43. # Only if we have gotten to ths point, is the feature enabled
  44. from django_rq import get_queue
  45. webhook_queue = get_queue('default')
  46. # enqueue the webhooks:
  47. for webhook in webhooks:
  48. webhook_queue.enqueue(
  49. "extras.webhooks_worker.process_webhook",
  50. webhook,
  51. serializer.data,
  52. instance._meta.model_name,
  53. action,
  54. str(timezone.now()),
  55. user.username,
  56. request_id
  57. )