Skip to content

Conversation

@NarayanBavisetti
Copy link
Collaborator

@NarayanBavisetti NarayanBavisetti commented Jul 25, 2024

chore:

  • now only admins or the creator of the issue, cycle, module,view, page can perform the delete operation.

Issue Link: WEB-2043

Summary by CodeRabbit

  • New Features

    • Enhanced access control for the deletion of cycles, inbox issues, modules, issues, and views, restricting permissions to admins and creators.
    • Implemented role-based checks for deleting pages, ensuring only authorized users can perform deletions.
  • Bug Fixes

    • Resolved issues where unauthorized users could delete cycles, inbox issues, modules, issues, and views.
  • Documentation

    • Updated import statements to include ProjectMember and WorkspaceMember for permission checks across various views.
  • Refactor

    • Streamlined deletion logic for improved readability and maintainability across multiple components.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 25, 2024

Walkthrough

The recent changes bolster security across various API views by implementing stricter permission checks for deleting cycles, issues, modules, and pages. Users must now be either admins or creators to perform deletions, ensuring that only authorized individuals can modify project components. This enhances the overall integrity of the system while streamlining the access control logic.

Changes

File Path Change Summary
apiserver/plane/api/views/cycle.py Added permission check in delete method for cycle deletion based on user role (admin or creator).
apiserver/plane/api/views/inbox.py Refactored delete method to enforce role-based deletion for inbox issues.
apiserver/plane/api/views/issue.py Updated post and delete methods to include permission checks for issue management.
apiserver/plane/api/views/module.py Introduced permission check in delete method for module deletion based on user roles and creator status.
apiserver/plane/app/views/cycle/base.py Added permission checks in destroy method for cycle deletions based on user roles.
apiserver/plane/app/views/inbox/base.py Restructured destroy method to enforce role-based deletion of inbox issues.
apiserver/plane/app/views/issue/base.py Enhanced destroy and delete methods with stricter access checks for issues.
apiserver/plane/app/views/issue/draft.py Added role-based access checks for issue deletion in destroy method.
apiserver/plane/app/views/module/base.py Introduced role checks in destroy method for module deletion.
apiserver/plane/app/views/page/base.py Added permission validation in destroy method for page deletions.
apiserver/plane/app/views/view/base.py Implemented permission checks in destroy methods for workspace and project views, enhancing security.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant API
    participant ProjectMember
    participant WorkspaceMember

    User->>API: Request delete action
    API->>ProjectMember: Check user role and status
    ProjectMember-->>API: Return role status
    alt Authorized
        API->>Database: Delete item
        Database-->>API: Confirm deletion
        API-->>User: Return success response
    else Not Authorized
        API-->>User: Return 403 Forbidden
    end

    User->>API: Request delete action on workspace
    API->>WorkspaceMember: Check membership and role
    WorkspaceMember-->>API: Return membership status
    alt Authorized
        API->>Database: Delete workspace
        Database-->>API: Confirm deletion
        API-->>User: Return success response
    else Not Authorized
        API-->>User: Return 403 Forbidden
    end
Loading

🐇 In a world where permissions reign,
A check was added, easing the strain.
Admins and creators lead the way,
Deleting items, come what may!
Security's tighter, the code more bright,
Hooray for changes that feel just right! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@NarayanBavisetti NarayanBavisetti marked this pull request as ready for review July 25, 2024 13:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Outside diff range, codebase verification and nitpick comments (3)
apiserver/plane/api/views/cycle.py (1)

380-383: Improve error message clarity.

The error message should specify that only admins or the creator can delete the cycle, not the issue.

-                {"error": "Only admin or creator can delete the issue"},
+                {"error": "Only admin or creator can delete the cycle"},
apiserver/plane/app/views/cycle/base.py (2)

1056-1059: Improve error message clarity.

The error message should specify that only admins or the owner can delete the cycle, not the view.

-                {"error": "Only admin or owner can delete the view"},
+                {"error": "Only admin or owner can delete the cycle"},

1043-1045: Ensure the cycle object retrieval handles non-existent cycles.

The destroy method in apiserver/plane/app/views/cycle/base.py does not handle cases where the cycle does not exist, which can lead to unhandled exceptions. Consider adding exception handling for DoesNotExist exceptions to improve robustness.

  • apiserver/plane/app/views/cycle/base.py:1043-1045
