Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion services/actions/src/rpc/updateTeamSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import { invalidateAllUserCaches } from "../utils/cubeCache.js";
import { fetchGraphQL } from "../utils/graphql.js";
import { isPortalAdmin } from "../utils/portalAdmin.js";

const getTeamQuery = `
query GetTeamSettings($team_id: uuid!) {
teams_by_pk(id: $team_id) {
settings
}
}
`;

const updateTeamSettingsMutation = `
mutation ($team_id: uuid!, $settings: jsonb!) {
update_teams_by_pk(pk_columns: {id: $team_id}, _set: {settings: $settings}) {
Expand Down Expand Up @@ -94,10 +102,22 @@ export default async (session, input, headers) => {
};
}

// Read current settings and merge to avoid overwriting existing keys
const currentRes = await fetchGraphQL(getTeamQuery, { team_id: teamId });
const currentSettings = currentRes?.data?.teams_by_pk?.settings || {};
const merged = { ...currentSettings };
for (const [key, value] of Object.entries(settings)) {
if (value === null) {
delete merged[key];
} else {
merged[key] = value;
}
}

// Update team settings
const res = await fetchGraphQL(
updateTeamSettingsMutation,
{ team_id: teamId, settings },
{ team_id: teamId, settings: merged },
headers?.authorization
);

Expand Down
2 changes: 2 additions & 0 deletions services/cubejs/src/utils/defineUserScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ export const getDataSourceAccessList = (
}

const { access_list: accessList } = dataSourceMemberRole;
const hasAccessList = accessList != null;
const dataSourceAccessList =
accessList?.config?.datasources?.[selectedDataSourceId]?.cubes;

return {
role: dataSourceMemberRole?.team_role,
hasAccessList,
dataSourceAccessList,
};
};
Expand Down
10 changes: 9 additions & 1 deletion services/cubejs/src/utils/queryRewrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function extractCubeNames(query) {
*/
const queryRewrite = async (query, { securityContext }) => {
const { userScope } = securityContext;
const { dataSourceAccessList, role, teamProperties, memberProperties } = userScope;
const { dataSourceAccessList, hasAccessList, role, teamProperties, memberProperties } = userScope;

// --- Step 1: Rule-based row filtering (applies to ALL roles) ---
const rules = await loadRules();
Expand Down Expand Up @@ -139,6 +139,14 @@ const queryRewrite = async (query, { securityContext }) => {
return query;
}

// No access list assigned (access_list_id is NULL) → no restrictions configured.
// Auto-provisioned members start without an access list and get full access
// until an admin explicitly assigns one to scope their permissions.
if (!hasAccessList) {
return query;
}

// Access list IS assigned but has no entry for this datasource → deny.
if (!dataSourceAccessList) {
throw new Error("403: You have no access to the datasource");
}
Expand Down
Loading