chore: skip create sync plugin when the authenticator for given user … (#4252)

* chore: skip create sync plugin when the authenticator for given user is local

* chore: bump collab
This commit is contained in:
Nathan.fooo 2023-12-30 07:05:26 +08:00 committed by GitHub
parent 50694bb589
commit 7ba3020ab3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 174 additions and 127 deletions

View File

@ -9,8 +9,6 @@ import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
import 'auth/auth_service.dart';
/// A service to manage realtime interactions with Supabase. /// A service to manage realtime interactions with Supabase.
/// ///
/// `SupbaseRealtimeService` handles subscribing to table changes in Supabase /// `SupbaseRealtimeService` handles subscribing to table changes in Supabase
@ -37,10 +35,10 @@ class SupabaseRealtimeService {
}, },
onInvalidAuth: (message) async { onInvalidAuth: (message) async {
Log.error(message); Log.error(message);
await getIt<AuthService>().signOut();
channel?.unsubscribe(); channel?.unsubscribe();
channel = null; channel = null;
if (!isLoggingOut) { if (!isLoggingOut) {
isLoggingOut = true;
await runAppFlowy(); await runAppFlowy();
} }
}, },

View File

@ -883,7 +883,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -902,7 +902,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -932,7 +932,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-derive" name = "collab-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -944,7 +944,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -963,7 +963,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -977,7 +977,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -1019,7 +1019,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1040,7 +1040,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1066,7 +1066,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",

View File

@ -67,14 +67,14 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }

View File

@ -733,7 +733,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -752,7 +752,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -782,7 +782,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-derive" name = "collab-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -794,7 +794,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -813,7 +813,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -827,7 +827,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -869,7 +869,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-persistence" name = "collab-persistence"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -890,7 +890,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -916,7 +916,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e7d77a4b233886c4e9b7e03934c03d3e4489ec86#e7d77a4b233886c4e9b7e03934c03d3e4489ec86" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f#cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",

View File

@ -109,11 +109,11 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e7d77a4b233886c4e9b7e03934c03d3e4489ec86" } collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cf6aae1fbeb97d7b2f475fcdfc73217942ed8c8f" }

View File

