diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 2ac55b19cb22e..65f8c31a9130b 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,6 +1,5 @@ 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'; @@ -439,17 +438,18 @@ export class CompilerApi { const applicablePolicies = await this.getApplicablePolicies(evaluatedCube, context, compilers); const computeMemberVisibility = (item) => { - let isIncluded = false; - let isExplicitlyExcluded = false; for (const policy of applicablePolicies) { if (policy.memberLevel) { - isIncluded = policy.memberLevel.includesMembers.includes(item.name) || isIncluded; - isExplicitlyExcluded = policy.memberLevel.excludesMembers.includes(item.name) || isExplicitlyExcluded; + if (policy.memberLevel.includesMembers.includes(item.name) && + !policy.memberLevel.excludesMembers.includes(item.name)) { + return true; + } } else { - isIncluded = true; + // If there's no memberLevel policy, we assume that all members are visible + return true; } } - return isIncluded && !isExplicitlyExcluded; + return false; }; for (const dimension of cube.config.dimensions) { diff --git a/packages/cubejs-testing/birdbox-fixtures/rbac/model/cubes/line_items.js b/packages/cubejs-testing/birdbox-fixtures/rbac/model/cubes/line_items.js index c4941a5051b73..7013052b0169e 100644 --- a/packages/cubejs-testing/birdbox-fixtures/rbac/model/cubes/line_items.js +++ b/packages/cubejs-testing/birdbox-fixtures/rbac/model/cubes/line_items.js @@ -55,7 +55,10 @@ cube('line_items', { // This is to test dynamic values based on security context values: [`${security_context.auth?.userAttributes?.minDefaultId || 20000}`], }] - } + }, + memberLevel: { + excludes: ['count', 'price', 'price_dim'], + }, }, { role: 'admin', @@ -69,7 +72,7 @@ cube('line_items', { allowAll: true, }, memberLevel: { - excludes: ['created_at'], + excludes: ['price_dim'], }, }, { diff --git a/packages/cubejs-testing/test/__snapshots__/smoke-rbac.test.ts.snap b/packages/cubejs-testing/test/__snapshots__/smoke-rbac.test.ts.snap index b429076171933..256ad6116bd81 100644 --- a/packages/cubejs-testing/test/__snapshots__/smoke-rbac.test.ts.snap +++ b/packages/cubejs-testing/test/__snapshots__/smoke-rbac.test.ts.snap @@ -1,46 +1,46 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Cube RBAC Engine RBAC via REST API line_items hidden created_at: line_items_view_no_policy_rest 1`] = ` +exports[`Cube RBAC Engine RBAC via REST API line_items hidden price_dim: line_items_view_no_policy_rest 1`] = ` Array [ Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-01-01T23:00:21.000", + "line_items_view_no_policy.count": "3", + "line_items_view_no_policy.price_dim": 33, }, Object { "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-02-27T06:09:59.000", + "line_items_view_no_policy.price_dim": 34, }, Object { "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-02-27T11:38:04.000", + "line_items_view_no_policy.price_dim": 35, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-03-06T17:41:43.000", + "line_items_view_no_policy.count": "7", + "line_items_view_no_policy.price_dim": 36, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-03-07T19:41:43.000", + "line_items_view_no_policy.count": "3", + "line_items_view_no_policy.price_dim": 37, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-03-13T22:34:22.000", + "line_items_view_no_policy.count": "3", + "line_items_view_no_policy.price_dim": 38, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-03-21T21:13:47.000", + "line_items_view_no_policy.count": "2", + "line_items_view_no_policy.price_dim": 39, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-05-01T07:26:55.000", + "line_items_view_no_policy.count": "3", + "line_items_view_no_policy.price_dim": 40, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-05-13T07:03:15.000", + "line_items_view_no_policy.count": "5", + "line_items_view_no_policy.price_dim": 41, }, Object { - "line_items_view_no_policy.count": "1", - "line_items_view_no_policy.created_at": "2016-05-15T22:44:26.000", + "line_items_view_no_policy.count": "2", + "line_items_view_no_policy.price_dim": 42, }, ] `; @@ -98,80 +98,80 @@ Array [ "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2018-10-23T07:54:39.000Z, "price": 267, - "price_dim": 267, "quantity": 2, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2018-01-01T13:50:20.000Z, "price": 263, - "price_dim": 263, "quantity": 7, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2017-05-13T21:23:08.000Z, "price": 180, - "price_dim": 180, "quantity": 8, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2018-04-10T22:51:15.000Z, "price": 169, - "price_dim": 169, "quantity": 6, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2017-07-16T15:00:34.000Z, "price": 156, - "price_dim": 156, "quantity": 1, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2019-05-23T04:25:27.000Z, "price": 36, - "price_dim": 36, "quantity": 5, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2018-09-29T20:29:30.000Z, "price": 245, - "price_dim": 245, "quantity": 4, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2019-04-17T03:32:54.000Z, "price": 232, - "price_dim": 232, "quantity": 8, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2019-11-15T18:22:17.000Z, "price": 63, - "price_dim": 63, "quantity": 8, }, Object { "__cubeJoinField": null, "__user": null, "count": "1", + "created_at": 2019-12-16T08:09:36.000Z, "price": 68, - "price_dim": 68, "quantity": 6, }, ] diff --git a/packages/cubejs-testing/test/smoke-rbac.test.ts b/packages/cubejs-testing/test/smoke-rbac.test.ts index 4a326289580ca..763844635510e 100644 --- a/packages/cubejs-testing/test/smoke-rbac.test.ts +++ b/packages/cubejs-testing/test/smoke-rbac.test.ts @@ -203,12 +203,12 @@ describe('Cube RBAC Engine', () => { }); }); - test('line_items hidden created_at', async () => { + test('line_items hidden price_dim', async () => { let query: Query = { measures: ['line_items.count'], - dimensions: ['line_items.created_at'], + dimensions: ['line_items.price_dim'], order: { - 'line_items.created_at': 'asc', + 'line_items.price_dim': 'asc', }, }; let error = ''; @@ -220,9 +220,9 @@ describe('Cube RBAC Engine', () => { expect(error).toContain('You requested hidden member'); query = { measures: ['line_items_view_no_policy.count'], - dimensions: ['line_items_view_no_policy.created_at'], + dimensions: ['line_items_view_no_policy.price_dim'], order: { - 'line_items_view_no_policy.created_at': 'asc', + 'line_items_view_no_policy.price_dim': 'asc', }, limit: 10, };