Analysis chain

Ensure the cycle object is retrieved correctly.

The retrieval of the cycle object appears to be correct, but ensure that it handles cases where the cycle does not exist.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the cycle object retrieval handles non-existent cycles.

# Test: Search for the usage of `Cycle.objects.get` in the `destroy` method.
rg --type python -A 5 $'Cycle.objects.get'

Length of output: 72


Script:

#!/bin/bash
# Description: Verify that the cycle object retrieval handles non-existent cycles.

# Test: Search for the usage of `Cycle.objects.get` in the `destroy` method.
rg --type py -A 5 'Cycle.objects.get'

Length of output: 4031


Script:

#!/bin/bash
# Description: Verify that the cycle object retrieval handles non-existent cycles by checking for exception handling.

# Test: Search for exception handling in the `destroy` method in the target file.
rg --type py -A 10 'def destroy' apiserver/plane/app/views/cycle/base.py

Length of output: 861

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 43103a1 and d690923.

Files selected for processing (11)
  • apiserver/plane/api/views/cycle.py (2 hunks)
  • apiserver/plane/api/views/inbox.py (1 hunks)
  • apiserver/plane/api/views/issue.py (2 hunks)
  • apiserver/plane/api/views/module.py (2 hunks)
  • apiserver/plane/app/views/cycle/base.py (2 hunks)
  • apiserver/plane/app/views/inbox/base.py (1 hunks)
  • apiserver/plane/app/views/issue/base.py (3 hunks)
  • apiserver/plane/app/views/issue/draft.py (2 hunks)
  • apiserver/plane/app/views/module/base.py (2 hunks)
  • apiserver/plane/app/views/page/base.py (1 hunks)
  • apiserver/plane/app/views/view/base.py (2 hunks)
Additional comments not posted (6)
apiserver/plane/app/views/issue/base.py (1)

621-632: Ensure consistent permission checks.

The permission checks are duplicated. The first check verifies if the user is an admin, while the second check verifies if the user is an admin again but with different roles. Consolidate these checks into a single block to avoid redundancy and potential inconsistencies.

-        if ProjectMember.objects.filter(
-            workspace__slug=slug,
-            member=request.user,
-            role=20,
-            project_id=project_id,
-            is_active=True,
-        ).exists():
-            return Response(
-                {"error": "Only admin can perform this action"},
-                status=status.HTTP_403_FORBIDDEN,
-            )
+        if 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 can perform this action"},
+                status=status.HTTP_403_FORBIDDEN,
+            )

Likely invalid or redundant comment.

apiserver/plane/api/views/module.py (1)

269-282: Ensure correct permission check logic.

The permission check logic ensures that only admins or the creator can delete the module. This enhances security by restricting deletion permissions to authorized users.

apiserver/plane/app/views/module/base.py (1)

741-755: Ensure correct permission check logic.

The permission check logic ensures that only admins or the creator can delete the module. This enhances security by restricting deletion permissions to authorized users.

apiserver/plane/api/views/issue.py (1)

392-405: Ensure correct permission check logic.

The permission check logic ensures that only admins or the creator can delete the issue. This enhances security by restricting deletion permissions to authorized users.

apiserver/plane/api/views/cycle.py (1)

367-369: Ensure the cycle object is retrieved correctly.

The retrieval of the cycle object appears to be correct, but ensure that it handles cases where the cycle does not exist.

apiserver/plane/app/views/cycle/base.py (1)

1046-1059: Correctness of permission check logic.

The permission check logic correctly ensures that only admins or the owner can delete a cycle. However, the condition and cycle.owned_by != request.user should be or cycle.owned_by != request.user to ensure proper validation.

-            ).exists()
-            and cycle.owned_by != request.user
+            ).exists()
+            or cycle.owned_by != request.user

Likely invalid or redundant comment.

