diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 20abab13a033e..7418428ade32c 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,5 +1,6 @@ import crypto from 'crypto'; import R from 'ramda'; +import { getEnv } from '@cubejs-backend/shared'; import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler'; import { v4 as uuidv4 } from 'uuid'; import { NativeInstance } from '@cubejs-backend/native'; @@ -421,12 +422,10 @@ export class CompilerApi { } /** - * if RBAC is enabled, this method is used to filter out the cubes that the - * user doesn't have access from meta responses. - * It evaluates all applicable memeberLevel accessPolicies givean a context - * and retains members that are allowed by any policy (most permissive set). + * if RBAC is enabled, this method is used to patch isVisible property of cube members + * based on access policies. */ - async filterVisibilityByAccessPolicy(compilers, context, cubes) { + async patchVisibilityByAccessPolicy(compilers, context, cubes) { const isMemberVisibleInContext = {}; const { cubeEvaluator } = compilers; @@ -467,56 +466,55 @@ export class CompilerApi { } } - const visibilityFilterForCube = (cube) => { + const visibilityPatcherForCube = (cube) => { const evaluatedCube = cubeEvaluator.cubeFromPath(cube.config.name); if (!cubeEvaluator.isRbacEnabledForCube(evaluatedCube)) { - return (item) => item.isVisible; + return (item) => item; } - return (item) => (item.isVisible && isMemberVisibleInContext[item.name] || false); + return (item) => ({ + ...item, + isVisible: item.isVisible && isMemberVisibleInContext[item.name] + }); }; return cubes .map((cube) => ({ config: { ...cube.config, - measures: cube.config.measures?.filter(visibilityFilterForCube(cube)), - dimensions: cube.config.dimensions?.filter(visibilityFilterForCube(cube)), - segments: cube.config.segments?.filter(visibilityFilterForCube(cube)), + measures: cube.config.measures?.map(visibilityPatcherForCube(cube)), + dimensions: cube.config.dimensions?.map(visibilityPatcherForCube(cube)), + segments: cube.config.segments?.map(visibilityPatcherForCube(cube)), }, - })).filter( - cube => cube.config.measures?.length || - cube.config.dimensions?.length || - cube.config.segments?.length - ); + })); } async metaConfig(requestContext, options = {}) { const { includeCompilerId, ...restOptions } = options; const compilers = await this.getCompilers(restOptions); const { cubes } = compilers.metaTransformer; - const filteredCubes = await this.filterVisibilityByAccessPolicy( + const patchedCubes = await this.patchVisibilityByAccessPolicy( compilers, requestContext, cubes ); if (includeCompilerId) { return { - cubes: filteredCubes, + cubes: patchedCubes, compilerId: compilers.compilerId, }; } - return filteredCubes; + return patchedCubes; } async metaConfigExtended(requestContext, options) { const compilers = await this.getCompilers(options); - const filteredCubes = await this.filterVisibilityByAccessPolicy( + const patchedCubes = await this.patchVisibilityByAccessPolicy( compilers, requestContext, compilers.metaTransformer?.cubes ); return { - metaConfig: filteredCubes, + metaConfig: patchedCubes, cubeDefinitions: compilers.metaTransformer?.cubeEvaluator?.cubeDefinitions, }; }