fix: fix various publish issues

This commit is contained in:
Zack Fu Zi Xiang 2024-06-29 11:23:23 +08:00
parent b02f8a2844
commit 395486adc3
No known key found for this signature in database
7 changed files with 72 additions and 20 deletions

View file

@ -117,9 +117,6 @@ pub enum AppError {
#[error("{0}")]
OverrideWithIncorrectData(String),
#[error("{0}")]
PublishNamespaceNotSet(String),
#[error("{0}")]
PublishNamespaceAlreadyTaken(String),
}
@ -180,7 +177,6 @@ impl AppError {
AppError::NoRequiredData(_) => ErrorCode::NoRequiredData,
AppError::OverrideWithIncorrectData(_) => ErrorCode::OverrideWithIncorrectData,
AppError::Utf8Error(_) => ErrorCode::Internal,
AppError::PublishNamespaceNotSet(_) => ErrorCode::PublishNamespaceNotSet,
AppError::PublishNamespaceAlreadyTaken(_) => ErrorCode::PublishNamespaceAlreadyTaken,
}
}

View file

@ -887,7 +887,7 @@ pub async fn update_workspace_publish_namespace<'a, E: Executor<'a, Database = P
pub async fn select_workspace_publish_namespace<'a, E: Executor<'a, Database = Postgres>>(
executor: E,
workspace_id: &Uuid,
) -> Result<Option<String>, AppError> {
) -> Result<String, AppError> {
let res = sqlx::query_scalar!(
r#"
SELECT publish_namespace

View file

@ -0,0 +1,9 @@
-- Update existing null values to ensure no nulls are present before adding NOT NULL constraint
UPDATE public.af_workspace
SET publish_namespace = uuid_generate_v4()::text
WHERE publish_namespace IS NULL;
-- Alter the column to set NOT NULL constraint and a default value
ALTER TABLE public.af_workspace
ALTER COLUMN publish_namespace SET NOT NULL,
ALTER COLUMN publish_namespace SET DEFAULT uuid_generate_v4()::text;

View file

@ -47,6 +47,7 @@ pub const WORKSPACE_MEMBER_PATTERN: &str = "/api/workspace/{workspace_id}/member
pub const WORKSPACE_INVITE_PATTERN: &str = "/api/workspace/{workspace_id}/invite";
pub const COLLAB_PATTERN: &str = "/api/workspace/{workspace_id}/collab/{object_id}";
pub const V1_COLLAB_PATTERN: &str = "/api/workspace/v1/{workspace_id}/collab/{object_id}";
pub const WORKSPACE_PUBLISH_PATTERN: &str = "/api/workspace/{workspace_id}/publish";
pub const WORKSPACE_PUBLISH_NAMESPACE_PATTERN: &str =
"/api/workspace/{workspace_id}/publish-namespace";

View file

@ -21,7 +21,7 @@ use database_entity::dto::AFRole;
use crate::api::workspace::{
WORKSPACE_INVITE_PATTERN, WORKSPACE_MEMBER_PATTERN, WORKSPACE_PATTERN,
WORKSPACE_PUBLISH_NAMESPACE_PATTERN,
WORKSPACE_PUBLISH_NAMESPACE_PATTERN, WORKSPACE_PUBLISH_PATTERN,
};
use crate::middleware::access_control_mw::{AccessResource, MiddlewareAccessControl};
use crate::state::UserCache;
@ -48,6 +48,10 @@ where
],
// Require role for given resources
require_role_rules: vec![
(
ResourceDef::new(WORKSPACE_PUBLISH_PATTERN),
[(Method::DELETE, AFRole::Member)].into(),
),
// Only the Owner can manager the workspace members
(
ResourceDef::new(WORKSPACE_MEMBER_PATTERN),

View file

@ -132,15 +132,7 @@ pub async fn get_workspace_publish_namespace(
pg_pool: &PgPool,
workspace_id: &Uuid,
) -> Result<String, AppError> {
let namespace = match select_workspace_publish_namespace(pg_pool, workspace_id).await? {
Some(namespace) => namespace,
None => {
return Err(AppError::PublishNamespaceNotSet(
"publish namespace is not set for the workspace".to_string(),
))
},
};
Ok(namespace)
select_workspace_publish_namespace(pg_pool, workspace_id).await
}
pub async fn publish_collabs(

View file

@ -1,4 +1,5 @@
use client_api::entity::{PublishCollabItem, PublishCollabMetadata};
use client_api::entity::{AFRole, PublishCollabItem, PublishCollabMetadata};
use client_api_test::TestClient;
use client_api_test::{generate_unique_registered_user_client, localhost_client};
#[tokio::test]
@ -7,13 +8,11 @@ async fn test_set_publish_namespace_set() {
let workspace_id = get_first_workspace_string(&c).await;
{
// cannot get namespace if not set
let err = c
// can get namespace before setting, which is random string
let _ = c
.get_workspace_publish_namespace(&workspace_id.to_string())
.await
.err()
.unwrap();
assert_eq!(format!("{:?}", err.code), "PublishNamespaceNotSet");
}
let namespace = uuid::Uuid::new_v4().to_string();
@ -127,6 +126,20 @@ async fn test_publish_doc() {
.await
.unwrap();
assert_eq!(blob, "yrs_encoded_data_1");
let publish_info = guest_client
.get_published_collab_info(&view_id_2)
.await
.unwrap();
assert_eq!(publish_info.namespace, Some(my_namespace.clone()));
assert_eq!(publish_info.publish_name, publish_name_2);
assert_eq!(publish_info.view_id, view_id_2);
let blob = guest_client
.get_published_collab_blob(&my_namespace, publish_name_2)
.await
.unwrap();
assert_eq!(blob, "yrs_encoded_data_2");
}
c.unpublish_collabs(&workspace_id, &[view_id_1])
@ -200,6 +213,43 @@ async fn get_first_workspace_string(c: &client_api::Client) -> String {
.to_string()
}
#[tokio::test]
async fn workspace_member_publish_unpublish() {
let client_1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = client_1.workspace_id().await;
let client_2 = TestClient::new_user_without_ws_conn().await;
client_1
.invite_and_accepted_workspace_member(&workspace_id, &client_2, AFRole::Member)
.await
.unwrap();
let view_id = uuid::Uuid::new_v4();
// member can publish without owner setting namespace
client_2
.api_client
.publish_collabs::<MyCustomMetadata, &[u8]>(
&workspace_id,
vec![PublishCollabItem {
meta: PublishCollabMetadata {
view_id,
publish_name: "publish-name-1".to_string(),
metadata: MyCustomMetadata {
title: "my_title_1".to_string(),
},
},
data: "yrs_encoded_data_1".as_bytes(),
}],
)
.await
.unwrap();
client_2
.api_client
.unpublish_collabs(&workspace_id, &[view_id])
.await
.unwrap();
}
#[derive(serde::Serialize, serde::Deserialize)]
struct MyCustomMetadata {
title: String,