Comment on lines 336 to 349
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and page.owned_by != request.user
):
return Response(
{"error": "Only admin or owner can delete the page"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent permission checks.

The permission checks are duplicated. The first check verifies if the user is an admin or owner, while the second check verifies if the user is an admin or owner again but with different roles. Consolidate these checks into a single block to avoid redundancy and potential inconsistencies.

-        if (
-            ProjectMember.objects.filter(
-                workspace__slug=slug,
-                member=request.user,
-                role__in=[15, 10, 5],
-                project_id=project_id,
-                is_active=True,
-            ).exists()
-            and page.owned_by != request.user
-        ):
-            return Response(
-                {"error": "Only admin or owner can delete the page"},
-                status=status.HTTP_403_FORBIDDEN,
-            )
+        if not (
+            ProjectMember.objects.filter(
+                workspace__slug=slug,
+                member=request.user,
+                role__in=[15, 10, 5],
+                project_id=project_id,
+                is_active=True,
+            ).exists()
+            or request.user.id == page.owned_by_id
+        ):
+            return Response(
+                {"error": "Only admin or owner can delete the page"},
+                status=status.HTTP_403_FORBIDDEN,
+            )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and page.owned_by != request.user
):
return Response(
{"error": "Only admin or owner can delete the page"},
status=status.HTTP_403_FORBIDDEN,
)
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
or request.user.id == page.owned_by_id
):
return Response(
{"error": "Only admin or owner can delete the page"},
status=status.HTTP_403_FORBIDDEN,
)

Comment on lines 370 to 383
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and cycle.owned_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness of permission check logic.

The permission check logic correctly ensures that only admins or the creator can delete a cycle. However, the condition and cycle.owned_by != request.user should be or cycle.owned_by != request.user to ensure proper validation.

-            ).exists()
-            and cycle.owned_by != request.user
+            ).exists()
+            or cycle.owned_by != request.user

Committable suggestion was skipped due to low confidence.

Comment on lines 560 to 577
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
).delete()
).first()
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
issue.delete()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent permission checks.

The permission checks are duplicated. The first check verifies if the user is an admin or creator, while the second check verifies if the user is an admin or creator again but with different roles. Consolidate these checks into a single block to avoid redundancy and potential inconsistencies.

-            issue = Issue.objects.filter(
-                workspace__slug=slug, project_id=project_id, pk=issue_id
-            ).first()
-            if (
-                ProjectMember.objects.filter(
-                    workspace__slug=slug,
-                    member=request.user,
-                    role__in=[15, 10, 5],
-                    project_id=project_id,
-                    is_active=True,
-                ).exists()
-                and issue.created_by != request.user
-            ):
-                return Response(
-                    {"error": "Only admin or creator can delete the issue"},
-                    status=status.HTTP_403_FORBIDDEN,
-                )
-            issue.delete()
+        issue = Issue.objects.filter(
+            workspace__slug=slug, project_id=project_id, pk=issue_id
+        ).first()
+        if not (
+            ProjectMember.objects.filter(
+                workspace__slug=slug,
+                member=request.user,
+                role__in=[15, 10, 5],
+                project_id=project_id,
+                is_active=True,
+            ).exists()
+            or issue.created_by == request.user
+        ):
+            return Response(
+                {"error": "Only admin or creator can delete the issue"},
+                status=status.HTTP_403_FORBIDDEN,
+            )
+        issue.delete()
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
).delete()
).first()
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
issue.delete()
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
).first()
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
or issue.created_by == request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
issue.delete()

Comment on lines 399 to 412
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor permission checks for clarity and efficiency.

Refactor the permission checks to improve readability and efficiency.

- if (
-     ProjectMember.objects.filter(
-         workspace__slug=slug,
-         member=request.user,
-         role__in=[15, 10, 5],
-         project_id=project_id,
-         is_active=True,
-     ).exists()
-     and issue.created_by != request.user
- ):
+ if not (
+     ProjectMember.objects.filter(
+         workspace__slug=slug,
+         member=request.user,
+         role__in=[15, 10, 5],
+         project_id=project_id,
+         is_active=True,
+     ).exists()
+     or issue.created_by == request.user
+ ):
     return Response(
         {"error": "Only admin or creator can delete the issue"},
         status=status.HTTP_403_FORBIDDEN,
     )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
or issue.created_by == request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)

Comment on lines +396 to 397
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the issue exists before proceeding with deletion.

Add a check to ensure the issue exists before proceeding with the deletion logic to avoid potential errors.

+ issue = Issue.objects.filter(
+     workspace__slug=slug, project_id=project_id, pk=issue_id
+ ).first()
+ if not issue:
+     return Response(
+         {"error": "Issue not found"},
+         status=status.HTTP_404_NOT_FOUND,
+     )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
issue = Issue.objects.filter(
workspace__slug=slug, project_id=project_id, pk=issue_id
).first()
if not issue:
return Response(
{"error": "Issue not found"},
status=status.HTTP_404_NOT_FOUND,
)

Comment on lines 385 to 397
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor permission checks for clarity and efficiency.

Refactor the permission checks to improve readability and efficiency.

- if (
-     ProjectMember.objects.filter(
-         workspace__slug=slug,
-         member=request.user,
-         role__in=[15, 10, 5],
-         project_id=project_id,
-         is_active=True,
-     ).exists()
-     and issue.created_by != request.user
- ):
+ if not (
+     ProjectMember.objects.filter(
+         workspace__slug=slug,
+         member=request.user,
+         role__in=[15, 10, 5],
+         project_id=project_id,
+         is_active=True,
+     ).exists()
+     or issue.created_by == request.user
+ ):
     return Response(
         {"error": "Only admin or creator can delete the issue"},
         status=status.HTTP_403_FORBIDDEN,
     )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
or issue.created_by == request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)

Comment on lines 553 to 567
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent permission checks.

The permission checks are duplicated. The first check verifies if the user is an admin or creator, while the second check verifies if the user is an admin or creator again but with different roles. Consolidate these checks into a single block to avoid redundancy and potential inconsistencies.

-        if (
-            ProjectMember.objects.filter(
-                workspace__slug=slug,
-                member=request.user,
-                role__in=[15, 10, 5],
-                project_id=project_id,
-                is_active=True,
-            ).exists()
-            and issue.created_by != request.user
-        ):
-            return Response(
-                {"error": "Only admin or creator can delete the issue"},
-                status=status.HTTP_403_FORBIDDEN,
-            )
+        if not (
+            ProjectMember.objects.filter(
+                workspace__slug=slug,
+                member=request.user,
+                role__in=[15, 10, 5],
+                project_id=project_id,
+                is_active=True,
+            ).exists()
+            or issue.created_by == request.user
+        ):
+            return Response(
+                {"error": "Only admin or creator can delete the issue"},
+                status=status.HTTP_403_FORBIDDEN,
+            )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
or issue.created_by == request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)

Comment on lines 384 to 397
if (
ProjectMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
project_id=project_id,
is_active=True,
).exists()
and issue.created_by != request.user
):
return Response(
{"error": "Only admin or creator can delete the issue"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the issue exists before proceeding with deletion.

Add a check to ensure the issue exists before proceeding with the deletion logic to avoid potential errors.

+ issue = Issue.objects.filter(
+     workspace__slug=slug, project_id=project_id, pk=pk
+ ).first()
+ if not issue:
+     return Response(
+         {"error": "Issue not found"},
+         status=status.HTTP_404_NOT_FOUND,
+     )

Committable suggestion was skipped due to low confidence.

Comment on lines 429 to 438
if (
ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=20,
is_active=True,
).exists()
or project_view.owned_by == request.user
):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor permission checks for clarity and efficiency.

Refactor the permission checks to improve readability and efficiency.

- if (
-     ProjectMember.objects.filter(
-         workspace__slug=slug,
-         project_id=project_id,
-         member=request.user,
-         role=20,
-         is_active=True,
-     ).exists()
-     or project_view.owned_by == request.user
- ):
+ if not (
+     ProjectMember.objects.filter(
+         workspace__slug=slug,
+         project_id=project_id,
+         member=request.user,
+         role=20,
+         is_active=True,
+     ).exists()
+     or project_view.owned_by == request.user
+ ):
     return Response(
         {"error": "Only admin or owner can delete the view"},
         status=status.HTTP_400_BAD_REQUEST,
     )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=20,
is_active=True,
).exists()
or project_view.owned_by == request.user
):
if not (
ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=20,
is_active=True,
).exists()
or project_view.owned_by == request.user
):
return Response(
{"error": "Only admin or owner can delete the view"},
status=status.HTTP_400_BAD_REQUEST,
)

