(webhook) add webhook logic and synchronization utils

adding webhooks logic to send serialized team memberships data
to a designated serie of webhooks.
This commit is contained in:
Marie PUPO JEAMMET
2024-03-22 14:47:08 +01:00
committed by Marie
parent 7ea6342a01
commit ebf58f42c9
13 changed files with 813 additions and 9 deletions

View File

@@ -0,0 +1,75 @@
"""Fire webhooks with synchronous retries"""
import logging
import requests
from core.enums import WebhookStatusChoices
from .scim import SCIMClient
logger = logging.getLogger(__name__)
class WebhookSCIMClient:
"""Wraps the SCIM client to record call results on webhooks."""
def __getattr__(self, name):
"""Handle calls from webhooks to synchronize a team access with a distant application."""
def wrapper(team, user):
"""
Wrap SCIMClient calls to handle retries, error handling and storing result in the
calling Webhook instance.
"""
for webhook in team.webhooks.all():
if not webhook.url:
continue
client = SCIMClient()
status = WebhookStatusChoices.FAILURE
try:
response = getattr(client, name)(webhook, user)
except requests.exceptions.RetryError as exc:
logger.error(
"%s synchronization failed due to max retries exceeded with url %s",
name,
webhook.url,
exc_info=exc,
)
except requests.exceptions.RequestException as exc:
logger.error(
"%s synchronization failed with %s.",
name,
webhook.url,
exc_info=exc,
)
else:
extra = {
"response": response.content,
}
# pylint: disable=no-member
if response.status_code == requests.codes.ok:
logger.info(
"%s synchronization succeeded with %s",
name,
webhook.url,
extra=extra,
)
status = WebhookStatusChoices.SUCCESS
else:
logger.error(
"%s synchronization failed with %s",
name,
webhook.url,
extra=extra,
)
webhook._meta.model.objects.filter(id=webhook.id).update(status=status) # noqa
return wrapper
scim_synchronizer = WebhookSCIMClient()