From 7f5de2d70e51699dc00b2f238131a6d72ded4ba3 Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Thu, 18 Nov 2021 19:51:40 -0800 Subject: [PATCH] Adding SecureComponent to list groups and group details page (#1238) Signed-off-by: Lenin Alevski Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> --- .../src/common/SecureComponent/permissions.ts | 5 + .../src/screens/Console/Groups/Groups.tsx | 132 +++++++++++----- .../screens/Console/Groups/GroupsDetails.tsx | 145 +++++++++++------- 3 files changed, 188 insertions(+), 94 deletions(-) diff --git a/portal-ui/src/common/SecureComponent/permissions.ts b/portal-ui/src/common/SecureComponent/permissions.ts index e8e79bbb7..c502d4d89 100644 --- a/portal-ui/src/common/SecureComponent/permissions.ts +++ b/portal-ui/src/common/SecureComponent/permissions.ts @@ -112,6 +112,11 @@ export const IAM_SCOPES = { S3_GET_BUCKET_LOCATION: "s3:GetBucketLocation", S3_DELETE_BUCKET_POLICY: "s3:DeleteBucketPolicy", S3_ABORT_MULTIPART_UPLOAD: "s3:AbortMultipartUpload", + ADMIN_ADD_USER_TO_GROUP: "admin:AddUserToGroup", + ADMIN_REMOVE_USER_FROM_GROUP: "admin:RemoveUserFromGroup", + ADMIN_GET_GROUP: "admin:GetGroup", + ADMIN_ENABLE_GROUP: "admin:EnableGroup", + ADMIN_DISABLE_GROUP: "admin:DisableGroup", S3_ALL_ACTIONS: "s3:*", ADMIN_ALL_ACTIONS: "admin:*", }; diff --git a/portal-ui/src/screens/Console/Groups/Groups.tsx b/portal-ui/src/screens/Console/Groups/Groups.tsx index bfdadc9f1..54e3537e0 100644 --- a/portal-ui/src/screens/Console/Groups/Groups.tsx +++ b/portal-ui/src/screens/Console/Groups/Groups.tsx @@ -43,6 +43,13 @@ import history from "../../../history"; import AButton from "../Common/AButton/AButton"; import PageLayout from "../Common/Layout/PageLayout"; import SearchBox from "../Common/SearchBox"; +import { + CONSOLE_UI_RESOURCE, + IAM_SCOPES, +} from "../../../common/SecureComponent/permissions"; +import SecureComponent, { + hasPermission, +} from "../../../common/SecureComponent/SecureComponent"; interface IGroupsProps { classes: any; @@ -85,27 +92,43 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => { isLoading(true); }, []); + const displayGroups = hasPermission(CONSOLE_UI_RESOURCE, [ + IAM_SCOPES.ADMIN_LIST_GROUPS, + ]); + + const deleteGroup = hasPermission(CONSOLE_UI_RESOURCE, [ + IAM_SCOPES.ADMIN_REMOVE_USER_FROM_GROUP, + ]); + + const getGroup = hasPermission(CONSOLE_UI_RESOURCE, [ + IAM_SCOPES.ADMIN_GET_GROUP, + ]); + useEffect(() => { if (loading) { - const fetchRecords = () => { - api - .invoke("GET", `/api/v1/groups`) - .then((res: GroupsList) => { - let resGroups: string[] = []; - if (res.groups !== null) { - resGroups = res.groups.sort(stringSort); - } - setRecords(resGroups); - isLoading(false); - }) - .catch((err: ErrorResponseHandler) => { - setErrorSnackMessage(err); - isLoading(false); - }); - }; - fetchRecords(); + if (displayGroups) { + const fetchRecords = () => { + api + .invoke("GET", `/api/v1/groups`) + .then((res: GroupsList) => { + let resGroups: string[] = []; + if (res.groups !== null) { + resGroups = res.groups.sort(stringSort); + } + setRecords(resGroups); + isLoading(false); + }) + .catch((err: ErrorResponseHandler) => { + setErrorSnackMessage(err); + isLoading(false); + }); + }; + fetchRecords(); + } else { + isLoading(false); + } } - }, [loading, setErrorSnackMessage]); + }, [loading, setErrorSnackMessage, displayGroups]); const closeAddModalAndRefresh = () => { setGroupOpen(false); @@ -134,8 +157,16 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => { }; const tableActions = [ - { type: "view", onClick: viewAction }, - { type: "delete", onClick: deleteAction }, + { + type: "view", + onClick: viewAction, + disableButtonFunction: () => !getGroup, + }, + { + type: "delete", + onClick: deleteAction, + disableButtonFunction: () => !deleteGroup, + }, ]; return ( @@ -173,19 +204,27 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => { onChange={setFilter} classes={classes} /> - + + - {loading && } {!loading && ( @@ -245,18 +284,27 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => { users with membership in that group inherit that policy. Groups support more simplified management of user permissions on the MinIO Tenant. -
-
- To get started,{" "} - { - setSelectedGroup(null); - setGroupOpen(true); - }} + - Create a Group - - . +
+
+ To get started,{" "} + { + setSelectedGroup(null); + setGroupOpen(true); + }} + > + Create a Group + + . +
} /> diff --git a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx index d4eb6086b..e866d2bf3 100644 --- a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx +++ b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx @@ -33,6 +33,13 @@ import BackLink from "../../../common/BackLink"; import PanelTitle from "../Common/PanelTitle/PanelTitle"; import BoxIconButton from "../Common/BoxIconButton/BoxIconButton"; import SearchBox from "../Common/SearchBox"; +import { + CONSOLE_UI_RESOURCE, + IAM_SCOPES, +} from "../../../common/SecureComponent/permissions"; +import SecureComponent, { + hasPermission, +} from "../../../common/SecureComponent/SecureComponent"; const styles = (theme: Theme) => createStyles({ @@ -154,16 +161,22 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => { const isGroupEnabled = groupEnabled === "enabled"; const memberActionText = members.length > 0 ? "Edit Members" : "Add Members"; + const getGroupDetails = hasPermission(CONSOLE_UI_RESOURCE, [ + IAM_SCOPES.ADMIN_GET_GROUP, + ]); + function fetchGroupInfo() { - api - .invoke("GET", `/api/v1/group?name=${encodeURI(groupName)}`) - .then((res: any) => { - setGroupDetails(res); - }) - .catch((err) => { - setModalErrorSnackMessage(err); - setGroupDetails({}); - }); + if (getGroupDetails) { + api + .invoke("GET", `/api/v1/group?name=${encodeURI(groupName)}`) + .then((res: any) => { + setGroupDetails(res); + }) + .catch((err) => { + setModalErrorSnackMessage(err); + setGroupDetails({}); + }); + } } function toggleGroupStatus(nextStatus: boolean) { @@ -192,28 +205,40 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => { }} classes={classes} /> - + +
- + + +
); @@ -274,31 +299,47 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => { {isGroupEnabled ? "Enabled" : "Disabled"} - { - toggleGroupStatus(!isGroupEnabled); - }} - switchOnly - /> - -
- { - setDeleteOpen(true); - }} - size="large" - > - - -
-
+ + { + toggleGroupStatus(!isGroupEnabled); + }} + switchOnly + /> + + + + +
+ { + setDeleteOpen(true); + }} + size="large" + > + + +
+
+
} />