diff --git a/src/db/models/favorite/index.ts b/src/db/models/favorite/index.ts index 82d27eb0..a1dff773 100644 --- a/src/db/models/favorite/index.ts +++ b/src/db/models/favorite/index.ts @@ -17,6 +17,8 @@ import {getEntryPermissionsByWorkbook} from '../../../services/new/workbook/util import {EntryPermissions} from '../../../services/new/entry/types'; +import {WorkbookInstance} from '../../../registry/common/entities/workbook/types'; + interface Favorite extends MT.FavoriteColumns {} class Favorite extends Model { static get tableName() { @@ -188,33 +190,30 @@ class Favorite extends Model { }, ); - const workbookIds = workbookList.map((workbook) => workbook.model.workbookId); - - const workbookPermissionsMap = new Map(); - - if (includePermissionsInfo) { - await Promise.all( - workbookList.map(async (workbook) => { - try { - const permissions = await getEntryPermissionsByWorkbook({ - ctx, - workbook, - bypassEnabled: false, - }); - workbookPermissionsMap.set(workbook.model.workbookId, permissions); - } catch (e) {} - }), - ); - } + const entryPermissionsMap = new Map(); + const workbooksMap = new Map(); + + workbookList.forEach((workbook) => { + workbooksMap.set(workbook.model.workbookId, workbook); + }); workbookEntries.forEach((entry) => { - if (entry?.workbookId && workbookIds.includes(entry.workbookId)) { + if (entry?.workbookId && workbooksMap.has(entry.workbookId)) { + const workbook = workbooksMap.get(entry.workbookId); + + if (workbook && includePermissionsInfo) { + const permissions = getEntryPermissionsByWorkbook({ + ctx, + workbook, + scope: entry.scope, + }); + entryPermissionsMap.set(entry.entryId, permissions); + } + let isLocked = false; - if (workbookPermissionsMap.has(entry.workbookId)) { - const isReadPermission = workbookPermissionsMap.get( - entry.workbookId, - )?.read; + if (entryPermissionsMap.has(entry.entryId)) { + const isReadPermission = entryPermissionsMap.get(entry.entryId)?.read; if (!isReadPermission) { isLocked = true; @@ -224,7 +223,7 @@ class Favorite extends Model { result.push({ ...entry, permissions: includePermissionsInfo - ? workbookPermissionsMap.get(entry.workbookId) + ? entryPermissionsMap.get(entry.entryId) : undefined, isLocked, }); diff --git a/src/db/models/navigation/index.ts b/src/db/models/navigation/index.ts index d0dc27f0..e5ce7c96 100644 --- a/src/db/models/navigation/index.ts +++ b/src/db/models/navigation/index.ts @@ -1,4 +1,4 @@ -import {raw, TransactionOrKnex} from 'objection'; +import {raw} from 'objection'; import {Model} from '../..'; import Utils from '../../../utils'; import Revision from '../revision'; @@ -13,6 +13,7 @@ import {EntryPermissions} from '../../../services/new/entry/types'; import {getEntryPermissionsByWorkbook} from '../../../services/new/workbook/utils'; import {getWorkbooksListByIds} from '../../../services/new/workbook/get-workbooks-list-by-ids'; +import {WorkbookInstance} from '../../../registry/common/entities/workbook/types'; interface Navigation extends MT.EntryColumns { isLocked?: boolean; @@ -70,7 +71,6 @@ class Navigation extends Model { isPrivateRoute, }: MT.GetEntriesConfig, ctx: MT.CTX, - trx?: TransactionOrKnex, ) { ctx.log('GET_ENTRIES_REQUEST', { tenantId, @@ -253,34 +253,30 @@ class Navigation extends Model { }, ); - const workbookIds = workbookList.map((workbook) => workbook.model.workbookId); - - const workbookPermissionsMap = new Map(); - - if (includePermissionsInfo) { - await Promise.all( - workbookList.map(async (workbook) => { - try { - const permissions = await getEntryPermissionsByWorkbook({ - ctx, - trx, - workbook, - bypassEnabled: false, - }); - workbookPermissionsMap.set(workbook.model.workbookId, permissions); - } catch (e) {} - }), - ); - } + const entryPermissionsMap = new Map(); + const workbooksMap = new Map(); + + workbookList.forEach((workbook) => { + workbooksMap.set(workbook.model.workbookId, workbook); + }); workbookEntries.forEach((entry) => { - if (entry?.workbookId && workbookIds.includes(entry.workbookId)) { + if (entry?.workbookId && workbooksMap.has(entry.workbookId)) { + const workbook = workbooksMap.get(entry.workbookId); + + if (workbook && includePermissionsInfo) { + const permissions = getEntryPermissionsByWorkbook({ + ctx, + workbook, + scope: entry.scope, + }); + entryPermissionsMap.set(entry.entryId, permissions); + } + let isLocked = false; - if (workbookPermissionsMap.has(entry.workbookId)) { - const isReadPermission = workbookPermissionsMap.get( - entry.workbookId, - )?.read; + if (entryPermissionsMap.has(entry.entryId)) { + const isReadPermission = entryPermissionsMap.get(entry.entryId)?.read; if (!isReadPermission) { isLocked = true; @@ -290,7 +286,7 @@ class Navigation extends Model { result.push({ ...entry, permissions: includePermissionsInfo - ? workbookPermissionsMap.get(entry.workbookId) + ? entryPermissionsMap.get(entry.entryId) : undefined, isLocked, }); diff --git a/src/services/entry/actions/create-in-workbook.ts b/src/services/entry/actions/create-in-workbook.ts index 2be3e2b5..0dcf9cdd 100644 --- a/src/services/entry/actions/create-in-workbook.ts +++ b/src/services/entry/actions/create-in-workbook.ts @@ -101,14 +101,12 @@ export async function createEntryInWorkbook( const {accessServiceEnabled} = ctx.config; - let permissions: Optional; + const workbook = await getWorkbook( + {ctx, skipCheckPermissions: isPrivateRoute}, + {workbookId, includePermissionsInfo}, + ); const createdEntry = await transaction(Entry.primary, async (trx) => { - const workbook = await getWorkbook( - {ctx, trx, skipCheckPermissions: isPrivateRoute}, - {workbookId}, - ); - if (accessServiceEnabled && !isPrivateRoute) { await checkWorkbookPermission({ ctx, @@ -118,14 +116,6 @@ export async function createEntryInWorkbook( }); } - if (includePermissionsInfo) { - permissions = await getEntryPermissionsByWorkbook({ - ctx, - workbook, - bypassEnabled: isPrivateRoute, - }); - } - const [entryId, revId] = await Promise.all([getId(), getId()]); // TODO: DLS.addEntity / iam registrate entry @@ -174,8 +164,15 @@ export async function createEntryInWorkbook( }); const resultEntry: Entry & {permissions?: UsPermission} = createdEntry!; + let permissions: Optional; if (includePermissionsInfo) { + permissions = getEntryPermissionsByWorkbook({ + ctx, + workbook, + scope: resultEntry.scope, + }); + resultEntry.permissions = permissions; } diff --git a/src/services/entry/actions/get-entry-relations.ts b/src/services/entry/actions/get-entry-relations.ts index 62a369a1..ecb6edd2 100644 --- a/src/services/entry/actions/get-entry-relations.ts +++ b/src/services/entry/actions/get-entry-relations.ts @@ -63,7 +63,14 @@ export async function getEntryRelations(ctx: CTX, params: GetEntryRelationsData) }); } - let iamPermissions: Optional; + if (!entry.workbookId && !isPrivateRoute) { + await checkEntry(ctx, Entry.replica, {verifiableEntry: entry}); + } + + let relations = await getRelatedEntries(ctx, { + entryIds: [entryId], + direction: validatedDirection, + }); if (entry.workbookId) { const workbook = await getWorkbook( @@ -74,27 +81,26 @@ export async function getEntryRelations(ctx: CTX, params: GetEntryRelationsData) {workbookId: entry.workbookId, includePermissionsInfo}, ); - if (includePermissionsInfo) { - iamPermissions = await getEntryPermissionsByWorkbook({ - ctx, - workbook, - bypassEnabled: isPrivateRoute, - }); - } - } else if (!isPrivateRoute) { - await checkEntry(ctx, Entry.replica, {verifiableEntry: entry}); - } + relations = relations.filter( + (relationEntry) => relationEntry.workbookId === entry.workbookId, + ); - let relations = await getRelatedEntries(ctx, { - entryIds: [entryId], - direction: validatedDirection, - }); + relations = relations.map((item) => { + let iamPermissions: Optional; - if (entry.workbookId) { - relations = relations.map((item) => ({ - ...item, - permissions: iamPermissions, - })) as Entry[]; + if (includePermissionsInfo) { + iamPermissions = getEntryPermissionsByWorkbook({ + ctx, + workbook, + scope: entry.scope, + }); + } + + return { + ...item, + permissions: iamPermissions, + }; + }) as Entry[]; } else { if (!isPrivateRoute && ctx.config.dlsEnabled) { relations = await DLS.checkBulkPermission( diff --git a/src/services/new/entry/get-entry-by-key.ts b/src/services/new/entry/get-entry-by-key.ts index a6a9846d..2ebb02bc 100644 --- a/src/services/new/entry/get-entry-by-key.ts +++ b/src/services/new/entry/get-entry-by-key.ts @@ -3,7 +3,7 @@ import {checkFetchedEntry} from './utils'; import {EntryPermissions} from './types'; import {ServiceArgs} from '../types'; import {getReplica} from '../utils'; -import {Entry} from '../../../db/models/new/entry'; +import {Entry, EntryColumn} from '../../../db/models/new/entry'; import {DlsActions} from '../../../types/models'; import {US_ERRORS} from '../../../const'; import Utils, {logInfo} from '../../../utils'; @@ -118,13 +118,14 @@ export const getEntryByKey = async ( if (!isPrivateRoute) { const workbook = await getWorkbook( {ctx, trx}, - {workbookId: joinedEntryRevision.workbookId}, + {workbookId: joinedEntryRevision.workbookId, includePermissionsInfo}, ); if (includePermissionsInfo) { - iamPermissions = await getEntryPermissionsByWorkbook({ + iamPermissions = getEntryPermissionsByWorkbook({ ctx, workbook, + scope: joinedEntryRevision[EntryColumn.Scope], }); } } diff --git a/src/services/new/entry/get-entry.ts b/src/services/new/entry/get-entry.ts index 3d00fd3a..9df44e1c 100644 --- a/src/services/new/entry/get-entry.ts +++ b/src/services/new/entry/get-entry.ts @@ -3,7 +3,7 @@ import {EntryPermissions} from './types'; import {checkFetchedEntry} from './utils'; import {getReplica, checkEntryIdInEmbed} from '../utils'; import {ServiceArgs} from '../types'; -import {Entry} from '../../../db/models/new/entry'; +import {Entry, EntryColumn} from '../../../db/models/new/entry'; import {JoinedEntryRevisionFavorite} from '../../../db/presentations/joined-entry-revision-favorite'; import {DlsActions} from '../../../types/models'; import Utils, {logInfo} from '../../../utils'; @@ -118,13 +118,17 @@ export const getEntry = async ( if (checkWorkbookEnabled) { const workbook = await getWorkbook( {ctx, trx}, - {workbookId: joinedEntryRevisionFavorite.workbookId}, + { + workbookId: joinedEntryRevisionFavorite.workbookId, + includePermissionsInfo, + }, ); if (includePermissionsInfo) { - iamPermissions = await getEntryPermissionsByWorkbook({ + iamPermissions = getEntryPermissionsByWorkbook({ ctx, workbook, + scope: joinedEntryRevisionFavorite[EntryColumn.Scope], }); } } diff --git a/src/services/new/workbook/get-workbook-content.ts b/src/services/new/workbook/get-workbook-content.ts index 20f17076..dab1f615 100644 --- a/src/services/new/workbook/get-workbook-content.ts +++ b/src/services/new/workbook/get-workbook-content.ts @@ -162,19 +162,18 @@ export const getWorkbookContent = async ( const nextPageToken = Utils.getNextPageToken(page, pageSize, entriesPage.total); - let permissions: Optional; - - if (includePermissionsInfo) { - permissions = await getEntryPermissionsByWorkbook({ - ctx, - trx: targetTrx, - workbook, - bypassEnabled: skipCheckPermissions, - }); - } - const entries: Array = entriesPage.results.map((entry) => { + let permissions: Optional; + + if (includePermissionsInfo) { + permissions = getEntryPermissionsByWorkbook({ + ctx, + workbook, + scope: entry.scope, + }); + } + entry.permissions = permissions; entry.isLocked = false; return entry; diff --git a/src/services/new/workbook/utils/get-entry-permissions-by-workbook.ts b/src/services/new/workbook/utils/get-entry-permissions-by-workbook.ts index 647d60c3..8219ea84 100644 --- a/src/services/new/workbook/utils/get-entry-permissions-by-workbook.ts +++ b/src/services/new/workbook/utils/get-entry-permissions-by-workbook.ts @@ -1,55 +1,35 @@ -import {TransactionOrKnex} from 'objection'; import {AppContext} from '@gravity-ui/nodekit'; import {Permissions} from '../../../../entities/workbook'; -import {getParentIds} from '../../collection/utils'; -import {getReplica} from '../../utils'; import type {WorkbookInstance} from '../../../../registry/common/entities/workbook/types'; import {Feature, isEnabledFeature} from '../../../../components/features'; +import type {EntryScope as EntryScopeType} from '../../../../types/models'; +import {EntryScope} from '../../../../db/models/new/entry'; -export const getEntryPermissionsByWorkbook = async ({ +export const getEntryPermissionsByWorkbook = ({ ctx, - trx, workbook, - bypassEnabled, + scope, }: { ctx: AppContext; - trx?: TransactionOrKnex; workbook: WorkbookInstance; - bypassEnabled?: boolean; + scope?: EntryScopeType | null; }) => { - const {accessServiceEnabled} = ctx.config; - - if (!accessServiceEnabled || bypassEnabled) { - return { - execute: true, - read: true, - edit: true, - admin: true, - }; - } - - if (workbook.permissions === undefined) { - let parentIds: string[] = []; - - if (workbook.model.collectionId !== null) { - parentIds = await getParentIds({ - ctx, - trx: getReplica(trx), - collectionId: workbook.model.collectionId, - }); - } - - await workbook.fetchAllPermissions({parentIds}); - } - const permissions = workbook.permissions as Permissions; - return { - execute: isEnabledFeature(ctx, Feature.UseLimitedView) - ? permissions.limitedView - : permissions.view, + const view = isEnabledFeature(ctx, Feature.UseLimitedView) + ? permissions.limitedView + : permissions.view; + + const mappedPermission = { + execute: view, read: permissions.view, edit: permissions.update, admin: permissions.updateAccessBindings, }; + + if (scope === EntryScope.Dash || scope === EntryScope.Widget) { + mappedPermission.read = view; + } + + return mappedPermission; }; diff --git a/src/types/models/tables-columns.ts b/src/types/models/tables-columns.ts index 55b28af9..8f003943 100644 --- a/src/types/models/tables-columns.ts +++ b/src/types/models/tables-columns.ts @@ -83,6 +83,7 @@ export interface LinksColumns { export interface FavoriteColumns { workbookId: string | null; + scope: EntryScope; entryId: string; tenantId: string; login: string;