ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: блокировка и удаление участников воркспейса в God Mode

This commit is contained in:
DCCONSTRUCTIONS
2026-04-29 01:15:17 +03:00
parent 7bf416ec1f
commit 4ba3aab02e
19 changed files with 598 additions and 42 deletions
@@ -32,6 +32,7 @@ from plane.db.models import (
)
from plane.db.models.project import ProjectNetwork
from plane.utils.host import base_host
from plane.utils.workspace_bans import is_workspace_member_currently_banned, release_workspace_member_ban
class ProjectInvitationsViewset(BaseViewSet):
@@ -195,7 +196,19 @@ class ProjectJoinEndpoint(BaseAPIView):
)
if project_invite.responded_at is None:
project_invite.accepted = request.data.get("accepted", False)
accepted = request.data.get("accepted", False)
if accepted:
user = User.objects.filter(email=email).first()
workspace_member = WorkspaceMember.objects.filter(workspace__slug=slug, member=user).first()
if is_workspace_member_currently_banned(workspace_member):
return Response(
{"error": "You are banned from this workspace"},
status=status.HTTP_403_FORBIDDEN,
)
if workspace_member is not None and workspace_member.is_banned:
release_workspace_member_ban(workspace_member)
project_invite.accepted = accepted
project_invite.responded_at = timezone.now()
project_invite.save()
@@ -50,6 +50,7 @@ from plane.bgtasks.event_tracking_task import track_event
from plane.utils.url import contains_url
from plane.utils.analytics_events import WORKSPACE_CREATED, WORKSPACE_DELETED
from plane.utils.csv_utils import sanitize_csv_row
from plane.utils.workspace_bans import release_expired_workspace_bans
class WorkSpaceViewSet(BaseViewSet):
@@ -207,6 +208,8 @@ class UserWorkSpacesEndpoint(BaseAPIView):
use_read_replica = True
def get(self, request):
release_expired_workspace_bans(member=request.user)
fields = [field for field in request.GET.get("fields", "").split(",") if field]
member_count = (
WorkspaceMember.objects.filter(workspace=OuterRef("id"), member__is_bot=False, is_active=True)
@@ -31,6 +31,7 @@ from plane.db.models import User, Workspace, WorkspaceMember, WorkspaceMemberInv
from plane.utils.cache import invalidate_cache, invalidate_cache_directly
from plane.utils.host import base_host
from plane.utils.analytics_events import USER_JOINED_WORKSPACE, USER_INVITED_TO_WORKSPACE
from plane.utils.workspace_bans import is_workspace_member_currently_banned, release_workspace_member_ban
from .. import BaseViewSet
@@ -85,6 +86,17 @@ class WorkspaceInvitationsViewset(BaseViewSet):
status=status.HTTP_400_BAD_REQUEST,
)
banned_workspace_members = WorkspaceMember.objects.filter(
workspace_id=workspace.id,
member__email__in=[email.get("email") for email in emails],
is_banned=True,
).select_related("member")
if any(is_workspace_member_currently_banned(workspace_member) for workspace_member in banned_workspace_members):
return Response(
{"error": "Some users are banned from this workspace"},
status=status.HTTP_400_BAD_REQUEST,
)
workspace_invitations = []
for email in emails:
try:
@@ -174,7 +186,23 @@ class WorkspaceJoinEndpoint(BaseAPIView):
# If already responded then return error
if workspace_invite.responded_at is None:
workspace_invite.accepted = request.data.get("accepted", False)
accepted = request.data.get("accepted", False)
if accepted:
user = User.objects.filter(email=workspace_invite.email).first()
workspace_member = (
WorkspaceMember.objects.filter(workspace=workspace_invite.workspace, member=user).first()
if user is not None
else None
)
if is_workspace_member_currently_banned(workspace_member):
return Response(
{"error": "You are banned from this workspace"},
status=status.HTTP_403_FORBIDDEN,
)
if workspace_member is not None and workspace_member.is_banned:
release_workspace_member_ban(workspace_member)
workspace_invite.accepted = accepted
workspace_invite.responded_at = timezone.now()
workspace_invite.save()
@@ -260,6 +288,17 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet):
# If the user is already a member of workspace and was deactivated then activate the user
for invitation in workspace_invitations:
workspace_member = WorkspaceMember.objects.filter(
workspace_id=invitation.workspace_id, member=request.user
).first()
if is_workspace_member_currently_banned(workspace_member):
return Response(
{"error": "You are banned from one or more invited workspaces"},
status=status.HTTP_403_FORBIDDEN,
)
if workspace_member is not None and workspace_member.is_banned:
release_workspace_member_ban(workspace_member)
invalidate_cache_directly(
path=f"/api/workspaces/{invitation.workspace.slug}/members/",
user=False,