[WEB-3600] fix: private project join issue (#6799)
* fix: private project join issue * chore: return network value * fix: refactor * fix: refactor * fix: type * chore: added restricition for private projects * chore: removed extra validations * chore: added value to access enum --------- Co-authored-by: sangeethailango <sangeethailango21@gmail.com> Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
This commit is contained in:
parent
cebd0b3599
commit
41447e566a
6 changed files with 48 additions and 10 deletions
|
|
@ -179,6 +179,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
"inbox_view",
|
||||
"guest_view_all_features",
|
||||
"project_lead",
|
||||
"network",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"created_by",
|
||||
|
|
|
|||
|
|
@ -16,17 +16,17 @@ from rest_framework.permissions import AllowAny
|
|||
# Module imports
|
||||
from .base import BaseViewSet, BaseAPIView
|
||||
from plane.app.serializers import ProjectMemberInviteSerializer
|
||||
|
||||
from plane.app.permissions import allow_permission, ROLE
|
||||
|
||||
from plane.db.models import (
|
||||
ProjectMember,
|
||||
Workspace,
|
||||
ProjectMemberInvite,
|
||||
User,
|
||||
WorkspaceMember,
|
||||
Project,
|
||||
IssueUserProperty,
|
||||
)
|
||||
from plane.db.models.project import ProjectNetwork
|
||||
|
||||
|
||||
class ProjectInvitationsViewset(BaseViewSet):
|
||||
|
|
@ -128,6 +128,7 @@ class UserProjectInvitationsViewset(BaseViewSet):
|
|||
.select_related("workspace", "workspace__owner", "project")
|
||||
)
|
||||
|
||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER], level="WORKSPACE")
|
||||
def create(self, request, slug):
|
||||
project_ids = request.data.get("project_ids", [])
|
||||
|
||||
|
|
@ -136,11 +137,20 @@ class UserProjectInvitationsViewset(BaseViewSet):
|
|||
member=request.user, workspace__slug=slug, is_active=True
|
||||
)
|
||||
|
||||
if workspace_member.role not in [ROLE.ADMIN.value, ROLE.MEMBER.value]:
|
||||
return Response(
|
||||
{"error": "You do not have permission to join the project"},
|
||||
status=status.HTTP_403_FORBIDDEN,
|
||||
)
|
||||
# Get all the projects
|
||||
projects = Project.objects.filter(
|
||||
id__in=project_ids, workspace__slug=slug
|
||||
).only("id", "network")
|
||||
# Check if user has permission to join each project
|
||||
for project in projects:
|
||||
if (
|
||||
project.network == ProjectNetwork.SECRET.value
|
||||
and workspace_member.role != ROLE.ADMIN.value
|
||||
):
|
||||
return Response(
|
||||
{"error": "Only workspace admins can join private project"},
|
||||
status=status.HTTP_403_FORBIDDEN,
|
||||
)
|
||||
|
||||
workspace_role = workspace_member.role
|
||||
workspace = workspace_member.workspace
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# Python imports
|
||||
import pytz
|
||||
from uuid import uuid4
|
||||
from enum import Enum
|
||||
|
||||
# Django imports
|
||||
from django.conf import settings
|
||||
|
|
@ -17,6 +18,15 @@ from .base import BaseModel
|
|||
ROLE_CHOICES = ((20, "Admin"), (15, "Member"), (5, "Guest"))
|
||||
|
||||
|
||||
class ProjectNetwork(Enum):
|
||||
SECRET = 0
|
||||
PUBLIC = 2
|
||||
|
||||
@classmethod
|
||||
def choices(cls):
|
||||
return [(0, "Secret"), (2, "Public")]
|
||||
|
||||
|
||||
def get_default_props():
|
||||
return {
|
||||
"filters": {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ export enum EUserPermissions {
|
|||
|
||||
export type TUserPermissions = EUserPermissions.ADMIN | EUserPermissions.MEMBER | EUserPermissions.GUEST;
|
||||
|
||||
// project network
|
||||
export enum EProjectNetwork {
|
||||
PRIVATE = 0,
|
||||
PUBLIC = 2,
|
||||
}
|
||||
|
||||
// project pages
|
||||
export enum EPageAccess {
|
||||
PUBLIC = 0,
|
||||
|
|
|
|||
2
packages/types/src/project/projects.d.ts
vendored
2
packages/types/src/project/projects.d.ts
vendored
|
|
@ -27,6 +27,7 @@ export interface IPartialProject {
|
|||
inbox_view: boolean;
|
||||
guest_view_all_features?: boolean;
|
||||
project_lead?: IUserLite | string | null;
|
||||
network?: number;
|
||||
// Timestamps
|
||||
created_at?: Date;
|
||||
updated_at?: Date;
|
||||
|
|
@ -50,7 +51,6 @@ export interface IProject extends IPartialProject {
|
|||
anchor?: string | null;
|
||||
is_favorite?: boolean;
|
||||
members?: string[];
|
||||
network?: number;
|
||||
timezone?: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import useSWR from "swr";
|
|||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// components
|
||||
import { EProjectNetwork } from "@plane/types/src/enums";
|
||||
import { JoinProject } from "@/components/auth-screens";
|
||||
import { LogoSpinner } from "@/components/common";
|
||||
import { ComicBoxButton, DetailedEmptyState } from "@/components/empty-state";
|
||||
|
|
@ -70,6 +71,11 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
|||
workspaceSlug.toString(),
|
||||
projectId?.toString()
|
||||
);
|
||||
const isWorkspaceAdmin = allowPermissions(
|
||||
[EUserPermissions.ADMIN],
|
||||
EUserPermissionsLevel.WORKSPACE,
|
||||
workspaceSlug.toString()
|
||||
);
|
||||
|
||||
// Initialize module timeline chart
|
||||
useEffect(() => {
|
||||
|
|
@ -168,10 +174,15 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
|||
);
|
||||
|
||||
// check if the user don't have permission to access the project
|
||||
if (projectExists && projectId && hasPermissionToCurrentProject === false) return <JoinProject />;
|
||||
if (
|
||||
((projectExists?.network && projectExists?.network !== EProjectNetwork.PRIVATE) || isWorkspaceAdmin) &&
|
||||
projectId &&
|
||||
hasPermissionToCurrentProject === false
|
||||
)
|
||||
return <JoinProject />;
|
||||
|
||||
// check if the project info is not found.
|
||||
if (loader === "loaded" && !projectExists && projectId && !!hasPermissionToCurrentProject === false)
|
||||
if (loader === "loaded" && projectId && !!hasPermissionToCurrentProject === false)
|
||||
return (
|
||||
<div className="grid h-screen place-items-center bg-custom-background-100">
|
||||
<DetailedEmptyState
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue