Skip to content

Mrc-6385 Manage Read Access for packet groups #189

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

absternator
Copy link
Contributor

This PR adds the ability to manage read permissions on the packet groups page (home page) as seen on figma. There is slight difference in the modal dialog, the pills being different color currently not possible with multi select we use, thus have decided to color code the drop down itself and add a literal "Role" | "User" to help decide. This can all be changed when/if we choose to overhaul the permission forms as per figma discussions, ticket here.

This is branched off the API for managing permissions, thus the endpoint itself may change slightly (shouldn't affect this review)

Below are the changes and assumptions made about how the logic is working:

Note: Permission logic can be seen in hasPermission.ts, should make things clearer than me explaining.

  • On the page, show the update icon only if the user has packet. manage permission
  • On modal, a user can only grant/remove packet.read scoped to packetGroup (eg. packet.read:packetGroup:groupA)
    • To grant permission, user/role must currently not be able to read that packetGroup. If they have global permission then the user/role wont show up in select dropdown(as they already have permission to read).
    • To remove permission, user/role must have the read permission scoped to the packet group. If they have global access they will not show up (as we are only allowed to remove scoped to the permission group)

Testing:
Sign in with admin and create users and roles. Play around adding permissions and removing permissions in the user manage page and then also in the home page modal with managing read access. Ensure the behaviour is as expected. (as in roles/users should be added/removed and show up as expected in dropdowns)

Below are images of changes:

image
image
image

@absternator absternator requested a review from EmmaLRussell April 3, 2025 19:24

return (
<li key={packetGroup.latestId} className="p-4 flex flex-col border-b">
Copy link
Contributor Author

Choose a reason for hiding this comment

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

just put inside div to add button no changes


try {
await fetcher({
url: `${appConfig.apiUrl()}/roles/${packetGroupName}/read-permissions`,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

subject to change as per pauls review

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good file to understand permission logic

};

/**
* Checks if a user has direct read access to the given packet group
Copy link
Contributor Author

Choose a reason for hiding this comment

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

below are just helper funcs for top one

Copy link

codecov bot commented Apr 3, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.33%. Comparing base (351798b) to head (eefa283).
Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #189      +/-   ##
==========================================
+ Coverage   97.15%   97.33%   +0.17%     
==========================================
  Files         150      155       +5     
  Lines        1476     1575      +99     
  Branches      425      462      +37     
==========================================
+ Hits         1434     1533      +99     
  Misses         41       41              
  Partials        1        1              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

* This function retrieves roles and users that have read permissions for a specific packet group.
* It does NOT include those with global read permissions, manage permissions, etc.
*/
export const getRolesUsersWithReadGroupPermission = (
Copy link
Contributor Author

@absternator absternator Apr 3, 2025

Choose a reason for hiding this comment

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

is used in remove read permissions multi-select

* This function retrieves roles and users that cannot read a specific packet group.
* It includes those with global read permissions, manage permissions, etc.
*/
export const getRolesAndUsersCantReadGroup = (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is used in grant read permissions multi-select

Copy link
Contributor

@EmmaLRussell EmmaLRussell left a comment

Choose a reason for hiding this comment

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

Looks good! Works as expected.

I definitely think it would be worth putting in the the single select style dialogs sooner rather than later as it will simplify the UI and make all permission holders immediately visible.

Could you put a tooltip on the Update access icons?

Could add an e2e test! 😀

render={({ field }) => (
<FormItem>
<FormDescription className="text-xs mb-0.5">
Select roles or specific users to grant read access to the packet group. Roles or users with global read
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Select roles or specific users to grant read access to the packet group. Roles or users with global read
Select roles or specific users to grant read access to this packet group. Roles or users with global read

<FormDescription className="text-xs mb-0.5">
Select roles or specific users to grant read access to the packet group. Roles or users with global read
access cannot be added here as they already have the required permissions. Similarly, roles or users
with global permissions cannot have their access removed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
with global permissions cannot have their access removed.
with global access cannot have their access removed here.

Comment on lines +55 to +61
url: `${appConfig.apiUrl()}/packetGroups/${packetGroupName}/read-permission`,
body: {
roleNamesToAdd: values.roleNamesToAdd,
roleNamesToRemove: values.roleNamesToRemove
},
method: "PUT"
});
Copy link
Contributor

Choose a reason for hiding this comment

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

So this is just updating "roles" because users are roles too...?

I'm guessing when we change the dialogs to be single-select we'll probably want to change the API to just accept a single list of updates roles with permssions - if that's not already being done in this round.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup beacuse we have username roles....

sounds good with API changes when we do single select

Comment on lines 17 to 23
const rolesWithRead = roles.filter((role) =>
hasPacketReadPermissionForGroup(mapPermissionsToNames(role.rolePermissions), packetGroupName)
);

const usersWithRead = users.filter((user) =>
hasPacketReadPermissionForGroup(mapPermissionsToNames(user.specificPermissions), packetGroupName)
);
Copy link
Contributor

Choose a reason for hiding this comment

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

These don't actually exclude users or roles with global permissions as they may have been granted specific read permission as well as having global permissions. It's a bit messy that that is allowed at all, but it does seem misleading to include those in the list that you can remove access from here, when they will still have global permission even when specific permission is removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ohh yesss good catch updated...


const usersCantRead = users.filter(
(user) =>
!userHasDirectReadPermission(user, packetGroupName) && !userHasReadPermissionViaRole(user, roles, packetGroupName)
Copy link
Contributor

Choose a reason for hiding this comment

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

So we don't include users as available to add permissions for if they already have permission by virtue of a role they hold? I feel like that maybe should go into the blurb in dialog too explaining about global permissions. Something like

"You also cannot add or remove access here for specific users who have access via a role.".. with maybe a link the the Manage access page ("Role membership should be managed here")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea ive added the first line... didn't add link to manage access because they may not have user.manage permission page to visit link...

* This function retrieves roles and users that cannot read a specific packet group.
* It includes those with global read permissions, manage permissions, etc.
*/
export const getRolesAndUsersCantReadGroup = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
export const getRolesAndUsersCantReadGroup = (
export const getRolesAndUsersWithoutReadGroupPermission = (

With and Without should really be consistent with each other.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i intentionally didnt make it consistent because they are not really opposite.. used cantReadGroup here because it means exactly that they cant read group at all (could be due to global permissions).. if I used withoutReadGroup that would be different as they could still read with global permissions without specifically having the read Group permission

* This function retrieves roles and users that have read permissions for a specific packet group.
* It does NOT include those with global read permissions, manage permissions, etc.
*/
export const getRolesUsersWithReadGroupPermission = (
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
export const getRolesUsersWithReadGroupPermission = (
export const getRolesAndUsersWithReadGroupPermission = (

Copy link
Contributor Author

Choose a reason for hiding this comment

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

have updated to getRolesAndUsersWithOnlyReadGroupPermission

Comment on lines 33 to 35
if ([packetGroupName, tag].filter((x) => x !== undefined).length > 1) {
throw new Error("Only one of packetGroupName or tag can be provided");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Should also be an error if both tag and packetId are defined?

@@ -1,5 +1,35 @@
import { UserState } from "../../app/components/providers/types/UserTypes";
import { buildScopedPermission } from "../constructPermissionName";
Copy link
Member

Choose a reason for hiding this comment

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

The frontend really should not have this much authorization logic in it. Doing a bit of authorization on the current user to decide which bits to turn on and off in the UI may be okay, but doing authorization on other users is pretty strange.

IMO the backend should have a GET /read-permission that tells you which roles have read access to the packet group, and then you'd use that to filter the list of roles that can be added/removed. The response to the GET could also tell you whether they have scoped access to the packet group (and therefore can be revoked) or if they have a more global access to it (eg. they have packet.read).

In #189 you wrote

  • allow reading of all roles in packet.manage permission (this will be needed by FE so they can decide what roles to add/remove)

In retrospect I think this was maybe not a good direction. Someone with packet.manage.foo should only be able to list all the roles and get the read-permission of foo, but they shouldn't be able to list all the permissions that all the roles have.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lets have a chat about this tommroow

Base automatically changed from mrc-6369-update-read-access to main April 9, 2025 07:44
@absternator absternator requested a review from EmmaLRussell April 9, 2025 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants