From 2c8c139c6276641a8b9322f848fb28d934416a50 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:59:50 +0530 Subject: [PATCH] [WEB - 898] fix: external webhooks (#4119) * fix: project webhooks * fix: issue and issue comment webhooks * dev: remove module and cycle issue webhooks * fix: linting errors --- apiserver/plane/api/serializers/issue.py | 4 +-- apiserver/plane/api/serializers/user.py | 2 ++ apiserver/plane/api/urls/project.py | 2 +- apiserver/plane/api/views/base.py | 8 ++++- apiserver/plane/api/views/issue.py | 2 -- apiserver/plane/api/views/project.py | 40 ++++++++++++---------- apiserver/plane/app/permissions/project.py | 4 +-- apiserver/plane/bgtasks/webhook_task.py | 13 ++----- 8 files changed, 37 insertions(+), 38 deletions(-) diff --git a/apiserver/plane/api/serializers/issue.py b/apiserver/plane/api/serializers/issue.py index c78b109ef..c40f56ccc 100644 --- a/apiserver/plane/api/serializers/issue.py +++ b/apiserver/plane/api/serializers/issue.py @@ -79,7 +79,7 @@ class IssueSerializer(BaseSerializer): parsed_str = html.tostring(parsed, encoding="unicode") data["description_html"] = parsed_str - except Exception as e: + except Exception: raise serializers.ValidationError("Invalid HTML passed") # Validate assignees are from project @@ -366,7 +366,7 @@ class IssueCommentSerializer(BaseSerializer): parsed_str = html.tostring(parsed, encoding="unicode") data["comment_html"] = parsed_str - except Exception as e: + except Exception: raise serializers.ValidationError("Invalid HTML passed") return data diff --git a/apiserver/plane/api/serializers/user.py b/apiserver/plane/api/serializers/user.py index fe50021b5..ea50440e0 100644 --- a/apiserver/plane/api/serializers/user.py +++ b/apiserver/plane/api/serializers/user.py @@ -1,5 +1,6 @@ # Module imports from plane.db.models import User + from .base import BaseSerializer @@ -12,5 +13,6 @@ class UserLiteSerializer(BaseSerializer): "last_name", "avatar", "display_name", + "email", ] read_only_fields = fields diff --git a/apiserver/plane/api/urls/project.py b/apiserver/plane/api/urls/project.py index 490371cca..5efb85bb0 100644 --- a/apiserver/plane/api/urls/project.py +++ b/apiserver/plane/api/urls/project.py @@ -12,7 +12,7 @@ urlpatterns = [ name="project", ), path( - "workspaces//projects//", + "workspaces//projects//", ProjectAPIEndpoint.as_view(), name="project", ), diff --git a/apiserver/plane/api/views/base.py b/apiserver/plane/api/views/base.py index 0cf5e8731..13047eb78 100644 --- a/apiserver/plane/api/views/base.py +++ b/apiserver/plane/api/views/base.py @@ -7,6 +7,7 @@ import zoneinfo from django.conf import settings from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import IntegrityError +from django.urls import resolve from django.utils import timezone from rest_framework import status from rest_framework.permissions import IsAuthenticated @@ -165,7 +166,12 @@ class BaseAPIView(TimezoneMixin, APIView, BasePaginator): @property def project_id(self): - return self.kwargs.get("project_id", None) + project_id = self.kwargs.get("project_id", None) + if project_id: + return project_id + + if resolve(self.request.path_info).url_name == "project": + return self.kwargs.get("pk", None) @property def fields(self): diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 4b59dc020..53998c49f 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -308,8 +308,6 @@ class IssueAPIEndpoint(WebhookMixin, BaseAPIView): actor_id=str(request.user.id), issue_id=str(pk), project_id=str(project_id), - external_id__isnull=False, - external_source__isnull=False, current_instance=current_instance, epoch=int(timezone.now().timestamp()), ) diff --git a/apiserver/plane/api/views/project.py b/apiserver/plane/api/views/project.py index e0bce5514..885b7dda5 100644 --- a/apiserver/plane/api/views/project.py +++ b/apiserver/plane/api/views/project.py @@ -1,27 +1,29 @@ # Django imports -from django.utils import timezone from django.db import IntegrityError -from django.db.models import Exists, OuterRef, Q, F, Func, Subquery, Prefetch +from django.db.models import Exists, F, Func, OuterRef, Prefetch, Q, Subquery +from django.utils import timezone # Third party imports from rest_framework import status from rest_framework.response import Response from rest_framework.serializers import ValidationError +from plane.api.serializers import ProjectSerializer +from plane.app.permissions import ProjectBasePermission + # Module imports from plane.db.models import ( - Workspace, - Project, - ProjectMember, - ProjectDeployBoard, - State, Cycle, - Module, - IssueProperty, Inbox, + IssueProperty, + Module, + Project, + ProjectDeployBoard, + ProjectMember, + State, + Workspace, ) -from plane.app.permissions import ProjectBasePermission -from plane.api.serializers import ProjectSerializer + from .base import BaseAPIView, WebhookMixin @@ -103,8 +105,8 @@ class ProjectAPIEndpoint(WebhookMixin, BaseAPIView): .distinct() ) - def get(self, request, slug, project_id=None): - if project_id is None: + def get(self, request, slug, pk=None): + if pk is None: sort_order_query = ProjectMember.objects.filter( member=request.user, project_id=OuterRef("pk"), @@ -135,7 +137,7 @@ class ProjectAPIEndpoint(WebhookMixin, BaseAPIView): expand=self.expand, ).data, ) - project = self.get_queryset().get(workspace__slug=slug, pk=project_id) + project = self.get_queryset().get(workspace__slug=slug, pk=pk) serializer = ProjectSerializer( project, fields=self.fields, @@ -259,10 +261,10 @@ class ProjectAPIEndpoint(WebhookMixin, BaseAPIView): status=status.HTTP_410_GONE, ) - def patch(self, request, slug, project_id=None): + def patch(self, request, slug, pk): try: workspace = Workspace.objects.get(slug=slug) - project = Project.objects.get(pk=project_id) + project = Project.objects.get(pk=pk) if project.archived_at: return Response( @@ -291,7 +293,7 @@ class ProjectAPIEndpoint(WebhookMixin, BaseAPIView): name="Triage", group="backlog", description="Default state for managing all Inbox Issues", - project_id=project_id, + project_id=pk, color="#ff7700", ) @@ -322,8 +324,8 @@ class ProjectAPIEndpoint(WebhookMixin, BaseAPIView): status=status.HTTP_410_GONE, ) - def delete(self, request, slug, project_id): - project = Project.objects.get(pk=project_id, workspace__slug=slug) + def delete(self, request, slug, pk): + project = Project.objects.get(pk=pk, workspace__slug=slug) project.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/apiserver/plane/app/permissions/project.py b/apiserver/plane/app/permissions/project.py index 80775cbf6..2ba2a1b64 100644 --- a/apiserver/plane/app/permissions/project.py +++ b/apiserver/plane/app/permissions/project.py @@ -1,8 +1,8 @@ # Third Party imports -from rest_framework.permissions import BasePermission, SAFE_METHODS +from rest_framework.permissions import SAFE_METHODS, BasePermission # Module import -from plane.db.models import WorkspaceMember, ProjectMember +from plane.db.models import ProjectMember, WorkspaceMember # Permission Mappings Admin = 20 diff --git a/apiserver/plane/bgtasks/webhook_task.py b/apiserver/plane/bgtasks/webhook_task.py index 6537e3b21..5ee0244c7 100644 --- a/apiserver/plane/bgtasks/webhook_task.py +++ b/apiserver/plane/bgtasks/webhook_task.py @@ -202,16 +202,7 @@ def send_webhook(event, payload, kw, action, slug, bulk, current_site): if webhooks: if action in ["POST", "PATCH"]: if bulk and event in ["cycle_issue", "module_issue"]: - event_data = IssueExpandSerializer( - Issue.objects.filter( - pk__in=[ - str(event.get("issue")) for event in payload - ] - ).prefetch_related("issue_cycle", "issue_module"), - many=True, - ).data - event = "issue" - action = "PATCH" + return else: event_data = [ get_model_data( @@ -219,7 +210,7 @@ def send_webhook(event, payload, kw, action, slug, bulk, current_site): event_id=( payload.get("id") if isinstance(payload, dict) - else None + else kw.get("pk") ), many=False, )