mirror of
https://github.com/AppFlowy-IO/AppFlowy-Cloud.git
synced 2025-04-19 03:24:42 -04:00
fix: fix various publish issues
This commit is contained in:
parent
b02f8a2844
commit
395486adc3
7 changed files with 72 additions and 20 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
9
migrations/20240629035230_publish_collab_6.sql
Normal file
9
migrations/20240629035230_publish_collab_6.sql
Normal 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;
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue