From c77fe3b5ae6760bb76c39d29a55c63b564afad4b Mon Sep 17 00:00:00 2001 From: Maxim Leonovich Date: Wed, 6 Nov 2024 13:49:34 -0800 Subject: [PATCH 1/2] fix: ignore Data Access Policy-defined visibility in dev-mode and playground --- packages/cubejs-server-core/src/core/CompilerApi.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 20abab13a033e..09e2097a2e18e 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'; @@ -468,11 +469,14 @@ export class CompilerApi { } const visibilityFilterForCube = (cube) => { + const isDevMode = getEnv('devMode'); const evaluatedCube = cubeEvaluator.cubeFromPath(cube.config.name); if (!cubeEvaluator.isRbacEnabledForCube(evaluatedCube)) { - return (item) => item.isVisible; + return (item) => isDevMode || context.signedWithPlaygroundAuthSecret || item.isVisible; } - return (item) => (item.isVisible && isMemberVisibleInContext[item.name] || false); + return (item) => ( + (isDevMode || context.signedWithPlaygroundAuthSecret || item.isVisible) && + isMemberVisibleInContext[item.name] || false); }; return cubes From 0fa361638f2f612fd23f4eb42d7bbab9ff88cb41 Mon Sep 17 00:00:00 2001 From: Maxim Leonovich Date: Wed, 6 Nov 2024 15:21:34 -0800 Subject: [PATCH 2/2] fix: patch isVisible when applying member level policies --- .../src/core/CompilerApi.js | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 09e2097a2e18e..7418428ade32c 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -422,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; @@ -468,59 +466,55 @@ export class CompilerApi { } } - const visibilityFilterForCube = (cube) => { - const isDevMode = getEnv('devMode'); + const visibilityPatcherForCube = (cube) => { const evaluatedCube = cubeEvaluator.cubeFromPath(cube.config.name); if (!cubeEvaluator.isRbacEnabledForCube(evaluatedCube)) { - return (item) => isDevMode || context.signedWithPlaygroundAuthSecret || item.isVisible; + return (item) => item; } - return (item) => ( - (isDevMode || context.signedWithPlaygroundAuthSecret || 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, }; }