Comment on lines 119 to 131
if (
WorkspaceMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
is_active=True,
).exists()
and workspace_view.owned_by != request.user
):
return Response(
{"error": "You do not have permission to delete this view"},
status=status.HTTP_403_FORBIDDEN,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor permission checks for clarity and efficiency.

Refactor the permission checks to improve readability and efficiency.

- if (
-     WorkspaceMember.objects.filter(
-         workspace__slug=slug,
-         member=request.user,
-         role__in=[15, 10, 5],
-         is_active=True,
-     ).exists()
-     and workspace_view.owned_by != request.user
- ):
+ if not (
+     WorkspaceMember.objects.filter(
+         workspace__slug=slug,
+         member=request.user,
+         role__in=[15, 10, 5],
+         is_active=True,
+     ).exists()
+     or workspace_view.owned_by == request.user
+ ):
     return Response(
         {"error": "You do not have permission to delete this view"},
         status=status.HTTP_403_FORBIDDEN,
     )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
WorkspaceMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
is_active=True,
).exists()
and workspace_view.owned_by != request.user
):
return Response(
{"error": "You do not have permission to delete this view"},
status=status.HTTP_403_FORBIDDEN,
)
if not (
WorkspaceMember.objects.filter(
workspace__slug=slug,
member=request.user,
role__in=[15, 10, 5],
is_active=True,
).exists()
or workspace_view.owned_by == request.user
):
return Response(
{"error": "You do not have permission to delete this view"},
status=status.HTTP_403_FORBIDDEN,
)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d690923 and 5d0861f.

Files selected for processing (10)
  • apiserver/plane/api/views/cycle.py (2 hunks)
  • apiserver/plane/api/views/inbox.py (1 hunks)
  • apiserver/plane/api/views/issue.py (2 hunks)
  • apiserver/plane/api/views/module.py (2 hunks)
  • apiserver/plane/app/views/cycle/base.py (2 hunks)
  • apiserver/plane/app/views/inbox/base.py (1 hunks)
  • apiserver/plane/app/views/issue/base.py (3 hunks)
  • apiserver/plane/app/views/issue/draft.py (2 hunks)
  • apiserver/plane/app/views/module/base.py (2 hunks)
  • apiserver/plane/app/views/page/base.py (1 hunks)
Files skipped from review as they are similar to previous changes (9)
  • apiserver/plane/api/views/cycle.py
  • apiserver/plane/api/views/inbox.py
  • apiserver/plane/api/views/issue.py
  • apiserver/plane/api/views/module.py
  • apiserver/plane/app/views/inbox/base.py
  • apiserver/plane/app/views/issue/base.py
  • apiserver/plane/app/views/issue/draft.py
  • apiserver/plane/app/views/module/base.py
  • apiserver/plane/app/views/page/base.py
Additional comments not posted (4)
apiserver/plane/app/views/cycle/base.py (4)

50-50: Import statement update looks good.

The import statement for ProjectMember is necessary for the new permission logic.


1046-1058: Permission check logic looks good.

The permission check ensures that only the owner or an admin can delete the cycle. This enhances security.


1059-1065: Asynchronous task for issue activity looks good.

The issue_activity.delay call ensures that the activity is logged asynchronously, which is good for performance.


1066-1067: Cycle deletion logic looks good.

The cycle deletion is straightforward and follows the permission check.

Comment on lines +1043 to +1045
cycle = Cycle.objects.get(
workspace__slug=slug, project_id=project_id, pk=pk
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure proper exception handling for Cycle.objects.get.

Using get without exception handling can raise Cycle.DoesNotExist if the cycle is not found. It's better to handle this exception.

-  cycle = Cycle.objects.get(
+  try:
+      cycle = Cycle.objects.get(
+          workspace__slug=slug, project_id=project_id, pk=pk
+      )
+  except Cycle.DoesNotExist:
+      return Response(
+          {"error": "Cycle not found"},
+          status=status.HTTP_404_NOT_FOUND,
+      )
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cycle = Cycle.objects.get(
workspace__slug=slug, project_id=project_id, pk=pk
)
try:
cycle = Cycle.objects.get(
workspace__slug=slug, project_id=project_id, pk=pk
)
except Cycle.DoesNotExist:
return Response(
{"error": "Cycle not found"},
status=status.HTTP_404_NOT_FOUND,
)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5d0861f and d098925.

Files selected for processing (1)
  • apiserver/plane/app/views/view/base.py (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apiserver/plane/app/views/view/base.py

@pushya22 pushya22 changed the title [WEB-2043] chore: added permission for delete operation [WEB-2043] chore: updated permissions for delete operation Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants