@cubejs-backend/testing 1.6.38 → 1.6.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -186,6 +186,42 @@ module.exports = {
186
186
  },
187
187
  };
188
188
  }
189
+ if (user === 'region_user') {
190
+ if (password && password !== 'region_user_password') {
191
+ throw new Error(`Password doesn't match for ${user}`);
192
+ }
193
+ return {
194
+ password,
195
+ superuser: false,
196
+ securityContext: {
197
+ auth: {
198
+ username: 'region_user',
199
+ userAttributes: {
200
+ allowedProductIds: [1, 2],
201
+ },
202
+ roles: [],
203
+ groups: ['user_group', 'region_group'],
204
+ },
205
+ },
206
+ };
207
+ }
208
+ if (user === 'region_user_no_filter') {
209
+ if (password && password !== 'region_user_no_filter_password') {
210
+ throw new Error(`Password doesn't match for ${user}`);
211
+ }
212
+ return {
213
+ password,
214
+ superuser: false,
215
+ securityContext: {
216
+ auth: {
217
+ username: 'region_user_no_filter',
218
+ userAttributes: {},
219
+ roles: [],
220
+ groups: ['user_group'],
221
+ },
222
+ },
223
+ };
224
+ }
189
225
  if (user === 'sc_test') {
190
226
  if (password && password !== 'sc_test_password') {
191
227
  throw new Error(`Password doesn't match for ${user}`);
@@ -132,6 +132,92 @@ cubes:
132
132
  member_masking:
133
133
  includes: "*"
134
134
 
135
+ # Cube exercising different reference forms inside a mask.sql on a member
136
+ # that is re-exposed via a prefixed view. Each masked dimension encodes its
137
+ # reference style; the view tests exercise routing them through the view
138
+ # alias (e.g. `view_mask_test.base_pid_full`). Mask compiles in the owning
139
+ # cube's context so CUBE / cross-cube references resolve the same way as
140
+ # on the underlying cube. Names are kept short to stay under Postgres's
141
+ # 63-char identifier limit once the view prefix is added.
142
+ - name: view_mask_base
143
+ sql_table: public.line_items
144
+
145
+ dimensions:
146
+ - name: id
147
+ sql: id
148
+ type: number
149
+ primary_key: true
150
+
151
+ - name: product_id
152
+ sql: product_id
153
+ type: number
154
+
155
+ # Reference form: {cube.member}
156
+ - name: pid_full
157
+ sql: product_id
158
+ type: number
159
+ mask:
160
+ sql: |
161
+ CASE
162
+ WHEN { groups.filter("'sensitive_data_access'") }
163
+ THEN {view_mask_base.product_id}
164
+ ELSE -1
165
+ END
166
+
167
+ # Reference form: {CUBE.member}
168
+ - name: pid_cube_ref
169
+ sql: product_id
170
+ type: number
171
+ mask:
172
+ sql: |
173
+ CASE
174
+ WHEN { groups.filter("'sensitive_data_access'") }
175
+ THEN {CUBE.product_id}
176
+ ELSE -1
177
+ END
178
+
179
+ # Reference form: {CUBE}.column
180
+ - name: pid_cube_col
181
+ sql: product_id
182
+ type: number
183
+ mask:
184
+ sql: |
185
+ CASE
186
+ WHEN { groups.filter("'sensitive_data_access'") }
187
+ THEN {CUBE}.product_id
188
+ ELSE -1
189
+ END
190
+
191
+ # Reference form: {cube}.column (literal cube name)
192
+ - name: pid_cube_name
193
+ sql: product_id
194
+ type: number
195
+ mask:
196
+ sql: |
197
+ CASE
198
+ WHEN { groups.filter("'sensitive_data_access'") }
199
+ THEN {view_mask_base}.product_id
200
+ ELSE -1
201
+ END
202
+
203
+ measures:
204
+ - name: count
205
+ type: count
206
+
207
+ access_policy:
208
+ - role: "*"
209
+ member_level:
210
+ includes:
211
+ - id
212
+ - product_id
213
+ - count
214
+ member_masking:
215
+ includes:
216
+ - pid_full
217
+ - pid_cube_ref
218
+ - pid_cube_col
219
+ - pid_cube_name
220
+
135
221
  views:
136
222
  # View with full access at view level - but cube masking still applies (RLS pattern)
137
223
  # Excludes members with {CUBE} references in SQL (secret_string, secret_boolean)
@@ -198,6 +284,39 @@ views:
198
284
  row_level:
199
285
  allow_all: true
200
286
 
287
+ # View re-exposing masks from view_mask_base through a prefixed join-path.
288
+ # Mirrors the user-reported scenario of a view that carries masks written
289
+ # with different cube reference styles; the mask must still compile and
290
+ # resolve against the underlying cube.
291
+ - name: view_mask_test
292
+ public: true
293
+
294
+ cubes:
295
+ - join_path: view_mask_base
296
+ prefix: true
297
+ includes:
298
+ - id
299
+ - product_id
300
+ - pid_full
301
+ - pid_cube_ref
302
+ - pid_cube_col
303
+ - pid_cube_name
304
+ - count
305
+
306
+ access_policy:
307
+ - role: "*"
308
+ member_level:
309
+ includes:
310
+ - view_mask_base_id
311
+ - view_mask_base_product_id
312
+ - view_mask_base_count
313
+ member_masking:
314
+ includes:
315
+ - view_mask_base_pid_full
316
+ - view_mask_base_pid_cube_ref
317
+ - view_mask_base_pid_cube_col
318
+ - view_mask_base_pid_cube_name
319
+
201
320
  # View over a cube where all members are hidden.
202
321
  # The view adds its own masking policy — members that are invisible at
203
322
  # the cube level become accessible (some masked, some real) through the view.
@@ -0,0 +1,24 @@
1
+ cubes:
2
+ - name: region_test
3
+ sql_table: public.line_items
4
+
5
+ measures:
6
+ - name: count
7
+ type: count
8
+
9
+ dimensions:
10
+ - name: id
11
+ sql: id
12
+ type: number
13
+ primary_key: true
14
+
15
+ - name: product_id
16
+ sql: product_id
17
+ type: number
18
+
19
+ access_policy:
20
+ - role: "*"
21
+ member_level:
22
+ includes: "*"
23
+ row_level:
24
+ allow_all: true
@@ -0,0 +1,24 @@
1
+ views:
2
+ - name: region_test_view
3
+ cubes:
4
+ - join_path: region_test
5
+ includes: "*"
6
+ access_policy:
7
+ - group: user_group
8
+ conditions:
9
+ - if: "{ security_context.auth.groups and security_context.auth.groups.includes('region_group') }"
10
+ member_level:
11
+ includes: "*"
12
+ row_level:
13
+ filters:
14
+ - member: product_id
15
+ operator: equals
16
+ values: security_context.auth.userAttributes.allowedProductIds
17
+
18
+ - group: user_group
19
+ conditions:
20
+ - if: "{ not (security_context.auth.groups and security_context.auth.groups.includes('region_group')) }"
21
+ member_level:
22
+ includes: "*"
23
+ row_level:
24
+ allow_all: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cubejs-backend/testing",
3
- "version": "1.6.38",
3
+ "version": "1.6.40",
4
4
  "description": "Cube.js e2e tests",
5
5
  "author": "Cube Dev, Inc.",
6
6
  "repository": {
@@ -100,15 +100,15 @@
100
100
  "birdbox-fixtures"
101
101
  ],
102
102
  "dependencies": {
103
- "@cubejs-backend/cubestore-driver": "1.6.38",
103
+ "@cubejs-backend/cubestore-driver": "1.6.40",
104
104
  "@cubejs-backend/dotenv": "^9.0.2",
105
- "@cubejs-backend/ksql-driver": "1.6.38",
106
- "@cubejs-backend/postgres-driver": "1.6.38",
107
- "@cubejs-backend/query-orchestrator": "1.6.38",
108
- "@cubejs-backend/schema-compiler": "1.6.38",
109
- "@cubejs-backend/shared": "1.6.38",
110
- "@cubejs-backend/testing-shared": "1.6.38",
111
- "@cubejs-client/ws-transport": "1.6.38",
105
+ "@cubejs-backend/ksql-driver": "1.6.40",
106
+ "@cubejs-backend/postgres-driver": "1.6.40",
107
+ "@cubejs-backend/query-orchestrator": "1.6.40",
108
+ "@cubejs-backend/schema-compiler": "1.6.40",
109
+ "@cubejs-backend/shared": "1.6.40",
110
+ "@cubejs-backend/testing-shared": "1.6.40",
111
+ "@cubejs-client/ws-transport": "1.6.40",
112
112
  "dedent": "^0.7.0",
113
113
  "fs-extra": "^8.1.0",
114
114
  "http-proxy": "^1.18.1",
@@ -119,8 +119,8 @@
119
119
  },
120
120
  "devDependencies": {
121
121
  "@4tw/cypress-drag-drop": "^1.6.0",
122
- "@cubejs-backend/linter": "1.6.38",
123
- "@cubejs-client/core": "1.6.38",
122
+ "@cubejs-backend/linter": "1.6.40",
123
+ "@cubejs-client/core": "1.6.40",
124
124
  "@jest/globals": "^29",
125
125
  "@types/dedent": "^0.7.0",
126
126
  "@types/http-proxy": "^1.17.5",
@@ -146,5 +146,5 @@
146
146
  "eslintConfig": {
147
147
  "extends": "../cubejs-linter"
148
148
  },
149
- "gitHead": "7f1ec2ec0b59a9a0e4749b8edff17326b0423ebb"
149
+ "gitHead": "ca686109d640b6b9e8ba0f4dc484f6de266d5860"
150
150
  }