Merge pull request #7779 from AppFlowy-IO/server_type

refactor: server type name
This commit is contained in:
Nathan.fooo 2025-04-18 18:55:10 +08:00 committed by GitHub
commit d24383b6ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 208 additions and 291 deletions

View File

@ -1,4 +1,4 @@
use crate::server_layer::{Server, ServerProvider}; use crate::server_layer::ServerProvider;
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin}; use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use client_api::entity::ai_dto::RepeatedRelatedQuestion; use client_api::entity::ai_dto::RepeatedRelatedQuestion;
use client_api::entity::workspace_dto::PublishInfoView; use client_api::entity::workspace_dto::PublishInfoView;
@ -35,7 +35,7 @@ use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
use flowy_storage_pub::cloud::{ObjectIdentity, ObjectValue, StorageCloudService}; use flowy_storage_pub::cloud::{ObjectIdentity, ObjectValue, StorageCloudService};
use flowy_storage_pub::storage::{CompletedPartRequest, CreateUploadResponse, UploadPartResponse}; use flowy_storage_pub::storage::{CompletedPartRequest, CreateUploadResponse, UploadPartResponse};
use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider}; use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider};
use flowy_user_pub::entities::{Authenticator, UserTokenState}; use flowy_user_pub::entities::{AuthType, UserTokenState};
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
use serde_json::Value; use serde_json::Value;
use std::collections::HashMap; use std::collections::HashMap;
@ -186,18 +186,18 @@ impl UserCloudServiceProvider for ServerProvider {
} }
} }
/// 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 [AuthType] and save to disk for next use.
/// ///
/// Each [Authenticator] has a corresponding [Server]. The [Server] is used /// Each [AuthType] has a corresponding [AuthType]. The [AuthType] is used
/// to create a new [AppFlowyServer] if it doesn't exist. Once the [Server] is set, /// to create a new [AppFlowyServer] if it doesn't exist. Once the [AuthType] is set,
/// it will be used when user open the app again. /// it will be used when user open the app again.
/// ///
fn set_user_authenticator(&self, authenticator: &Authenticator) { fn set_server_auth_type(&self, auth_type: &AuthType) {
self.set_authenticator(authenticator.clone()); self.set_auth_type(*auth_type);
} }
fn get_user_authenticator(&self) -> Authenticator { fn get_server_auth_type(&self) -> AuthType {
self.get_authenticator() self.get_auth_type()
} }
fn set_network_reachable(&self, reachable: bool) { fn set_network_reachable(&self, reachable: bool) {
@ -211,7 +211,7 @@ impl UserCloudServiceProvider for ServerProvider {
self.encryption.set_secret(secret); self.encryption.set_secret(secret);
} }
/// Returns the [UserCloudService] base on the current [Server]. /// Returns the [UserCloudService] base on the current [AuthType].
/// Creates a new [AppFlowyServer] if it doesn't exist. /// Creates a new [AppFlowyServer] if it doesn't exist.
fn get_user_service(&self) -> Result<Arc<dyn UserCloudService>, FlowyError> { fn get_user_service(&self) -> Result<Arc<dyn UserCloudService>, FlowyError> {
let user_service = self.get_server()?.user_service(); let user_service = self.get_server()?.user_service();
@ -219,9 +219,9 @@ impl UserCloudServiceProvider for ServerProvider {
} }
fn service_url(&self) -> String { fn service_url(&self) -> String {
match self.get_server_type() { match self.get_auth_type() {
Server::Local => "".to_string(), AuthType::Local => "".to_string(),
Server::AppFlowyCloud => AFCloudConfiguration::from_env() AuthType::AppFlowyCloud => AFCloudConfiguration::from_env()
.map(|config| config.base_url) .map(|config| config.base_url)
.unwrap_or_default(), .unwrap_or_default(),
} }
@ -578,12 +578,15 @@ impl DocumentCloudService for ServerProvider {
impl CollabCloudPluginProvider for ServerProvider { impl CollabCloudPluginProvider for ServerProvider {
fn provider_type(&self) -> CollabPluginProviderType { fn provider_type(&self) -> CollabPluginProviderType {
self.get_server_type().into() match self.get_auth_type() {
AuthType::Local => CollabPluginProviderType::Local,
AuthType::AppFlowyCloud => CollabPluginProviderType::AppFlowyCloud,
}
} }
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
// If the user is local, we don't need to create a sync plugin. // If the user is local, we don't need to create a sync plugin.
if self.get_server_type().is_local() { if self.get_auth_type().is_local() {
debug!( debug!(
"User authenticator is local, skip create sync plugin for: {}", "User authenticator is local, skip create sync plugin for: {}",
context context

View File

@ -1,6 +1,6 @@
#![allow(unused_doc_comments)] #![allow(unused_doc_comments)]
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabPluginProviderType}; use collab_integrate::collab_builder::AppFlowyCollabBuilder;
use flowy_ai::ai_manager::AIManager; use flowy_ai::ai_manager::AIManager;
use flowy_database2::DatabaseManager; use flowy_database2::DatabaseManager;
use flowy_document::manager::DocumentManager; use flowy_document::manager::DocumentManager;
@ -34,7 +34,7 @@ use crate::config::AppFlowyCoreConfig;
use crate::deps_resolve::file_storage_deps::FileStorageResolver; use crate::deps_resolve::file_storage_deps::FileStorageResolver;
use crate::deps_resolve::*; use crate::deps_resolve::*;
use crate::log_filter::init_log; use crate::log_filter::init_log;
use crate::server_layer::{current_server_type, Server, ServerProvider}; use crate::server_layer::{current_server_type, ServerProvider};
use deps_resolve::reminder_deps::CollabInteractImpl; use deps_resolve::reminder_deps::CollabInteractImpl;
use flowy_sqlite::DBConnection; use flowy_sqlite::DBConnection;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
@ -131,12 +131,12 @@ impl AppFlowyCore {
store_preference.clone(), store_preference.clone(),
)); ));
let server_type = current_server_type(); let auth_type = current_server_type();
debug!("🔥runtime:{}, server:{}", runtime, server_type); debug!("🔥runtime:{}, server:{}", runtime, auth_type);
let server_provider = Arc::new(ServerProvider::new( let server_provider = Arc::new(ServerProvider::new(
config.clone(), config.clone(),
server_type, auth_type,
Arc::downgrade(&store_preference), Arc::downgrade(&store_preference),
ServerUserImpl(Arc::downgrade(&authenticate_user)), ServerUserImpl(Arc::downgrade(&authenticate_user)),
)); ));
@ -314,15 +314,6 @@ impl AppFlowyCore {
} }
} }
impl From<Server> for CollabPluginProviderType {
fn from(server_type: Server) -> Self {
match server_type {
Server::Local => CollabPluginProviderType::Local,
Server::AppFlowyCloud => CollabPluginProviderType::AppFlowyCloud,
}
}
}
struct ServerUserImpl(Weak<AuthenticateUser>); struct ServerUserImpl(Weak<AuthenticateUser>);
impl ServerUserImpl { impl ServerUserImpl {

View File

@ -1,179 +1,108 @@
use crate::AppFlowyCoreConfig; use crate::AppFlowyCoreConfig;
use af_plugin::manager::PluginManager; use af_plugin::manager::PluginManager;
use arc_swap::ArcSwapOption; use arc_swap::{ArcSwap, ArcSwapOption};
use dashmap::DashMap; use dashmap::DashMap;
use flowy_ai::local_ai::controller::LocalAIController; use flowy_ai::local_ai::controller::LocalAIController;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_server::af_cloud::define::{AIUserServiceImpl, LoginUserService}; use flowy_server::af_cloud::{
use flowy_server::af_cloud::AppFlowyCloudServer; define::{AIUserServiceImpl, LoginUserService},
AppFlowyCloudServer,
};
use flowy_server::local_server::LocalServer; use flowy_server::local_server::LocalServer;
use flowy_server::{AppFlowyEncryption, AppFlowyServer, EncryptionImpl}; use flowy_server::{AppFlowyEncryption, AppFlowyServer, EncryptionImpl};
use flowy_server_pub::AuthenticatorType; use flowy_server_pub::AuthenticatorType;
use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::kv::KVStorePreferences;
use flowy_user_pub::entities::*; use flowy_user_pub::entities::*;
use serde_repr::*; use std::sync::atomic::{AtomicBool, Ordering};
use std::fmt::{Display, Formatter};
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum Server {
/// Local server provider.
/// Offline mode, no user authentication and the data is stored locally.
Local = 0,
/// AppFlowy Cloud server provider.
/// See: https://github.com/AppFlowy-IO/AppFlowy-Cloud
AppFlowyCloud = 1,
}
impl Server {
pub fn is_local(&self) -> bool {
matches!(self, Server::Local)
}
}
impl Display for Server {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Server::Local => write!(f, "Local"),
Server::AppFlowyCloud => write!(f, "AppFlowyCloud"),
}
}
}
/// The [ServerProvider] provides list of [AppFlowyServer] base on the [Authenticator]. Using
/// the auth type, the [ServerProvider] will create a new [AppFlowyServer] if it doesn't
/// exist.
/// Each server implements the [AppFlowyServer] trait, which provides the [UserCloudService], etc.
pub struct ServerProvider { pub struct ServerProvider {
config: AppFlowyCoreConfig, config: AppFlowyCoreConfig,
providers: DashMap<Server, Arc<dyn AppFlowyServer>>, providers: DashMap<AuthType, Arc<dyn AppFlowyServer>>,
pub(crate) encryption: Arc<dyn AppFlowyEncryption>, auth_type: ArcSwap<AuthType>,
#[allow(dead_code)]
pub(crate) store_preferences: Weak<KVStorePreferences>,
pub(crate) user_enable_sync: AtomicBool,
/// The authenticator type of the user.
authenticator: AtomicU8,
user: Arc<dyn LoginUserService>, user: Arc<dyn LoginUserService>,
pub(crate) uid: Arc<ArcSwapOption<i64>>,
pub local_ai: Arc<LocalAIController>, pub local_ai: Arc<LocalAIController>,
pub uid: Arc<ArcSwapOption<i64>>,
pub user_enable_sync: Arc<AtomicBool>,
pub encryption: Arc<dyn AppFlowyEncryption>,
} }
impl ServerProvider { impl ServerProvider {
pub fn new( pub fn new(
config: AppFlowyCoreConfig, config: AppFlowyCoreConfig,
server: Server, initial_auth: AuthType,
store_preferences: Weak<KVStorePreferences>, store_preferences: Weak<KVStorePreferences>,
server_user: impl LoginUserService + 'static, user_service: impl LoginUserService + 'static,
) -> Self { ) -> Self {
let user = Arc::new(server_user); let user = Arc::new(user_service);
let encryption = EncryptionImpl::new(None); let auth_type = ArcSwap::from(Arc::new(initial_auth));
let user_service = Arc::new(AIUserServiceImpl(user.clone())); let encryption = Arc::new(EncryptionImpl::new(None)) as Arc<dyn AppFlowyEncryption>;
let plugin_manager = Arc::new(PluginManager::new()); let ai_user = Arc::new(AIUserServiceImpl(user.clone()));
let plugins = Arc::new(PluginManager::new());
let local_ai = Arc::new(LocalAIController::new( let local_ai = Arc::new(LocalAIController::new(
plugin_manager.clone(), plugins,
store_preferences.clone(), store_preferences,
user_service.clone(), ai_user.clone(),
)); ));
Self { ServerProvider {
config, config,
providers: DashMap::new(), providers: DashMap::new(),
user_enable_sync: AtomicBool::new(true), encryption,
authenticator: AtomicU8::new(Authenticator::from(server) as u8), user_enable_sync: Arc::new(AtomicBool::new(true)),
encryption: Arc::new(encryption), auth_type,
store_preferences,
uid: Default::default(),
user, user,
uid: Default::default(),
local_ai, local_ai,
} }
} }
pub fn get_server_type(&self) -> Server { pub fn set_auth_type(&self, new_auth_type: AuthType) {
match Authenticator::from(self.authenticator.load(Ordering::Acquire) as i32) { let old_type = self.get_auth_type();
Authenticator::Local => Server::Local, if old_type != new_auth_type {
Authenticator::AppFlowyCloud => Server::AppFlowyCloud, self.auth_type.store(Arc::new(new_auth_type));
self.providers.remove(&old_type);
} }
} }
pub fn set_authenticator(&self, authenticator: Authenticator) { pub fn get_auth_type(&self) -> AuthType {
let old_server_type = self.get_server_type(); *self.auth_type.load_full().as_ref()
self
.authenticator
.store(authenticator as u8, Ordering::Release);
let new_server_type = self.get_server_type();
if old_server_type != new_server_type {
self.providers.remove(&old_server_type);
}
} }
pub fn get_authenticator(&self) -> Authenticator { /// Lazily create or fetch an AppFlowyServer instance
Authenticator::from(self.authenticator.load(Ordering::Acquire) as i32)
}
/// Returns a [AppFlowyServer] trait implementation base on the provider_type.
pub fn get_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> { pub fn get_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
let server_type = self.get_server_type(); let auth_type = self.get_auth_type();
if let Some(entry) = self.providers.get(&auth_type) {
if let Some(provider) = self.providers.get(&server_type) { return Ok(entry.clone());
return Ok(provider.value().clone());
} }
let server = match server_type { let server: Arc<dyn AppFlowyServer> = match auth_type {
Server::Local => { AuthType::Local => Arc::new(LocalServer::new(self.user.clone(), self.local_ai.clone())),
let server = Arc::new(LocalServer::new(self.user.clone(), self.local_ai.clone())); AuthType::AppFlowyCloud => {
Ok::<Arc<dyn AppFlowyServer>, FlowyError>(server) let cfg = self
}, .config
Server::AppFlowyCloud => { .cloud_config
let config = self.config.cloud_config.clone().ok_or_else(|| { .clone()
FlowyError::internal().with_context("AppFlowyCloud configuration is missing") .ok_or_else(|| FlowyError::internal().with_context("Missing cloud config"))?;
})?; Arc::new(AppFlowyCloudServer::new(
let server = Arc::new(AppFlowyCloudServer::new( cfg,
config,
self.user_enable_sync.load(Ordering::Acquire), self.user_enable_sync.load(Ordering::Acquire),
self.config.device_id.clone(), self.config.device_id.clone(),
self.config.app_version.clone(), self.config.app_version.clone(),
self.user.clone(), self.user.clone(),
)); ))
Ok::<Arc<dyn AppFlowyServer>, FlowyError>(server)
}, },
}?; };
self.providers.insert(server_type.clone(), server.clone()); self.providers.insert(auth_type, server.clone());
Ok(server) Ok(server)
} }
} }
impl From<Authenticator> for Server { /// Determine current server type from ENV
fn from(auth_provider: Authenticator) -> Self { pub fn current_server_type() -> AuthType {
match auth_provider {
Authenticator::Local => Server::Local,
Authenticator::AppFlowyCloud => Server::AppFlowyCloud,
}
}
}
impl From<Server> for Authenticator {
fn from(ty: Server) -> Self {
match ty {
Server::Local => Authenticator::Local,
Server::AppFlowyCloud => Authenticator::AppFlowyCloud,
}
}
}
impl From<&Authenticator> for Server {
fn from(auth_provider: &Authenticator) -> Self {
Self::from(auth_provider.clone())
}
}
pub fn current_server_type() -> Server {
match AuthenticatorType::from_env() { match AuthenticatorType::from_env() {
AuthenticatorType::Local => Server::Local, AuthenticatorType::Local => AuthType::Local,
AuthenticatorType::AppFlowyCloud => Server::AppFlowyCloud, AuthenticatorType::AppFlowyCloud => AuthType::AppFlowyCloud,
} }
} }

View File

@ -14,11 +14,11 @@ use flowy_folder::manager::{FolderInitDataSource, FolderManager};
use flowy_storage::manager::StorageManager; use flowy_storage::manager::StorageManager;
use flowy_user::event_map::UserStatusCallback; use flowy_user::event_map::UserStatusCallback;
use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider}; use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider};
use flowy_user_pub::entities::{Authenticator, UserProfile, UserWorkspace}; use flowy_user_pub::entities::{AuthType, UserProfile, UserWorkspace};
use lib_dispatch::runtime::AFPluginRuntime; use lib_dispatch::runtime::AFPluginRuntime;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
use crate::server_layer::{Server, ServerProvider}; use crate::server_layer::ServerProvider;
pub(crate) struct UserStatusCallbackImpl { pub(crate) struct UserStatusCallbackImpl {
pub(crate) collab_builder: Arc<AppFlowyCollabBuilder>, pub(crate) collab_builder: Arc<AppFlowyCollabBuilder>,
@ -49,16 +49,14 @@ impl UserStatusCallback for UserStatusCallbackImpl {
async fn did_init( async fn did_init(
&self, &self,
user_id: i64, user_id: i64,
user_authenticator: &Authenticator, auth_type: &AuthType,
cloud_config: &Option<UserCloudConfig>, cloud_config: &Option<UserCloudConfig>,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,
authenticator: &Authenticator, authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
let workspace_id = user_workspace.workspace_id()?; let workspace_id = user_workspace.workspace_id()?;
self self.server_provider.set_auth_type(*auth_type);
.server_provider
.set_user_authenticator(user_authenticator);
if let Some(cloud_config) = cloud_config { if let Some(cloud_config) = cloud_config {
self self
@ -83,7 +81,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
.await?; .await?;
self self
.database_manager .database_manager
.initialize(user_id, authenticator == &Authenticator::Local) .initialize(user_id, authenticator == &AuthType::Local)
.await?; .await?;
self.document_manager.initialize(user_id).await?; self.document_manager.initialize(user_id).await?;
@ -97,7 +95,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
user_id: i64, user_id: i64,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
device_id: &str, device_id: &str,
authenticator: &Authenticator, authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
event!( event!(
tracing::Level::TRACE, tracing::Level::TRACE,
@ -127,12 +125,9 @@ impl UserStatusCallback for UserStatusCallbackImpl {
user_profile: &UserProfile, user_profile: &UserProfile,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
device_id: &str, device_id: &str,
authenticator: &Authenticator, auth_type: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
self self.server_provider.set_auth_type(*auth_type);
.server_provider
.set_user_authenticator(&user_profile.authenticator);
let server_type = self.server_provider.get_server_type();
event!( event!(
tracing::Level::TRACE, tracing::Level::TRACE,
@ -158,17 +153,17 @@ impl UserStatusCallback for UserStatusCallbackImpl {
) )
.await .await
{ {
Ok(doc_state) => match server_type { Ok(doc_state) => match auth_type {
Server::Local => FolderInitDataSource::LocalDisk { AuthType::Local => FolderInitDataSource::LocalDisk {
create_if_not_exist: true, create_if_not_exist: true,
}, },
Server::AppFlowyCloud => FolderInitDataSource::Cloud(doc_state), AuthType::AppFlowyCloud => FolderInitDataSource::Cloud(doc_state),
}, },
Err(err) => match server_type { Err(err) => match auth_type {
Server::Local => FolderInitDataSource::LocalDisk { AuthType::Local => FolderInitDataSource::LocalDisk {
create_if_not_exist: true, create_if_not_exist: true,
}, },
Server::AppFlowyCloud => { AuthType::AppFlowyCloud => {
return Err(err); return Err(err);
}, },
}, },
@ -188,7 +183,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
self self
.database_manager .database_manager
.initialize_with_new_user(user_profile.uid, authenticator.is_local()) .initialize_with_new_user(user_profile.uid, auth_type.is_local())
.await .await
.context("DatabaseManager error")?; .context("DatabaseManager error")?;
@ -212,7 +207,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
&self, &self,
user_id: i64, user_id: i64,
user_workspace: &UserWorkspace, user_workspace: &UserWorkspace,
authenticator: &Authenticator, authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
self self
.folder_manager .folder_manager

View File

@ -3,9 +3,8 @@ use client_api::entity::auth_dto::{UpdateUserParams, UserMetaData};
use client_api::entity::{AFRole, AFUserProfile, AFWorkspaceInvitationStatus, AFWorkspaceMember}; use client_api::entity::{AFRole, AFUserProfile, AFWorkspaceInvitationStatus, AFWorkspaceMember};
use flowy_user_pub::entities::{ use flowy_user_pub::entities::{
Authenticator, Role, UpdateUserProfileParams, UserProfile, WorkspaceInvitationStatus, AuthType, Role, UpdateUserProfileParams, UserProfile, WorkspaceInvitationStatus, WorkspaceMember,
WorkspaceMember, USER_METADATA_ICON_URL, USER_METADATA_OPEN_AI_KEY, USER_METADATA_ICON_URL, USER_METADATA_OPEN_AI_KEY, USER_METADATA_STABILITY_AI_KEY,
USER_METADATA_STABILITY_AI_KEY,
}; };
use crate::af_cloud::impls::user::util::encryption_type_from_profile; use crate::af_cloud::impls::user::util::encryption_type_from_profile;
@ -60,7 +59,7 @@ pub fn user_profile_from_af_profile(
icon_url: icon_url.unwrap_or_default(), icon_url: icon_url.unwrap_or_default(),
openai_key: openai_key.unwrap_or_default(), openai_key: openai_key.unwrap_or_default(),
stability_ai_key: stability_ai_key.unwrap_or_default(), stability_ai_key: stability_ai_key.unwrap_or_default(),
authenticator: Authenticator::AppFlowyCloud, authenticator: AuthType::AppFlowyCloud,
encryption_type, encryption_type,
uid: profile.uid, uid: profile.uid,
updated_at: profile.updated_at, updated_at: profile.updated_at,

View File

@ -20,7 +20,7 @@ use tokio_stream::wrappers::WatchStream;
use uuid::Uuid; use uuid::Uuid;
use crate::entities::{ use crate::entities::{
AuthResponse, Authenticator, Role, UpdateUserProfileParams, UserCredentials, UserProfile, AuthResponse, AuthType, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
UserTokenState, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember, UserTokenState, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
}; };
@ -84,13 +84,9 @@ pub trait UserCloudServiceProvider: Send + Sync {
/// * `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 authenticator when user sign in or sign up. fn set_server_auth_type(&self, auth_type: &AuthType);
///
/// # Arguments
/// * `authenticator`: An `Authenticator` object.
fn set_user_authenticator(&self, authenticator: &Authenticator);
fn get_user_authenticator(&self) -> Authenticator; fn get_server_auth_type(&self) -> AuthType;
/// Sets the network reachability /// Sets the network reachability
/// ///

View File

@ -1,3 +1,4 @@
use std::fmt::{Display, Formatter};
use std::str::FromStr; use std::str::FromStr;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
@ -32,7 +33,7 @@ pub struct SignInParams {
pub email: String, pub email: String,
pub password: String, pub password: String,
pub name: String, pub name: String,
pub auth_type: Authenticator, pub auth_type: AuthType,
} }
#[derive(Serialize, Deserialize, Default, Debug)] #[derive(Serialize, Deserialize, Default, Debug)]
@ -40,7 +41,7 @@ pub struct SignUpParams {
pub email: String, pub email: String,
pub name: String, pub name: String,
pub password: String, pub password: String,
pub auth_type: Authenticator, pub auth_type: AuthType,
pub device_id: String, pub device_id: String,
} }
@ -103,7 +104,7 @@ impl UserAuthResponse for AuthResponse {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct UserCredentials { pub struct UserCredentials {
/// Currently, the token is only used when the [Authenticator] is AppFlowyCloud /// Currently, the token is only used when the [AuthType] is AppFlowyCloud
pub token: Option<String>, pub token: Option<String>,
/// The user id /// The user id
@ -180,7 +181,7 @@ pub struct UserProfile {
pub icon_url: String, pub icon_url: String,
pub openai_key: String, pub openai_key: String,
pub stability_ai_key: String, pub stability_ai_key: String,
pub authenticator: Authenticator, pub authenticator: AuthType,
// If the encryption_sign is not empty, which means the user has enabled the encryption. // If the encryption_sign is not empty, which means the user has enabled the encryption.
pub encryption_type: EncryptionType, pub encryption_type: EncryptionType,
pub updated_at: i64, pub updated_at: i64,
@ -226,11 +227,11 @@ impl FromStr for EncryptionType {
} }
} }
impl<T> From<(&T, &Authenticator)> for UserProfile impl<T> From<(&T, &AuthType)> for UserProfile
where where
T: UserAuthResponse, T: UserAuthResponse,
{ {
fn from(params: (&T, &Authenticator)) -> Self { fn from(params: (&T, &AuthType)) -> Self {
let (value, auth_type) = params; let (value, auth_type) = params;
let (icon_url, openai_key, stability_ai_key) = { let (icon_url, openai_key, stability_ai_key) = {
value value
@ -258,7 +259,7 @@ where
token: value.user_token().unwrap_or_default(), token: value.user_token().unwrap_or_default(),
icon_url, icon_url,
openai_key, openai_key,
authenticator: auth_type.clone(), authenticator: *auth_type,
encryption_type: value.encryption_type(), encryption_type: value.encryption_type(),
stability_ai_key, stability_ai_key,
updated_at: value.updated_at(), updated_at: value.updated_at(),
@ -349,9 +350,9 @@ impl UpdateUserProfileParams {
} }
} }
#[derive(Debug, Clone, Hash, Serialize_repr, Deserialize_repr, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Hash, Serialize_repr, Deserialize_repr, Eq, PartialEq)]
#[repr(u8)] #[repr(u8)]
pub enum Authenticator { pub enum AuthType {
/// It's a local server, we do fake sign in default. /// It's a local server, we do fake sign in default.
Local = 0, Local = 0,
/// Currently not supported. It will be supported in the future when the /// Currently not supported. It will be supported in the future when the
@ -359,28 +360,37 @@ pub enum Authenticator {
AppFlowyCloud = 1, AppFlowyCloud = 1,
} }
impl Default for Authenticator { impl Display for AuthType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
AuthType::Local => write!(f, "Local"),
AuthType::AppFlowyCloud => write!(f, "AppFlowyCloud"),
}
}
}
impl Default for AuthType {
fn default() -> Self { fn default() -> Self {
Self::Local Self::Local
} }
} }
impl Authenticator { impl AuthType {
pub fn is_local(&self) -> bool { pub fn is_local(&self) -> bool {
matches!(self, Authenticator::Local) matches!(self, AuthType::Local)
} }
pub fn is_appflowy_cloud(&self) -> bool { pub fn is_appflowy_cloud(&self) -> bool {
matches!(self, Authenticator::AppFlowyCloud) matches!(self, AuthType::AppFlowyCloud)
} }
} }
impl From<i32> for Authenticator { impl From<i32> for AuthType {
fn from(value: i32) -> Self { fn from(value: i32) -> Self {
match value { match value {
0 => Authenticator::Local, 0 => AuthType::Local,
1 => Authenticator::AppFlowyCloud, 1 => AuthType::AppFlowyCloud,
_ => Authenticator::Local, _ => AuthType::Local,
} }
} }
} }

View File

@ -235,20 +235,20 @@ pub enum AuthenticatorPB {
AppFlowyCloud = 2, AppFlowyCloud = 2,
} }
impl From<Authenticator> for AuthenticatorPB { impl From<AuthType> for AuthenticatorPB {
fn from(auth_type: Authenticator) -> Self { fn from(auth_type: AuthType) -> Self {
match auth_type { match auth_type {
Authenticator::Local => AuthenticatorPB::Local, AuthType::Local => AuthenticatorPB::Local,
Authenticator::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud, AuthType::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud,
} }
} }
} }
impl From<AuthenticatorPB> for Authenticator { impl From<AuthenticatorPB> for AuthType {
fn from(pb: AuthenticatorPB) -> Self { fn from(pb: AuthenticatorPB) -> Self {
match pb { match pb {
AuthenticatorPB::Local => Authenticator::Local, AuthenticatorPB::Local => AuthType::Local,
AuthenticatorPB::AppFlowyCloud => Authenticator::AppFlowyCloud, AuthenticatorPB::AppFlowyCloud => AuthType::AppFlowyCloud,
} }
} }
} }

View File

@ -45,7 +45,7 @@ pub async fn sign_in_with_email_password_handler(
let manager = upgrade_manager(manager)?; let manager = upgrade_manager(manager)?;
let params: SignInParams = data.into_inner().try_into()?; let params: SignInParams = data.into_inner().try_into()?;
let old_authenticator = manager.cloud_services.get_user_authenticator(); let old_authenticator = manager.cloud_services.get_server_auth_type();
match manager match manager
.sign_in_with_password(&params.email, &params.password) .sign_in_with_password(&params.email, &params.password)
.await .await
@ -54,7 +54,7 @@ pub async fn sign_in_with_email_password_handler(
Err(err) => { Err(err) => {
manager manager
.cloud_services .cloud_services
.set_user_authenticator(&old_authenticator); .set_server_auth_type(&old_authenticator);
return Err(err); return Err(err);
}, },
} }
@ -76,15 +76,13 @@ pub async fn sign_up(
) -> DataResult<UserProfilePB, FlowyError> { ) -> DataResult<UserProfilePB, FlowyError> {
let manager = upgrade_manager(manager)?; let manager = upgrade_manager(manager)?;
let params: SignUpParams = data.into_inner().try_into()?; let params: SignUpParams = data.into_inner().try_into()?;
let authenticator = params.auth_type.clone(); let auth_type = params.auth_type;
let prev_authenticator = manager.cloud_services.get_user_authenticator(); let prev_auth_type = manager.cloud_services.get_server_auth_type();
match manager.sign_up(authenticator, BoxAny::new(params)).await { match manager.sign_up(auth_type, BoxAny::new(params)).await {
Ok(profile) => data_result_ok(UserProfilePB::from(profile)), Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
Err(err) => { Err(err) => {
manager manager.cloud_services.set_server_auth_type(&prev_auth_type);
.cloud_services
.set_user_authenticator(&prev_authenticator);
Err(err) Err(err)
}, },
} }
@ -119,7 +117,7 @@ pub async fn get_user_profile_handler(
// When the user is logged in with a local account, the email field is a placeholder and should // When the user is logged in with a local account, the email field is a placeholder and should
// not be exposed to the client. So we set the email field to an empty string. // not be exposed to the client. So we set the email field to an empty string.
if user_profile.authenticator == Authenticator::Local { if user_profile.authenticator == AuthType::Local {
user_profile.email = "".to_string(); user_profile.email = "".to_string();
} }
@ -341,7 +339,7 @@ pub async fn oauth_sign_in_handler(
) -> DataResult<UserProfilePB, FlowyError> { ) -> DataResult<UserProfilePB, FlowyError> {
let manager = upgrade_manager(manager)?; let manager = upgrade_manager(manager)?;
let params = data.into_inner(); let params = data.into_inner();
let authenticator: Authenticator = params.authenticator.into(); let authenticator: AuthType = params.authenticator.into();
let user_profile = manager let user_profile = manager
.sign_up(authenticator, BoxAny::new(params.map)) .sign_up(authenticator, BoxAny::new(params.map))
.await?; .await?;
@ -355,7 +353,7 @@ pub async fn gen_sign_in_url_handler(
) -> DataResult<SignInUrlPB, FlowyError> { ) -> DataResult<SignInUrlPB, FlowyError> {
let manager = upgrade_manager(manager)?; let manager = upgrade_manager(manager)?;
let params = data.into_inner(); let params = data.into_inner();
let authenticator: Authenticator = params.authenticator.into(); let authenticator: AuthType = params.authenticator.into();
let sign_in_url = manager let sign_in_url = manager
.generate_sign_in_url_with_email(&authenticator, &params.email) .generate_sign_in_url_with_email(&authenticator, &params.email)
.await?; .await?;

View File

@ -86,12 +86,12 @@ pub fn init(user_manager: Weak<UserManager>) -> AFPlugin {
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
#[event_err = "FlowyError"] #[event_err = "FlowyError"]
pub enum UserEvent { pub enum UserEvent {
/// Only use when the [Authenticator] is Local or SelfHosted /// Only use when the [AuthType] is Local or SelfHosted
/// Logging into an account using a register email and password /// Logging into an account using a register email and password
#[event(input = "SignInPayloadPB", output = "GotrueTokenResponsePB")] #[event(input = "SignInPayloadPB", output = "GotrueTokenResponsePB")]
SignInWithEmailPassword = 0, SignInWithEmailPassword = 0,
/// Only use when the [Authenticator] is Local or SelfHosted /// Only use when the [AuthType] is Local or SelfHosted
/// Creating a new account /// Creating a new account
#[event(input = "SignUpPayloadPB", output = "UserProfilePB")] #[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
SignUp = 1, SignUp = 1,
@ -129,7 +129,7 @@ pub enum UserEvent {
OauthSignIn = 10, OauthSignIn = 10,
/// Get the OAuth callback url /// Get the OAuth callback url
/// Only use when the [Authenticator] is AFCloud /// Only use when the [AuthType] is AFCloud
#[event(input = "SignInUrlPayloadPB", output = "SignInUrlPB")] #[event(input = "SignInUrlPayloadPB", output = "SignInUrlPB")]
GenerateSignInURL = 11, GenerateSignInURL = 11,
@ -165,7 +165,7 @@ pub enum UserEvent {
OpenAnonUser = 26, OpenAnonUser = 26,
/// Push a realtime event to the user. Currently, the realtime event /// Push a realtime event to the user. Currently, the realtime event
/// is only used when the auth type is: [Authenticator::Supabase]. /// is only used when the auth type is: [AuthType::Supabase].
/// ///
#[event(input = "RealtimePayloadPB")] #[event(input = "RealtimePayloadPB")]
PushRealtimeEvent = 27, PushRealtimeEvent = 27,
@ -281,19 +281,19 @@ pub enum UserEvent {
#[async_trait] #[async_trait]
pub trait UserStatusCallback: Send + Sync + 'static { pub trait UserStatusCallback: Send + Sync + 'static {
/// When the [Authenticator] changed, this method will be called. Currently, the auth type /// When the [AuthType] changed, this method will be called. Currently, the auth type
/// will be changed when the user sign in or sign up. /// will be changed when the user sign in or sign up.
fn authenticator_did_changed(&self, _authenticator: Authenticator) {} fn authenticator_did_changed(&self, _authenticator: AuthType) {}
/// This will be called after the application launches if the user is already signed in. /// This will be called after the application launches if the user is already signed in.
/// If the user is not signed in, this method will not be called /// If the user is not signed in, this method will not be called
async fn did_init( async fn did_init(
&self, &self,
_user_id: i64, _user_id: i64,
_user_authenticator: &Authenticator, _user_authenticator: &AuthType,
_cloud_config: &Option<UserCloudConfig>, _cloud_config: &Option<UserCloudConfig>,
_user_workspace: &UserWorkspace, _user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
Ok(()) Ok(())
} }
@ -303,7 +303,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
_user_id: i64, _user_id: i64,
_user_workspace: &UserWorkspace, _user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
Ok(()) Ok(())
} }
@ -314,7 +314,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
_user_profile: &UserProfile, _user_profile: &UserProfile,
_user_workspace: &UserWorkspace, _user_workspace: &UserWorkspace,
_device_id: &str, _device_id: &str,
_authenticator: &Authenticator, _auth_type: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
Ok(()) Ok(())
} }
@ -326,7 +326,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
&self, &self,
_user_id: i64, _user_id: i64,
_user_workspace: &UserWorkspace, _user_workspace: &UserWorkspace,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
Ok(()) Ok(())
} }

View File

@ -7,7 +7,7 @@ use tracing::{instrument, trace};
use collab_integrate::CollabKVDB; use collab_integrate::CollabKVDB;
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use crate::migrations::migration::UserDataMigration; use crate::migrations::migration::UserDataMigration;
use flowy_user_pub::session::Session; use flowy_user_pub::session::Session;
@ -39,7 +39,7 @@ impl UserDataMigration for CollabDocKeyWithWorkspaceIdMigration {
&self, &self,
session: &Session, session: &Session,
collab_db: &Arc<CollabKVDB>, collab_db: &Arc<CollabKVDB>,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
trace!( trace!(
"migrate key with workspace id:{}", "migrate key with workspace id:{}",

View File

@ -11,7 +11,7 @@ use tracing::{event, instrument};
use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError}; use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError};
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use crate::migrations::migration::UserDataMigration; use crate::migrations::migration::UserDataMigration;
use crate::migrations::util::load_collab; use crate::migrations::util::load_collab;
@ -41,12 +41,12 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration {
&self, &self,
session: &Session, session: &Session,
collab_db: &Arc<CollabKVDB>, collab_db: &Arc<CollabKVDB>,
authenticator: &Authenticator, authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
// - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version. // - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version.
// - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct. // - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct.
// - This migration step is only necessary for users who are transitioning from a local version of AppFlowy to the cloud version. // - This migration step is only necessary for users who are transitioning from a local version of AppFlowy to the cloud version.
if !matches!(authenticator, Authenticator::Local) { if !matches!(authenticator, AuthType::Local) {
return Ok(()); return Ok(());
} }
collab_db.with_write_txn(|write_txn| { collab_db.with_write_txn(|write_txn| {

View File

@ -7,7 +7,7 @@ use flowy_error::FlowyResult;
use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::kv::KVStorePreferences;
use flowy_sqlite::schema::user_data_migration_records; use flowy_sqlite::schema::user_data_migration_records;
use flowy_sqlite::ConnectionPool; use flowy_sqlite::ConnectionPool;
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use flowy_user_pub::session::Session; use flowy_user_pub::session::Session;
use semver::Version; use semver::Version;
use tracing::info; use tracing::info;
@ -54,7 +54,7 @@ impl UserLocalDataMigration {
pub fn run( pub fn run(
self, self,
migrations: Vec<Box<dyn UserDataMigration>>, migrations: Vec<Box<dyn UserDataMigration>>,
authenticator: &Authenticator, authenticator: &AuthType,
app_version: &Version, app_version: &Version,
) -> FlowyResult<Vec<String>> { ) -> FlowyResult<Vec<String>> {
let mut applied_migrations = vec![]; let mut applied_migrations = vec![];
@ -98,7 +98,7 @@ pub trait UserDataMigration {
&self, &self,
user: &Session, user: &Session,
collab_db: &Arc<CollabKVDB>, collab_db: &Arc<CollabKVDB>,
authenticator: &Authenticator, authenticator: &AuthType,
) -> FlowyResult<()>; ) -> FlowyResult<()>;
} }

View File

@ -7,7 +7,7 @@ use tracing::instrument;
use collab_integrate::{CollabKVAction, CollabKVDB}; use collab_integrate::{CollabKVAction, CollabKVDB};
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use crate::migrations::migration::UserDataMigration; use crate::migrations::migration::UserDataMigration;
use crate::migrations::util::load_collab; use crate::migrations::util::load_collab;
@ -39,7 +39,7 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
&self, &self,
session: &Session, session: &Session,
collab_db: &Arc<CollabKVDB>, collab_db: &Arc<CollabKVDB>,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
collab_db.with_write_txn(|write_txn| { collab_db.with_write_txn(|write_txn| {
if let Ok(collab) = load_collab( if let Ok(collab) = load_collab(

View File

@ -7,7 +7,7 @@ use tracing::instrument;
use collab_integrate::{CollabKVAction, CollabKVDB}; use collab_integrate::{CollabKVAction, CollabKVDB};
use flowy_error::FlowyResult; use flowy_error::FlowyResult;
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use crate::migrations::migration::UserDataMigration; use crate::migrations::migration::UserDataMigration;
use crate::migrations::util::load_collab; use crate::migrations::util::load_collab;
@ -37,7 +37,7 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
&self, &self,
session: &Session, session: &Session,
collab_db: &Arc<CollabKVDB>, collab_db: &Arc<CollabKVDB>,
_authenticator: &Authenticator, _authenticator: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
collab_db.with_write_txn(|write_txn| { collab_db.with_write_txn(|write_txn| {
if let Ok(collab) = load_collab( if let Ok(collab) = load_collab(

View File

@ -30,7 +30,7 @@ use flowy_folder_pub::entities::{
}; };
use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::kv::KVStorePreferences;
use flowy_user_pub::cloud::{UserCloudService, UserCollabParams}; use flowy_user_pub::cloud::{UserCloudService, UserCollabParams};
use flowy_user_pub::entities::{user_awareness_object_id, Authenticator}; use flowy_user_pub::entities::{user_awareness_object_id, AuthType};
use flowy_user_pub::session::Session; use flowy_user_pub::session::Session;
use rayon::prelude::*; use rayon::prelude::*;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -1175,7 +1175,7 @@ pub async fn upload_collab_objects_data(
uid: i64, uid: i64,
user_collab_db: Weak<CollabKVDB>, user_collab_db: Weak<CollabKVDB>,
workspace_id: &Uuid, workspace_id: &Uuid,
user_authenticator: &Authenticator, user_authenticator: &AuthType,
collab_data: ImportedCollabData, collab_data: ImportedCollabData,
user_cloud_service: Arc<dyn UserCloudService>, user_cloud_service: Arc<dyn UserCloudService>,
) -> Result<(), FlowyError> { ) -> Result<(), FlowyError> {

View File

@ -31,8 +31,8 @@ pub struct UserTable {
} }
#[allow(deprecated)] #[allow(deprecated)]
impl From<(UserProfile, Authenticator)> for UserTable { impl From<(UserProfile, AuthType)> for UserTable {
fn from(value: (UserProfile, Authenticator)) -> Self { fn from(value: (UserProfile, AuthType)) -> Self {
let (user_profile, auth_type) = value; let (user_profile, auth_type) = value;
let encryption_type = serde_json::to_string(&user_profile.encryption_type).unwrap_or_default(); let encryption_type = serde_json::to_string(&user_profile.encryption_type).unwrap_or_default();
UserTable { UserTable {
@ -62,7 +62,7 @@ impl From<UserTable> for UserProfile {
token: table.token, token: table.token,
icon_url: table.icon_url, icon_url: table.icon_url,
openai_key: table.openai_key, openai_key: table.openai_key,
authenticator: Authenticator::from(table.auth_type), authenticator: AuthType::from(table.auth_type),
encryption_type: EncryptionType::from_str(&table.encryption_type).unwrap_or_default(), encryption_type: EncryptionType::from_str(&table.encryption_type).unwrap_or_default(),
stability_ai_key: table.stability_ai_key, stability_ai_key: table.stability_ai_key,
updated_at: table.updated_at, updated_at: table.updated_at,

View File

@ -141,7 +141,7 @@ impl UserManager {
// If the current authenticator is different from the authenticator in the session and it's // If the current authenticator is different from the authenticator in the session and it's
// not a local authenticator, we need to sign out the user. // not a local authenticator, we need to sign out the user.
if user.authenticator != Authenticator::Local && user.authenticator != current_authenticator { if user.authenticator != AuthType::Local && user.authenticator != current_authenticator {
event!( event!(
tracing::Level::INFO, tracing::Level::INFO,
"Authenticator changed from {:?} to {:?}", "Authenticator changed from {:?} to {:?}",
@ -349,9 +349,9 @@ impl UserManager {
pub async fn sign_in( pub async fn sign_in(
&self, &self,
params: SignInParams, params: SignInParams,
authenticator: Authenticator, authenticator: AuthType,
) -> Result<UserProfile, FlowyError> { ) -> Result<UserProfile, FlowyError> {
self.cloud_services.set_user_authenticator(&authenticator); self.cloud_services.set_server_auth_type(&authenticator);
let response: AuthResponse = self let response: AuthResponse = self
.cloud_services .cloud_services
@ -398,25 +398,25 @@ impl UserManager {
#[tracing::instrument(level = "info", skip(self, params))] #[tracing::instrument(level = "info", skip(self, params))]
pub async fn sign_up( pub async fn sign_up(
&self, &self,
authenticator: Authenticator, auth_type: AuthType,
params: BoxAny, params: BoxAny,
) -> Result<UserProfile, FlowyError> { ) -> Result<UserProfile, FlowyError> {
// sign out the current user if there is one // sign out the current user if there is one
let migration_user = self.get_migration_user(&authenticator).await; let migration_user = self.get_migration_user(&auth_type).await;
self.cloud_services.set_user_authenticator(&authenticator); self.cloud_services.set_server_auth_type(&auth_type);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
let response: AuthResponse = auth_service.sign_up(params).await?; let response: AuthResponse = auth_service.sign_up(params).await?;
let new_user_profile = UserProfile::from((&response, &authenticator)); let new_user_profile = UserProfile::from((&response, &auth_type));
if new_user_profile.encryption_type.require_encrypt_secret() { if new_user_profile.encryption_type.require_encrypt_secret() {
self.auth_process.lock().await.replace(UserAuthProcess { self.auth_process.lock().await.replace(UserAuthProcess {
user_profile: new_user_profile.clone(), user_profile: new_user_profile.clone(),
migration_user, migration_user,
response, response,
authenticator, authenticator: auth_type,
}); });
} else { } else {
self self
.continue_sign_up(&new_user_profile, migration_user, response, &authenticator) .continue_sign_up(&new_user_profile, migration_user, response, &auth_type)
.await?; .await?;
} }
Ok(new_user_profile) Ok(new_user_profile)
@ -450,12 +450,12 @@ impl UserManager {
new_user_profile: &UserProfile, new_user_profile: &UserProfile,
migration_user: Option<AnonUser>, migration_user: Option<AnonUser>,
response: AuthResponse, response: AuthResponse,
authenticator: &Authenticator, auth_type: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
let new_session = Session::from(&response); let new_session = Session::from(&response);
self.prepare_user(&new_session).await; self.prepare_user(&new_session).await;
self self
.save_auth_data(&response, authenticator, &new_session) .save_auth_data(&response, auth_type, &new_session)
.await?; .await?;
let _ = self let _ = self
.initial_user_awareness(&new_session, &new_user_profile.authenticator) .initial_user_awareness(&new_session, &new_user_profile.authenticator)
@ -469,7 +469,7 @@ impl UserManager {
new_user_profile, new_user_profile,
&new_session.user_workspace, &new_session.user_workspace,
&self.authenticate_user.user_config.device_id, &self.authenticate_user.user_config.device_id,
authenticator, auth_type,
) )
.await?; .await?;
@ -493,7 +493,7 @@ impl UserManager {
new_user_profile.uid new_user_profile.uid
); );
self self
.migrate_anon_user_data_to_cloud(&old_user, &new_session, authenticator) .migrate_anon_user_data_to_cloud(&old_user, &new_session, auth_type)
.await?; .await?;
self.remove_anon_user(); self.remove_anon_user();
let _ = self let _ = self
@ -709,10 +709,10 @@ impl UserManager {
pub(crate) async fn generate_sign_in_url_with_email( pub(crate) async fn generate_sign_in_url_with_email(
&self, &self,
authenticator: &Authenticator, authenticator: &AuthType,
email: &str, email: &str,
) -> Result<String, FlowyError> { ) -> Result<String, FlowyError> {
self.cloud_services.set_user_authenticator(authenticator); self.cloud_services.set_server_auth_type(authenticator);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
let url = auth_service.generate_sign_in_url_with_email(email).await?; let url = auth_service.generate_sign_in_url_with_email(email).await?;
@ -726,7 +726,7 @@ impl UserManager {
) -> Result<GotrueTokenResponse, FlowyError> { ) -> Result<GotrueTokenResponse, FlowyError> {
self self
.cloud_services .cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud); .set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
let response = auth_service.sign_in_with_password(email, password).await?; let response = auth_service.sign_in_with_password(email, password).await?;
Ok(response) Ok(response)
@ -739,7 +739,7 @@ impl UserManager {
) -> Result<(), FlowyError> { ) -> Result<(), FlowyError> {
self self
.cloud_services .cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud); .set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
auth_service auth_service
.sign_in_with_magic_link(email, redirect_to) .sign_in_with_magic_link(email, redirect_to)
@ -754,7 +754,7 @@ impl UserManager {
) -> Result<GotrueTokenResponse, FlowyError> { ) -> Result<GotrueTokenResponse, FlowyError> {
self self
.cloud_services .cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud); .set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
let response = auth_service.sign_in_with_passcode(email, passcode).await?; let response = auth_service.sign_in_with_passcode(email, passcode).await?;
Ok(response) Ok(response)
@ -766,7 +766,7 @@ impl UserManager {
) -> Result<String, FlowyError> { ) -> Result<String, FlowyError> {
self self
.cloud_services .cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud); .set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?; let auth_service = self.cloud_services.get_user_service()?;
let url = auth_service let url = auth_service
.generate_oauth_url_with_provider(oauth_provider) .generate_oauth_url_with_provider(oauth_provider)
@ -778,7 +778,7 @@ impl UserManager {
async fn save_auth_data( async fn save_auth_data(
&self, &self,
response: &impl UserAuthResponse, response: &impl UserAuthResponse,
authenticator: &Authenticator, authenticator: &AuthType,
session: &Session, session: &Session,
) -> Result<(), FlowyError> { ) -> Result<(), FlowyError> {
let user_profile = UserProfile::from((response, authenticator)); let user_profile = UserProfile::from((response, authenticator));
@ -798,7 +798,7 @@ impl UserManager {
.authenticate_user .authenticate_user
.set_session(Some(session.clone().into()))?; .set_session(Some(session.clone().into()))?;
self self
.save_user(uid, (user_profile, authenticator.clone()).into()) .save_user(uid, (user_profile, *authenticator).into())
.await?; .await?;
Ok(()) Ok(())
} }
@ -827,14 +827,14 @@ impl UserManager {
&self, &self,
old_user: &AnonUser, old_user: &AnonUser,
_new_user_session: &Session, _new_user_session: &Session,
authenticator: &Authenticator, authenticator: &AuthType,
) -> Result<(), FlowyError> { ) -> Result<(), FlowyError> {
let old_collab_db = self let old_collab_db = self
.authenticate_user .authenticate_user
.database .database
.get_collab_db(old_user.session.user_id)?; .get_collab_db(old_user.session.user_id)?;
if authenticator == &Authenticator::AppFlowyCloud { if authenticator == &AuthType::AppFlowyCloud {
self self
.migration_anon_user_on_appflowy_cloud_sign_up(old_user, &old_collab_db) .migration_anon_user_on_appflowy_cloud_sign_up(old_user, &old_collab_db)
.await?; .await?;
@ -853,10 +853,10 @@ impl UserManager {
} }
} }
fn current_authenticator() -> Authenticator { fn current_authenticator() -> AuthType {
match AuthenticatorType::from_env() { match AuthenticatorType::from_env() {
AuthenticatorType::Local => Authenticator::Local, AuthenticatorType::Local => AuthType::Local,
AuthenticatorType::AppFlowyCloud => Authenticator::AppFlowyCloud, AuthenticatorType::AppFlowyCloud => AuthType::AppFlowyCloud,
} }
} }

View File

@ -4,7 +4,7 @@ use tracing::instrument;
use crate::entities::UserProfilePB; use crate::entities::UserProfilePB;
use crate::user_manager::UserManager; use crate::user_manager::UserManager;
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_user_pub::entities::Authenticator; use flowy_user_pub::entities::AuthType;
use crate::migrations::AnonUser; use crate::migrations::AnonUser;
use flowy_user_pub::session::Session; use flowy_user_pub::session::Session;
@ -12,10 +12,7 @@ use flowy_user_pub::session::Session;
pub const ANON_USER: &str = "anon_user"; pub const ANON_USER: &str = "anon_user";
impl UserManager { impl UserManager {
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn get_migration_user( pub async fn get_migration_user(&self, current_authenticator: &AuthType) -> Option<AnonUser> {
&self,
current_authenticator: &Authenticator,
) -> Option<AnonUser> {
// No need to migrate if the user is already local // No need to migrate if the user is already local
if current_authenticator.is_local() { if current_authenticator.is_local() {
return None; return None;

View File

@ -12,7 +12,7 @@ use collab_integrate::CollabKVDB;
use collab_user::core::{UserAwareness, UserAwarenessNotifier}; use collab_user::core::{UserAwareness, UserAwarenessNotifier};
use dashmap::try_result::TryResult; use dashmap::try_result::TryResult;
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_user_pub::entities::{user_awareness_object_id, Authenticator}; use flowy_user_pub::entities::{user_awareness_object_id, AuthType};
use tracing::{error, info, instrument, trace}; use tracing::{error, info, instrument, trace};
use uuid::Uuid; use uuid::Uuid;
@ -119,9 +119,8 @@ impl UserManager {
pub(crate) async fn initial_user_awareness( pub(crate) async fn initial_user_awareness(
&self, &self,
session: &Session, session: &Session,
authenticator: &Authenticator, auth_type: &AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
let authenticator = authenticator.clone();
let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id); let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id);
// Try to acquire mutable access to `is_loading_awareness`. // Try to acquire mutable access to `is_loading_awareness`.
@ -156,11 +155,11 @@ impl UserManager {
let is_exist_on_disk = self let is_exist_on_disk = self
.authenticate_user .authenticate_user
.is_collab_on_disk(session.user_id, &object_id.to_string())?; .is_collab_on_disk(session.user_id, &object_id.to_string())?;
if authenticator.is_local() || is_exist_on_disk { if auth_type.is_local() || is_exist_on_disk {
trace!( trace!(
"Initializing new user awareness from disk:{}, {:?}", "Initializing new user awareness from disk:{}, {:?}",
object_id, object_id,
authenticator auth_type
); );
let collab_db = self.get_collab_db(session.user_id)?; let collab_db = self.get_collab_db(session.user_id)?;
let workspace_id = session.user_workspace.workspace_id()?; let workspace_id = session.user_workspace.workspace_id()?;
@ -185,9 +184,9 @@ impl UserManager {
} else { } else {
info!( info!(
"Initializing new user awareness from server:{}, {:?}", "Initializing new user awareness from server:{}, {:?}",
object_id, authenticator object_id, auth_type
); );
self.load_awareness_from_server(session, object_id, authenticator.clone())?; self.load_awareness_from_server(session, object_id, *auth_type)?;
} }
} else { } else {
return Err(FlowyError::new( return Err(FlowyError::new(
@ -209,7 +208,7 @@ impl UserManager {
&self, &self,
session: &Session, session: &Session,
object_id: Uuid, object_id: Uuid,
authenticator: Authenticator, authenticator: AuthType,
) -> FlowyResult<()> { ) -> FlowyResult<()> {
// Clone necessary data // Clone necessary data
let session = session.clone(); let session = session.clone();

View File

@ -1,11 +1,11 @@
use crate::migrations::AnonUser; use crate::migrations::AnonUser;
use flowy_user_pub::entities::{AuthResponse, Authenticator, UserProfile}; use flowy_user_pub::entities::{AuthResponse, AuthType, UserProfile};
/// recording the intermediate state of the sign-in/sign-up process /// recording the intermediate state of the sign-in/sign-up process
#[derive(Clone)] #[derive(Clone)]
pub struct UserAuthProcess { pub struct UserAuthProcess {
pub user_profile: UserProfile, pub user_profile: UserProfile,
pub response: AuthResponse, pub response: AuthResponse,
pub authenticator: Authenticator, pub authenticator: AuthType,
pub migration_user: Option<AnonUser>, pub migration_user: Option<AnonUser>,
} }