upgrade access controls to use biome 2

This commit is contained in:
Nate Kelley 2025-10-09 10:19:04 -06:00
parent 30b7d30753
commit a62664184a
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
19 changed files with 97 additions and 102 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -1,7 +1,7 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"extends": ["../../biome.json"],
"$schema": "https://biomejs.dev/schemas/2.2.5/schema.json",
"extends": ["../../biome2.json"],
"files": {
"include": ["src/**/*"]
"includes": ["src/**/*"]
}
}

View File

@ -32,7 +32,8 @@
"@buster/env-utils": "workspace:*",
"@buster/typescript-config": "workspace:*",
"@buster/vitest-config": "workspace:*",
"lru-cache": "^11.1.0",
"@biomejs/biome": "2.2.5",
"lru-cache": "^11.2.2",
"node-sql-parser": "^5.3.12",
"yaml": "^2.8.1",
"zod": "catalog:",

View File

@ -464,11 +464,8 @@ export async function hasAllDatasetsAccess(userId: string, datasetIds: string[])
// --- Step 3: Check specific permissions for each dataset ---
for (const datasetId of input.datasetIds) {
const datasetOrgId = datasetInfos.find(
(info: {
id: string;
organizationId: string;
deletedAt: string | null;
}) => info.id === datasetId
(info: { id: string; organizationId: string; deletedAt: string | null }) =>
info.id === datasetId
)?.organizationId;
if (!datasetOrgId) {

View File

@ -1,9 +1,9 @@
import { beforeEach, describe, expect, it } from 'vitest';
import {
clearAllCaches,
getCacheStats,
getCachedCascadingPermission,
getCachedPermission,
getCacheStats,
invalidateAsset,
invalidateOnPermissionChange,
invalidateUser,

View File

@ -1,10 +1,10 @@
import type { User } from '@buster/database/queries';
import {
checkChatsContainingAsset,
checkCollectionsContainingAsset,
checkDashboardsContainingMetric,
checkReportsContainingMetric,
} from '@buster/database/queries';
import type { User } from '@buster/database/queries';
import type { AssetType } from '@buster/database/schema-types';
import type { AssetPermissionRole, WorkspaceSharing } from '../types/asset-permissions';
import { AccessControlError } from '../types/errors';

View File

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { checkPermission, computeEffectivePermission } from './checks';
import type { AssetPermissionResult } from './checks';
import { checkPermission, computeEffectivePermission } from './checks';
// Mock database queries
vi.mock('@buster/database/queries', () => ({

View File

@ -1,9 +1,9 @@
import type { User } from '@buster/database/queries';
import {
type CheckAssetPermissionParams,
checkAssetPermission as checkDbAssetPermission,
getUserOrganizationsByUserId,
} from '@buster/database/queries';
import type { User } from '@buster/database/queries';
import type { AssetType } from '@buster/database/schema-types';
import type { AssetPermissionRole, OrganizationMembership, WorkspaceSharing } from '../types';
import { getHighestPermission, isPermissionSufficient } from '../types/asset-permissions';

View File

@ -1,6 +1,6 @@
// Asset permissions module exports
export * from './permissions';
export * from './checks';
export * from './cascading-permissions';
export * from './cache';
export * from './cascading-permissions';
export * from './checks';
export * from './permissions';

View File

@ -1,5 +1,5 @@
import { checkPermission } from './checks';
import type { AssetPermissionCheck } from './checks';
import { checkPermission } from './checks';
/**
* Cached version of hasAssetPermission

View File

@ -1,10 +1,10 @@
import {
type ListAssetPermissionsParams,
type RemoveAssetPermissionParams,
bulkCreateAssetPermissions,
createAssetPermission,
findUserByEmail,
type ListAssetPermissionsParams,
listAssetPermissions,
type RemoveAssetPermissionParams,
removeAssetPermission,
} from '@buster/database/queries';
import type { AssetType } from '@buster/database/schema-types';

View File

@ -2,9 +2,9 @@ import { beforeEach, describe, expect, it } from 'vitest';
import type { PermissionedDataset } from '../types/dataset-permissions';
import {
clearAllCaches,
getCacheStats,
getCachedDatasetAccess,
getCachedPermissionedDatasets,
getCacheStats,
invalidateDataset,
invalidateOnPermissionChange,
invalidateUser,

View File

@ -1,4 +1,4 @@
// Dataset permissions module exports
export * from './permissions';
export * from './cache';
export * from './permissions';

View File

@ -1,89 +1,80 @@
// Export all types
export * from './types';
// Export asset permissions (excluding cache functions to avoid conflicts)
export {
// From permissions.ts
hasAssetPermission,
createPermission,
createPermissionByEmail,
removePermission,
removePermissionByEmail,
listPermissions,
// From checks.ts
checkPermission,
computeEffectivePermission,
type AssetPermissionCheck,
type AssetPermissionResult,
// From cascading-permissions.ts
checkCascadingPermissions,
checkMetricDashboardAccess,
checkMetricChatAccess,
checkMetricCollectionAccess,
checkMetricReportAccess,
checkDashboardChatAccess,
checkDashboardCollectionAccess,
} from './assets';
// Export dataset permissions
export * from './datasets';
// Export user utilities
export * from './users';
// Export SQL permissions
export * from './sql-permissions';
// Export cache functions separately
export {
clearAllCaches,
invalidateUser,
invalidateOnPermissionChange,
getCacheStats as getAssetCacheStats,
} from './assets/cache';
// Export legacy access control functionality (for backward compatibility)
export {
AccessControlsError,
type Permission,
type Role,
type AccessControlOptions,
} from './types';
// Export legacy access control functions
export {
checkPermission as legacyCheckPermission,
hasRole,
validateAccess,
getPermissionedDatasets as legacyGetPermissionedDatasets,
hasDatasetAccess as legacyHasDatasetAccess,
hasAllDatasetsAccess as legacyHasAllDatasetsAccess,
hasDatasetAccess as legacyHasDatasetAccess,
hasRole,
type PermissionedDataset as LegacyPermissionedDataset,
validateAccess,
} from './access-controls';
// Export asset permissions (excluding cache functions to avoid conflicts)
export {
type AssetPermissionCheck,
type AssetPermissionResult,
// From cascading-permissions.ts
checkCascadingPermissions,
checkDashboardChatAccess,
checkDashboardCollectionAccess,
checkMetricChatAccess,
checkMetricCollectionAccess,
checkMetricDashboardAccess,
checkMetricReportAccess,
// From checks.ts
checkPermission,
computeEffectivePermission,
createPermission,
createPermissionByEmail,
// From permissions.ts
hasAssetPermission,
listPermissions,
removePermission,
removePermissionByEmail,
} from './assets';
// Export cache functions separately
export {
clearAllCaches,
getCacheStats as getAssetCacheStats,
invalidateOnPermissionChange,
invalidateUser,
} from './assets/cache';
export { canUserAccessChat } from './chats';
// Export cached version and cache management functions
export {
canUserAccessChatCached,
getCacheStats,
resetCacheStats,
clearCache,
getCacheStats,
invalidateAccess,
invalidateUserAccess,
invalidateChatAccess,
invalidateUserAccess,
resetCacheStats,
} from './chats-cached';
// Export utility functions
export { formatPermissionName, buildAccessQuery } from './utils';
// Export dataset permissions
export * from './datasets';
// Export SQL permissions
export * from './sql-permissions';
export * from './types';
// Export legacy access control functionality (for backward compatibility)
export {
type AccessControlOptions,
AccessControlsError,
type Permission,
type Role,
} from './types';
// Export user organization functions
export {
checkUserInOrganization,
getUserOrganizations,
checkEmailDomainForOrganization,
getOrganizationWithDefaults,
checkUserInOrganization,
createUserInOrganization,
type UserOrganizationInfo,
getOrganizationWithDefaults,
getUserOrganizations,
type OrganizationWithDefaults,
type UserOrganizationInfo,
} from './user-organizations';
// Export user utilities
export * from './users';
// Export utility functions
export { buildAccessQuery, formatPermissionName } from './utils';

View File

@ -1,3 +1,3 @@
export * from './execute-with-permission-check';
export * from './parser-helpers';
export * from './validator';
export * from './execute-with-permission-check';

View File

@ -1,10 +1,13 @@
import pkg from 'node-sql-parser';
const { Parser } = pkg;
import type { BaseFrom, ColumnRefItem, Join, Select } from 'node-sql-parser';
import * as yaml from 'yaml';
export type { QueryTypeCheckResult } from '@buster/data-source';
// Import checkQueryIsReadOnly from data-source package
export { checkQueryIsReadOnly } from '@buster/data-source';
export type { QueryTypeCheckResult } from '@buster/data-source';
export interface ParsedTable {
database?: string;
@ -155,7 +158,7 @@ export function extractPhysicalTables(sql: string, dataSourceSyntax?: string): P
*/
export function parseTableReference(tableRef: string): ParsedTable {
// Remove any quotes and trim
let cleanRef = tableRef.replace(/["'`\[\]]/g, '').trim();
let cleanRef = tableRef.replace(/["'`[\]]/g, '').trim();
// Handle node-sql-parser format: "type::database::table" or "type::table"
if (cleanRef.includes('::')) {

View File

@ -1,12 +1,12 @@
import { getPermissionedDatasets } from '../datasets/permissions';
import {
type ParsedDataset,
type ParsedTable,
checkQueryIsReadOnly,
extractColumnReferences,
extractDatasetsFromYml,
extractPhysicalTables,
extractTablesFromYml,
type ParsedDataset,
type ParsedTable,
tablesMatch,
validateWildcardUsage,
} from './parser-helpers';

View File

@ -2,8 +2,8 @@ import { z } from 'zod';
// Re-export all internal types
export * from './types/asset-permissions';
export * from './types/dataset-permissions';
export * from './types/cascading-permissions';
export * from './types/dataset-permissions';
export * from './types/errors';
// Custom error class for access control operations (legacy - use AccessControlError instead)

View File

@ -1016,6 +1016,9 @@ importers:
packages/access-controls:
dependencies:
'@biomejs/biome':
specifier: 2.2.5
version: 2.2.5
'@buster/data-source':
specifier: workspace:*
version: link:../data-source
@ -1035,8 +1038,8 @@ importers:
specifier: 'catalog:'
version: 0.44.5(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(bun-types@1.2.23(@types/react@19.1.13))(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7)
lru-cache:
specifier: ^11.1.0
version: 11.1.0
specifier: ^11.2.2
version: 11.2.2
node-sql-parser:
specifier: ^5.3.12
version: 5.3.12
@ -9568,14 +9571,14 @@ packages:
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
lru-cache@11.1.0:
resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==}
engines: {node: 20 || >=22}
lru-cache@11.2.1:
resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==}
engines: {node: 20 || >=22}
lru-cache@11.2.2:
resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==}
engines: {node: 20 || >=22}
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@ -13215,7 +13218,7 @@ snapshots:
'@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
lru-cache: 11.2.1
lru-cache: 11.2.2
'@asamuzakjp/dom-selector@6.5.4':
dependencies:
@ -22925,10 +22928,10 @@ snapshots:
lru-cache@10.4.3: {}
lru-cache@11.1.0: {}
lru-cache@11.2.1: {}
lru-cache@11.2.2: {}
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@ -24378,7 +24381,7 @@ snapshots:
path-scurry@2.0.0:
dependencies:
lru-cache: 11.2.1
lru-cache: 11.2.2
minipass: 7.1.2
path-to-regexp@0.1.12: {}