import django_filters
|
from core.permissions import ViewClassPermission, all_permissions
|
from django.utils.decorators import method_decorator
|
from django_filters.rest_framework import DjangoFilterBackend
|
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
from projects import models as project_models
|
from rest_framework import generics
|
from rest_framework.exceptions import NotFound
|
from rest_framework.permissions import AllowAny, IsAuthenticated
|
from rest_framework.response import Response
|
from rest_framework.views import APIView
|
|
from .models import Webhook, WebhookAction
|
from .serializers import WebhookSerializer, WebhookSerializerForUpdate
|
|
|
class WebhookFilterSet(django_filters.FilterSet):
|
project = django_filters.ModelChoiceFilter(
|
field_name='project', queryset=project_models.Project.objects.all(), null_label='isnull'
|
)
|
|
|
@method_decorator(
|
name='get',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='List all webhooks',
|
description='List all webhooks set up for your organization.',
|
parameters=[
|
OpenApiParameter(
|
name='project',
|
type=OpenApiTypes.STR,
|
location='query',
|
description='Project ID',
|
),
|
],
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'list',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
@method_decorator(
|
name='post',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Create a webhook',
|
description='Create a webhook for your organization.',
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'create',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
class WebhookListAPI(generics.ListCreateAPIView):
|
queryset = Webhook.objects.all()
|
serializer_class = WebhookSerializer
|
permission_classes = [IsAuthenticated]
|
filter_backends = [DjangoFilterBackend]
|
filterset_class = WebhookFilterSet
|
permission_required = ViewClassPermission(
|
GET=all_permissions.webhooks_view,
|
POST=all_permissions.webhooks_change,
|
)
|
|
def get_queryset(self):
|
return Webhook.objects.filter(organization=self.request.user.active_organization)
|
|
def perform_create(self, serializer):
|
project = serializer.validated_data.get('project')
|
if project is None or project.organization_id != self.request.user.active_organization.id:
|
raise NotFound('Project not found.')
|
serializer.save(organization=self.request.user.active_organization)
|
|
|
@method_decorator(
|
name='get',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Get webhook info',
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'get',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
@method_decorator(
|
name='put',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Save webhook info',
|
request=WebhookSerializerForUpdate,
|
extensions={
|
'x-fern-audiences': ['internal'],
|
},
|
),
|
)
|
@method_decorator(
|
name='patch',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Update webhook info',
|
request=WebhookSerializerForUpdate,
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'update',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
@method_decorator(
|
name='delete',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Delete webhook info',
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'delete',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
class WebhookAPI(generics.RetrieveUpdateDestroyAPIView):
|
queryset = Webhook.objects.all()
|
serializer_class = WebhookSerializer
|
permission_classes = [IsAuthenticated]
|
permission_required = ViewClassPermission(
|
GET=all_permissions.webhooks_view,
|
PATCH=all_permissions.webhooks_change,
|
PUT=all_permissions.webhooks_change,
|
DELETE=all_permissions.webhooks_change,
|
)
|
|
def get_serializer_class(self):
|
if self.request.method in ['PUT', 'PATCH']:
|
return WebhookSerializerForUpdate
|
return super().get_serializer_class()
|
|
def get_queryset(self):
|
return Webhook.objects.filter(organization=self.request.user.active_organization)
|
|
|
@method_decorator(
|
name='get',
|
decorator=extend_schema(
|
tags=['Webhooks'],
|
summary='Get all webhook actions',
|
description='Get descriptions of all available webhook actions to set up webhooks.',
|
responses={
|
200: OpenApiResponse(
|
description='Object with webhook action descriptions.',
|
response={
|
'type': 'object',
|
'properties': {
|
action: {
|
'type': 'object',
|
'properties': {
|
'name': {'type': 'string'},
|
'description': {'type': 'string'},
|
'key': {'type': 'string'},
|
'organization-only': {'type': 'boolean'},
|
},
|
'required': ['name', 'description', 'key', 'organization-only'],
|
}
|
for action in WebhookAction.ACTIONS.keys()
|
},
|
},
|
),
|
},
|
parameters=[
|
OpenApiParameter(
|
name='organization-only',
|
location='query',
|
description='organization-only or not',
|
type=OpenApiTypes.BOOL,
|
)
|
],
|
extensions={
|
'x-fern-sdk-group-name': 'webhooks',
|
'x-fern-sdk-method-name': 'info',
|
'x-fern-audiences': ['public'],
|
},
|
),
|
)
|
class WebhookInfoAPI(APIView):
|
permission_classes = [AllowAny]
|
|
def get(self, request, *args, **kwargs):
|
result = {
|
key: {
|
'name': value['name'],
|
'description': value['description'],
|
'key': value['key'],
|
'organization-only': value.get('organization-only', False),
|
}
|
for key, value in WebhookAction.ACTIONS.items()
|
}
|
organization_only = request.query_params.get('organization-only')
|
if organization_only is not None:
|
organization_only = organization_only == 'true'
|
result = {
|
key: value
|
for key, value in result.items()
|
if value.get('organization-only', False) == organization_only
|
}
|
return Response(data=result)
|