From 9fc6c81119a4e587094756d6d247593bd892390a Mon Sep 17 00:00:00 2001 From: Thomas Draier Date: Fri, 3 Jan 2025 15:18:15 +0100 Subject: [PATCH] Revert "[front] Allow multiple wrappers to run and fetch resources (#9682)" (#9738) This reverts commit 4030dd04b397bf3029c8d1123dad6b4fc4854774. --- front/lib/api/resource_wrappers.ts | 389 +++++------------- .../apps/[aId]/runs/[runId]/index.ts | 4 +- .../spaces/[spaceId]/apps/[aId]/runs/index.ts | 5 +- .../v1/w/[wId]/spaces/[spaceId]/apps/index.ts | 4 +- .../data_source_views/[dsvId]/index.ts | 37 +- .../data_source_views/[dsvId]/search.ts | 27 +- .../[spaceId]/data_source_views/index.ts | 4 +- .../data_sources/[dsId]/folders/[fId].ts | 36 +- .../data_sources/[dsId]/folders/index.ts | 16 +- .../spaces/[spaceId]/data_sources/index.ts | 4 +- .../apps/[aId]/datasets/[name]/index.ts | 5 +- .../[spaceId]/apps/[aId]/datasets/index.ts | 7 +- .../spaces/[spaceId]/apps/[aId]/index.ts | 5 +- .../[runId]/blocks/[type]/[name]/index.ts | 7 +- .../apps/[aId]/runs/[runId]/status.ts | 5 +- .../spaces/[spaceId]/apps/[aId]/runs/index.ts | 7 +- .../spaces/[spaceId]/apps/[aId]/state.ts | 5 +- .../w/[wId]/spaces/[spaceId]/apps/index.ts | 4 +- .../[dsvId]/content-nodes.ts | 29 +- .../[dsvId]/documents/[documentId]/index.ts | 23 +- .../data_source_views/[dsvId]/index.ts | 29 +- .../[dsvId]/tables/[tableId]/index.ts | 22 +- .../data_source_views/[dsvId]/tables/index.ts | 29 +- .../[spaceId]/data_source_views/index.ts | 5 +- .../data_sources/[dsId]/configuration.ts | 4 +- .../[dsId]/documents/[documentId]/index.ts | 5 +- .../data_sources/[dsId]/documents/index.ts | 4 +- .../[spaceId]/data_sources/[dsId]/index.ts | 4 +- .../[dsId]/tables/[tableId]/index.ts | 14 +- .../data_sources/[dsId]/tables/index.ts | 4 +- .../spaces/[spaceId]/data_sources/index.ts | 4 +- .../api/w/[wId]/spaces/[spaceId]/index.ts | 4 +- .../api/w/[wId]/spaces/[spaceId]/members.ts | 15 +- .../spaces/[spaceId]/trackers/[tId]/index.ts | 4 +- .../[wId]/spaces/[spaceId]/trackers/index.ts | 4 +- 35 files changed, 302 insertions(+), 472 deletions(-) diff --git a/front/lib/api/resource_wrappers.ts b/front/lib/api/resource_wrappers.ts index 82ef9c15e5d1..ec7f808cb980 100644 --- a/front/lib/api/resource_wrappers.ts +++ b/front/lib/api/resource_wrappers.ts @@ -4,102 +4,47 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { Authenticator } from "@app/lib/auth"; import type { SessionWithUser } from "@app/lib/iam/provider"; import { DataSourceResource } from "@app/lib/resources/data_source_resource"; -import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; import { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; -const RESOURCE_KEYS = ["space", "dataSource", "dataSourceView"] as const; - -type ResourceKey = (typeof RESOURCE_KEYS)[number]; - // This is a type that represents the resources that can be extracted from an API route type KeyToResource = { space: SpaceResource; dataSource: DataSourceResource; - dataSourceView: DataSourceViewResource; }; -type ResourceMap = { - [K in U]: KeyToResource[K]; -}; +type ResourceMap = { [K in ResourceKey]: KeyToResource[K] }; -type OptionsMap = { - [K in U]: { - requireCanAdministrate?: boolean; - requireCanList?: boolean; - requireCanRead?: boolean; - requireCanWrite?: boolean; - }; -}; +type ResourceKey = keyof KeyToResource; -// Resolvers must be in reverse order : last one is applied first. -const resolvers = [ - withDataSourceViewFromRoute, - withDataSourceFromRoute, - withSpaceFromRoute, -]; +const resolver: { + [K in ResourceKey]: ( + handler: ResourceHandler + ) => ( + req: NextApiRequest, + res: NextApiResponse>, + auth: Authenticator, + sessionOrKeyAuthType: A + ) => Promise | void; +} = { + space: withSpaceFromRoute, + dataSource: withDataSourceFromRoute, +}; type SessionOrKeyAuthType = Authenticator | SessionWithUser | null; -type ResourceResolver = ( - req: NextApiRequest, - res: NextApiResponse>, - auth: Authenticator, - resources: Partial>, - options: Partial>, - sessionOrKeyAuth: A -) => Promise | void; - -type HandlerWithResources< +type ResourceHandler< T, - A extends SessionOrKeyAuthType, U extends ResourceKey, + A extends SessionOrKeyAuthType, > = ( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - resources: ResourceMap, + routeResource: ResourceMap[U], sessionOrKeyAuth: A ) => Promise | void; -function isResourceMap( - obj: any, - keys: ResourceKey[] -): obj is ResourceMap { - return keys.every((key) => key in obj); -} - -function spaceCheck(space: SpaceResource | null): space is SpaceResource { - return (space && !space.isConversations()) ?? false; -} - -function hasPermission( - auth: Authenticator, - resource: SpaceResource | DataSourceResource | DataSourceViewResource, - options: - | { - requireCanAdministrate?: boolean; - requireCanList?: boolean; - requireCanRead?: boolean; - requireCanWrite?: boolean; - } - | true - | undefined -) { - if (typeof options === "object") { - if ( - (options.requireCanAdministrate === true && - !resource.canAdministrate(auth)) || - (options.requireCanList === true && !resource.canList(auth)) || - (options.requireCanRead === true && !resource.canRead(auth)) || - (options.requireCanWrite === true && !resource.canWrite(auth)) - ) { - return false; - } - } - return true; -} - /* * API routes containing resource strings that require some handling logic can * use this wrapper to extract the resource, make the checks, apply the logic @@ -111,45 +56,8 @@ export function withResourceFetchingFromRoute< T, U extends ResourceKey, A extends SessionOrKeyAuthType, ->( - handler: HandlerWithResources, - options: OptionsMap -): ( - req: NextApiRequest, - res: NextApiResponse>, - auth: Authenticator, - sessionOrKeyAuth: A -) => Promise | void { - const wrappedHandler = resolvers.reduce( - (acc, resolver) => resolver(acc), - ( - req: NextApiRequest, - res: NextApiResponse>, - auth: Authenticator, - resources: Partial>, - options: Partial>, - sessionOrKeyAuth: A - ) => { - const keys = RESOURCE_KEYS.filter((key) => key in options); - if (!isResourceMap(resources, keys)) { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Invalid parameters.", - }, - }); - } - return handler(req, res, auth, resources, sessionOrKeyAuth); - } - ); - - return ( - req: NextApiRequest, - res: NextApiResponse>, - auth: Authenticator, - sessionOrKeyAuth: A - ) => wrappedHandler(req, res, auth, {}, options, sessionOrKeyAuth); +>(handler: ResourceHandler, resource: U) { + return resolver[resource](handler); } /** @@ -157,62 +65,48 @@ export function withResourceFetchingFromRoute< * not a conversation space, etc. and provide the space resource to the handler. */ function withSpaceFromRoute( - handler: ResourceResolver -): ResourceResolver { + handler: ResourceHandler +) { return async ( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - resources: Partial>, - options: Partial>, sessionOrKeyAuth: A ) => { const { spaceId } = req.query; - if (spaceId) { - // Handling the case where `spaceId` is undefined to keep support for the - // legacy endpoint for v1 routes (global space assumed in that case). - const shouldKeepLegacyEndpointSupport = - sessionOrKeyAuth === null || sessionOrKeyAuth instanceof Authenticator; - - if (typeof spaceId !== "string" && !shouldKeepLegacyEndpointSupport) { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Invalid space id.", - }, - }); - } - - const space = - shouldKeepLegacyEndpointSupport && typeof spaceId !== "string" - ? await SpaceResource.fetchWorkspaceGlobalSpace(auth) - : // casting is fine since conditions checked above exclude - // possibility of `spaceId` being undefined - await SpaceResource.fetchById(auth, spaceId as string); - - if (!spaceCheck(space) || !hasPermission(auth, space, options.space)) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "space_not_found", - message: "The space you requested was not found.", - }, - }); - } - - return handler( - req, - res, - auth, - { ...resources, space }, - options, - sessionOrKeyAuth - ); + // Handling the case where `spaceId` is undefined to keep support for the + // legacy endpoint for v1 routes (global space assumed in that case). + const shouldKeepLegacyEndpointSupport = + sessionOrKeyAuth === null || sessionOrKeyAuth instanceof Authenticator; + + if (typeof spaceId !== "string" && !shouldKeepLegacyEndpointSupport) { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid space id.", + }, + }); } - return handler(req, res, auth, resources, options, sessionOrKeyAuth); + const space = + shouldKeepLegacyEndpointSupport && typeof spaceId !== "string" + ? await SpaceResource.fetchWorkspaceGlobalSpace(auth) + : // casting is fine since conditions checked above exclude + // possibility of `spaceId` being undefined + await SpaceResource.fetchById(auth, spaceId as string); + + if (!space || !space.canList(auth) || space.isConversations()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "space_not_found", + message: "The space you requested was not found.", + }, + }); + } + return handler(req, res, auth, space, sessionOrKeyAuth); }; } @@ -222,131 +116,44 @@ function withSpaceFromRoute( * also supports the legacy usage of connectors with /w/[wId]/data_source/[dsId]/ */ function withDataSourceFromRoute( - handler: ResourceResolver -): ResourceResolver { + handler: ResourceHandler +) { return async ( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - resources: Partial>, - options: Partial>, sessionOrKeyAuth: A ) => { const { dsId } = req.query; + const { wId } = req.query; + if (typeof dsId !== "string" || typeof wId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } - if (dsId) { - if (typeof dsId !== "string") { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Invalid path parameters.", - }, - }); - } - - const dataSource = await DataSourceResource.fetchById(auth, dsId); - - const shouldKeepLegacyEndpointSupport = - sessionOrKeyAuth === null || sessionOrKeyAuth instanceof Authenticator; + const dataSource = await DataSourceResource.fetchById(auth, dsId); - if (!dataSource) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } + const shouldKeepLegacyEndpointSupport = + sessionOrKeyAuth === null || sessionOrKeyAuth instanceof Authenticator; - let { space } = resources; + let { spaceId } = req.query; - if (!space) { - if (shouldKeepLegacyEndpointSupport) { - if (auth.isSystemKey()) { - // We also handle the legacy usage of connectors that taps into connected data sources which - // are not in the global space. If this is a system key we trust it and set the `spaceId` to the - // dataSource.space.sId. - space = dataSource.space; - } else { - space = await SpaceResource.fetchWorkspaceGlobalSpace(auth); - } + if (typeof spaceId !== "string") { + if (shouldKeepLegacyEndpointSupport) { + if (auth.isSystemKey()) { + // We also handle the legacy usage of connectors that taps into connected data sources which + // are not in the global space. If this is a system key we trust it and set the `spaceId` to the + // dataSource.space.sId. + spaceId = dataSource?.space.sId; } else { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Invalid space id.", - }, - }); + spaceId = (await SpaceResource.fetchWorkspaceGlobalSpace(auth)).sId; } - } - - if ( - dataSource.space.sId !== space.sId || - !spaceCheck(space) || - !hasPermission(auth, dataSource, options.dataSource) - ) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } - - return handler( - req, - res, - auth, - { ...resources, dataSource, space }, - options, - sessionOrKeyAuth - ); - } - - return handler(req, res, auth, resources, options, sessionOrKeyAuth); - }; -} - -/** - * for /w/[wId]/spaces/[spaceId]/data_source_view/[dsvId]/ => check the data source exists, - * that it's not in a conversation space, etc. and provide the data source resource to the handler. - * also supports the legacy usage of connectors with /w/[wId]/data_source/[dsId]/ - */ -function withDataSourceViewFromRoute( - handler: ResourceResolver -): ResourceResolver { - return async ( - req: NextApiRequest, - res: NextApiResponse>, - auth: Authenticator, - resources: Partial>, - options: Partial>, - sessionOrKeyAuth: A - ) => { - const { dsvId } = req.query; - - if (dsvId) { - if (typeof dsvId !== "string") { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Invalid path parameters.", - }, - }); - } - - const dataSourceView = await DataSourceViewResource.fetchById( - auth, - dsvId - ); - - const { space } = resources; - if (!space) { + } else { return apiError(req, res, { status_code: 400, api_error: { @@ -355,32 +162,28 @@ function withDataSourceViewFromRoute( }, }); } + } - if ( - !dataSourceView || - dataSourceView.space.sId !== space.sId || - !spaceCheck(space) || - !hasPermission(auth, dataSourceView, options.dataSourceView) - ) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_view_not_found", - message: "The data source view you requested was not found.", - }, - }); - } + if (!dataSource || dataSource.space.sId !== spaceId) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); + } - return handler( - req, - res, - auth, - { ...resources, dataSource: dataSourceView.dataSource, dataSourceView }, - options, - sessionOrKeyAuth - ); + if (!dataSource.space || dataSource.space.isConversations()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "space_not_found", + message: "The space you requested was not found.", + }, + }); } - return handler(req, res, auth, resources, options, sessionOrKeyAuth); + return handler(req, res, auth, dataSource, sessionOrKeyAuth); }; } diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/index.ts index fdbc251d67f0..e99f70857c73 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/index.ts @@ -73,7 +73,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.getNonNullableWorkspace(); @@ -145,5 +145,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts index a0e04e7faf09..fc6e2acaf12a 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts @@ -176,7 +176,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource }, + space: SpaceResource, keyAuth: Authenticator ): Promise { const owner = auth.getNonNullableWorkspace(); @@ -506,8 +506,7 @@ async function handler( } export default withPublicAPIAuthentication( - // Check read on the workspace authenticator - for public space, everybody can read - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }), + withResourceFetchingFromRoute(handler, "space"), { allowUserOutsideCurrentWorkspace: true, } diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/index.ts index a29c8ba02557..d5b26d2a96ee 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/apps/index.ts @@ -85,7 +85,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { if (!space.canList(auth)) { return apiError(req, res, { @@ -120,5 +120,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts index ea1af36c835a..3396bd4e237b 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts @@ -9,7 +9,8 @@ import { withPublicAPIAuthentication } from "@app/lib/api/auth_wrappers"; import { handlePatchDataSourceView } from "@app/lib/api/data_source_view"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import type { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; /** @@ -151,9 +152,35 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + space: SpaceResource ): Promise { - if (!dataSourceView.canList(auth)) { + const { dsvId } = req.query; + if (typeof dsvId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + if (!dataSourceView || dataSourceView.space.sId !== space.sId) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_view_not_found", + message: "The data source view you requested was not found.", + }, + }); + } + + if ( + !dataSourceView || + req.query.spaceId !== dataSourceView.space.sId || + !dataSourceView.canList(auth) + ) { return apiError(req, res, { status_code: 404, api_error: { @@ -228,7 +255,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/search.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/search.ts index b706b23732a5..82e1f8e64ee2 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/search.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/search.ts @@ -9,7 +9,8 @@ import { withPublicAPIAuthentication } from "@app/lib/api/auth_wrappers"; import { handleDataSourceSearch } from "@app/lib/api/data_sources"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import type { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; /** @@ -151,9 +152,25 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + space: SpaceResource ): Promise { - if (!dataSourceView.canRead(auth)) { + const { dsvId } = req.query; + if (typeof dsvId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + if ( + !dataSourceView || + dataSourceView.space.sId !== space.sId || + !dataSourceView.canRead(auth) + ) { return apiError(req, res, { status_code: 404, api_error: { @@ -226,7 +243,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanRead: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/index.ts index 42de901c6a0e..badb1ff824ea 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_source_views/index.ts @@ -59,7 +59,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { if (!space.canList(auth)) { return apiError(req, res, { @@ -95,5 +95,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/[fId].ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/[fId].ts index db20a4e4aa9a..95b817f8fd19 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/[fId].ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/[fId].ts @@ -31,7 +31,7 @@ async function handler( > >, auth: Authenticator, - { dataSource }: { dataSource: DataSourceResource } + dataSource: DataSourceResource ): Promise { const { fId } = req.query; @@ -59,16 +59,6 @@ async function handler( switch (req.method) { case "GET": - if (!dataSource.canList(auth)) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } - const docRes = await coreAPI.getDataSourceFolder({ projectId: dataSource.dustAPIProjectId, dataSourceId: dataSource.dustAPIDataSourceId, @@ -92,16 +82,6 @@ async function handler( return; case "POST": - if (!dataSource.canWrite(auth)) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: "You are not allowed to update data in this data source.", - }, - }); - } - const r = UpsertDataSourceFolderRequestSchema.safeParse(req.body); if (r.error) { @@ -173,16 +153,6 @@ async function handler( return; case "DELETE": - if (!dataSource.canWrite(auth)) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: "You are not allowed to update data in this data source.", - }, - }); - } - const delRes = await coreAPI.deleteDataSourceFolder({ projectId: dataSource.dustAPIProjectId, dataSourceId: dataSource.dustAPIDataSourceId, @@ -220,7 +190,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { - dataSource: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "dataSource") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/index.ts index d0c136325c4b..63fbef3a8406 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/folders/index.ts @@ -19,7 +19,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { dataSource }: { dataSource: DataSourceResource } + dataSource: DataSourceResource ): Promise { const coreAPI = new CoreAPI(config.getCoreAPIConfig(), logger); if (!auth.isSystemKey()) { @@ -34,16 +34,6 @@ async function handler( switch (req.method) { case "GET": - if (!dataSource.canList(auth)) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } - const limit = req.query.limit ? parseInt(req.query.limit as string) : 10; const offset = req.query.offset ? parseInt(req.query.offset as string) @@ -87,7 +77,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { - dataSource: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "dataSource") ); diff --git a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/index.ts b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/index.ts index 2064d8154ccf..ca79e18d0f8f 100644 --- a/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/index.ts +++ b/front/pages/api/v1/w/[wId]/spaces/[spaceId]/data_sources/index.ts @@ -54,7 +54,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const dataSources = await DataSourceResource.listBySpace(auth, space); @@ -87,5 +87,5 @@ async function handler( } export default withPublicAPIAuthentication( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/[name]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/[name]/index.ts index 906e9576c282..336e11592816 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/[name]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/[name]/index.ts @@ -23,8 +23,9 @@ export type GetDatasetResponseBody = { dataset: DatasetType }; async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.workspace(); if (!owner) { @@ -232,5 +233,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/index.ts index e89c3f7aa92b..d745c5ad8e84 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/datasets/index.ts @@ -50,8 +50,9 @@ async function handler( res: NextApiResponse< WithAPIErrorResponse >, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { aId } = req.query; if (typeof aId !== "string") { @@ -211,7 +212,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - // Interacting with datasets requires write access to the app's space. - // Read permission is not enough as it's available to all space users (or everybody for public spaces) - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/index.ts index ae95eb607463..b0f085cb7eed 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/index.ts @@ -25,8 +25,9 @@ const PatchAppBodySchema = t.type({ async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { aId } = req.query; if (typeof aId !== "string") { @@ -134,5 +135,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/blocks/[type]/[name]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/blocks/[type]/[name]/index.ts index 66d9db6b198d..8f83a0ff6ab1 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/blocks/[type]/[name]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/blocks/[type]/[name]/index.ts @@ -24,8 +24,9 @@ export type GetRunBlockResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { aId } = req.query; if (typeof aId !== "string") { @@ -107,7 +108,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - // App block runs contain sensitive data and requires write access to the app's space. - // Read permission is not enough as it's available to all space users (or everybody for public spaces) - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/status.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/status.ts index b4111a2d2be0..b2f7db6ebf5e 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/status.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/[runId]/status.ts @@ -18,8 +18,9 @@ export type GetRunStatusResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ) { const { aId } = req.query; if (typeof aId !== "string") { @@ -108,5 +109,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts index cddc56c1c3ad..cbd9d94053e2 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/runs/index.ts @@ -1,5 +1,6 @@ import type { RunType, WithAPIErrorResponse } from "@dust-tt/types"; -import { CoreAPI, credentialsFromProviders } from "@dust-tt/types"; +import { credentialsFromProviders } from "@dust-tt/types"; +import { CoreAPI } from "@dust-tt/types"; import type { NextApiRequest, NextApiResponse } from "next"; import { withSessionAuthenticationForWorkspace } from "@app/lib/api/auth_wrappers"; @@ -31,7 +32,7 @@ async function handler( WithAPIErrorResponse >, auth: Authenticator, - { space }: { space: SpaceResource }, + space: SpaceResource, session: SessionWithUser ) { const { aId } = req.query; @@ -265,5 +266,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/state.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/state.ts index 861e1f96c868..2c1aa4f103a7 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/state.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/[aId]/state.ts @@ -15,8 +15,9 @@ export type PostStateResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { aId } = req.query; if (typeof aId !== "string") { @@ -109,5 +110,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/index.ts index d6c98f8bd92d..ed998bec3352 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/apps/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/apps/index.ts @@ -25,7 +25,7 @@ async function handler( WithAPIErrorResponse >, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.getNonNullableWorkspace(); @@ -117,5 +117,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/content-nodes.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/content-nodes.ts index 5111ead7195e..5fdbdc2aca91 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/content-nodes.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/content-nodes.ts @@ -13,7 +13,8 @@ import { getContentNodesForDataSourceView } from "@app/lib/api/data_source_view" import { getOffsetPaginationParams } from "@app/lib/api/pagination"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import type { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; const GetContentNodesOrChildrenRequestBody = t.type({ @@ -34,10 +35,28 @@ export type GetDataSourceViewContentNodes = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + space: SpaceResource ): Promise { - if (!dataSourceView.canList(auth)) { + const { dsvId } = req.query; + if (typeof dsvId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + + if ( + !dataSourceView || + space.sId !== dataSourceView.space.sId || + !dataSourceView.canList(auth) + ) { return apiError(req, res, { status_code: 404, api_error: { @@ -117,7 +136,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/documents/[documentId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/documents/[documentId]/index.ts index 6e7b03457f2b..a0f30bb77484 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/documents/[documentId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/documents/[documentId]/index.ts @@ -6,7 +6,7 @@ import { withSessionAuthenticationForWorkspace } from "@app/lib/api/auth_wrapper import apiConfig from "@app/lib/api/config"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; import logger from "@app/logger/logger"; import { apiError } from "@app/logger/withlogging"; @@ -27,20 +27,21 @@ async function handler( res: NextApiResponse< WithAPIErrorResponse >, - auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + auth: Authenticator ): Promise { - const { documentId } = req.query; - if (typeof documentId !== "string") { + const { dsvId, documentId } = req.query; + if (typeof dsvId !== "string" || typeof documentId !== "string") { return apiError(req, res, { - status_code: 400, + status_code: 404, api_error: { - type: "invalid_request_error", - message: "Invalid document id.", + type: "data_source_view_not_found", + message: "The data source view you requested was not found.", }, }); } - if (!dataSourceView.canRead(auth)) { + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + if (!dataSourceView || !dataSourceView.canRead(auth)) { return apiError(req, res, { status_code: 404, api_error: { @@ -90,7 +91,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanRead: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts index b84cf28da9e6..bb1b324b2252 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/index.ts @@ -8,8 +8,9 @@ import { withSessionAuthenticationForWorkspace } from "@app/lib/api/auth_wrapper import { handlePatchDataSourceView } from "@app/lib/api/data_source_view"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; import { KillSwitchResource } from "@app/lib/resources/kill_switch_resource"; +import type { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; export type PatchDataSourceViewResponseBody = { @@ -23,10 +24,28 @@ export type GetDataSourceViewResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + space: SpaceResource ): Promise { - if (!dataSourceView.canList(auth)) { + const { dsvId } = req.query; + if (typeof dsvId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + + if ( + !dataSourceView || + space.sId !== dataSourceView.space.sId || + !dataSourceView.canList(auth) + ) { return apiError(req, res, { status_code: 404, api_error: { @@ -154,7 +173,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/[tableId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/[tableId]/index.ts index e8b773bb423d..330d6a905bcd 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/[tableId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/[tableId]/index.ts @@ -6,7 +6,7 @@ import { withSessionAuthenticationForWorkspace } from "@app/lib/api/auth_wrapper import apiConfig from "@app/lib/api/config"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; import logger from "@app/logger/logger"; import { apiError } from "@app/logger/withlogging"; @@ -27,22 +27,22 @@ async function handler( res: NextApiResponse< WithAPIErrorResponse >, - auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + auth: Authenticator ): Promise { - const { tableId } = req.query; + const { dsvId, tableId } = req.query; - if (typeof tableId !== "string") { + if (typeof dsvId !== "string" || typeof tableId !== "string") { return apiError(req, res, { - status_code: 400, + status_code: 404, api_error: { - type: "invalid_request_error", - message: "Invalid table id.", + type: "data_source_view_not_found", + message: "The data source view you requested was not found.", }, }); } - if (!dataSourceView.canRead(auth)) { + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + if (!dataSourceView || !dataSourceView.canRead(auth)) { return apiError(req, res, { status_code: 404, api_error: { @@ -89,7 +89,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanRead: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/index.ts index 19f76c5fc3b2..54e9273d70ff 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/[dsvId]/tables/index.ts @@ -9,7 +9,8 @@ import { getContentNodesForDataSourceView } from "@app/lib/api/data_source_view" import { getOffsetPaginationParams } from "@app/lib/api/pagination"; import { withResourceFetchingFromRoute } from "@app/lib/api/resource_wrappers"; import type { Authenticator } from "@app/lib/auth"; -import type { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import { DataSourceViewResource } from "@app/lib/resources/data_source_view_resource"; +import type { SpaceResource } from "@app/lib/resources/space_resource"; import { apiError } from "@app/logger/withlogging"; export type ListTablesResponseBody = { @@ -19,10 +20,28 @@ export type ListTablesResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { dataSourceView }: { dataSourceView: DataSourceViewResource } + space: SpaceResource ): Promise { - if (!dataSourceView.canList(auth)) { + const { dsvId } = req.query; + if (typeof dsvId !== "string") { + return apiError(req, res, { + status_code: 400, + api_error: { + type: "invalid_request_error", + message: "Invalid path parameters.", + }, + }); + } + + const dataSourceView = await DataSourceViewResource.fetchById(auth, dsvId); + + if ( + !dataSourceView || + space.sId !== dataSourceView.space.sId || + !dataSourceView.canList(auth) + ) { return apiError(req, res, { status_code: 404, api_error: { @@ -81,7 +100,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { - dataSourceView: { requireCanList: true }, - }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/index.ts index 65e774b50351..24de75e7dbbe 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_source_views/index.ts @@ -46,8 +46,9 @@ async function handler( GetSpaceDataSourceViewsResponseBody | PostSpaceDataSourceViewsResponseBody > >, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { switch (req.method) { case "GET": { @@ -231,5 +232,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/configuration.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/configuration.ts index 474cb4eda568..533a03b0f352 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/configuration.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/configuration.ts @@ -35,7 +35,7 @@ async function handler( > >, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { dsId } = req.query; if (typeof dsId !== "string") { @@ -179,5 +179,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/[documentId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/[documentId]/index.ts index bff299183488..9984e4d99527 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/[documentId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/[documentId]/index.ts @@ -37,8 +37,9 @@ export type PatchDocumentResponseBody = { async function handler( req: NextApiRequest, res: NextApiResponse>, + auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { documentId, dsId } = req.query; if (typeof dsId !== "string" || typeof documentId !== "string") { @@ -232,5 +233,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/index.ts index 4d7635cf23ec..d3241dd9df90 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/documents/index.ts @@ -32,7 +32,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { dsId } = req.query; if (typeof dsId !== "string") { @@ -180,5 +180,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/index.ts index 54818729bb11..46c5b0f20bed 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/index.ts @@ -27,7 +27,7 @@ async function handler( WithAPIErrorResponse >, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { dsId } = req.query; if (typeof dsId !== "string") { @@ -168,5 +168,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/[tableId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/[tableId]/index.ts index 3b792a950952..5d3172a69c9f 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/[tableId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/[tableId]/index.ts @@ -32,7 +32,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { tableId, dsId } = req.query; @@ -123,16 +123,6 @@ async function handler( return; case "DELETE": - if (!dataSource.canWrite(auth)) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: "You are not allowed to update data in this data source.", - }, - }); - } - const delRes = await deleteTable({ owner: auth.getNonNullableWorkspace(), dataSource, @@ -178,5 +168,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/index.ts index a207d2170d90..95d2fcf68c70 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/[dsId]/tables/index.ts @@ -28,7 +28,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const { dsId } = req.query; if (typeof dsId !== "string") { @@ -127,5 +127,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/index.ts index 6e2fc0063d07..06ae511deec0 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/data_sources/index.ts @@ -88,7 +88,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.getNonNullableWorkspace(); const plan = auth.getNonNullablePlan(); @@ -504,5 +504,5 @@ const handleDataSourceWithProvider = async ({ }; export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/index.ts index 7faf1258b63f..f5b253965026 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/index.ts @@ -46,7 +46,7 @@ async function handler( WithAPIErrorResponse >, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { switch (req.method) { case "GET": { @@ -241,5 +241,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/members.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/members.ts index f8cf416dead2..81ea12a0f18d 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/members.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/members.ts @@ -19,7 +19,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { if (!space.isRegular()) { return apiError(req, res, { @@ -33,17 +33,6 @@ async function handler( switch (req.method) { case "PATCH": { - if (!space.canAdministrate(auth)) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "workspace_auth_error", - message: - "Only users that are `admins` can administrate space members.", - }, - }); - } - const bodyValidation = PatchSpaceMembersRequestBodySchema.decode( req.body ); @@ -103,5 +92,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanList: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/[tId]/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/[tId]/index.ts index 32711f1484a8..d2a47e1822e4 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/[tId]/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/[tId]/index.ts @@ -19,7 +19,7 @@ async function handler( WithAPIErrorResponse >, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.workspace(); if (!owner) { @@ -166,5 +166,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanWrite: true } }) + withResourceFetchingFromRoute(handler, "space") ); diff --git a/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/index.ts b/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/index.ts index cfc315345632..8e949704eb09 100644 --- a/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/index.ts +++ b/front/pages/api/w/[wId]/spaces/[spaceId]/trackers/index.ts @@ -55,7 +55,7 @@ async function handler( req: NextApiRequest, res: NextApiResponse>, auth: Authenticator, - { space }: { space: SpaceResource } + space: SpaceResource ): Promise { const owner = auth.workspace(); if (!owner) { @@ -165,5 +165,5 @@ async function handler( } export default withSessionAuthenticationForWorkspace( - withResourceFetchingFromRoute(handler, { space: { requireCanRead: true } }) + withResourceFetchingFromRoute(handler, "space") );