diff --git a/plane-src/apps/api/plane/app/views/workspace/invite.py b/plane-src/apps/api/plane/app/views/workspace/invite.py index ad09c73..815ca78 100644 --- a/plane-src/apps/api/plane/app/views/workspace/invite.py +++ b/plane-src/apps/api/plane/app/views/workspace/invite.py @@ -46,6 +46,12 @@ from plane.utils.workspace_bans import is_workspace_member_currently_banned, rel from .. import BaseViewSet +NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES = ( + WorkspaceMemberInvite.NODEDC_APPROVAL_NOT_REQUIRED, + WorkspaceMemberInvite.NODEDC_APPROVAL_APPROVED, +) + + class WorkspaceInvitationsViewset(BaseViewSet): """Endpoint for creating, listing and deleting workspaces""" @@ -156,9 +162,17 @@ class WorkspaceInvitationsViewset(BaseViewSet): approval_response = request_nodedc_workspace_invite_approval(request, workspace, invitation) approval_request = approval_response.get("taskerInviteRequest") if isinstance(approval_response, dict) else None approval_request_id = approval_request.get("id") if isinstance(approval_request, dict) else None + approval_request_status = approval_request.get("status") if isinstance(approval_request, dict) else None + update_fields = ["updated_at"] if approval_request_id: invitation.nodedc_approval_request_id = approval_request_id - invitation.save(update_fields=["nodedc_approval_request_id", "updated_at"]) + update_fields.append("nodedc_approval_request_id") + if approval_request_status == "approved": + invitation.nodedc_approval_status = WorkspaceMemberInvite.NODEDC_APPROVAL_APPROVED + invitation.nodedc_approval_decided_at = timezone.now() + update_fields.extend(["nodedc_approval_status", "nodedc_approval_decided_at"]) + if len(update_fields) > 1: + invitation.save(update_fields=update_fields) approved_requests.append(approval_request_id) invited_user = User.objects.filter(email__iexact=invitation.email, is_bot=False).first() publish_nodedc_workspace_event_on_commit( @@ -423,7 +437,13 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet): def get_queryset(self): return self.filter_queryset( - super().get_queryset().filter(email=self.request.user.email).select_related("workspace") + super() + .get_queryset() + .filter( + email=self.request.user.email, + nodedc_approval_status__in=NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES, + ) + .select_related("workspace") ) @invalidate_cache(path="/api/workspaces/", user=False) @@ -431,9 +451,17 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet): def create(self, request): invitations = request.data.get("invitations", []) workspace_invitations = WorkspaceMemberInvite.objects.filter( - pk__in=invitations, email=request.user.email + pk__in=invitations, + email=request.user.email, + nodedc_approval_status__in=NODEDC_ACCEPTABLE_WORKSPACE_INVITE_APPROVAL_STATUSES, ).order_by("-created_at") + if len(set(invitations)) != workspace_invitations.count(): + return Response( + {"error": "NODE.DC has not approved one or more workspace invitations yet"}, + status=status.HTTP_403_FORBIDDEN, + ) + # If the user is already a member of workspace and was deactivated then activate the user accepted_notifications = [] for invitation in workspace_invitations: