mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
test: Af cloud workspace member (#3779)
* chore: implement workspace memeber events * chore: add workspace member test * chore: fix fmt
This commit is contained in:
parent
ad21a61ffb
commit
48582cb718
@ -421,7 +421,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||
@ -436,7 +436,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
ONLY_ACTIVE_ARCH = false;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = AppFlowy;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -558,7 +558,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||
@ -573,6 +573,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
ONLY_ACTIVE_ARCH = false;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = AppFlowy;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -586,7 +587,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
||||
@ -601,7 +602,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
ONLY_ACTIVE_ARCH = false;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.appflowy.appflowy.flutter;
|
||||
PRODUCT_NAME = AppFlowy;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
32
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
32
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -762,7 +762,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1292,7 +1292,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa 1.0.6",
|
||||
"phf 0.8.0",
|
||||
"phf 0.11.2",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -1438,7 +1438,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -2117,6 +2117,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio-postgres",
|
||||
"url",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2781,7 +2782,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2797,7 +2798,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"jsonwebtoken",
|
||||
@ -3232,7 +3233,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3451,6 +3452,7 @@ dependencies = [
|
||||
"thread-id",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4307,6 +4309,7 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
@ -4398,6 +4401,19 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
@ -4901,7 +4917,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -5623,7 +5639,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab-entity",
|
||||
|
@ -38,7 +38,7 @@ custom-protocol = ["tauri/custom-protocol"]
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "cc6b451104e7154b38df5ae9c4e7215a61fcf172" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c87d0f05e988a02e9272a42722b304289be320e4" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
16
frontend/rust-lib/Cargo.lock
generated
16
frontend/rust-lib/Cargo.lock
generated
@ -660,7 +660,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1265,7 +1265,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -1940,6 +1940,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio-postgres",
|
||||
"url",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2440,7 +2441,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2456,7 +2457,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"jsonwebtoken",
|
||||
@ -2816,7 +2817,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -2951,6 +2952,7 @@ dependencies = [
|
||||
"thread-id",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4251,7 +4253,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -4872,7 +4874,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=c87d0f05e988a02e9272a42722b304289be320e4#c87d0f05e988a02e9272a42722b304289be320e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab-entity",
|
||||
|
@ -82,7 +82,7 @@ incremental = false
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "cc6b451104e7154b38df5ae9c4e7215a61fcf172" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c87d0f05e988a02e9272a42722b304289be320e4" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
@ -25,6 +25,7 @@ lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
supabase_integrate = ["collab-plugins/postgres_storage_plugin", "collab-plugins/rocksdb_plugin"]
|
||||
appflowy_cloud_integrate = ["collab-plugins/rocksdb_plugin"]
|
||||
snapshot_plugin = ["collab-plugins/snapshot_plugin"]
|
||||
supabase_integrate = ["collab-plugins/postgres_storage_plugin", "rocksdb_plugin"]
|
||||
appflowy_cloud_integrate = ["rocksdb_plugin"]
|
||||
snapshot_plugin = ["collab-plugins/snapshot_plugin"]
|
||||
rocksdb_plugin = ["collab-plugins/rocksdb_plugin"]
|
@ -2,13 +2,51 @@ use flowy_folder2::entities::icon::UpdateViewIconPayloadPB;
|
||||
use flowy_folder2::entities::*;
|
||||
use flowy_folder2::event_map::FolderEvent;
|
||||
use flowy_folder2::event_map::FolderEvent::*;
|
||||
use flowy_user::entities::{
|
||||
AddWorkspaceMemberPB, QueryWorkspacePB, RemoveWorkspaceMemberPB, RepeatedWorkspaceMemberPB,
|
||||
WorkspaceMemberPB,
|
||||
};
|
||||
use flowy_user::errors::FlowyError;
|
||||
use flowy_user::event_map::UserEvent;
|
||||
|
||||
use crate::event_builder::EventBuilder;
|
||||
use crate::EventIntegrationTest;
|
||||
|
||||
impl EventIntegrationTest {
|
||||
// Must sign up/ sign in first
|
||||
pub async fn add_workspace_member(&self, workspace_id: &str, email: &str) {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(UserEvent::AddWorkspaceMember)
|
||||
.payload(AddWorkspaceMemberPB {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
email: email.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn delete_workspace_member(&self, workspace_id: &str, email: &str) {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(UserEvent::RemoveWorkspaceMember)
|
||||
.payload(RemoveWorkspaceMemberPB {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
email: email.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn get_workspace_members(&self, workspace_id: &str) -> Vec<WorkspaceMemberPB> {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(UserEvent::GetWorkspaceMember)
|
||||
.payload(QueryWorkspacePB {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<RepeatedWorkspaceMemberPB>()
|
||||
.items
|
||||
}
|
||||
|
||||
pub async fn get_current_workspace(&self) -> WorkspaceSettingPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::GetCurrentWorkspace)
|
||||
|
@ -0,0 +1,50 @@
|
||||
use event_integration::EventIntegrationTest;
|
||||
|
||||
use crate::util::get_af_cloud_config;
|
||||
|
||||
#[tokio::test]
|
||||
async fn af_cloud_add_workspace_member_test() {
|
||||
if get_af_cloud_config().is_some() {
|
||||
let test_1 = EventIntegrationTest::new();
|
||||
let user_1 = test_1.af_cloud_sign_up().await;
|
||||
|
||||
let test_2 = EventIntegrationTest::new();
|
||||
let user_2 = test_2.af_cloud_sign_up().await;
|
||||
|
||||
let members = test_1.get_workspace_members(&user_1.workspace_id).await;
|
||||
assert_eq!(members.len(), 1);
|
||||
assert_eq!(members[0].email, user_1.email);
|
||||
|
||||
test_1
|
||||
.add_workspace_member(&user_1.workspace_id, &user_2.email)
|
||||
.await;
|
||||
|
||||
let members = test_1.get_workspace_members(&user_1.workspace_id).await;
|
||||
assert_eq!(members.len(), 2);
|
||||
assert_eq!(members[0].email, user_1.email);
|
||||
assert_eq!(members[1].email, user_2.email);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn af_cloud_delete_workspace_member_test() {
|
||||
if get_af_cloud_config().is_some() {
|
||||
let test_1 = EventIntegrationTest::new();
|
||||
let user_1 = test_1.af_cloud_sign_up().await;
|
||||
|
||||
let test_2 = EventIntegrationTest::new();
|
||||
let user_2 = test_2.af_cloud_sign_up().await;
|
||||
|
||||
test_1
|
||||
.add_workspace_member(&user_1.workspace_id, &user_2.email)
|
||||
.await;
|
||||
|
||||
test_1
|
||||
.delete_workspace_member(&user_1.workspace_id, &user_2.email)
|
||||
.await;
|
||||
|
||||
let members = test_1.get_workspace_members(&user_1.workspace_id).await;
|
||||
assert_eq!(members.len(), 1);
|
||||
assert_eq!(members[0].email, user_1.email);
|
||||
}
|
||||
}
|
@ -1 +1,2 @@
|
||||
mod test;
|
||||
mod auth_test;
|
||||
mod member_test;
|
||||
|
@ -9,7 +9,7 @@ edition = "2021"
|
||||
collab = { version = "0.1.0" }
|
||||
collab-document = { version = "0.1.0" }
|
||||
collab-entity = { version = "0.1.0" }
|
||||
collab-integrate = { workspace = true }
|
||||
collab-integrate = { workspace = true, features = ["rocksdb_plugin", "snapshot_plugin"] }
|
||||
flowy-document-deps = { workspace = true }
|
||||
flowy-storage = { workspace = true }
|
||||
|
||||
@ -37,6 +37,7 @@ tokio-stream = { version = "0.1.14", features = ["sync"] }
|
||||
[dev-dependencies]
|
||||
tempfile = "3.4.0"
|
||||
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
|
||||
collab-integrate = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
flowy-codegen = { path = "../../../shared-lib/flowy-codegen"}
|
||||
|
@ -11,6 +11,7 @@ protobuf = { version = "2.28.0" }
|
||||
bytes = "1.4"
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
validator = "0.16.0"
|
||||
|
||||
fancy-regex = { version = "0.11.0" }
|
||||
lib-dispatch = { workspace = true, optional = true }
|
||||
|
@ -3,6 +3,7 @@ use std::fmt::Debug;
|
||||
|
||||
use protobuf::ProtobufError;
|
||||
use thiserror::Error;
|
||||
use validator::{ValidationError, ValidationErrors};
|
||||
|
||||
use flowy_derive::ProtoBuf;
|
||||
|
||||
@ -132,6 +133,18 @@ impl std::convert::From<protobuf::ProtobufError> for FlowyError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidationError> for FlowyError {
|
||||
fn from(value: ValidationError) -> Self {
|
||||
FlowyError::new(ErrorCode::InvalidParams, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidationErrors> for FlowyError {
|
||||
fn from(value: ValidationErrors) -> Self {
|
||||
FlowyError::new(ErrorCode::InvalidParams, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for FlowyError {
|
||||
fn from(e: anyhow::Error) -> Self {
|
||||
e.downcast::<FlowyError>()
|
||||
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use client_api::entity::workspace_dto::CreateWorkspaceMember;
|
||||
use client_api::entity::workspace_dto::{CreateWorkspaceMember, WorkspaceMemberChangeset};
|
||||
use client_api::entity::{AFRole, AFWorkspace, InsertCollabParams, OAuthProvider};
|
||||
use collab_entity::CollabObject;
|
||||
|
||||
@ -13,7 +13,7 @@ use lib_infra::box_any::BoxAny;
|
||||
use lib_infra::future::FutureResult;
|
||||
|
||||
use crate::af_cloud::impls::user::dto::{
|
||||
af_update_from_update_params, user_profile_from_af_profile,
|
||||
af_update_from_update_params, from_af_workspace_member, to_af_role, user_profile_from_af_profile,
|
||||
};
|
||||
use crate::af_cloud::impls::user::util::encryption_type_from_profile;
|
||||
use crate::af_cloud::{AFCloudClient, AFServer};
|
||||
@ -155,6 +155,38 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn update_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
workspace_id: String,
|
||||
role: Role,
|
||||
) -> FutureResult<(), Error> {
|
||||
let try_get_client = self.server.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let changeset = WorkspaceMemberChangeset::new(user_email).with_role(to_af_role(role));
|
||||
try_get_client?
|
||||
.update_workspace_member(workspace_id, changeset)
|
||||
.await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn get_workspace_members(
|
||||
&self,
|
||||
workspace_id: String,
|
||||
) -> FutureResult<Vec<WorkspaceMember>, Error> {
|
||||
let try_get_client = self.server.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let members = try_get_client?
|
||||
.get_workspace_members(&workspace_id)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(from_af_workspace_member)
|
||||
.collect();
|
||||
Ok(members)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_user_awareness_updates(&self, _uid: i64) -> FutureResult<Vec<Vec<u8>>, Error> {
|
||||
// TODO(nathan): implement the RESTful API for this
|
||||
FutureResult::new(async { Ok(vec![]) })
|
||||
|
@ -1,9 +1,9 @@
|
||||
use anyhow::Error;
|
||||
use client_api::entity::auth_dto::{UpdateUserParams, UserMetaData};
|
||||
use client_api::entity::AFUserProfile;
|
||||
use client_api::entity::{AFRole, AFUserProfile, AFWorkspaceMember};
|
||||
|
||||
use flowy_user_deps::entities::{
|
||||
AuthType, UpdateUserProfileParams, UserProfile, USER_METADATA_ICON_URL,
|
||||
AuthType, Role, UpdateUserProfileParams, UserProfile, WorkspaceMember, USER_METADATA_ICON_URL,
|
||||
USER_METADATA_OPEN_AI_KEY, USER_METADATA_STABILITY_AI_KEY,
|
||||
};
|
||||
|
||||
@ -63,3 +63,27 @@ pub fn user_profile_from_af_profile(
|
||||
updated_at: profile.updated_at,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_af_role(role: Role) -> AFRole {
|
||||
match role {
|
||||
Role::Owner => AFRole::Owner,
|
||||
Role::Member => AFRole::Member,
|
||||
Role::Guest => AFRole::Guest,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_af_role(role: AFRole) -> Role {
|
||||
match role {
|
||||
AFRole::Owner => Role::Owner,
|
||||
AFRole::Member => Role::Member,
|
||||
AFRole::Guest => Role::Guest,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_af_workspace_member(member: AFWorkspaceMember) -> WorkspaceMember {
|
||||
WorkspaceMember {
|
||||
email: member.email,
|
||||
role: from_af_role(member.role),
|
||||
name: member.name,
|
||||
}
|
||||
}
|
||||
|
@ -120,22 +120,6 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
|
||||
FutureResult::new(async { Ok(vec![]) })
|
||||
}
|
||||
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
_workspace_id: String,
|
||||
) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn remove_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
_workspace_id: String,
|
||||
) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn get_user_awareness_updates(&self, _uid: i64) -> FutureResult<Vec<Vec<u8>>, Error> {
|
||||
FutureResult::new(async { Ok(vec![]) })
|
||||
}
|
||||
|
@ -234,22 +234,6 @@ where
|
||||
Ok(user_workspaces)
|
||||
})
|
||||
}
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
_workspace_id: String,
|
||||
) -> FutureResult<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn remove_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
_workspace_id: String,
|
||||
) -> FutureResult<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_user_awareness_updates(&self, uid: i64) -> FutureResult<Vec<Vec<u8>>, Error> {
|
||||
let try_get_postgrest = self.server.try_get_weak_postgrest();
|
||||
let awareness_id = uid.to_string();
|
||||
|
@ -13,7 +13,8 @@ use lib_infra::box_any::BoxAny;
|
||||
use lib_infra::future::FutureResult;
|
||||
|
||||
use crate::entities::{
|
||||
AuthResponse, UpdateUserProfileParams, UserCredentials, UserProfile, UserWorkspace,
|
||||
AuthResponse, Role, UpdateUserProfileParams, UserCredentials, UserProfile, UserWorkspace,
|
||||
WorkspaceMember,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -57,6 +58,7 @@ impl Display for UserCloudConfig {
|
||||
|
||||
/// Provide the generic interface for the user cloud service
|
||||
/// The user cloud service is responsible for the user authentication and user profile management
|
||||
#[allow(unused_variables)]
|
||||
pub trait UserCloudService: Send + Sync + 'static {
|
||||
/// Sign up a new account.
|
||||
/// The type of the params is defined the this trait's implementation.
|
||||
@ -98,13 +100,33 @@ pub trait UserCloudService: Send + Sync + 'static {
|
||||
&self,
|
||||
user_email: String,
|
||||
workspace_id: String,
|
||||
) -> FutureResult<(), Error>;
|
||||
) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn remove_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
workspace_id: String,
|
||||
) -> FutureResult<(), Error>;
|
||||
) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn update_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
workspace_id: String,
|
||||
role: Role,
|
||||
) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn get_workspace_members(
|
||||
&self,
|
||||
workspace_id: String,
|
||||
) -> FutureResult<Vec<WorkspaceMember>, Error> {
|
||||
FutureResult::new(async { Ok(vec![]) })
|
||||
}
|
||||
|
||||
fn get_user_awareness_updates(&self, uid: i64) -> FutureResult<Vec<Vec<u8>>, Error>;
|
||||
|
||||
|
@ -377,3 +377,16 @@ pub enum UserTokenState {
|
||||
Refresh { token: String },
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Role {
|
||||
Owner,
|
||||
Member,
|
||||
Guest,
|
||||
}
|
||||
|
||||
pub struct WorkspaceMember {
|
||||
pub email: String,
|
||||
pub role: Role,
|
||||
pub name: String,
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
use validator::ValidationError;
|
||||
|
||||
pub use auth::*;
|
||||
pub use realtime::*;
|
||||
pub use reminder::*;
|
||||
pub use user_profile::*;
|
||||
pub use user_setting::*;
|
||||
pub use workspace_member::*;
|
||||
|
||||
pub mod auth;
|
||||
pub mod date_time;
|
||||
@ -11,3 +14,11 @@ pub mod realtime;
|
||||
mod reminder;
|
||||
mod user_profile;
|
||||
mod user_setting;
|
||||
mod workspace_member;
|
||||
|
||||
pub fn required_not_empty_str(s: &str) -> Result<(), ValidationError> {
|
||||
if s.is_empty() {
|
||||
return Err(ValidationError::new("should not be empty string"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use validator::ValidationError;
|
||||
|
||||
pub use user_email::*;
|
||||
pub use user_icon::*;
|
||||
pub use user_id::*;
|
||||
@ -14,3 +16,10 @@ mod user_name;
|
||||
mod user_openai_key;
|
||||
mod user_password;
|
||||
mod user_stability_ai_key;
|
||||
|
||||
pub fn validate_not_empty_str(s: &str) -> Result<(), ValidationError> {
|
||||
if s.is_empty() {
|
||||
return Err(ValidationError::new("should not be empty string"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -235,24 +235,6 @@ impl From<UserWorkspace> for UserWorkspacePB {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct AddWorkspaceUserPB {
|
||||
#[pb(index = 1)]
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct RemoveWorkspaceUserPB {
|
||||
#[pb(index = 1)]
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone)]
|
||||
pub struct RepeatedHistoricalUserPB {
|
||||
#[pb(index = 1)]
|
||||
|
105
frontend/rust-lib/flowy-user/src/entities/workspace_member.rs
Normal file
105
frontend/rust-lib/flowy-user/src/entities/workspace_member.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use validator::Validate;
|
||||
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_user_deps::entities::{Role, WorkspaceMember};
|
||||
|
||||
use crate::entities::required_not_empty_str;
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone)]
|
||||
pub struct WorkspaceMemberPB {
|
||||
#[pb(index = 1)]
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub name: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub role: AFRolePB,
|
||||
}
|
||||
|
||||
impl From<WorkspaceMember> for WorkspaceMemberPB {
|
||||
fn from(value: WorkspaceMember) -> Self {
|
||||
Self {
|
||||
email: value.email,
|
||||
name: value.name,
|
||||
role: value.role.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone)]
|
||||
pub struct RepeatedWorkspaceMemberPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<WorkspaceMemberPB>,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone, Validate)]
|
||||
pub struct AddWorkspaceMemberPB {
|
||||
#[pb(index = 1)]
|
||||
#[validate(custom = "required_not_empty_str")]
|
||||
pub workspace_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
#[validate(email)]
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone, Validate)]
|
||||
pub struct QueryWorkspacePB {
|
||||
#[pb(index = 1)]
|
||||
#[validate(custom = "required_not_empty_str")]
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone, Validate)]
|
||||
pub struct RemoveWorkspaceMemberPB {
|
||||
#[pb(index = 1)]
|
||||
#[validate(custom = "required_not_empty_str")]
|
||||
pub workspace_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
#[validate(email)]
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Clone, Validate)]
|
||||
pub struct UpdateWorkspaceMemberPB {
|
||||
#[pb(index = 1)]
|
||||
#[validate(custom = "required_not_empty_str")]
|
||||
pub workspace_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
#[validate(email)]
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub role: AFRolePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Clone, Default)]
|
||||
pub enum AFRolePB {
|
||||
Owner = 0,
|
||||
Member = 1,
|
||||
#[default]
|
||||
Guest = 2,
|
||||
}
|
||||
|
||||
impl From<AFRolePB> for Role {
|
||||
fn from(value: AFRolePB) -> Self {
|
||||
match value {
|
||||
AFRolePB::Owner => Role::Owner,
|
||||
AFRolePB::Member => Role::Member,
|
||||
AFRolePB::Guest => Role::Guest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Role> for AFRolePB {
|
||||
fn from(value: Role) -> Self {
|
||||
match value {
|
||||
Role::Owner => AFRolePB::Owner,
|
||||
Role::Member => AFRolePB::Member,
|
||||
Role::Guest => AFRolePB::Guest,
|
||||
}
|
||||
}
|
||||
}
|
@ -445,32 +445,6 @@ pub async fn open_workspace_handler(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn add_user_to_workspace_handler(
|
||||
data: AFPluginData<AddWorkspaceUserPB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params = data.into_inner();
|
||||
manager
|
||||
.add_user_to_workspace(params.email, params.workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn remove_user_from_workspace_handler(
|
||||
data: AFPluginData<RemoveWorkspaceUserPB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params = data.into_inner();
|
||||
manager
|
||||
.remove_user_to_workspace(params.email, params.workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, manager), err)]
|
||||
pub async fn update_network_state_handler(
|
||||
data: AFPluginData<NetworkStatePB>,
|
||||
@ -591,3 +565,58 @@ pub async fn update_reminder_event_handler(
|
||||
manager.update_reminder(params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub async fn add_workspace_member_handler(
|
||||
data: AFPluginData<AddWorkspaceMemberPB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let data = data.validate()?.into_inner();
|
||||
let manager = upgrade_manager(manager)?;
|
||||
manager
|
||||
.add_workspace_member(data.email, data.workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub async fn delete_workspace_member_handler(
|
||||
data: AFPluginData<RemoveWorkspaceMemberPB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let data = data.validate()?.into_inner();
|
||||
let manager = upgrade_manager(manager)?;
|
||||
manager
|
||||
.remove_workspace_member(data.email, data.workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub async fn get_workspace_member_handler(
|
||||
data: AFPluginData<QueryWorkspacePB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<RepeatedWorkspaceMemberPB, FlowyError> {
|
||||
let data = data.validate()?.into_inner();
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let members = manager
|
||||
.get_workspace_members(data.workspace_id)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(WorkspaceMemberPB::from)
|
||||
.collect();
|
||||
data_result_ok(RepeatedWorkspaceMemberPB { items: members })
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub async fn update_workspace_member_handler(
|
||||
data: AFPluginData<UpdateWorkspaceMemberPB>,
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let data = data.validate()?.into_inner();
|
||||
let manager = upgrade_manager(manager)?;
|
||||
manager
|
||||
.update_workspace_member(data.email, data.workspace_id, data.role.into())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use crate::errors::FlowyError;
|
||||
use crate::event_handler::*;
|
||||
use crate::manager::UserManager;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn init(user_session: Weak<UserManager>) -> AFPlugin {
|
||||
let store_preferences = user_session
|
||||
.upgrade()
|
||||
@ -39,20 +40,9 @@ pub fn init(user_session: Weak<UserManager>) -> AFPlugin {
|
||||
.event(UserEvent::CheckEncryptionSign, check_encrypt_secret_handler)
|
||||
.event(UserEvent::OauthSignIn, oauth_handler)
|
||||
.event(UserEvent::GetSignInURL, get_sign_in_url_handler)
|
||||
.event(
|
||||
UserEvent::GetOauthURLWithProvider,
|
||||
sign_in_with_provider_handler,
|
||||
)
|
||||
.event(
|
||||
UserEvent::GetAllUserWorkspaces,
|
||||
get_all_user_workspace_handler,
|
||||
)
|
||||
.event(UserEvent::GetOauthURLWithProvider, sign_in_with_provider_handler)
|
||||
.event(UserEvent::GetAllUserWorkspaces, get_all_user_workspace_handler)
|
||||
.event(UserEvent::OpenWorkspace, open_workspace_handler)
|
||||
.event(UserEvent::AddUserToWorkspace, add_user_to_workspace_handler)
|
||||
.event(
|
||||
UserEvent::RemoveUserToWorkspace,
|
||||
remove_user_from_workspace_handler,
|
||||
)
|
||||
.event(UserEvent::UpdateNetworkState, update_network_state_handler)
|
||||
.event(UserEvent::GetHistoricalUsers, get_historical_users_handler)
|
||||
.event(UserEvent::OpenHistoricalUser, open_historical_users_handler)
|
||||
@ -64,14 +54,142 @@ pub fn init(user_session: Weak<UserManager>) -> AFPlugin {
|
||||
.event(UserEvent::ResetWorkspace, reset_workspace_handler)
|
||||
.event(UserEvent::SetDateTimeSettings, set_date_time_settings)
|
||||
.event(UserEvent::GetDateTimeSettings, get_date_time_settings)
|
||||
.event(
|
||||
UserEvent::SetNotificationSettings,
|
||||
set_notification_settings,
|
||||
)
|
||||
.event(
|
||||
UserEvent::GetNotificationSettings,
|
||||
get_notification_settings,
|
||||
)
|
||||
.event(UserEvent::SetNotificationSettings, set_notification_settings)
|
||||
.event(UserEvent::GetNotificationSettings, get_notification_settings)
|
||||
// Workspace member
|
||||
.event(UserEvent::AddWorkspaceMember, add_workspace_member_handler)
|
||||
.event(UserEvent::RemoveWorkspaceMember, delete_workspace_member_handler)
|
||||
.event(UserEvent::GetWorkspaceMember, get_workspace_member_handler)
|
||||
.event(UserEvent::UpdateWorkspaceMember, update_workspace_member_handler,)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "FlowyError"]
|
||||
pub enum UserEvent {
|
||||
/// Only use when the [AuthType] is Local or SelfHosted
|
||||
/// Logging into an account using a register email and password
|
||||
#[event(input = "SignInPayloadPB", output = "UserProfilePB")]
|
||||
SignIn = 0,
|
||||
|
||||
/// Only use when the [AuthType] is Local or SelfHosted
|
||||
/// Creating a new account
|
||||
#[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
|
||||
SignUp = 1,
|
||||
|
||||
/// Logging out fo an account
|
||||
#[event()]
|
||||
SignOut = 2,
|
||||
|
||||
/// Update the user information
|
||||
#[event(input = "UpdateUserProfilePayloadPB")]
|
||||
UpdateUserProfile = 3,
|
||||
|
||||
/// Get the user information
|
||||
#[event(output = "UserProfilePB")]
|
||||
GetUserProfile = 4,
|
||||
|
||||
/// Initialize resources for the current user after launching the application
|
||||
///
|
||||
#[event()]
|
||||
InitUser = 6,
|
||||
|
||||
/// Change the visual elements of the interface, such as theme, font and more
|
||||
#[event(input = "AppearanceSettingsPB")]
|
||||
SetAppearanceSetting = 7,
|
||||
|
||||
/// Get the appearance setting
|
||||
#[event(output = "AppearanceSettingsPB")]
|
||||
GetAppearanceSetting = 8,
|
||||
|
||||
/// Get the settings of the user, such as the user storage folder
|
||||
#[event(output = "UserSettingPB")]
|
||||
GetUserSetting = 9,
|
||||
|
||||
#[event(input = "OauthSignInPB", output = "UserProfilePB")]
|
||||
OauthSignIn = 10,
|
||||
|
||||
/// Get the OAuth callback url
|
||||
/// Only use when the [AuthType] is AFCloud
|
||||
#[event(input = "SignInUrlPayloadPB", output = "SignInUrlPB")]
|
||||
GetSignInURL = 11,
|
||||
|
||||
#[event(input = "OauthProviderPB", output = "OauthProviderDataPB")]
|
||||
GetOauthURLWithProvider = 12,
|
||||
|
||||
#[event(input = "UpdateCloudConfigPB")]
|
||||
SetCloudConfig = 13,
|
||||
|
||||
#[event(output = "UserCloudConfigPB")]
|
||||
GetCloudConfig = 14,
|
||||
|
||||
#[event(input = "UserSecretPB")]
|
||||
SetEncryptionSecret = 15,
|
||||
|
||||
#[event(output = "UserEncryptionConfigurationPB")]
|
||||
CheckEncryptionSign = 16,
|
||||
|
||||
/// Return the all the workspaces of the user
|
||||
#[event()]
|
||||
GetAllUserWorkspaces = 20,
|
||||
|
||||
#[event(input = "UserWorkspacePB")]
|
||||
OpenWorkspace = 21,
|
||||
|
||||
#[event(input = "NetworkStatePB")]
|
||||
UpdateNetworkState = 24,
|
||||
|
||||
#[event(output = "RepeatedHistoricalUserPB")]
|
||||
GetHistoricalUsers = 25,
|
||||
|
||||
#[event(input = "HistoricalUserPB")]
|
||||
OpenHistoricalUser = 26,
|
||||
|
||||
/// Push a realtime event to the user. Currently, the realtime event
|
||||
/// is only used when the auth type is: [AuthType::Supabase].
|
||||
///
|
||||
#[event(input = "RealtimePayloadPB")]
|
||||
PushRealtimeEvent = 27,
|
||||
|
||||
#[event(input = "ReminderPB")]
|
||||
CreateReminder = 28,
|
||||
|
||||
#[event(output = "RepeatedReminderPB")]
|
||||
GetAllReminders = 29,
|
||||
|
||||
#[event(input = "ReminderIdentifierPB")]
|
||||
RemoveReminder = 30,
|
||||
|
||||
#[event(input = "ReminderPB")]
|
||||
UpdateReminder = 31,
|
||||
|
||||
#[event(input = "ResetWorkspacePB")]
|
||||
ResetWorkspace = 32,
|
||||
|
||||
/// Change the Date/Time formats globally
|
||||
#[event(input = "DateTimeSettingsPB")]
|
||||
SetDateTimeSettings = 33,
|
||||
|
||||
/// Retrieve the Date/Time formats
|
||||
#[event(output = "DateTimeSettingsPB")]
|
||||
GetDateTimeSettings = 34,
|
||||
|
||||
#[event(input = "NotificationSettingsPB")]
|
||||
SetNotificationSettings = 35,
|
||||
|
||||
#[event(output = "NotificationSettingsPB")]
|
||||
GetNotificationSettings = 36,
|
||||
|
||||
#[event(output = "AddWorkspaceMemberPB")]
|
||||
AddWorkspaceMember = 37,
|
||||
|
||||
#[event(output = "RemoveWorkspaceMemberPB")]
|
||||
RemoveWorkspaceMember = 38,
|
||||
|
||||
#[event(output = "UpdateWorkspaceMemberPB")]
|
||||
UpdateWorkspaceMember = 39,
|
||||
|
||||
#[event(output = "QueryWorkspacePB")]
|
||||
GetWorkspaceMember = 40,
|
||||
}
|
||||
|
||||
pub struct SignUpContext {
|
||||
@ -205,126 +323,3 @@ impl UserStatusCallback for DefaultUserStatusCallback {
|
||||
to_fut(async { Ok(()) })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "FlowyError"]
|
||||
pub enum UserEvent {
|
||||
/// Only use when the [AuthType] is Local or SelfHosted
|
||||
/// Logging into an account using a register email and password
|
||||
#[event(input = "SignInPayloadPB", output = "UserProfilePB")]
|
||||
SignIn = 0,
|
||||
|
||||
/// Only use when the [AuthType] is Local or SelfHosted
|
||||
/// Creating a new account
|
||||
#[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
|
||||
SignUp = 1,
|
||||
|
||||
/// Logging out fo an account
|
||||
#[event()]
|
||||
SignOut = 2,
|
||||
|
||||
/// Update the user information
|
||||
#[event(input = "UpdateUserProfilePayloadPB")]
|
||||
UpdateUserProfile = 3,
|
||||
|
||||
/// Get the user information
|
||||
#[event(output = "UserProfilePB")]
|
||||
GetUserProfile = 4,
|
||||
|
||||
/// Initialize resources for the current user after launching the application
|
||||
///
|
||||
#[event()]
|
||||
InitUser = 6,
|
||||
|
||||
/// Change the visual elements of the interface, such as theme, font and more
|
||||
#[event(input = "AppearanceSettingsPB")]
|
||||
SetAppearanceSetting = 7,
|
||||
|
||||
/// Get the appearance setting
|
||||
#[event(output = "AppearanceSettingsPB")]
|
||||
GetAppearanceSetting = 8,
|
||||
|
||||
/// Get the settings of the user, such as the user storage folder
|
||||
#[event(output = "UserSettingPB")]
|
||||
GetUserSetting = 9,
|
||||
|
||||
#[event(input = "OauthSignInPB", output = "UserProfilePB")]
|
||||
OauthSignIn = 10,
|
||||
|
||||
/// Get the OAuth callback url
|
||||
/// Only use when the [AuthType] is AFCloud
|
||||
#[event(input = "SignInUrlPayloadPB", output = "SignInUrlPB")]
|
||||
GetSignInURL = 11,
|
||||
|
||||
#[event(input = "OauthProviderPB", output = "OauthProviderDataPB")]
|
||||
GetOauthURLWithProvider = 12,
|
||||
|
||||
#[event(input = "UpdateCloudConfigPB")]
|
||||
SetCloudConfig = 13,
|
||||
|
||||
#[event(output = "UserCloudConfigPB")]
|
||||
GetCloudConfig = 14,
|
||||
|
||||
#[event(input = "UserSecretPB")]
|
||||
SetEncryptionSecret = 15,
|
||||
|
||||
#[event(output = "UserEncryptionConfigurationPB")]
|
||||
CheckEncryptionSign = 16,
|
||||
|
||||
/// Return the all the workspaces of the user
|
||||
#[event()]
|
||||
GetAllUserWorkspaces = 20,
|
||||
|
||||
#[event(input = "UserWorkspacePB")]
|
||||
OpenWorkspace = 21,
|
||||
|
||||
#[event(input = "AddWorkspaceUserPB")]
|
||||
AddUserToWorkspace = 22,
|
||||
|
||||
#[event(input = "RemoveWorkspaceUserPB")]
|
||||
RemoveUserToWorkspace = 23,
|
||||
|
||||
#[event(input = "NetworkStatePB")]
|
||||
UpdateNetworkState = 24,
|
||||
|
||||
#[event(output = "RepeatedHistoricalUserPB")]
|
||||
GetHistoricalUsers = 25,
|
||||
|
||||
#[event(input = "HistoricalUserPB")]
|
||||
OpenHistoricalUser = 26,
|
||||
|
||||
/// Push a realtime event to the user. Currently, the realtime event
|
||||
/// is only used when the auth type is: [AuthType::Supabase].
|
||||
///
|
||||
#[event(input = "RealtimePayloadPB")]
|
||||
PushRealtimeEvent = 27,
|
||||
|
||||
#[event(input = "ReminderPB")]
|
||||
CreateReminder = 28,
|
||||
|
||||
#[event(output = "RepeatedReminderPB")]
|
||||
GetAllReminders = 29,
|
||||
|
||||
#[event(input = "ReminderIdentifierPB")]
|
||||
RemoveReminder = 30,
|
||||
|
||||
#[event(input = "ReminderPB")]
|
||||
UpdateReminder = 31,
|
||||
|
||||
#[event(input = "ResetWorkspacePB")]
|
||||
ResetWorkspace = 32,
|
||||
|
||||
/// Change the Date/Time formats globally
|
||||
#[event(input = "DateTimeSettingsPB")]
|
||||
SetDateTimeSettings = 33,
|
||||
|
||||
/// Retrieve the Date/Time formats
|
||||
#[event(output = "DateTimeSettingsPB")]
|
||||
GetDateTimeSettings = 34,
|
||||
|
||||
#[event(input = "NotificationSettingsPB")]
|
||||
SetNotificationSettings = 35,
|
||||
|
||||
#[event(output = "NotificationSettingsPB")]
|
||||
GetNotificationSettings = 36,
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use collab_entity::{CollabObject, CollabType};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_sqlite::schema::user_workspace_table;
|
||||
use flowy_sqlite::{query_dsl::*, ConnectionPool, ExpressionMethods};
|
||||
use flowy_user_deps::entities::UserWorkspace;
|
||||
use flowy_user_deps::entities::{Role, UserWorkspace, WorkspaceMember};
|
||||
|
||||
use crate::entities::{RepeatedUserWorkspacePB, ResetWorkspacePB};
|
||||
use crate::manager::UserManager;
|
||||
@ -30,28 +30,54 @@ impl UserManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_user_to_workspace(
|
||||
pub async fn add_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
to_workspace_id: String,
|
||||
workspace_id: String,
|
||||
) -> FlowyResult<()> {
|
||||
self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.add_workspace_member(user_email, to_workspace_id)
|
||||
.add_workspace_member(user_email, workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_user_to_workspace(
|
||||
pub async fn remove_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
from_workspace_id: String,
|
||||
workspace_id: String,
|
||||
) -> FlowyResult<()> {
|
||||
self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.remove_workspace_member(user_email, from_workspace_id)
|
||||
.remove_workspace_member(user_email, workspace_id)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_workspace_members(
|
||||
&self,
|
||||
workspace_id: String,
|
||||
) -> FlowyResult<Vec<WorkspaceMember>> {
|
||||
let members = self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.get_workspace_members(workspace_id)
|
||||
.await?;
|
||||
Ok(members)
|
||||
}
|
||||
|
||||
pub async fn update_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
workspace_id: String,
|
||||
role: Role,
|
||||
) -> FlowyResult<()> {
|
||||
self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.update_workspace_member(user_email, workspace_id, role)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ derivative = "2.2.0"
|
||||
serde_json = {version = "1.0", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
serde_repr = { version = "0.1", optional = true }
|
||||
validator = "0.16.1"
|
||||
|
||||
#optional crate
|
||||
bincode = { version = "1.3", optional = true}
|
||||
|
@ -2,6 +2,7 @@ use std::fmt::{Debug, Formatter};
|
||||
use std::ops;
|
||||
|
||||
use bytes::Bytes;
|
||||
use validator::ValidationErrors;
|
||||
|
||||
use crate::{
|
||||
byte_trait::*,
|
||||
@ -11,6 +12,12 @@ use crate::{
|
||||
util::ready::{ready, Ready},
|
||||
};
|
||||
|
||||
pub trait AFPluginDataValidator {
|
||||
fn validate(self) -> Result<Self, ValidationErrors>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
pub struct AFPluginData<T>(pub T);
|
||||
|
||||
impl<T> AFPluginData<T> {
|
||||
@ -27,6 +34,16 @@ impl<T> ops::Deref for AFPluginData<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AFPluginDataValidator for AFPluginData<T>
|
||||
where
|
||||
T: validator::Validate,
|
||||
{
|
||||
fn validate(self) -> Result<Self, ValidationErrors> {
|
||||
self.0.validate()?;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ops::DerefMut for AFPluginData<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
&mut self.0
|
||||
|
Loading…
Reference in New Issue
Block a user