@ -1,4 +1,4 @@
use std::fmt::Debug; use std::fmt::{Debug, Display};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use anyhow::Error; use anyhow::Error;
@ -16,13 +16,13 @@ use tracing::trace;
use lib_infra::future::Fut; use lib_infra::future::Fut;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum CollabDataSource { pub enum CollabPluginProviderType {
Local, Local,
AppFlowyCloud, AppFlowyCloud,
Supabase, Supabase,
} }
pub enum CollabStorageProviderContext { pub enum CollabPluginProviderContext {
Local, Local,
AppFlowyCloud { AppFlowyCloud {
uid: i64, uid: i64,
@ -37,23 +37,43 @@ pub enum CollabStorageProviderContext {
}, },
} }
pub trait CollabStorageProvider: Send + Sync + 'static { impl Display for CollabPluginProviderContext {
fn storage_source(&self) -> CollabDataSource; fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
CollabPluginProviderContext::Local => "Local".to_string(),
CollabPluginProviderContext::AppFlowyCloud {
uid: _,
collab_object,
local_collab: _,
} => collab_object.to_string(),
CollabPluginProviderContext::Supabase {
uid: _,
collab_object,
local_collab: _,
local_collab_db: _,
} => collab_object.to_string(),
};
write!(f, "{}", str)
}
}
fn get_plugins(&self, context: CollabStorageProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>>; pub trait CollabCloudPluginProvider: Send + Sync + 'static {
fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>>;
fn is_sync_enabled(&self) -> bool; fn is_sync_enabled(&self) -> bool;
} }
impl<T> CollabStorageProvider for Arc<T> impl<T> CollabCloudPluginProvider for Arc<T>
where where
T: CollabStorageProvider, T: CollabCloudPluginProvider,
{ {
fn storage_source(&self) -> CollabDataSource { fn provider_type(&self) -> CollabPluginProviderType {
(**self).storage_source() (**self).provider_type()
} }
fn get_plugins(&self, context: CollabStorageProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> {
(**self).get_plugins(context) (**self).get_plugins(context)
} }
@ -65,7 +85,7 @@ where
pub struct AppFlowyCollabBuilder { pub struct AppFlowyCollabBuilder {
network_reachability: CollabNetworkReachability, network_reachability: CollabNetworkReachability,
workspace_id: RwLock<Option<String>>, workspace_id: RwLock<Option<String>>,
cloud_storage: tokio::sync::RwLock<Arc<dyn CollabStorageProvider>>, plugin_provider: tokio::sync::RwLock<Arc<dyn CollabCloudPluginProvider>>,
snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>, snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>,
rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>, rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>,
device_id: String, device_id: String,
@ -89,11 +109,11 @@ impl CollabBuilderConfig {
} }
impl AppFlowyCollabBuilder { impl AppFlowyCollabBuilder {
pub fn new<T: CollabStorageProvider>(storage_provider: T, device_id: String) -> Self { pub fn new<T: CollabCloudPluginProvider>(storage_provider: T, device_id: String) -> Self {
Self { Self {
network_reachability: CollabNetworkReachability::new(), network_reachability: CollabNetworkReachability::new(),
workspace_id: Default::default(), workspace_id: Default::default(),
cloud_storage: tokio::sync::RwLock::new(Arc::new(storage_provider)), plugin_provider: tokio::sync::RwLock::new(Arc::new(storage_provider)),
snapshot_persistence: Default::default(), snapshot_persistence: Default::default(),
rocksdb_backup: Default::default(), rocksdb_backup: Default::default(),
device_id, device_id,
@ -219,20 +239,20 @@ impl AppFlowyCollabBuilder {
{ {
let collab_object = self.collab_object(uid, object_id, object_type)?; let collab_object = self.collab_object(uid, object_id, object_type)?;
if build_config.sync_enable { if build_config.sync_enable {
let cloud_storage_type = self.cloud_storage.read().await.storage_source(); let provider_type = self.plugin_provider.read().await.provider_type();
let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id); let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id);
let _enter = span.enter(); let _enter = span.enter();
match cloud_storage_type { match provider_type {
CollabDataSource::AppFlowyCloud => { CollabPluginProviderType::AppFlowyCloud => {
#[cfg(feature = "appflowy_cloud_integrate")] #[cfg(feature = "appflowy_cloud_integrate")]
{ {
trace!("init appflowy cloud collab plugins"); trace!("init appflowy cloud collab plugins");
let local_collab = Arc::downgrade(&collab); let local_collab = Arc::downgrade(&collab);
let plugins = self let plugins = self
.cloud_storage .plugin_provider
.read() .read()
.await .await
.get_plugins(CollabStorageProviderContext::AppFlowyCloud { .get_plugins(CollabPluginProviderContext::AppFlowyCloud {
uid, uid,
collab_object: collab_object.clone(), collab_object: collab_object.clone(),
local_collab, local_collab,
@ -245,17 +265,17 @@ impl AppFlowyCollabBuilder {
} }
} }
}, },
CollabDataSource::Supabase => { CollabPluginProviderType::Supabase => {
#[cfg(feature = "supabase_integrate")] #[cfg(feature = "supabase_integrate")]
{ {
trace!("init supabase collab plugins"); trace!("init supabase collab plugins");
let local_collab = Arc::downgrade(&collab); let local_collab = Arc::downgrade(&collab);
let local_collab_db = collab_db.clone(); let local_collab_db = collab_db.clone();
let plugins = self let plugins = self
.cloud_storage .plugin_provider
.read() .read()
.await .await
.get_plugins(CollabStorageProviderContext::Supabase { .get_plugins(CollabPluginProviderContext::Supabase {
uid, uid,
collab_object: collab_object.clone(), collab_object: collab_object.clone(),
local_collab, local_collab,
@ -267,7 +287,7 @@ impl AppFlowyCollabBuilder {
} }
} }
}, },
CollabDataSource::Local => {}, CollabPluginProviderType::Local => {},
} }
} }

View File

@ -54,7 +54,10 @@ pub struct ServerProvider {
pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>, pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>,
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) store_preferences: Weak<StorePreferences>, pub(crate) store_preferences: Weak<StorePreferences>,
pub(crate) enable_sync: RwLock<bool>, pub(crate) user_enable_sync: RwLock<bool>,
/// The authenticator type of the user.
pub(crate) user_authenticator: RwLock<Authenticator>,
pub(crate) uid: Arc<RwLock<Option<i64>>>, pub(crate) uid: Arc<RwLock<Option<i64>>>,
} }
@ -69,7 +72,8 @@ impl ServerProvider {
config, config,
server: RwLock::new(server), server: RwLock::new(server),
providers: RwLock::new(HashMap::new()), providers: RwLock::new(HashMap::new()),
enable_sync: RwLock::new(true), user_enable_sync: RwLock::new(true),
user_authenticator: RwLock::new(Authenticator::Local),
encryption: RwLock::new(Arc::new(encryption)), encryption: RwLock::new(Arc::new(encryption)),
store_preferences, store_preferences,
uid: Default::default(), uid: Default::default(),
@ -112,7 +116,7 @@ impl ServerProvider {
let config = AFCloudConfiguration::from_env()?; let config = AFCloudConfiguration::from_env()?;
let server = Arc::new(AppFlowyCloudServer::new( let server = Arc::new(AppFlowyCloudServer::new(
config, config,
*self.enable_sync.read(), *self.user_enable_sync.read(),
self.config.device_id.clone(), self.config.device_id.clone(),
)); ));
@ -126,7 +130,7 @@ impl ServerProvider {
Ok::<Arc<dyn AppFlowyServer>, FlowyError>(Arc::new(SupabaseServer::new( Ok::<Arc<dyn AppFlowyServer>, FlowyError>(Arc::new(SupabaseServer::new(
uid, uid,
config, config,
*self.enable_sync.read(), *self.user_enable_sync.read(),
self.config.device_id.clone(), self.config.device_id.clone(),
encryption, encryption,
))) )))

View File

@ -8,10 +8,10 @@ use collab::core::origin::{CollabClient, CollabOrigin};
use collab::preclude::CollabPlugin; use collab::preclude::CollabPlugin;
use collab_entity::CollabType; use collab_entity::CollabType;
use tokio_stream::wrappers::WatchStream; use tokio_stream::wrappers::WatchStream;
use tracing::instrument; use tracing::{debug, instrument};
use collab_integrate::collab_builder::{ use collab_integrate::collab_builder::{
CollabDataSource, CollabStorageProvider, CollabStorageProviderContext, CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType,
}; };
use collab_integrate::postgres::SupabaseDBPlugin; use collab_integrate::postgres::SupabaseDBPlugin;
use flowy_database_deps::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; use flowy_database_deps::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot};
@ -71,20 +71,14 @@ impl UserCloudServiceProvider for ServerProvider {
fn set_enable_sync(&self, uid: i64, enable_sync: bool) { fn set_enable_sync(&self, uid: i64, enable_sync: bool) {
if let Ok(server) = self.get_server(&self.get_server_type()) { if let Ok(server) = self.get_server(&self.get_server_type()) {
server.set_enable_sync(uid, enable_sync); server.set_enable_sync(uid, enable_sync);
*self.enable_sync.write() = enable_sync; *self.user_enable_sync.write() = enable_sync;
*self.uid.write() = Some(uid); *self.uid.write() = Some(uid);
} }
} }
fn set_network_reachable(&self, reachable: bool) { fn set_user_authenticator(&self, authenticator: &Authenticator) {
if let Ok(server) = self.get_server(&self.get_server_type()) { debug!("set user authenticator: {:?}", authenticator);
server.set_network_reachable(reachable); *self.user_authenticator.write() = authenticator.clone();
}
}
fn set_encrypt_secret(&self, secret: String) {
tracing::info!("🔑Set encrypt secret");
self.encryption.write().set_secret(secret);
} }
/// When user login, the provider type is set by the [Authenticator] and save to disk for next use. /// When user login, the provider type is set by the [Authenticator] and save to disk for next use.
@ -98,6 +92,17 @@ impl UserCloudServiceProvider for ServerProvider {
self.set_server_type(server_type.clone()); self.set_server_type(server_type.clone());
} }
fn set_network_reachable(&self, reachable: bool) {
if let Ok(server) = self.get_server(&self.get_server_type()) {
server.set_network_reachable(reachable);
}
}
fn set_encrypt_secret(&self, secret: String) {
tracing::info!("🔑Set encrypt secret");
self.encryption.write().set_secret(secret);
}
fn get_authenticator(&self) -> Authenticator { fn get_authenticator(&self) -> Authenticator {
let server_type = self.get_server_type(); let server_type = self.get_server_type();
Authenticator::from(server_type) Authenticator::from(server_type)
@ -315,16 +320,25 @@ impl DocumentCloudService for ServerProvider {
} }
} }
impl CollabStorageProvider for ServerProvider { impl CollabCloudPluginProvider for ServerProvider {
fn storage_source(&self) -> CollabDataSource { fn provider_type(&self) -> CollabPluginProviderType {
self.get_server_type().into() self.get_server_type().into()
} }
#[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))] #[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))]
fn get_plugins(&self, context: CollabStorageProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> {
// If the user is local, we don't need to create a sync plugin.
if self.user_authenticator.read().is_local() {
debug!(
"User authenticator is local, skip create sync plugin for: {}",
context
);
return to_fut(async move { vec![] });
}
match context { match context {
CollabStorageProviderContext::Local => to_fut(async move { vec![] }), CollabPluginProviderContext::Local => to_fut(async move { vec![] }),
CollabStorageProviderContext::AppFlowyCloud { CollabPluginProviderContext::AppFlowyCloud {
uid: _, uid: _,
collab_object, collab_object,
local_collab, local_collab,
@ -332,6 +346,9 @@ impl CollabStorageProvider for ServerProvider {
if let Ok(server) = self.get_server(&Server::AppFlowyCloud) { if let Ok(server) = self.get_server(&Server::AppFlowyCloud) {
to_fut(async move { to_fut(async move {
let mut plugins: Vec<Arc<dyn CollabPlugin>> = vec![]; let mut plugins: Vec<Arc<dyn CollabPlugin>> = vec![];
// If the user is local, we don't need to create a sync plugin.
match server.collab_ws_channel(&collab_object.object_id).await { match server.collab_ws_channel(&collab_object.object_id).await {
Ok(Some((channel, ws_connect_state, is_connected))) => { Ok(Some((channel, ws_connect_state, is_connected))) => {
let origin = CollabOrigin::Client(CollabClient::new( let origin = CollabOrigin::Client(CollabClient::new(
@ -369,7 +386,7 @@ impl CollabStorageProvider for ServerProvider {
to_fut(async move { vec![] }) to_fut(async move { vec![] })
} }
}, },
CollabStorageProviderContext::Supabase { CollabPluginProviderContext::Supabase {
uid, uid,
collab_object, collab_object,
local_collab, local_collab,
@ -397,7 +414,7 @@ impl CollabStorageProvider for ServerProvider {
} }
fn is_sync_enabled(&self) -> bool { fn is_sync_enabled(&self) -> bool {
*self.enable_sync.read() *self.user_enable_sync.read()
} }
} }

View File

@ -28,11 +28,10 @@ pub(crate) struct UserStatusCallbackImpl {
} }
impl UserStatusCallback for UserStatusCallbackImpl { impl UserStatusCallback for UserStatusCallbackImpl {
fn authenticator_did_changed(&self, _auth_type: Authenticator) {}
fn did_init( fn did_init(
&self, &self,
user_id: i64, user_id: i64,
user_authenticator: &Authenticator,
cloud_config: &Option<UserCloudConfig>, cloud_config: &Option<UserCloudConfig>,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,
@ -44,6 +43,10 @@ impl UserStatusCallback for UserStatusCallbackImpl {
let database_manager = self.database_manager.clone(); let database_manager = self.database_manager.clone();
let document_manager = self.document_manager.clone(); let document_manager = self.document_manager.clone();
self
.server_provider
.set_user_authenticator(user_authenticator);
if let Some(cloud_config) = cloud_config { if let Some(cloud_config) = cloud_config {
self self
.server_provider .server_provider
@ -131,6 +134,9 @@ impl UserStatusCallback for UserStatusCallbackImpl {
let database_manager = self.database_manager.clone(); let database_manager = self.database_manager.clone();
let user_workspace = user_workspace.clone(); let user_workspace = user_workspace.clone();
let document_manager = self.document_manager.clone(); let document_manager = self.document_manager.clone();
self
.server_provider
.set_user_authenticator(&user_profile.authenticator);
let server_type = self.server_provider.get_server_type(); let server_type = self.server_provider.get_server_type();
to_fut(async move { to_fut(async move {

View File

@ -7,7 +7,7 @@ use std::time::Duration;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tracing::{debug, error, event, info, instrument}; use tracing::{debug, error, event, info, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabDataSource}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProviderType};
use flowy_database2::DatabaseManager; use flowy_database2::DatabaseManager;
use flowy_document2::manager::DocumentManager; use flowy_document2::manager::DocumentManager;
use flowy_folder2::manager::FolderManager; use flowy_folder2::manager::FolderManager;
@ -238,12 +238,12 @@ fn init_user_manager(
) )
} }
impl From<Server> for CollabDataSource { impl From<Server> for CollabPluginProviderType {
fn from(server_type: Server) -> Self { fn from(server_type: Server) -> Self {
match server_type { match server_type {
Server::Local => CollabDataSource::Local, Server::Local => CollabPluginProviderType::Local,
Server::AppFlowyCloud => CollabDataSource::AppFlowyCloud, Server::AppFlowyCloud => CollabPluginProviderType::AppFlowyCloud,
Server::Supabase => CollabDataSource::Supabase, Server::Supabase => CollabPluginProviderType::Supabase,
} }
} }
} }

View File

@ -14,7 +14,8 @@ use tracing_subscriber::{fmt::Subscriber, util::SubscriberInitExt, EnvFilter};
use uuid::Uuid; use uuid::Uuid;
use collab_integrate::collab_builder::{ use collab_integrate::collab_builder::{
AppFlowyCollabBuilder, CollabDataSource, CollabStorageProvider, CollabStorageProviderContext, AppFlowyCollabBuilder, CollabCloudPluginProvider, CollabPluginProviderContext,
CollabPluginProviderType,
}; };
use collab_integrate::RocksCollabDB; use collab_integrate::RocksCollabDB;
use flowy_document2::document::MutexDocument; use flowy_document2::document::MutexDocument;
@ -176,12 +177,12 @@ impl FileStorageService for DocumentTestFileStorageService {
struct DefaultCollabStorageProvider(); struct DefaultCollabStorageProvider();
#[async_trait] #[async_trait]
impl CollabStorageProvider for DefaultCollabStorageProvider { impl CollabCloudPluginProvider for DefaultCollabStorageProvider {
fn storage_source(&self) -> CollabDataSource { fn provider_type(&self) -> CollabPluginProviderType {
CollabDataSource::Local CollabPluginProviderType::Local
} }
fn get_plugins(&self, _context: CollabStorageProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> { fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> {
to_fut(async move { vec![] }) to_fut(async move { vec![] })
} }

View File

@ -85,6 +85,15 @@ pub trait UserCloudServiceProvider: Send + Sync + 'static {
/// * `enable_sync`: A boolean indicating whether synchronization should be enabled or disabled. /// * `enable_sync`: A boolean indicating whether synchronization should be enabled or disabled.
fn set_enable_sync(&self, uid: i64, enable_sync: bool); fn set_enable_sync(&self, uid: i64, enable_sync: bool);
/// Sets the authentication type for a user. The authentication type is the type when user sign in or sign up.
fn set_user_authenticator(&self, authenticator: &Authenticator);
/// Sets the authenticator when user sign in or sign up.
///
/// # Arguments
/// * `authenticator`: An `Authenticator` object.
fn set_authenticator(&self, authenticator: Authenticator);
/// Sets the network reachability status. /// Sets the network reachability status.
/// ///
/// # Arguments /// # Arguments
@ -97,12 +106,6 @@ pub trait UserCloudServiceProvider: Send + Sync + 'static {
/// * `secret`: A `String` representing the encryption secret. /// * `secret`: A `String` representing the encryption secret.
fn set_encrypt_secret(&self, secret: String); fn set_encrypt_secret(&self, secret: String);
/// Sets the authenticator used for authentication processes.
///
/// # Arguments
/// * `authenticator`: An `Authenticator` object.
fn set_authenticator(&self, authenticator: Authenticator);
/// Retrieves the current authenticator. /// Retrieves the current authenticator.
/// ///
/// # Returns /// # Returns

View File

@ -198,6 +198,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
fn did_init( fn did_init(
&self, &self,
user_id: i64, user_id: i64,
user_authenticator: &Authenticator,
cloud_config: &Option<UserCloudConfig>, cloud_config: &Option<UserCloudConfig>,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
device_id: &str, device_id: &str,
@ -229,6 +230,7 @@ impl UserStatusCallback for DefaultUserStatusCallback {
fn did_init( fn did_init(
&self, &self,
_user_id: i64, _user_id: i64,
_authenticator: &Authenticator,
_cloud_config: &Option<UserCloudConfig>, _cloud_config: &Option<UserCloudConfig>,
_user_workspace: &UserWorkspace, _user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,

View File

@ -112,6 +112,7 @@ impl UserManager {
pub fn close_db(&self) { pub fn close_db(&self) {
if let Ok(session) = self.get_session() { if let Ok(session) = self.get_session() {
info!("Close db for user: {}", session.user_id);
if let Err(err) = self.database.close(session.user_id) { if let Err(err) = self.database.close(session.user_id) {
error!("Close db failed: {:?}", err); error!("Close db failed: {:?}", err);
} }
@ -227,15 +228,12 @@ impl UserManager {
}, },
_ => error!("Failed to get collab db or sqlite pool"), _ => error!("Failed to get collab db or sqlite pool"),
} }
// Init the user awareness
self
.initialize_user_awareness(&session, UserAwarenessDataSource::Local)
.await;
let cloud_config = get_cloud_config(session.user_id, &self.store_preferences); let cloud_config = get_cloud_config(session.user_id, &self.store_preferences);
if let Err(e) = user_status_callback if let Err(e) = user_status_callback
.did_init( .did_init(
session.user_id, user.uid,
&user.authenticator,
&cloud_config, &cloud_config,
&session.user_workspace, &session.user_workspace,
&self.user_config.device_id, &self.user_config.device_id,
@ -244,6 +242,10 @@ impl UserManager {
{ {
error!("Failed to call did_init callback: {:?}", e); error!("Failed to call did_init callback: {:?}", e);
} }
// Init the user awareness
self
.initialize_user_awareness(&session, UserAwarenessDataSource::Local)
.await;
} }
Ok(()) Ok(())
} }
@ -312,17 +314,11 @@ impl UserManager {
send_auth_state_notification(AuthStateChangedPB { send_auth_state_notification(AuthStateChangedPB {
state: AuthStatePB::AuthStateSignIn, state: AuthStatePB::AuthStateSignIn,
message: "Sign in success".to_string(), message: "Sign in success".to_string(),
}) });
.send();
Ok(user_profile) Ok(user_profile)
} }
pub(crate) async fn update_authenticator(&self, authenticator: &Authenticator) { pub(crate) async fn update_authenticator(&self, authenticator: &Authenticator) {
self
.user_status_callback
.read()
.await
.authenticator_did_changed(authenticator.clone());
self.cloud_services.set_authenticator(authenticator.clone()); self.cloud_services.set_authenticator(authenticator.clone());
} }
@ -422,9 +418,6 @@ impl UserManager {
let _ = self.database.close(old_user.session.user_id); let _ = self.database.close(old_user.session.user_id);
} }
} }
self
.initialize_user_awareness(&new_session, user_awareness_source)
.await;
self self
.save_auth_data(&response, authenticator, &new_session) .save_auth_data(&response, authenticator, &new_session)
@ -442,11 +435,14 @@ impl UserManager {
) )
.await?; .await?;
self
.initialize_user_awareness(&new_session, user_awareness_source)
.await;
send_auth_state_notification(AuthStateChangedPB { send_auth_state_notification(AuthStateChangedPB {
state: AuthStatePB::AuthStateSignIn, state: AuthStatePB::AuthStateSignIn,
message: "Sign up success".to_string(), message: "Sign up success".to_string(),
}) });
.send();
Ok(()) Ok(())
} }
@ -575,8 +571,7 @@ impl UserManager {
send_auth_state_notification(AuthStateChangedPB { send_auth_state_notification(AuthStateChangedPB {
state: AuthStatePB::InvalidAuth, state: AuthStatePB::InvalidAuth,
message: "User is not found on the server".to_string(), message: "User is not found on the server".to_string(),
}) });
.send();
} }
Err(err) Err(err)
}, },
@ -676,13 +671,14 @@ impl UserManager {
} }
pub(crate) fn set_session(&self, session: Option<Session>) -> Result<(), FlowyError> { pub(crate) fn set_session(&self, session: Option<Session>) -> Result<(), FlowyError> {
debug!("Set current user: {:?}", session); debug!("Set current user session: {:?}", session);
match &session { match &session {
None => { None => {
self.current_session.write().take(); self.current_session.write().take();
self self
.store_preferences .store_preferences
.remove(&self.user_config.session_cache_key) .remove(self.user_config.session_cache_key.as_ref());
Ok(())
}, },
Some(session) => { Some(session) => {
self.current_session.write().replace(session.clone()); self.current_session.write().replace(session.clone());
@ -690,9 +686,9 @@ impl UserManager {
.store_preferences .store_preferences
.set_object(&self.user_config.session_cache_key, session.clone()) .set_object(&self.user_config.session_cache_key, session.clone())
.map_err(internal_error)?; .map_err(internal_error)?;
Ok(())
}, },
} }
Ok(())
} }
pub(crate) async fn generate_sign_in_url_with_email( pub(crate) async fn generate_sign_in_url_with_email(
@ -740,10 +736,10 @@ impl UserManager {
save_user_workspaces(uid, self.db_pool(uid)?, response.user_workspaces())?; save_user_workspaces(uid, self.db_pool(uid)?, response.user_workspaces())?;
event!(tracing::Level::INFO, "Save new user profile to disk"); event!(tracing::Level::INFO, "Save new user profile to disk");
self.set_session(Some(session.clone()))?;
self self
.save_user(uid, (user_profile, authenticator.clone()).into()) .save_user(uid, (user_profile, authenticator.clone()).into())
.await?; .await?;
self.set_session(Some(session.clone()))?;
Ok(()) Ok(())
} }

View File

@ -27,11 +27,12 @@ pub(crate) fn send_notification(id: &str, ty: UserNotification) -> NotificationB
} }
#[tracing::instrument(level = "trace")] #[tracing::instrument(level = "trace")]
pub(crate) fn send_auth_state_notification(payload: AuthStateChangedPB) -> NotificationBuilder { pub(crate) fn send_auth_state_notification(payload: AuthStateChangedPB) {
NotificationBuilder::new( NotificationBuilder::new(
"auth_state_change_notification", "auth_state_change_notification",
UserNotification::UserAuthStateChanged, UserNotification::UserAuthStateChanged,
USER_OBSERVABLE_SOURCE, USER_OBSERVABLE_SOURCE,
) )
.payload(payload) .payload(payload)
.send()
} }

View File

@ -73,8 +73,7 @@ pub(crate) fn validate_encryption_sign(user_profile: &UserProfile, encryption_si
send_auth_state_notification(AuthStateChangedPB { send_auth_state_notification(AuthStateChangedPB {
state: AuthStatePB::InvalidAuth, state: AuthStatePB::InvalidAuth,
message: "Encryption configuration was changed".to_string(), message: "Encryption configuration was changed".to_string(),
}) });
.send();
} }
is_valid is_valid
} }