mirror of
https://github.com/AppFlowy-IO/AppFlowy-Cloud.git
synced 2025-04-19 03:24:42 -04:00
chore: stop writing to af_collab_member
This commit is contained in:
parent
af38efe6d9
commit
c1c5bf7420
13 changed files with 40 additions and 333 deletions
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT rp.permission_id\n FROM af_role_permissions rp\n JOIN af_roles ON rp.role_id = af_roles.id\n WHERE af_roles.name = 'Owner';\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "permission_id",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "711debcb02d19b1de4ff7dfcf77c2a431c9fe83ffd362d41b7f0f14a2f241d4b"
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "CALL af_collab_upsert($1, $2, $3, $4, $5, $6)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Int4",
|
||||
"Int8",
|
||||
"Int4",
|
||||
"Bytea"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "7e413ca3430f3270e9f903c8bc2151a5f354cd951c20dbd6261d65dbdb503cbc"
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n WITH workspace_check AS (\n SELECT EXISTS(\n SELECT 1\n FROM af_workspace_member\n WHERE af_workspace_member.uid = (SELECT uid FROM af_user WHERE uuid = $1) AND\n af_workspace_member.workspace_id = $3\n ) AS \"workspace_exists\"\n ),\n collab_check AS (\n SELECT EXISTS(\n SELECT 1\n FROM af_collab_member\n WHERE oid = $2\n ) AS \"collab_exists\"\n )\n SELECT\n NOT collab_check.collab_exists OR (\n workspace_check.workspace_exists AND\n EXISTS(\n SELECT 1\n FROM af_collab_member\n JOIN af_permissions ON af_collab_member.permission_id = af_permissions.id\n WHERE\n af_collab_member.uid = (SELECT uid FROM af_user WHERE uuid = $1) AND\n af_collab_member.oid = $2 AND\n af_permissions.access_level > 20\n )\n ) AS \"permission_check\"\n FROM workspace_check, collab_check;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "permission_check",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "a6b4725375e940cacdcc622b5288a38253db8bd48ba0774344d20fb6957f9ca6"
|
||||
}
|
20
.sqlx/query-c62e3c19160fdbcf2ef7bc2c85ec012f628d593c8b2eba5e6ef3ba313045a696.json
generated
Normal file
20
.sqlx/query-c62e3c19160fdbcf2ef7bc2c85ec012f628d593c8b2eba5e6ef3ba313045a696.json
generated
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO af_collab (oid, blob, len, partition_key, encrypt, owner_uid, workspace_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (oid, partition_key)\n DO UPDATE SET blob = $2, len = $3, encrypt = $5, owner_uid = $6 WHERE excluded.workspace_id = af_collab.workspace_id;\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Bytea",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Int8",
|
||||
"Uuid"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c62e3c19160fdbcf2ef7bc2c85ec012f628d593c8b2eba5e6ef3ba313045a696"
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO af_collab_member (uid, oid, permission_id)\n SELECT * FROM UNNEST($1::bigint[], $2::uuid[], $3::int[])\n ON CONFLICT (uid, oid)\n DO NOTHING;\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8Array",
|
||||
"UuidArray",
|
||||
"Int4Array"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "ceaa58cd92cd2a4c554c2a57fee11fbfd0bdb2b0e1b777d8533ae7c37d3b69e2"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n WITH ins_user AS (\n INSERT INTO af_user (uid, uuid, email, name)\n VALUES ($1, $2, $3, $4)\n RETURNING uid\n ),\n owner_role AS (\n SELECT id FROM af_roles WHERE name = 'Owner'\n ),\n ins_workspace AS (\n INSERT INTO af_workspace (owner_uid)\n SELECT uid FROM ins_user\n RETURNING workspace_id, owner_uid\n ),\n ins_collab_member AS (\n INSERT INTO af_collab_member (uid, oid, permission_id)\n SELECT ins_workspace.owner_uid,\n ins_workspace.workspace_id::TEXT,\n (SELECT permission_id FROM af_role_permissions WHERE role_id = owner_role.id)\n FROM ins_workspace, owner_role\n )\n SELECT workspace_id FROM ins_workspace;\n ",
|
||||
"query": "\n WITH ins_user AS (\n INSERT INTO af_user (uid, uuid, email, name)\n VALUES ($1, $2, $3, $4)\n RETURNING uid\n ),\n owner_role AS (\n SELECT id FROM af_roles WHERE name = 'Owner'\n ),\n ins_workspace AS (\n INSERT INTO af_workspace (owner_uid)\n SELECT uid FROM ins_user\n RETURNING workspace_id, owner_uid\n )\n SELECT workspace_id FROM ins_workspace;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
|
@ -21,5 +21,5 @@
|
|||
false
|
||||
]
|
||||
},
|
||||
"hash": "ce3b2a3ddee0f420166719e39e0e4befa495bb6438ef88be860fa1e557bf9281"
|
||||
"hash": "e2b4d66736962d1e3d0b9cf687ce5c5e653b465462f53433a28cf314e5c87d6c"
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT uid, oid, access_level\n FROM af_collab_member\n INNER JOIN af_permissions\n ON af_collab_member.permission_id = af_permissions.id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "uid",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "oid",
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "access_level",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f1b56cf92eeb5f7ddda80876c1ecf5b6a5357a58d18b9bf6f14e6a2261bd1182"
|
||||
}
|
|
@ -7,11 +7,10 @@ use database_entity::dto::{
|
|||
use shared_entity::dto::workspace_dto::DatabaseRowUpdatedItem;
|
||||
|
||||
use crate::collab::{partition_key_from_collab_type, SNAPSHOT_PER_HOUR};
|
||||
use crate::pg_row::AFCollabRowMeta;
|
||||
use crate::pg_row::AFSnapshotRow;
|
||||
use crate::pg_row::{AFCollabMemberAccessLevelRow, AFCollabRowMeta};
|
||||
use app_error::AppError;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use futures_util::stream::BoxStream;
|
||||
|
||||
use sqlx::postgres::PgRow;
|
||||
use sqlx::{Error, Executor, PgPool, Postgres, Row, Transaction};
|
||||
|
@ -61,24 +60,24 @@ pub async fn insert_into_af_collab(
|
|||
);
|
||||
|
||||
sqlx::query!(
|
||||
r#"CALL af_collab_upsert($1, $2, $3, $4, $5, $6)"#,
|
||||
workspace_id,
|
||||
r#"
|
||||
INSERT INTO af_collab (oid, blob, len, partition_key, encrypt, owner_uid, workspace_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (oid, partition_key)
|
||||
DO UPDATE SET blob = $2, len = $3, encrypt = $5, owner_uid = $6 WHERE excluded.workspace_id = af_collab.workspace_id;
|
||||
"#,
|
||||
params.object_id,
|
||||
partition_key,
|
||||
*uid,
|
||||
encrypt,
|
||||
params.encoded_collab_v1.as_ref(),
|
||||
params.encoded_collab_v1.len() as i32,
|
||||
partition_key,
|
||||
encrypt,
|
||||
uid,
|
||||
workspace_id,
|
||||
)
|
||||
.execute(tx.deref_mut())
|
||||
.await
|
||||
.map_err(|err| {
|
||||
.await.map_err(|err| {
|
||||
AppError::Internal(anyhow!(
|
||||
"Update af_collab failed: workspace_id:{}, uid:{}, object_id:{}, collab_type:{}. error: {:?}",
|
||||
workspace_id,
|
||||
uid,
|
||||
params.object_id,
|
||||
params.collab_type,
|
||||
err,
|
||||
workspace_id, uid, params.object_id, params.collab_type, err,
|
||||
))
|
||||
})?;
|
||||
|
||||
|
@ -154,25 +153,12 @@ pub async fn insert_into_af_collab_bulk_for_user(
|
|||
let encrypt = 0;
|
||||
let workspace_uuid = Uuid::from_str(workspace_id)?;
|
||||
|
||||
// Insert values into the `af_collab_member` and `af_collab` tables in bulk
|
||||
// Insert values into `af_collab` tables in bulk
|
||||
let len = collab_params_list.len();
|
||||
let mut object_ids: Vec<Uuid> = Vec::with_capacity(len);
|
||||
let mut blobs: Vec<Vec<u8>> = Vec::with_capacity(len);
|
||||
let mut lengths: Vec<i32> = Vec::with_capacity(len);
|
||||
let mut partition_keys: Vec<i32> = Vec::with_capacity(len);
|
||||
let mut permission_ids: Vec<i32> = Vec::with_capacity(len);
|
||||
|
||||
let permission_id: i32 = sqlx::query_scalar!(
|
||||
r#"
|
||||
SELECT rp.permission_id
|
||||
FROM af_role_permissions rp
|
||||
JOIN af_roles ON rp.role_id = af_roles.id
|
||||
WHERE af_roles.name = 'Owner';
|
||||
"#
|
||||
)
|
||||
.fetch_one(tx.deref_mut())
|
||||
.await?;
|
||||
|
||||
let mut visited = HashSet::with_capacity(collab_params_list.len());
|
||||
for params in collab_params_list {
|
||||
let oid = Uuid::from_str(¶ms.object_id)?;
|
||||
|
@ -182,7 +168,6 @@ pub async fn insert_into_af_collab_bulk_for_user(
|
|||
blobs.push(params.encoded_collab_v1.to_vec());
|
||||
lengths.push(params.encoded_collab_v1.len() as i32);
|
||||
partition_keys.push(partition_key);
|
||||
permission_ids.push(permission_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,28 +199,6 @@ pub async fn insert_into_af_collab_bulk_for_user(
|
|||
))
|
||||
})?;
|
||||
|
||||
// Bulk insert into `af_collab_member` for the user and provided collab params
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO af_collab_member (uid, oid, permission_id)
|
||||
SELECT * FROM UNNEST($1::bigint[], $2::uuid[], $3::int[])
|
||||
ON CONFLICT (uid, oid)
|
||||
DO NOTHING;
|
||||
"#,
|
||||
&uids,
|
||||
&object_ids,
|
||||
&permission_ids
|
||||
)
|
||||
.execute(tx.deref_mut())
|
||||
.await
|
||||
.map_err(|err| {
|
||||
AppError::Internal(anyhow!(
|
||||
"Bulk insert/update into af_collab_member failed for uid: {}, error details: {:?}",
|
||||
uid,
|
||||
err
|
||||
))
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -571,21 +534,6 @@ pub async fn delete_collab_member(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn select_collab_member_access_level(
|
||||
pg_pool: &PgPool,
|
||||
) -> BoxStream<'_, sqlx::Result<AFCollabMemberAccessLevelRow>> {
|
||||
sqlx::query_as!(
|
||||
AFCollabMemberAccessLevelRow,
|
||||
r#"
|
||||
SELECT uid, oid, access_level
|
||||
FROM af_collab_member
|
||||
INNER JOIN af_permissions
|
||||
ON af_collab_member.permission_id = af_permissions.id
|
||||
"#
|
||||
)
|
||||
.fetch(pg_pool)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn select_collab_members(
|
||||
oid: &str,
|
||||
|
|
|
@ -130,13 +130,6 @@ pub async fn create_user<'a, E: Executor<'a, Database = Postgres>>(
|
|||
INSERT INTO af_workspace (owner_uid)
|
||||
SELECT uid FROM ins_user
|
||||
RETURNING workspace_id, owner_uid
|
||||
),
|
||||
ins_collab_member AS (
|
||||
INSERT INTO af_collab_member (uid, oid, permission_id)
|
||||
SELECT ins_workspace.owner_uid,
|
||||
ins_workspace.workspace_id::TEXT,
|
||||
(SELECT permission_id FROM af_role_permissions WHERE role_id = owner_role.id)
|
||||
FROM ins_workspace, owner_role
|
||||
)
|
||||
SELECT workspace_id FROM ins_workspace;
|
||||
"#,
|
||||
|
|
|
@ -210,60 +210,6 @@ pub async fn select_user_role<'a, E: Executor<'a, Database = Postgres>>(
|
|||
Ok(AFRole::from(row))
|
||||
}
|
||||
|
||||
/// Checks the user's permission to edit a collab object.
|
||||
/// user can edit collab if:
|
||||
/// 1. user is the member of the workspace
|
||||
/// 2. the collab object is not exist
|
||||
/// 3. the collab object is exist and the user is the member of the collab and the role is owner or member
|
||||
#[allow(dead_code)]
|
||||
pub async fn select_user_can_edit_collab(
|
||||
pg_pool: &PgPool,
|
||||
user_uuid: &Uuid,
|
||||
workspace_id: &Uuid,
|
||||
object_id: &str,
|
||||
) -> Result<bool, AppError> {
|
||||
let permission_check = sqlx::query_scalar!(
|
||||
r#"
|
||||
WITH workspace_check AS (
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
FROM af_workspace_member
|
||||
WHERE af_workspace_member.uid = (SELECT uid FROM af_user WHERE uuid = $1) AND
|
||||
af_workspace_member.workspace_id = $3
|
||||
) AS "workspace_exists"
|
||||
),
|
||||
collab_check AS (
|
||||
SELECT EXISTS(
|
||||
SELECT 1
|
||||
FROM af_collab_member
|
||||
WHERE oid = $2
|
||||
) AS "collab_exists"
|
||||
)
|
||||
SELECT
|
||||
NOT collab_check.collab_exists OR (
|
||||
workspace_check.workspace_exists AND
|
||||
EXISTS(
|
||||
SELECT 1
|
||||
FROM af_collab_member
|
||||
JOIN af_permissions ON af_collab_member.permission_id = af_permissions.id
|
||||
WHERE
|
||||
af_collab_member.uid = (SELECT uid FROM af_user WHERE uuid = $1) AND
|
||||
af_collab_member.oid = $2 AND
|
||||
af_permissions.access_level > 20
|
||||
)
|
||||
) AS "permission_check"
|
||||
FROM workspace_check, collab_check;
|
||||
"#,
|
||||
user_uuid,
|
||||
object_id,
|
||||
workspace_id,
|
||||
)
|
||||
.fetch_one(pg_pool)
|
||||
.await?;
|
||||
|
||||
Ok(permission_check.unwrap_or(false))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn upsert_workspace_member_with_txn(
|
||||
txn: &mut Transaction<'_, sqlx::Postgres>,
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
DROP PROCEDURE IF EXISTS af_collab_upsert
|
|
@ -8,37 +8,6 @@ use database_entity::dto::{
|
|||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::test]
|
||||
async fn collab_owner_permission_test() {
|
||||
let (c, _user) = generate_unique_registered_user_client().await;
|
||||
let workspace_id = workspace_id_from_client(&c).await;
|
||||
let object_id = Uuid::new_v4().to_string();
|
||||
let uid = c.get_profile().await.unwrap().uid;
|
||||
let encode_collab = test_encode_collab_v1(&object_id, "title", "hello world")
|
||||
.encode_to_bytes()
|
||||
.unwrap();
|
||||
|
||||
c.create_collab(CreateCollabParams {
|
||||
object_id: object_id.clone(),
|
||||
encoded_collab_v1: encode_collab,
|
||||
collab_type: CollabType::Unknown,
|
||||
workspace_id: workspace_id.clone(),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let member = c
|
||||
.get_collab_member(WorkspaceCollabIdentify {
|
||||
uid,
|
||||
object_id,
|
||||
workspace_id,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(member.permission.access_level, AFAccessLevel::FullAccess);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_collab_member_permission_test() {
|
||||
let (c, _user) = generate_unique_registered_user_client().await;
|
||||
|
@ -163,7 +132,7 @@ async fn add_collab_member_then_remove_test() {
|
|||
.await
|
||||
.unwrap()
|
||||
.0;
|
||||
assert_eq!(members.len(), 2);
|
||||
assert_eq!(members.len(), 1);
|
||||
|
||||
// Delete the member
|
||||
c_1
|
||||
|
@ -182,5 +151,5 @@ async fn add_collab_member_then_remove_test() {
|
|||
.await
|
||||
.unwrap()
|
||||
.0;
|
||||
assert_eq!(members.len(), 1);
|
||||
assert_eq!(members.len(), 0);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use app_error::ErrorCode;
|
||||
use client_api::entity::AFWorkspaceInvitationStatus;
|
||||
use client_api_test::{api_client_with_email, TestClient};
|
||||
use database_entity::dto::{AFAccessLevel, AFRole, QueryCollabMembers};
|
||||
use database_entity::dto::AFRole;
|
||||
use shared_entity::dto::workspace_dto::WorkspaceMemberInvitation;
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -9,7 +9,6 @@ async fn get_workspace_owner_after_sign_up_test() {
|
|||
let c1 = TestClient::new_user_without_ws_conn().await;
|
||||
let workspace_id = c1.workspace_id().await;
|
||||
|
||||
// after the user sign up, the user should be the owner of the workspace
|
||||
let members = c1
|
||||
.api_client
|
||||
.get_workspace_members(&workspace_id)
|
||||
|
@ -17,22 +16,6 @@ async fn get_workspace_owner_after_sign_up_test() {
|
|||
.unwrap();
|
||||
assert_eq!(members.len(), 1);
|
||||
assert_eq!(members[0].email, c1.email().await);
|
||||
|
||||
// after user sign up, the user should have full access to the workspace
|
||||
let collab_members = c1
|
||||
.api_client
|
||||
.get_collab_members(QueryCollabMembers {
|
||||
workspace_id: workspace_id.clone(),
|
||||
object_id: workspace_id.clone(),
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.0;
|
||||
assert_eq!(collab_members.len(), 1);
|
||||
assert_eq!(
|
||||
collab_members[0].permission.access_level,
|
||||
AFAccessLevel::FullAccess
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -254,48 +237,6 @@ async fn workspace_add_member() {
|
|||
|
||||
assert_eq!(members[3].email, guest.email().await);
|
||||
assert_eq!(members[3].role, AFRole::Guest);
|
||||
|
||||
// after adding the members to the workspace, we should be able to get the collab members
|
||||
// of the workspace.
|
||||
let collab_members = owner
|
||||
.api_client
|
||||
.get_collab_members(QueryCollabMembers {
|
||||
workspace_id: workspace_id.clone(),
|
||||
object_id: workspace_id.clone(),
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.0;
|
||||
|
||||
assert_eq!(collab_members.len(), 4);
|
||||
|
||||
// owner
|
||||
assert_eq!(collab_members[0].uid, owner.uid().await);
|
||||
assert_eq!(
|
||||
collab_members[0].permission.access_level,
|
||||
AFAccessLevel::FullAccess
|
||||
);
|
||||
|
||||
// other owner
|
||||
assert_eq!(collab_members[1].uid, other_owner.uid().await);
|
||||
assert_eq!(
|
||||
collab_members[1].permission.access_level,
|
||||
AFAccessLevel::FullAccess
|
||||
);
|
||||
|
||||
// member
|
||||
assert_eq!(collab_members[2].uid, member.uid().await);
|
||||
assert_eq!(
|
||||
collab_members[2].permission.access_level,
|
||||
AFAccessLevel::ReadAndWrite
|
||||
);
|
||||
|
||||
// guest
|
||||
assert_eq!(collab_members[3].uid, guest.uid().await);
|
||||
assert_eq!(
|
||||
collab_members[3].permission.access_level,
|
||||
AFAccessLevel::ReadOnly
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
Loading…
Add table
Reference in a new issue