diff --git a/packages/access-controls/src/datasets/cache.ts b/packages/access-controls/src/datasets/cache.ts index d9b4bb415..b963b5ef9 100644 --- a/packages/access-controls/src/datasets/cache.ts +++ b/packages/access-controls/src/datasets/cache.ts @@ -1,5 +1,5 @@ import { LRUCache } from 'lru-cache'; -import type { PermissionedDataset } from '../types/dataset-permissions'; +import type { DatasetAccessPath, PermissionedDataset } from '../types/dataset-permissions'; // Cache for dataset permissions - stores arrays of accessible datasets per user const datasetCache = new LRUCache< @@ -15,7 +15,13 @@ const datasetCache = new LRUCache< }); // Cache for individual dataset access checks -const accessCache = new LRUCache({ +interface CachedDatasetAccess { + hasAccess: boolean; + accessPath?: DatasetAccessPath; + userRole?: string; +} + +const accessCache = new LRUCache({ max: 5000, // Maximum 5k entries ttl: 30 * 1000, // 30 seconds updateAgeOnGet: true, @@ -63,7 +69,10 @@ export function setCachedPermissionedDatasets( /** * Get cached dataset access check result */ -export function getCachedDatasetAccess(userId: string, datasetId: string): boolean | undefined { +export function getCachedDatasetAccess( + userId: string, + datasetId: string +): CachedDatasetAccess | undefined { const key = `access:${userId}:${datasetId}`; const cached = accessCache.get(key); @@ -82,10 +91,10 @@ export function getCachedDatasetAccess(userId: string, datasetId: string): boole export function setCachedDatasetAccess( userId: string, datasetId: string, - hasAccess: boolean + accessResult: CachedDatasetAccess ): void { const key = `access:${userId}:${datasetId}`; - accessCache.set(key, hasAccess); + accessCache.set(key, accessResult); } /** diff --git a/packages/access-controls/src/datasets/permissions.ts b/packages/access-controls/src/datasets/permissions.ts index 86003f6b5..6f7af9397 100644 --- a/packages/access-controls/src/datasets/permissions.ts +++ b/packages/access-controls/src/datasets/permissions.ts @@ -28,7 +28,7 @@ export interface DatasetListResult { /** * Get all datasets a user has permission to access - * Implements the 5 access paths from the Rust code + * Implements the 6 access paths from the Rust code */ export async function getPermissionedDatasets( params: DatasetListParams @@ -88,18 +88,19 @@ export async function checkDatasetAccess(params: DatasetAccessCheck): Promise { const result = await db - .select({ count: assetPermissions.identityId }) + .select({ count: sql`COUNT(*)` }) .from(assetPermissions) .where( and( @@ -136,5 +136,5 @@ export async function countAssetPermissions( ) ); - return result.length; + return result[0]?.count ?? 0; } diff --git a/packages/database/src/queries/dataset-permissions/check-dataset-access.ts b/packages/database/src/queries/dataset-permissions/check-dataset-access.ts index d745852ca..1763e5e6e 100644 --- a/packages/database/src/queries/dataset-permissions/check-dataset-access.ts +++ b/packages/database/src/queries/dataset-permissions/check-dataset-access.ts @@ -26,7 +26,7 @@ export interface DatasetAccessResult { /** * Check if a user has access to a specific dataset - * Implements all 5 access paths from the Rust code + * Implements all 6 access paths from the Rust code */ export async function hasDatasetAccess( userId: string, diff --git a/packages/database/src/schema-types/enums.ts b/packages/database/src/schema-types/enums.ts index 958ea0e80..d92d6a2a9 100644 --- a/packages/database/src/schema-types/enums.ts +++ b/packages/database/src/schema-types/enums.ts @@ -28,4 +28,9 @@ export type IdentityType = 'user' | 'team' | 'organization'; export type WorkspaceSharing = 'none' | 'can_view' | 'can_edit' | 'full_access'; -export type UserOrganizationRole = 'workspace_admin' | 'data_admin' | 'querier' | 'viewer'; +export type UserOrganizationRole = + | 'workspace_admin' + | 'data_admin' + | 'querier' + | 'restricted_querier' + | 'viewer'; diff --git a/packages/server-shared/src/assets/asset-types.types.ts b/packages/server-shared/src/assets/asset-types.types.ts index dbbeabb05..0782a0d55 100644 --- a/packages/server-shared/src/assets/asset-types.types.ts +++ b/packages/server-shared/src/assets/asset-types.types.ts @@ -1,5 +1,20 @@ import { z } from 'zod'; -export const AssetTypeSchema = z.enum(['metric', 'dashboard', 'collection', 'chat']); +export const AssetTypeSchema = z.enum([ + 'dashboard', + 'thread', + 'chat', + 'metric_file', + 'dashboard_file', + 'collection', + 'data_source', + 'metric', + 'filter', + 'dataset', + 'tool', + 'source', + 'collection_file', + 'dataset_permission', +]); export type AssetType = z.infer;