From 98eeaab930226a0c1e7213a566055f9e184345ff Mon Sep 17 00:00:00 2001 From: Stanislas Polu Date: Wed, 24 Jan 2024 17:30:28 +0100 Subject: [PATCH] front: remove data sources visibility (#3414) * Remove data sources visibility * fixes * enforce admin only can delete connections in lib/api * Update front/pages/api/w/[wId]/data_sources/[name]/index.ts Co-authored-by: Flavien David --------- Co-authored-by: Flavien David --- front/lib/api/data_sources.ts | 75 +++++++++---------- front/lib/models/data_source.ts | 8 +- .../20230522_slack_doc_rename_incident.ts | 1 - .../[name]/documents/[documentId]/index.ts | 13 +--- .../[name]/documents/[documentId]/parents.ts | 13 +--- .../data_sources/[name]/documents/index.ts | 10 +++ .../v1/w/[wId]/data_sources/[name]/search.ts | 10 +++ .../data_sources/[name]/tables/[tId]/index.ts | 15 ++-- .../[name]/tables/[tId]/rows/[rId].ts | 6 +- .../[name]/tables/[tId]/rows/index.ts | 6 +- .../[wId]/data_sources/[name]/tables/index.ts | 15 ++-- .../w/[wId]/data_sources/[name]/tokenize.ts | 7 +- .../api/v1/w/[wId]/data_sources/index.ts | 10 +++ .../[name]/documents/[documentId]/index.ts | 3 +- .../data_sources/[name]/documents/index.ts | 43 ++++++++--- .../api/w/[wId]/data_sources/[name]/index.ts | 63 +++++----------- .../[name]/managed/bot_enabled.ts | 2 +- .../[name]/managed/permissions/index.ts | 3 +- .../data_sources/[name]/managed/update.ts | 22 +++--- .../api/w/[wId]/data_sources/[name]/search.ts | 13 +--- front/pages/api/w/[wId]/data_sources/index.ts | 5 +- .../pages/api/w/[wId]/data_sources/managed.ts | 2 - .../builder/data-sources/[name]/settings.tsx | 10 +-- .../w/[wId]/builder/data-sources/new.tsx | 1 - front/poke/temporal/activities.ts | 3 - types/src/front/data_source.ts | 3 - 26 files changed, 169 insertions(+), 193 deletions(-) diff --git a/front/lib/api/data_sources.ts b/front/lib/api/data_sources.ts index 85fce95c6316..7f21709df6ec 100644 --- a/front/lib/api/data_sources.ts +++ b/front/lib/api/data_sources.ts @@ -5,7 +5,6 @@ import type { Result, } from "@dust-tt/types"; import { ConnectorsAPI, CoreAPI, Err, Ok } from "@dust-tt/types"; -import { Op } from "sequelize"; import { getMembers } from "@app/lib/api/workspace"; import type { Authenticator } from "@app/lib/auth"; @@ -19,25 +18,19 @@ export async function getDataSource( name: string ): Promise { const owner = auth.workspace(); - if (!owner) { + + // This condition is critical it checks that we can identify the workspace and that the current + // auth is a user for this workspace. Checking `auth.isUser()` is critical as it would otherwise + // be possible to access data sources without being authenticated. + if (!owner || !auth.isUser()) { return null; } const dataSource = await DataSource.findOne({ - where: auth.isUser() - ? { - workspaceId: owner.id, - visibility: { - [Op.or]: ["public", "private", "unlisted"], - }, - name, - } - : { - workspaceId: owner.id, - // Do not include 'unlisted' here. - visibility: "public", - name, - }, + where: { + workspaceId: owner.id, + name, + }, }); if (!dataSource) { @@ -48,7 +41,6 @@ export async function getDataSource( id: dataSource.id, name: dataSource.name, description: dataSource.description, - visibility: dataSource.visibility, dustAPIProjectId: dataSource.dustAPIProjectId, connectorId: dataSource.connectorId, connectorProvider: dataSource.connectorProvider, @@ -60,23 +52,18 @@ export async function getDataSources( auth: Authenticator ): Promise { const owner = auth.workspace(); - if (!owner) { + + // This condition is critical it checks that we can identify the workspace and that the current + // auth is a user for this workspace. Checking `auth.isUser()` is critical as it would otherwise + // be possible to access data sources without being authenticated. + if (!owner || !auth.isUser()) { return []; } const dataSources = await DataSource.findAll({ - where: auth.isUser() - ? { - workspaceId: owner.id, - visibility: { - [Op.or]: ["public", "private", "unlisted"], - }, - } - : { - workspaceId: owner.id, - // Do not include 'unlisted' here. - visibility: "public", - }, + where: { + workspaceId: owner.id, + }, order: [["updatedAt", "DESC"]], }); @@ -85,7 +72,6 @@ export async function getDataSources( id: dataSource.id, name: dataSource.name, description: dataSource.description, - visibility: dataSource.visibility, dustAPIProjectId: dataSource.dustAPIProjectId, connectorId: dataSource.connectorId, connectorProvider: dataSource.connectorProvider, @@ -93,27 +79,30 @@ export async function getDataSources( }; }); } + export async function deleteDataSource( auth: Authenticator, dataSourceName: string ): Promise> { - const workspace = auth.workspace(); - if (!workspace) { + const owner = auth.workspace(); + if (!owner) { return new Err({ type: "workspace_not_found", message: "Could not find the workspace.", }); } - if (!auth.isAdmin()) { + + if (!auth.isBuilder()) { return new Err({ type: "workspace_auth_error", message: - "Only users that are `admins` for the current workspace can delete data sources.", + "Only users that are `builders` for the current workspace can delete data sources.", }); } + const dataSource = await DataSource.findOne({ where: { - workspaceId: workspace.id, + workspaceId: owner.id, name: dataSourceName, }, }); @@ -126,8 +115,16 @@ export async function deleteDataSource( const dustAPIProjectId = dataSource.dustAPIProjectId; - const connectorsAPI = new ConnectorsAPI(logger); if (dataSource.connectorId) { + if (!auth.isAdmin()) { + return new Err({ + type: "workspace_auth_error", + message: + "Only users that are `admins` for the current workspace can delete connected data sources.", + }); + } + + const connectorsAPI = new ConnectorsAPI(logger); const connDeleteRes = await connectorsAPI.deleteConnector( dataSource.connectorId.toString(), true @@ -139,6 +136,7 @@ export async function deleteDataSource( return new Err({ type: "internal_server_error", message: `Error deleting connector: ${connDeleteRes.error.error.message}`, + connectors_error: connDeleteRes.error, }); } } @@ -153,13 +151,14 @@ export async function deleteDataSource( return new Err({ type: "internal_server_error", message: `Error deleting core data source: ${coreDeleteRes.error.message}`, + data_source_error: coreDeleteRes.error, }); } await dataSource.destroy(); await launchScrubDataSourceWorkflow({ - wId: workspace.sId, + wId: owner.sId, dustAPIProjectId, }); if (dataSource.connectorProvider) diff --git a/front/lib/models/data_source.ts b/front/lib/models/data_source.ts index f221ffa21776..7bcb3c6a4e8b 100644 --- a/front/lib/models/data_source.ts +++ b/front/lib/models/data_source.ts @@ -21,7 +21,6 @@ export class DataSource extends Model< declare name: string; declare description: string | null; - declare visibility: "public" | "private"; declare assistantDefaultSelected: boolean; declare dustAPIProjectId: string; declare connectorId: string | null; @@ -55,10 +54,6 @@ DataSource.init( description: { type: DataTypes.TEXT, }, - visibility: { - type: DataTypes.STRING, - allowNull: false, - }, assistantDefaultSelected: { type: DataTypes.BOOLEAN, allowNull: false, @@ -79,8 +74,7 @@ DataSource.init( modelName: "data_source", sequelize: front_sequelize, indexes: [ - { fields: ["workspaceId", "visibility"] }, - { fields: ["workspaceId", "name", "visibility"] }, + { fields: ["workspaceId", "name"] }, { fields: ["workspaceId", "name"], unique: true }, ], } diff --git a/front/migrations/20230522_slack_doc_rename_incident.ts b/front/migrations/20230522_slack_doc_rename_incident.ts index 38bfd43e0fd8..c00057b57296 100644 --- a/front/migrations/20230522_slack_doc_rename_incident.ts +++ b/front/migrations/20230522_slack_doc_rename_incident.ts @@ -74,7 +74,6 @@ async function main() { let dataSource = await DataSource.create({ name: dataSourceName, description: dataSourceDescription, - visibility: "private", dustAPIProjectId: dustProject.value.project.project_id.toString(), workspaceId: workspaceId, }); diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts index cdd4ab9e4938..e2db6b094d56 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts @@ -67,7 +67,7 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { @@ -115,17 +115,6 @@ async function handler( return; case "POST": - if (!auth.isBuilder()) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: - "You can only alter the data souces of the workspaces for which you are a builder.", - }, - }); - } - if (dataSource.connectorId && !keyRes.value.isSystem) { return apiError(req, res, { status_code: 403, diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/parents.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/parents.ts index b958b6314b9d..3894b7e9f535 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/parents.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/[documentId]/parents.ts @@ -25,7 +25,7 @@ async function handler( ); const owner = auth.workspace(); - if (!owner) { + if (!owner || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { @@ -49,17 +49,6 @@ async function handler( switch (req.method) { case "POST": - if (!auth.isBuilder()) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: - "You can only alter the data souces of the workspaces for which you are a builder.", - }, - }); - } - if ( !req.body || !Array.isArray(req.body.parents) || diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/index.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/index.ts index 7c35e28f3803..c1af51ebe9b3 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/documents/index.ts @@ -26,6 +26,16 @@ async function handler( req.query.wId as string ); + if (!auth.isBuilder()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); + } + const dataSource = await getDataSource(auth, req.query.name as string); if (!dataSource) { diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/search.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/search.ts index c1c4eabc8cea..4776d1c82f41 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/search.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/search.ts @@ -63,6 +63,16 @@ async function handler( req.query.wId as string ); + if (!auth.isBuilder()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); + } + const dataSource = await getDataSource(auth, req.query.name as string); if (!dataSource) { diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/index.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/index.ts index bd38ee0c8abd..616cbfb12a48 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/index.ts @@ -28,19 +28,24 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { - type: "workspace_not_found", - message: "The workspace you requested was not found.", + type: "data_source_not_found", + message: "The data source you requested was not found.", }, }); } if (!isActivatedStructuredDB(owner)) { - res.status(404).end(); - return; + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); } const dataSource = await getDataSource(auth, req.query.name as string); diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/[rId].ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/[rId].ts index 3a1cab6f3b6e..b2ea80765f3e 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/[rId].ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/[rId].ts @@ -28,12 +28,12 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { - type: "workspace_not_found", - message: "The workspace you requested was not found.", + type: "data_source_not_found", + message: "The data source you requested was not found.", }, }); } diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/index.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/index.ts index 352db1a9bde2..750519df3a7b 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/[tId]/rows/index.ts @@ -56,12 +56,12 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { - type: "workspace_not_found", - message: "The workspace you requested was not found.", + type: "data_source_not_found", + message: "The data source you requested was not found.", }, }); } diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/index.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/index.ts index b35a30a49a1f..2a98d5eddb5b 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/tables/index.ts @@ -42,19 +42,24 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isBuilder()) { return apiError(req, res, { status_code: 404, api_error: { - type: "workspace_not_found", - message: "The workspace you requested was not found.", + type: "data_source_not_found", + message: "The data source you requested was not found.", }, }); } if (!isActivatedStructuredDB(owner)) { - res.status(404).end(); - return; + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); } const dataSource = await getDataSource(auth, req.query.name as string); diff --git a/front/pages/api/v1/w/[wId]/data_sources/[name]/tokenize.ts b/front/pages/api/v1/w/[wId]/data_sources/[name]/tokenize.ts index 9adb8bf6ef19..3441588d8742 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/[name]/tokenize.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/[name]/tokenize.ts @@ -40,13 +40,14 @@ async function handler( if (!auth.workspace() || !auth.isBuilder()) { return apiError(req, res, { - status_code: 403, + status_code: 404, api_error: { - type: "workspace_auth_error", - message: "You don't have permission to access this resource.", + type: "workspace_not_found", + message: "The workspace you requested was not found.", }, }); } + const dataSource = await getDataSource(auth, req.query.name as string); if (!dataSource) { diff --git a/front/pages/api/v1/w/[wId]/data_sources/index.ts b/front/pages/api/v1/w/[wId]/data_sources/index.ts index 50e0192563a7..441c19506d2d 100644 --- a/front/pages/api/v1/w/[wId]/data_sources/index.ts +++ b/front/pages/api/v1/w/[wId]/data_sources/index.ts @@ -23,6 +23,16 @@ async function handler( req.query.wId as string ); + if (!auth.isBuilder()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "workspace_not_found", + message: "The workspace you requested was not found.", + }, + }); + } + const dataSources = await getDataSources(auth); switch (req.method) { diff --git a/front/pages/api/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts b/front/pages/api/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts index 3a9a601a15e4..4148f61b7520 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/documents/[documentId]/index.ts @@ -33,7 +33,8 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + + if (!owner || !plan || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { diff --git a/front/pages/api/w/[wId]/data_sources/[name]/documents/index.ts b/front/pages/api/w/[wId]/data_sources/[name]/documents/index.ts index 6525bcfaeaff..cf6699e19470 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/documents/index.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/documents/index.ts @@ -5,7 +5,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { getDataSource } from "@app/lib/api/data_sources"; import { Authenticator, getSession } from "@app/lib/auth"; import logger from "@app/logger/logger"; -import { withLogging } from "@app/logger/withlogging"; +import { apiError, withLogging } from "@app/logger/withlogging"; export type GetDocumentsResponseBody = { documents: Array; @@ -26,16 +26,27 @@ async function handler( : await Authenticator.fromSession(session, req.query.wId as string); const owner = auth.workspace(); - if (!owner) { - res.status(404).end(); - return; + + if (!owner || !auth.isUser()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); } const dataSource = await getDataSource(auth, req.query.name as string); if (!dataSource) { - res.status(404).end(); - return; + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); } switch (req.method) { @@ -54,8 +65,15 @@ async function handler( }); if (documents.isErr()) { - res.status(400).end(); - return; + return apiError(req, res, { + status_code: 404, + api_error: { + type: "internal_server_error", + message: + "We encountered an error while fetching the data source documents.", + data_source_error: documents.error, + }, + }); } res.status(200).json({ @@ -65,8 +83,13 @@ async function handler( return; default: - res.status(405).end(); - return; + return apiError(req, res, { + status_code: 405, + api_error: { + type: "method_not_supported_error", + message: "The method passed is not supported, GET is expected.", + }, + }); } } diff --git a/front/pages/api/w/[wId]/data_sources/[name]/index.ts b/front/pages/api/w/[wId]/data_sources/[name]/index.ts index cb15c5ec0cb8..d417fe970f53 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/index.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/index.ts @@ -1,12 +1,10 @@ import type { DataSourceType } from "@dust-tt/types"; import type { ReturnedAPIErrorType } from "@dust-tt/types"; -import { CoreAPI } from "@dust-tt/types"; import type { NextApiRequest, NextApiResponse } from "next"; -import { getDataSource } from "@app/lib/api/data_sources"; +import { deleteDataSource, getDataSource } from "@app/lib/api/data_sources"; import { Authenticator, getSession } from "@app/lib/auth"; import { DataSource } from "@app/lib/models"; -import logger from "@app/logger/logger"; import { apiError, withLogging } from "@app/logger/withlogging"; export type GetOrPostDataSourceResponseBody = { @@ -26,7 +24,7 @@ async function handler( ); const owner = auth.workspace(); - if (!owner) { + if (!owner || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { @@ -56,16 +54,6 @@ async function handler( }, }); } - const dataSourceModel = await DataSource.findByPk(dataSource.id); - if (!dataSourceModel) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } switch (req.method) { case "GET": @@ -74,7 +62,6 @@ async function handler( id: dataSource.id, name: dataSource.name, description: dataSource.description, - visibility: dataSource.visibility, dustAPIProjectId: dataSource.dustAPIProjectId, connectorId: dataSource.connectorId, connectorProvider: dataSource.connectorProvider, @@ -95,6 +82,17 @@ async function handler( }); } + const dataSourceModel = await DataSource.findByPk(dataSource.id); + if (!dataSourceModel) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "data_source_not_found", + message: "The data source you requested was not found.", + }, + }); + } + let ds: DataSource; if (dataSource.connectorId) { // managed data source @@ -120,7 +118,6 @@ async function handler( if ( !req.body || (typeof req.body.description !== "string" && - typeof req.body.visibility !== "string" && typeof req.body.assistantDefaultSelected !== "boolean") ) { return apiError(req, res, { @@ -134,7 +131,6 @@ async function handler( const toUpdate: { description?: string | null; - visibility?: "public" | "private"; assistantDefaultSelected?: boolean; } = {}; @@ -142,20 +138,6 @@ async function handler( toUpdate.description = req.body.description || null; } - if (typeof req.body.visibility === "string") { - if (!["public", "private"].includes(req.body.visibility)) { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: - "The visibility field must be either `public` or `private` if provided.", - }, - }); - } - toUpdate.visibility = req.body.visibility; - } - if (typeof req.body.assistantDefaultSelected === "boolean") { toUpdate.assistantDefaultSelected = req.body.assistantDefaultSelected; } @@ -168,7 +150,6 @@ async function handler( id: ds.id, name: ds.name, description: ds.description, - visibility: ds.visibility, assistantDefaultSelected: ds.assistantDefaultSelected, dustAPIProjectId: ds.dustAPIProjectId, connectorId: ds.connectorId, @@ -188,6 +169,7 @@ async function handler( }); } + // We only expose deleted non-managed data sources. if (dataSource.connectorId) { return apiError(req, res, { status_code: 400, @@ -198,25 +180,14 @@ async function handler( }); } - const coreAPI = new CoreAPI(logger); - const dustDataSource = await coreAPI.deleteDataSource({ - projectId: dataSource.dustAPIProjectId, - dataSourceName: dataSource.name, - }); - - if (dustDataSource.isErr()) { + const dRes = await deleteDataSource(auth, dataSource.name); + if (dRes.isErr()) { return apiError(req, res, { status_code: 500, - api_error: { - type: "internal_server_error", - message: "Failed to delete the data source.", - data_source_error: dustDataSource.error, - }, + api_error: dRes.error, }); } - await dataSourceModel.destroy(); - res.status(204).end(); return; diff --git a/front/pages/api/w/[wId]/data_sources/[name]/managed/bot_enabled.ts b/front/pages/api/w/[wId]/data_sources/[name]/managed/bot_enabled.ts index e176f5746b19..28cdd99fa595 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/managed/bot_enabled.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/managed/bot_enabled.ts @@ -31,7 +31,7 @@ async function handler( ); const owner = auth.workspace(); - if (!owner) { + if (!owner || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { diff --git a/front/pages/api/w/[wId]/data_sources/[name]/managed/permissions/index.ts b/front/pages/api/w/[wId]/data_sources/[name]/managed/permissions/index.ts index 052dbde9f3de..168a600746d8 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/managed/permissions/index.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/managed/permissions/index.ts @@ -48,7 +48,8 @@ async function handler( ); const owner = auth.workspace(); - if (!owner) { + + if (!owner || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { diff --git a/front/pages/api/w/[wId]/data_sources/[name]/managed/update.ts b/front/pages/api/w/[wId]/data_sources/[name]/managed/update.ts index ce1039805a72..6005c6244fbd 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/managed/update.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/managed/update.ts @@ -43,6 +43,17 @@ async function handler( }); } + if (!auth.isAdmin()) { + return apiError(req, res, { + status_code: 403, + api_error: { + type: "data_source_auth_error", + message: + "Only the users that are `admins` for the current workspace can edit the permissions of a data source.", + }, + }); + } + const dataSource = await getDataSource(auth, req.query.name as string); if (!dataSource) { return apiError(req, res, { @@ -64,17 +75,6 @@ async function handler( }); } - if (!auth.isAdmin()) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "data_source_auth_error", - message: - "Only the users that are `admins` for the current workspace can edit the permissions of a data source.", - }, - }); - } - switch (req.method) { case "POST": const bodyValidation = diff --git a/front/pages/api/w/[wId]/data_sources/[name]/search.ts b/front/pages/api/w/[wId]/data_sources/[name]/search.ts index 9ca5acadf98c..88bc21f1ba4c 100644 --- a/front/pages/api/w/[wId]/data_sources/[name]/search.ts +++ b/front/pages/api/w/[wId]/data_sources/[name]/search.ts @@ -55,7 +55,7 @@ async function handler( ); const owner = auth.workspace(); - if (!owner) { + if (!owner || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { @@ -79,17 +79,6 @@ async function handler( switch (req.method) { case "GET": { - // Only member of the workspace can search a DataSource since it costs money for embedding. - if (!auth.isUser()) { - return apiError(req, res, { - status_code: 404, - api_error: { - type: "data_source_not_found", - message: "The data source you requested was not found.", - }, - }); - } - // I could not find a way to make the query params be an array if there is only one tag. if (req.query.tags_in && typeof req.query.tags_in === "string") { req.query.tags_in = [req.query.tags_in]; diff --git a/front/pages/api/w/[wId]/data_sources/index.ts b/front/pages/api/w/[wId]/data_sources/index.ts index a6eea7fb9103..153b02119d50 100644 --- a/front/pages/api/w/[wId]/data_sources/index.ts +++ b/front/pages/api/w/[wId]/data_sources/index.ts @@ -36,7 +36,7 @@ async function handler( const owner = auth.workspace(); const plan = auth.plan(); - if (!owner || !plan) { + if (!owner || !plan || !auth.isUser()) { return apiError(req, res, { status_code: 404, api_error: { @@ -69,7 +69,6 @@ async function handler( !req.body || !(typeof req.body.name == "string") || !(typeof req.body.description == "string") || - !["public", "private"].includes(req.body.visibility) || !(typeof req.body.assistantDefaultSelected === "boolean") ) { return apiError(req, res, { @@ -162,7 +161,6 @@ async function handler( const ds = await DataSource.create({ name: req.body.name, description: description, - visibility: req.body.visibility, dustAPIProjectId: dustProject.value.project.project_id.toString(), workspaceId: owner.id, assistantDefaultSelected: req.body.assistantDefaultSelected, @@ -173,7 +171,6 @@ async function handler( id: ds.id, name: ds.name, description: ds.description, - visibility: ds.visibility, dustAPIProjectId: ds.dustAPIProjectId, assistantDefaultSelected: ds.assistantDefaultSelected, connectorId: null, diff --git a/front/pages/api/w/[wId]/data_sources/managed.ts b/front/pages/api/w/[wId]/data_sources/managed.ts index f7c54d0a04fb..cc5b667abd20 100644 --- a/front/pages/api/w/[wId]/data_sources/managed.ts +++ b/front/pages/api/w/[wId]/data_sources/managed.ts @@ -294,7 +294,6 @@ async function handler( let dataSource = await DataSource.create({ name: dataSourceName, description: dataSourceDescription, - visibility: "private", dustAPIProjectId: dustProject.value.project.project_id.toString(), workspaceId: owner.id, assistantDefaultSelected, @@ -390,7 +389,6 @@ async function handler( id: dataSource.id, name: dataSource.name, description: dataSource.description, - visibility: dataSource.visibility, dustAPIProjectId: dataSource.dustAPIProjectId, connectorId: connectorsRes.value.id, connectorProvider: provider, diff --git a/front/pages/w/[wId]/builder/data-sources/[name]/settings.tsx b/front/pages/w/[wId]/builder/data-sources/[name]/settings.tsx index 5580c5a73de3..b877d3c5ba64 100644 --- a/front/pages/w/[wId]/builder/data-sources/[name]/settings.tsx +++ b/front/pages/w/[wId]/builder/data-sources/[name]/settings.tsx @@ -1,9 +1,5 @@ import { Button, DropdownMenu, TrashIcon } from "@dust-tt/sparkle"; -import type { - DataSourceType, - DataSourceVisibility, - WorkspaceType, -} from "@dust-tt/types"; +import type { DataSourceType, WorkspaceType } from "@dust-tt/types"; import type { SubscriptionType } from "@dust-tt/types"; import type { APIError } from "@dust-tt/types"; import { ChevronRightIcon } from "@heroicons/react/20/solid"; @@ -72,7 +68,6 @@ export default function DataSourceSettings({ settings: | { description: string; - visibility: DataSourceVisibility; assistantDefaultSelected: boolean; } | { assistantDefaultSelected: boolean } @@ -105,7 +100,6 @@ export default function DataSourceSettings({ dataSource={dataSource} handleUpdate={(settings: { description: string; - visibility: DataSourceVisibility; assistantDefaultSelected: boolean; }) => handleUpdate(settings)} gaTrackingId={gaTrackingId} @@ -125,7 +119,6 @@ function StandardDataSourceSettings({ dataSource: DataSourceType; handleUpdate: (settings: { description: string; - visibility: DataSourceVisibility; assistantDefaultSelected: boolean; }) => Promise; gaTrackingId: string; @@ -197,7 +190,6 @@ function StandardDataSourceSettings({ setIsSavingOrDeleting(true); await handleUpdate({ description: dataSourceDescription, - visibility: "private", assistantDefaultSelected: dataSource.assistantDefaultSelected, }); diff --git a/front/pages/w/[wId]/builder/data-sources/new.tsx b/front/pages/w/[wId]/builder/data-sources/new.tsx index b235cd50b263..b7b2530a88b2 100644 --- a/front/pages/w/[wId]/builder/data-sources/new.tsx +++ b/front/pages/w/[wId]/builder/data-sources/new.tsx @@ -119,7 +119,6 @@ export default function DataSourceNew({ body: JSON.stringify({ name: dataSourceName, description: dataSourceDescription, - visibility: "private", assistantDefaultSelected: false, }), }); diff --git a/front/poke/temporal/activities.ts b/front/poke/temporal/activities.ts index f31bc661195e..63b9fb6f48ed 100644 --- a/front/poke/temporal/activities.ts +++ b/front/poke/temporal/activities.ts @@ -101,9 +101,6 @@ export async function isWorkflowDeletableActivity({ const dataSources = await DataSource.findAll({ where: { workspaceId: workspace.id, - visibility: { - [Op.or]: ["public", "private", "unlisted"], - }, }, limit: 1, }); diff --git a/types/src/front/data_source.ts b/types/src/front/data_source.ts index b446d2c51fbe..d89d411dd53e 100644 --- a/types/src/front/data_source.ts +++ b/types/src/front/data_source.ts @@ -1,7 +1,5 @@ import { ModelId } from "../shared/model_id"; -export type DataSourceVisibility = "public" | "private"; - export const CONNECTOR_PROVIDERS = [ "confluence", "github", @@ -21,7 +19,6 @@ export type DataSourceType = { id: ModelId; name: string; description: string | null; - visibility: DataSourceVisibility; assistantDefaultSelected: boolean; dustAPIProjectId: string; connectorId: string | null;