-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[WEB-2589] Chore: inbox issue permissions #5763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -323,7 +323,7 @@ def create(self, request, slug, project_id): | |
| serializer.errors, status=status.HTTP_400_BAD_REQUEST | ||
| ) | ||
|
|
||
| @allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST]) | ||
| @allow_permission(allowed_roles=[ROLE.ADMIN], creator=True, model=Issue) | ||
| def partial_update(self, request, slug, project_id, pk): | ||
| inbox_id = Inbox.objects.filter( | ||
| workspace__slug=slug, project_id=project_id | ||
|
|
@@ -418,7 +418,7 @@ def partial_update(self, request, slug, project_id, pk): | |
| ) | ||
|
|
||
| # Only project admins and members can edit inbox issue attributes | ||
| if project_member.role > 5: | ||
| if project_member.role > 15: | ||
| serializer = InboxIssueSerializer( | ||
| inbox_issue, data=request.data, partial=True | ||
|
Comment on lines
+421
to
423
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Role condition may incorrectly restrict member access At line 421, the condition: if project_member.role > 15:
serializer = InboxIssueSerializer(
inbox_issue, data=request.data, partial=True
)
# Additional logic...This condition allows only users with a role greater than 15 (typically guests) to edit inbox issue attributes. According to the comment: # Only project admins and members can edit inbox issue attributesAdjust the condition to include admins and members by changing the comparison operator: -if project_member.role > 15:
+if project_member.role <= 15:
serializer = InboxIssueSerializer(
inbox_issue, data=request.data, partial=True
)This modification ensures that users with roles of admin ( |
||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,6 +89,12 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| const canDelete = | ||
| allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT, workspaceSlug, projectId) || | ||
| issue?.created_by === currentUser?.id; | ||
| const isProjectAdmin = allowPermissions( | ||
| [EUserPermissions.ADMIN], | ||
| EUserPermissionsLevel.PROJECT, | ||
| workspaceSlug, | ||
| projectId | ||
| ); | ||
|
Comment on lines
+92
to
+97
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Standardize permission variables for consistency You have introduced |
||
| const isAcceptedOrDeclined = inboxIssue?.status ? [-1, 1, 2].includes(inboxIssue.status) : undefined; | ||
| // days left for snooze | ||
| const numberOfDaysLeft = findHowManyDaysLeft(inboxIssue?.snoozed_till); | ||
|
|
@@ -199,6 +205,17 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| [handleInboxIssueNavigation] | ||
| ); | ||
|
|
||
| const handleActionWithPermission = (isAdmin: boolean, action: () => void, errorMessage: string) => { | ||
| if (isAdmin) action(); | ||
| else { | ||
| setToast({ | ||
| type: TOAST_TYPE.ERROR, | ||
| title: "Permission denied", | ||
| message: errorMessage, | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| useEffect(() => { | ||
| if (!isNotificationEmbed) document.addEventListener("keydown", onKeyDown); | ||
| return () => { | ||
|
|
@@ -293,7 +310,13 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| size="sm" | ||
| prependIcon={<CircleCheck className="w-3 h-3" />} | ||
| className="text-green-500 border-0.5 border-green-500 bg-green-500/20 focus:bg-green-500/20 focus:text-green-500 hover:bg-green-500/40 bg-opacity-20" | ||
| onClick={() => setAcceptIssueModal(true)} | ||
| onClick={() => | ||
| handleActionWithPermission( | ||
| isProjectAdmin, | ||
| () => setAcceptIssueModal(true), | ||
| "Only project admins can accept issues" | ||
| ) | ||
| } | ||
|
Comment on lines
+313
to
+319
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Synchronize button enablement with admin permissions The "Accept" button's Apply this diff to update - const canMarkAsAccepted = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
+ const canMarkAsAccepted = isProjectAdmin && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
|
||
| > | ||
| Accept | ||
| </Button> | ||
|
|
@@ -307,7 +330,13 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| size="sm" | ||
| prependIcon={<CircleX className="w-3 h-3" />} | ||
| className="text-red-500 border-0.5 border-red-500 bg-red-500/20 focus:bg-red-500/20 focus:text-red-500 hover:bg-red-500/40 bg-opacity-20" | ||
| onClick={() => setDeclineIssueModal(true)} | ||
| onClick={() => | ||
| handleActionWithPermission( | ||
| isProjectAdmin, | ||
| () => setDeclineIssueModal(true), | ||
| "Only project admins can deny issues" | ||
| ) | ||
| } | ||
|
Comment on lines
+333
to
+339
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Align "Decline" button availability with admin permissions Similarly, the "Decline" button should reflect admin-only permissions in both its availability and action handling. Update Apply this diff to update - const canMarkAsDeclined = isAllowed && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
+ const canMarkAsDeclined = isProjectAdmin && (inboxIssue?.status === 0 || inboxIssue?.status === -2);
|
||
| > | ||
| Decline | ||
| </Button> | ||
|
|
@@ -341,7 +370,15 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| {isAllowed && ( | ||
| <CustomMenu verticalEllipsis placement="bottom-start"> | ||
| {canMarkAsAccepted && ( | ||
| <CustomMenu.MenuItem onClick={handleIssueSnoozeAction}> | ||
| <CustomMenu.MenuItem | ||
| onClick={() => | ||
| handleActionWithPermission( | ||
| isProjectAdmin, | ||
| handleIssueSnoozeAction, | ||
| "Only project admins can snooze/Un-snooze issues" | ||
| ) | ||
| } | ||
| > | ||
|
Comment on lines
+373
to
+381
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Restrict "Snooze" action to admins in the menu The "Snooze" menu item's Apply this diff to adjust the menu item's visibility: - {canMarkAsAccepted && (
+ {isProjectAdmin && canMarkAsAccepted && (
|
||
| <div className="flex items-center gap-2"> | ||
| <Clock size={14} strokeWidth={2} /> | ||
| {inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 | ||
|
|
@@ -351,7 +388,15 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| </CustomMenu.MenuItem> | ||
| )} | ||
| {canMarkAsDuplicate && ( | ||
| <CustomMenu.MenuItem onClick={() => setSelectDuplicateIssue(true)}> | ||
| <CustomMenu.MenuItem | ||
| onClick={() => | ||
| handleActionWithPermission( | ||
| isProjectAdmin, | ||
| () => setSelectDuplicateIssue(true), | ||
| "Only project admins can mark issues as duplicate" | ||
| ) | ||
| } | ||
| > | ||
|
Comment on lines
+391
to
+399
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure "Mark as duplicate" action is admin-only The "Mark as duplicate" action should be accessible only to project admins. Currently, non-admin users might see this option due to the condition based on Apply this diff to update the visibility condition: - {canMarkAsDuplicate && (
+ {isProjectAdmin && canMarkAsDuplicate && (
|
||
| <div className="flex items-center gap-2"> | ||
| <FileStack size={14} strokeWidth={2} /> | ||
| Mark as duplicate | ||
|
|
@@ -401,6 +446,8 @@ export const InboxIssueActionsHeader: FC<TInboxIssueActionsHeader> = observer((p | |
| setIsMobileSidebar={setIsMobileSidebar} | ||
| isNotificationEmbed={isNotificationEmbed} | ||
| embedRemoveCurrentNotification={embedRemoveCurrentNotification} | ||
| isProjectAdmin={isProjectAdmin} | ||
| handleActionWithPermission={handleActionWithPermission} | ||
| /> | ||
| </div> | ||
| </> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect role check in access control logic
The condition in the
partial_updatemethod may not correctly enforce the intended access control. The current condition:Given that roles with lower numerical values indicate higher privileges (e.g.,
ROLE.ADMIN = 5,ROLE.MEMBER = 15,ROLE.GUEST = 20), this condition will deny access to admins who are not the creator, which might not be intended. The comment suggests that only project admins and the creator should access this endpoint.Consider adjusting the condition to allow admins and the creator to proceed:
This change ensures that users who are not admins (
role > 5) and are not the creator are denied access, aligning with the intended access control logic.