diff --git a/.sqlx/query-fffe6f01abf0e5d8649a49b5793ccb92a9f823f07c363341357ea74bf4f4a16d.json b/.sqlx/query-fffe6f01abf0e5d8649a49b5793ccb92a9f823f07c363341357ea74bf4f4a16d.json new file mode 100644 index 00000000..9e933d77 --- /dev/null +++ b/.sqlx/query-fffe6f01abf0e5d8649a49b5793ccb92a9f823f07c363341357ea74bf4f4a16d.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE af_workspace\n SET default_published_view_id = NULL\n WHERE workspace_id = $1\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [] + }, + "hash": "fffe6f01abf0e5d8649a49b5793ccb92a9f823f07c363341357ea74bf4f4a16d" +} diff --git a/libs/client-api/src/http_publish.rs b/libs/client-api/src/http_publish.rs index e8d29247..daae7e06 100644 --- a/libs/client-api/src/http_publish.rs +++ b/libs/client-api/src/http_publish.rs @@ -217,6 +217,23 @@ impl Client { AppResponse::<()>::from_response(resp).await?.into_error() } + pub async fn delete_default_publish_view( + &self, + workspace_id: &str, + ) -> Result<(), AppResponseError> { + let url = format!( + "{}/api/workspace/{}/publish-default", + self.base_url, workspace_id + ); + let resp = self + .http_client_with_auth(Method::DELETE, &url) + .await? + .send() + .await?; + log_request_id(&resp); + AppResponse::<()>::from_response(resp).await?.into_error() + } + pub async fn get_default_publish_view_info( &self, workspace_id: &str, diff --git a/libs/database/src/publish.rs b/libs/database/src/publish.rs index 4f64d115..85311af5 100644 --- a/libs/database/src/publish.rs +++ b/libs/database/src/publish.rs @@ -112,6 +112,36 @@ pub async fn update_workspace_default_publish_view<'a, E: Executor<'a, Database Ok(()) } +#[inline] +pub async fn update_workspace_default_publish_view_set_null< + 'a, + E: Executor<'a, Database = Postgres>, +>( + executor: E, + workspace_id: &Uuid, +) -> Result<(), AppError> { + let res = sqlx::query!( + r#" + UPDATE af_workspace + SET default_published_view_id = NULL + WHERE workspace_id = $1 + "#, + workspace_id, + ) + .execute(executor) + .await?; + + if res.rows_affected() != 1 { + tracing::error!( + "Failed to unset workspace default publish view, workspace_id: {}, rows_affected: {}", + workspace_id, + res.rows_affected() + ); + } + + Ok(()) +} + #[inline] pub async fn select_workspace_publish_namespace<'a, E: Executor<'a, Database = Postgres>>( executor: E, diff --git a/src/api/workspace.rs b/src/api/workspace.rs index d545c639..4eb98c78 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -199,6 +199,7 @@ pub fn workspace_scope() -> Scope { .service( web::resource("/{workspace_id}/publish-default") .route(web::put().to(put_workspace_default_published_view_handler)) + .route(web::delete().to(delete_workspace_default_published_view_handler)) .route(web::get().to(get_workspace_published_default_info_handler)), ) .service( @@ -1158,6 +1159,25 @@ async fn put_workspace_default_published_view_handler( Ok(Json(AppResponse::Ok())) } +async fn delete_workspace_default_published_view_handler( + user_uuid: UserUuid, + workspace_id: web::Path, + state: Data, +) -> Result>> { + let uid = state.user_cache.get_user_uid(&user_uuid).await?; + state + .workspace_access_control + .enforce_action(&uid, &workspace_id.to_string(), Action::Write) + .await?; + biz::workspace::publish::unset_workspace_default_publish_view( + &state.pg_pool, + &user_uuid, + &workspace_id, + ) + .await?; + Ok(Json(AppResponse::Ok())) +} + async fn get_workspace_published_default_info_handler( workspace_id: web::Path, state: Data, diff --git a/src/biz/workspace/publish.rs b/src/biz/workspace/publish.rs index 3ba13fce..bfba3b5e 100644 --- a/src/biz/workspace/publish.rs +++ b/src/biz/workspace/publish.rs @@ -4,7 +4,7 @@ use database::{ publish::{ select_all_published_collab_info, select_default_published_view_id, select_default_published_view_id_for_namespace, update_published_collabs, - update_workspace_default_publish_view, + update_workspace_default_publish_view, update_workspace_default_publish_view_set_null, }, }; use database_entity::dto::PatchPublishedCollab; @@ -113,6 +113,16 @@ pub async fn set_workspace_default_publish_view( Ok(()) } +pub async fn unset_workspace_default_publish_view( + pg_pool: &PgPool, + user_uuid: &Uuid, + workspace_id: &Uuid, +) -> Result<(), AppError> { + check_workspace_owner(pg_pool, user_uuid, workspace_id).await?; + update_workspace_default_publish_view_set_null(pg_pool, workspace_id).await?; + Ok(()) +} + pub async fn get_workspace_default_publish_view_info( pg_pool: &PgPool, workspace_id: &Uuid, diff --git a/tests/workspace/publish.rs b/tests/workspace/publish.rs index ce8a3498..4a955cb9 100644 --- a/tests/workspace/publish.rs +++ b/tests/workspace/publish.rs @@ -17,6 +17,7 @@ use collab_document::document::Document; use collab_entity::CollabType; use collab_folder::{CollabOrigin, Folder, UserId}; use itertools::Itertools; +use serde::{Deserialize, Serialize}; use shared_entity::dto::publish_dto::PublishDatabaseData; use std::collections::{HashMap, HashSet}; use std::thread::sleep; @@ -249,6 +250,16 @@ async fn test_publish_doc() { .unwrap(); assert_eq!(default_info_meta.info.view_id, view_id_1); assert_eq!(default_info_meta.meta.title, "my_title_1"); + + // Owner of workspace unset the default publish view + c.delete_default_publish_view(&workspace_id).await.unwrap(); + + // Public can no longer get default publish view info + let err = localhost_client() + .get_default_published_collab::>(&my_namespace) + .await + .unwrap_err(); + assert_eq!(err.code, ErrorCode::RecordNotFound, "{:?}", err); } { @@ -778,7 +789,7 @@ async fn workspace_member_publish_unpublish() { .unwrap(); } -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Debug, Serialize, Deserialize)] struct MyCustomMetadata { title: String, }