From 2ec7fa451c0970c15c0b0d35fe70e473889f9ea3 Mon Sep 17 00:00:00 2001 From: Stephen Smith Date: Wed, 1 Dec 2021 15:13:37 -0500 Subject: [PATCH] 18123: Disable controls related to group for built in groups. Arvados-DCO-1.1-Signed-off-by: Stephen Smith --- src/models/group.ts | 14 +++++++++- .../data-explorer/renderers.tsx | 27 ++++++++++++++----- .../group-details-panel.tsx | 6 +++-- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/models/group.ts b/src/models/group.ts index 7d144a58..a0c22212 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { ResourceKind, TrashableResource } from "./resource"; +import { ResourceKind, TrashableResource, ResourceObjectType, RESOURCE_UUID_REGEX } from "./resource"; export interface GroupResource extends TrashableResource { kind: ResourceKind.GROUP; @@ -19,3 +19,15 @@ export enum GroupClass { FILTER = 'filter', ROLE = 'role', } + +export const BUILTIN_GROUP_IDS = [ + 'fffffffffffffff', + 'anonymouspublic', + '000000000000000', +] + +export const isBuiltinGroup = (uuid: string) => { + const match = RESOURCE_UUID_REGEX.exec(uuid); + const parts = match ? match[0].split('-') : []; + return parts.length === 3 && parts[1] === ResourceObjectType.GROUP && BUILTIN_GROUP_IDS.includes(parts[2]); +}; diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx index a13269e5..5040746a 100644 --- a/src/views-components/data-explorer/renderers.tsx +++ b/src/views-components/data-explorer/renderers.tsx @@ -28,7 +28,7 @@ import { withResourceData } from 'views-components/data-explorer/with-resources' import { CollectionResource } from 'models/collection'; import { IllegalNamingWarning } from 'components/warning/warning'; import { loadResource } from 'store/resources/resources-actions'; -import { GroupClass, GroupResource } from 'models/group'; +import { GroupClass, GroupResource, isBuiltinGroup } from 'models/group'; import { openRemoveGroupMemberDialog } from 'store/group-details-panel/group-details-panel-actions'; import { setMemberIsHidden } from 'store/group-details-panel/group-details-panel-actions'; import { formatPermissionLevel } from 'views-components/sharing-dialog/permission-select'; @@ -215,12 +215,19 @@ export const ResourceLinkTailIsActive = connect( }, { toggleIsActive } )(renderIsActive); -const renderIsHidden = (props: { memberLinkUuid: string, permissionLinkUuid: string, hidden: boolean, setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void }) => { +const renderIsHidden = (props: { + memberLinkUuid: string, + permissionLinkUuid: string, + hidden: boolean, + canManage: boolean, + setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void + }) => { if (props.memberLinkUuid) { return props.setMemberIsHidden(props.memberLinkUuid, props.permissionLinkUuid, !props.hidden)} />; } else { return ; @@ -241,10 +248,12 @@ export const ResourceLinkTailIsHidden = connect( const permissionLinkUuid = permissions.length > 0 ? permissions[0].uuid : ''; const isVisible = link && group && permissions.length > 0; + // Consider whether the current user canManage this resurce in addition when it's possible + const isBuiltin = isBuiltinGroup(link?.headUuid || ''); return member?.kind === ResourceKind.USER - ? { memberLinkUuid: link?.uuid, permissionLinkUuid, hidden: !isVisible } - : { memberLinkUuid: '', permissionLinkUuid: '', hidden: false}; + ? { memberLinkUuid: link?.uuid, permissionLinkUuid, hidden: !isVisible, canManage: !isBuiltin } + : { memberLinkUuid: '', permissionLinkUuid: '', hidden: false, canManage: false }; }, { setMemberIsHidden } )(renderIsHidden); @@ -425,9 +434,11 @@ const renderLinkDelete = (dispatch: Dispatch, item: LinkResource, canManage: boo export const ResourceLinkDelete = connect( (state: RootState, props: { uuid: string }) => { const link = getResource(props.uuid)(state.resources); + const isBuiltin = isBuiltinGroup(link?.headUuid || '') || isBuiltinGroup(link?.tailUuid || ''); + return { item: link || { uuid: '', kind: ResourceKind.NONE }, - canManage: link && getResourceLinkCanManage(state, link), + canManage: link && getResourceLinkCanManage(state, link) && !isBuiltin, }; })((props: { item: LinkResource, canManage: boolean } & DispatchProp) => renderLinkDelete(props.dispatch, props.item, props.canManage)); @@ -463,10 +474,11 @@ const renderPermissionLevel = (dispatch: Dispatch, link: LinkResource, canManage export const ResourceLinkHeadPermissionLevel = connect( (state: RootState, props: { uuid: string }) => { const link = getResource(props.uuid)(state.resources); + const isBuiltin = isBuiltinGroup(link?.headUuid || '') || isBuiltinGroup(link?.tailUuid || ''); return { link: link || { uuid: '', name: '', kind: ResourceKind.NONE }, - canManage: link && getResourceLinkCanManage(state, link), + canManage: link && getResourceLinkCanManage(state, link) && !isBuiltin, }; })((props: { link: LinkResource, canManage: boolean } & DispatchProp) => renderPermissionLevel(props.dispatch, props.link, props.canManage)); @@ -474,10 +486,11 @@ export const ResourceLinkHeadPermissionLevel = connect( export const ResourceLinkTailPermissionLevel = connect( (state: RootState, props: { uuid: string }) => { const link = getResource(props.uuid)(state.resources); + const isBuiltin = isBuiltinGroup(link?.headUuid || '') || isBuiltinGroup(link?.tailUuid || ''); return { link: link || { uuid: '', name: '', kind: ResourceKind.NONE }, - canManage: link && getResourceLinkCanManage(state, link), + canManage: link && getResourceLinkCanManage(state, link) && !isBuiltin, }; })((props: { link: LinkResource, canManage: boolean } & DispatchProp) => renderPermissionLevel(props.dispatch, props.link, props.canManage)); diff --git a/src/views/group-details-panel/group-details-panel.tsx b/src/views/group-details-panel/group-details-panel.tsx index 932005a7..ae64b628 100644 --- a/src/views/group-details-panel/group-details-panel.tsx +++ b/src/views/group-details-panel/group-details-panel.tsx @@ -17,7 +17,7 @@ import { ResourcesState, getResource } from 'store/resources/resources'; import { Grid, Button, Tabs, Tab, Paper } from '@material-ui/core'; import { AddIcon } from 'components/icon/icon'; import { getUserUuid } from 'common/getuser'; -import { GroupResource } from 'models/group'; +import { GroupResource, isBuiltinGroup } from 'models/group'; export enum GroupDetailsPanelMembersColumnNames { FULL_NAME = "Name", @@ -134,7 +134,9 @@ const mapStateToProps = (state: RootState) => { return { resources: state.resources, - groupCanManage: userUuid ? group?.writableBy?.includes(userUuid) : false, + groupCanManage: userUuid && !isBuiltinGroup(group?.uuid || '') + ? group?.writableBy?.includes(userUuid) + : false, }; }; -- 2.30.2