[WEB-2126] chore: guest and viewer role permission (#5347)

* chore: user store code refactor

* chore: general unauthorized screen asset added

* chore: workspace setting sidebar options updated for guest and viewer

* chore: NotAuthorizedView component code updated

* chore: project setting layout code refactor

* chore: workspace setting members and exports page permission validation added

* chore: workspace members and exports settings page improvement

* chore: project invite modal updated

* chore: workspace setting unauthorized access empty state

* chore: workspace setting unauthorized access empty state

* chore: project settings sidebar permission updated

* fix: project settings user role permission updated

* chore: app sidebar role permission validation updated

* chore: app sidebar role permission validation

* chore: disabled page empty state validation

* chore: app sidebar add project improvement

* chore: guest role changes

* fix: user favorite

* chore: changed pages permission

* chore: guest role changes

* fix: app sidebar project item permission

* fix: project setting empty state flicker

* fix: workspace setting empty state flicker

* chore: granted notification permission to viewer

* chore: project invite and edit validation updated

* chore: favorite validation added for guest and viewer role

* chore: create view validation updated

* chore: views permission changes

* chore: create view empty state validation updated

* chore: created ENUM for permissions

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com>
This commit is contained in:
Anmol Singh Bhatia 2024-08-16 16:35:05 +05:30 committed by GitHub
parent d60e988ca1
commit 0a1c656865
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
62 changed files with 957 additions and 590 deletions

View file

@ -16,7 +16,9 @@ from rest_framework.response import Response
# Module imports
from ..base import BaseViewSet
from plane.app.permissions import ProjectBasePermission, ProjectLitePermission
from plane.app.permissions import (
allow_permission, ROLE
)
from plane.db.models import (
Inbox,
InboxIssue,
@ -39,9 +41,6 @@ from plane.bgtasks.issue_activities_task import issue_activity
class InboxViewSet(BaseViewSet):
permission_classes = [
ProjectBasePermission,
]
serializer_class = InboxSerializer
model = Inbox
@ -63,6 +62,7 @@ class InboxViewSet(BaseViewSet):
.select_related("workspace", "project")
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER])
def list(self, request, slug, project_id):
inbox = self.get_queryset().first()
return Response(
@ -70,9 +70,11 @@ class InboxViewSet(BaseViewSet):
status=status.HTTP_200_OK,
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER])
def perform_create(self, serializer):
serializer.save(project_id=self.kwargs.get("project_id"))
@allow_permission([ROLE.ADMIN, ROLE.MEMBER])
def destroy(self, request, slug, project_id, pk):
inbox = Inbox.objects.filter(
workspace__slug=slug, project_id=project_id, pk=pk
@ -88,9 +90,6 @@ class InboxViewSet(BaseViewSet):
class InboxIssueViewSet(BaseViewSet):
permission_classes = [
ProjectLitePermission,
]
serializer_class = InboxIssueSerializer
model = InboxIssue
@ -168,6 +167,7 @@ class InboxIssueViewSet(BaseViewSet):
)
).distinct()
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.VIEWER, ROLE.GUEST])
def list(self, request, slug, project_id):
inbox_id = Inbox.objects.filter(
workspace__slug=slug, project_id=project_id
@ -201,6 +201,14 @@ class InboxIssueViewSet(BaseViewSet):
if inbox_status:
inbox_issue = inbox_issue.filter(status__in=inbox_status)
if ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=5,
is_active=True,
).exists():
inbox_issue = inbox_issue.filter(created_by=request.user)
return self.paginate(
request=request,
queryset=(inbox_issue),
@ -210,6 +218,7 @@ class InboxIssueViewSet(BaseViewSet):
).data,
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def create(self, request, slug, project_id):
if not request.data.get("issue", {}).get("name", False):
return Response(
@ -312,12 +321,13 @@ class InboxIssueViewSet(BaseViewSet):
serializer.errors, status=status.HTTP_400_BAD_REQUEST
)
def partial_update(self, request, slug, project_id, issue_id):
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def partial_update(self, request, slug, project_id, pk):
inbox_id = Inbox.objects.filter(
workspace__slug=slug, project_id=project_id
).first()
inbox_issue = InboxIssue.objects.get(
issue_id=issue_id,
issue_id=pk,
workspace__slug=slug,
project_id=project_id,
inbox_id=inbox_id,
@ -458,7 +468,7 @@ class InboxIssueViewSet(BaseViewSet):
request.data, cls=DjangoJSONEncoder
),
actor_id=str(request.user.id),
issue_id=str(issue_id),
issue_id=str(pk),
project_id=str(project_id),
current_instance=current_instance,
epoch=int(timezone.now().timestamp()),
@ -493,7 +503,7 @@ class InboxIssueViewSet(BaseViewSet):
)
.get(
inbox_id=inbox_id.id,
issue_id=issue_id,
issue_id=pk,
project_id=project_id,
)
)
@ -506,7 +516,12 @@ class InboxIssueViewSet(BaseViewSet):
serializer = InboxIssueDetailSerializer(inbox_issue).data
return Response(serializer, status=status.HTTP_200_OK)
def retrieve(self, request, slug, project_id, issue_id):
@allow_permission(
allowed_roles=[ROLE.ADMIN, ROLE.MEMBER, ROLE.VIEWER],
creator=True,
model=Issue,
)
def retrieve(self, request, slug, project_id, pk):
inbox_id = Inbox.objects.filter(
workspace__slug=slug, project_id=project_id
).first()
@ -534,9 +549,7 @@ class InboxIssueViewSet(BaseViewSet):
Value([], output_field=ArrayField(UUIDField())),
),
)
.get(
inbox_id=inbox_id.id, issue_id=issue_id, project_id=project_id
)
.get(inbox_id=inbox_id.id, issue_id=pk, project_id=project_id)
)
issue = InboxIssueDetailSerializer(inbox_issue).data
return Response(
@ -544,12 +557,13 @@ class InboxIssueViewSet(BaseViewSet):
status=status.HTTP_200_OK,
)
def destroy(self, request, slug, project_id, issue_id):
@allow_permission(allowed_roles=[ROLE.ADMIN], creator=True, model=Issue)
def destroy(self, request, slug, project_id, pk):
inbox_id = Inbox.objects.filter(
workspace__slug=slug, project_id=project_id
).first()
inbox_issue = InboxIssue.objects.get(
issue_id=issue_id,
issue_id=pk,
workspace__slug=slug,
project_id=project_id,
inbox_id=inbox_id,
@ -559,21 +573,8 @@ class InboxIssueViewSet(BaseViewSet):
if inbox_issue.status in [-2, -1, 0, 2]:
# Delete the issue also
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
workspace__slug=slug, project_id=project_id, pk=pk
).first()
if issue.created_by_id != request.user.id and (
not ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role=20,
project_id=project_id,
is_active=True,
).exists()
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
issue.delete()
inbox_issue.delete()