forked from github/plane
chore: Page auth and other improvements (#3011)
* chore: project query optimised * chore: page permissions changed
This commit is contained in:
parent
bd4b5040b2
commit
bffba6b9dc
@ -103,7 +103,7 @@ class InboxIssueAPIEndpoint(BaseAPIView):
|
|||||||
if inbox is None and not project.inbox_view:
|
if inbox is None and not project.inbox_view:
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"error": "Inbox is not enabled for this project enable it through the project settings"
|
"error": "Inbox is not enabled for this project enable it through the project's api"
|
||||||
},
|
},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
@ -177,7 +177,7 @@ class InboxIssueAPIEndpoint(BaseAPIView):
|
|||||||
if inbox is None and not project.inbox_view:
|
if inbox is None and not project.inbox_view:
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"error": "Inbox is not enabled for this project enable it through the project settings"
|
"error": "Inbox is not enabled for this project enable it through the project's api"
|
||||||
},
|
},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
@ -311,7 +311,7 @@ class InboxIssueAPIEndpoint(BaseAPIView):
|
|||||||
if inbox is None and not project.inbox_view:
|
if inbox is None and not project.inbox_view:
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
"error": "Inbox is not enabled for this project enable it through the project settings"
|
"error": "Inbox is not enabled for this project enable it through the project's api"
|
||||||
},
|
},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
@ -103,16 +103,19 @@ class ProjectListSerializer(DynamicBaseSerializer):
|
|||||||
members = serializers.SerializerMethodField()
|
members = serializers.SerializerMethodField()
|
||||||
|
|
||||||
def get_members(self, obj):
|
def get_members(self, obj):
|
||||||
project_members = ProjectMember.objects.filter(
|
project_members = getattr(obj, "members_list", None)
|
||||||
project_id=obj.id,
|
if project_members is not None:
|
||||||
is_active=True,
|
# Filter members by the project ID
|
||||||
).values(
|
return [
|
||||||
"id",
|
{
|
||||||
"member_id",
|
"id": member.id,
|
||||||
"member__display_name",
|
"member_id": member.member_id,
|
||||||
"member__avatar",
|
"member__display_name": member.member.display_name,
|
||||||
)
|
"member__avatar": member.member.avatar,
|
||||||
return list(project_members)
|
}
|
||||||
|
for member in project_members
|
||||||
|
]
|
||||||
|
return []
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Project
|
model = Project
|
||||||
|
@ -130,7 +130,6 @@ from .page import (
|
|||||||
PageFavoriteViewSet,
|
PageFavoriteViewSet,
|
||||||
PageLogEndpoint,
|
PageLogEndpoint,
|
||||||
SubPagesEndpoint,
|
SubPagesEndpoint,
|
||||||
CreateIssueFromBlockEndpoint,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .search import GlobalSearchEndpoint, IssueSearchEndpoint
|
from .search import GlobalSearchEndpoint, IssueSearchEndpoint
|
||||||
|
@ -22,6 +22,7 @@ from plane.db.models import (
|
|||||||
IssueAssignee,
|
IssueAssignee,
|
||||||
IssueActivity,
|
IssueActivity,
|
||||||
PageLog,
|
PageLog,
|
||||||
|
ProjectMember,
|
||||||
)
|
)
|
||||||
from plane.app.serializers import (
|
from plane.app.serializers import (
|
||||||
PageSerializer,
|
PageSerializer,
|
||||||
@ -140,12 +141,6 @@ class PageViewSet(BaseViewSet):
|
|||||||
pk=page_id, workspace__slug=slug, project_id=project_id
|
pk=page_id, workspace__slug=slug, project_id=project_id
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
# only the owner can lock the page
|
|
||||||
if request.user.id != page.owned_by_id:
|
|
||||||
return Response(
|
|
||||||
{"error": "Only the page owner can lock the page"},
|
|
||||||
)
|
|
||||||
|
|
||||||
page.is_locked = True
|
page.is_locked = True
|
||||||
page.save()
|
page.save()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
@ -155,12 +150,6 @@ class PageViewSet(BaseViewSet):
|
|||||||
pk=page_id, workspace__slug=slug, project_id=project_id
|
pk=page_id, workspace__slug=slug, project_id=project_id
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
# only the owner can unlock the page
|
|
||||||
if request.user.id != page.owned_by_id:
|
|
||||||
return Response(
|
|
||||||
{"error": "Only the page owner can unlock the page"},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
|
||||||
)
|
|
||||||
page.is_locked = False
|
page.is_locked = False
|
||||||
page.save()
|
page.save()
|
||||||
|
|
||||||
@ -175,10 +164,16 @@ class PageViewSet(BaseViewSet):
|
|||||||
def archive(self, request, slug, project_id, page_id):
|
def archive(self, request, slug, project_id, page_id):
|
||||||
page = Page.objects.get(pk=page_id, workspace__slug=slug, project_id=project_id)
|
page = Page.objects.get(pk=page_id, workspace__slug=slug, project_id=project_id)
|
||||||
|
|
||||||
if page.owned_by_id != request.user.id:
|
# only the owner and admin can archive the page
|
||||||
|
if (
|
||||||
|
ProjectMember.objects.filter(
|
||||||
|
project_id=project_id, member=request.user, is_active=True, role__gt=20
|
||||||
|
).exists()
|
||||||
|
or request.user.id != page.owned_by_id
|
||||||
|
):
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "Only the owner of the page can archive a page"},
|
{"error": "Only the owner and admin can archive the page"},
|
||||||
status=status.HTTP_204_NO_CONTENT,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
unarchive_archive_page_and_descendants(page_id, datetime.now())
|
unarchive_archive_page_and_descendants(page_id, datetime.now())
|
||||||
@ -188,9 +183,15 @@ class PageViewSet(BaseViewSet):
|
|||||||
def unarchive(self, request, slug, project_id, page_id):
|
def unarchive(self, request, slug, project_id, page_id):
|
||||||
page = Page.objects.get(pk=page_id, workspace__slug=slug, project_id=project_id)
|
page = Page.objects.get(pk=page_id, workspace__slug=slug, project_id=project_id)
|
||||||
|
|
||||||
if page.owned_by_id != request.user.id:
|
# only the owner and admin can un archive the page
|
||||||
|
if (
|
||||||
|
ProjectMember.objects.filter(
|
||||||
|
project_id=project_id, member=request.user, is_active=True, role__gt=20
|
||||||
|
).exists()
|
||||||
|
or request.user.id != page.owned_by_id
|
||||||
|
):
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "Only the owner of the page can unarchive a page"},
|
{"error": "Only the owner and admin can un archive the page"},
|
||||||
status=status.HTTP_400_BAD_REQUEST,
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -216,6 +217,18 @@ class PageViewSet(BaseViewSet):
|
|||||||
def destroy(self, request, slug, project_id, pk):
|
def destroy(self, request, slug, project_id, pk):
|
||||||
page = Page.objects.get(pk=pk, workspace__slug=slug, project_id=project_id)
|
page = Page.objects.get(pk=pk, workspace__slug=slug, project_id=project_id)
|
||||||
|
|
||||||
|
# only the owner and admin can delete the page
|
||||||
|
if (
|
||||||
|
ProjectMember.objects.filter(
|
||||||
|
project_id=project_id, member=request.user, is_active=True, role__gt=20
|
||||||
|
).exists()
|
||||||
|
or request.user.id != page.owned_by_id
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{"error": "Only the owner and admin can delete the page"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
if page.archived_at is None:
|
if page.archived_at is None:
|
||||||
return Response(
|
return Response(
|
||||||
{"error": "The page should be archived before deleting"},
|
{"error": "The page should be archived before deleting"},
|
||||||
@ -227,7 +240,6 @@ class PageViewSet(BaseViewSet):
|
|||||||
parent_id=pk, project_id=project_id, workspace__slug=slug
|
parent_id=pk, project_id=project_id, workspace__slug=slug
|
||||||
).update(parent=None)
|
).update(parent=None)
|
||||||
|
|
||||||
|
|
||||||
page.delete()
|
page.delete()
|
||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
@ -310,36 +322,6 @@ class PageLogEndpoint(BaseAPIView):
|
|||||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
class CreateIssueFromBlockEndpoint(BaseAPIView):
|
|
||||||
permission_classes = [
|
|
||||||
ProjectEntityPermission,
|
|
||||||
]
|
|
||||||
|
|
||||||
def post(self, request, slug, project_id, page_id):
|
|
||||||
page = Page.objects.get(
|
|
||||||
workspace__slug=slug,
|
|
||||||
project_id=project_id,
|
|
||||||
pk=page_id,
|
|
||||||
)
|
|
||||||
issue = Issue.objects.create(
|
|
||||||
name=request.data.get("name"),
|
|
||||||
project_id=project_id,
|
|
||||||
)
|
|
||||||
_ = IssueAssignee.objects.create(
|
|
||||||
issue=issue, assignee=request.user, project_id=project_id
|
|
||||||
)
|
|
||||||
|
|
||||||
_ = IssueActivity.objects.create(
|
|
||||||
issue=issue,
|
|
||||||
actor=request.user,
|
|
||||||
project_id=project_id,
|
|
||||||
comment=f"created the issue from {page.name} block",
|
|
||||||
verb="created",
|
|
||||||
)
|
|
||||||
|
|
||||||
return Response(IssueLiteSerializer(issue).data, status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
|
|
||||||
class SubPagesEndpoint(BaseAPIView):
|
class SubPagesEndpoint(BaseAPIView):
|
||||||
permission_classes = [
|
permission_classes = [
|
||||||
ProjectEntityPermission,
|
ProjectEntityPermission,
|
||||||
|
@ -165,6 +165,7 @@ class ProjectViewSet(WebhookMixin, BaseViewSet):
|
|||||||
workspace__slug=slug,
|
workspace__slug=slug,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
).select_related("member"),
|
).select_related("member"),
|
||||||
|
to_attr='members_list'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.order_by("sort_order", "name")
|
.order_by("sort_order", "name")
|
||||||
|
Loading…
Reference in New Issue
Block a user