From a5e78803ff259ce6467ecbc286ee970f1bfda4aa Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Thu, 10 Sep 2020 17:28:08 -0400 Subject: [PATCH] 16811: Fix public favorites. Previously, these were 'star' links owned by the all users group. However, the all users group is now a 'role' and new rule (since issue #16007) is that 'role' groups cannot directly own things. So now public favorites are defined as a link owned by the system user with tail_uuid as the all users group. Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- .../favorite-service/favorite-service.ts | 26 ++++++++-- .../favorite-panel-middleware-service.ts | 3 +- .../public-favorites-middleware-service.ts | 6 ++- src/store/tree-picker/tree-picker-actions.ts | 52 +++++++++---------- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/src/services/favorite-service/favorite-service.ts b/src/services/favorite-service/favorite-service.ts index fbb2a52f..37c1380b 100644 --- a/src/services/favorite-service/favorite-service.ts +++ b/src/services/favorite-service/favorite-service.ts @@ -23,20 +23,38 @@ export class FavoriteService { ) { } create(data: { userUuid: string; resource: { uuid: string; name: string } }) { - return this.linkService.create({ - ownerUuid: data.userUuid, + const l = this.linkService.create({ + // If this is for the all users group, it must be owned by + // the system user. + ownerUuid: (data.userUuid.substr(-22) === "-j7d0g-fffffffffffffff" ? + data.userUuid.substr(0, 5) + "-tpzed-000000000000000" + : data.userUuid), tailUuid: data.userUuid, headUuid: data.resource.uuid, linkClass: LinkClass.STAR, name: data.resource.name }); + + if (data.userUuid.substr(-22) === "-j7d0g-fffffffffffffff") { + // If this is for the all users group, we need to create a + // permission link as well. + l.then(result => + this.linkService.create({ + tailUuid: data.userUuid, + headUuid: result.uuid, + linkClass: LinkClass.PERMISSION, + name: "can_read" + })); + } + + return l; } delete(data: { userUuid: string; resourceUuid: string; }) { return this.linkService .list({ filters: new FilterBuilder() - .addEqual('owner_uuid', data.userUuid) + .addEqual('tail_uuid', data.userUuid) .addEqual('head_uuid', data.resourceUuid) .addEqual('link_class', LinkClass.STAR) .getFilters() @@ -75,7 +93,7 @@ export class FavoriteService { .list({ filters: new FilterBuilder() .addIn("head_uuid", resourceUuids) - .addEqual("owner_uuid", userUuid) + .addEqual("tail_uuid", userUuid) .addEqual("link_class", LinkClass.STAR) .getFilters() }) diff --git a/src/store/favorite-panel/favorite-panel-middleware-service.ts b/src/store/favorite-panel/favorite-panel-middleware-service.ts index f45a62f8..c9a06fe6 100644 --- a/src/store/favorite-panel/favorite-panel-middleware-service.ts +++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts @@ -25,6 +25,7 @@ import { getSortColumn } from "~/store/data-explorer/data-explorer-reducer"; import { getDataExplorerColumnFilters } from '~/store/data-explorer/data-explorer-middleware-service'; import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters'; import { ResourceKind } from "~/models/resource"; +import { LinkClass } from "~/models/link"; export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -59,7 +60,7 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); const responseLinks = await this.services.linkService.list({ filters: new FilterBuilder() - .addEqual("link_class", 'star') + .addEqual("link_class", LinkClass.STAR) .addEqual('tail_uuid', getUserUuid(api.getState())) .addEqual('tail_kind', ResourceKind.USER) .getFilters() diff --git a/src/store/public-favorites-panel/public-favorites-middleware-service.ts b/src/store/public-favorites-panel/public-favorites-middleware-service.ts index 072cf4e4..7dee4834 100644 --- a/src/store/public-favorites-panel/public-favorites-middleware-service.ts +++ b/src/store/public-favorites-panel/public-favorites-middleware-service.ts @@ -54,14 +54,16 @@ export class PublicFavoritesMiddlewareService extends DataExplorerMiddlewareServ try { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); const uuidPrefix = api.getState().auth.config.uuidPrefix; - const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`; + const systemUuid = `${uuidPrefix}-tpzed-000000000000000`; + const allusersUuid = `${uuidPrefix}-j7d0g-fffffffffffffff`; const responseLinks = await this.services.linkService.list({ limit: dataExplorer.rowsPerPage, offset: dataExplorer.page * dataExplorer.rowsPerPage, filters: new FilterBuilder() .addEqual('link_class', LinkClass.STAR) .addILike("name", dataExplorer.searchValue) - .addEqual('owner_uuid', uuid) + .addIn('owner_uuid', [allusersUuid, systemUuid]) + .addEqual('tail_uuid', allusersUuid) .addIsA("head_uuid", typeFilters) .getFilters() }); diff --git a/src/store/tree-picker/tree-picker-actions.ts b/src/store/tree-picker/tree-picker-actions.ts index 5e880aad..49c1d60a 100644 --- a/src/store/tree-picker/tree-picker-actions.ts +++ b/src/store/tree-picker/tree-picker-actions.ts @@ -271,36 +271,36 @@ export const loadPublicFavoritesProject = (params: LoadFavoritesProjectParams) = async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { const { pickerId, includeCollections = false, includeFiles = false } = params; const uuidPrefix = getState().auth.config.uuidPrefix; - const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`; - if (uuid) { + const systemUuid = `${uuidPrefix}-tpzed-000000000000000`; + const allusersUuid = `${uuidPrefix}-j7d0g-fffffffffffffff`; - const filters = pipe( - (fb: FilterBuilder) => includeCollections - ? fb.addIsA('head_uuid', [ResourceKind.PROJECT, ResourceKind.COLLECTION]) - : fb.addIsA('head_uuid', [ResourceKind.PROJECT]), - fb => fb - .addEqual('link_class', LinkClass.STAR) - .addEqual('owner_uuid', uuid) - .getFilters(), - )(new FilterBuilder()); + const filters = pipe( + (fb: FilterBuilder) => includeCollections + ? fb.addIsA('head_uuid', [ResourceKind.PROJECT, ResourceKind.COLLECTION]) + : fb.addIsA('head_uuid', [ResourceKind.PROJECT]), + fb => fb + .addEqual('link_class', LinkClass.STAR) + .addIn('owner_uuid', [systemUuid, allusersUuid]) + .addEqual('tail_uuid', allusersUuid) + .getFilters(), + )(new FilterBuilder()); - const { items } = await services.linkService.list({ filters }); + const { items } = await services.linkService.list({ filters }); - dispatch(receiveTreePickerData({ - id: 'Public Favorites', - pickerId, - data: items, - extractNodeData: item => ({ - id: item.headUuid, - value: item, - status: item.headKind === ResourceKind.PROJECT + dispatch(receiveTreePickerData({ + id: 'Public Favorites', + pickerId, + data: items, + extractNodeData: item => ({ + id: item.headUuid, + value: item, + status: item.headKind === ResourceKind.PROJECT + ? TreeNodeStatus.INITIAL + : includeFiles ? TreeNodeStatus.INITIAL - : includeFiles - ? TreeNodeStatus.INITIAL - : TreeNodeStatus.LOADED - }), - })); - } + : TreeNodeStatus.LOADED + }), + })); }; export const receiveTreePickerProjectsData = (id: string, projects: ProjectResource[], pickerId: string) => -- 2.30.2