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::entity::ai_dto::RepeatedRelatedQuestion;
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::storage::{CompletedPartRequest, CreateUploadResponse, UploadPartResponse};
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 serde_json::Value;
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
/// to create a new [AppFlowyServer] if it doesn't exist. Once the [Server] is set,
/// Each [AuthType] has a corresponding [AuthType]. The [AuthType] is used
/// 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.
///
fn set_user_authenticator(&self, authenticator: &Authenticator) {
self.set_authenticator(authenticator.clone());
fn set_server_auth_type(&self, auth_type: &AuthType) {
self.set_auth_type(*auth_type);
}
fn get_user_authenticator(&self) -> Authenticator {
self.get_authenticator()
fn get_server_auth_type(&self) -> AuthType {
self.get_auth_type()
}
fn set_network_reachable(&self, reachable: bool) {
@ -211,7 +211,7 @@ impl UserCloudServiceProvider for ServerProvider {
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.
fn get_user_service(&self) -> Result<Arc<dyn UserCloudService>, FlowyError> {
let user_service = self.get_server()?.user_service();
@ -219,9 +219,9 @@ impl UserCloudServiceProvider for ServerProvider {
}
fn service_url(&self) -> String {
match self.get_server_type() {
Server::Local => "".to_string(),
Server::AppFlowyCloud => AFCloudConfiguration::from_env()
match self.get_auth_type() {
AuthType::Local => "".to_string(),
AuthType::AppFlowyCloud => AFCloudConfiguration::from_env()
.map(|config| config.base_url)
.unwrap_or_default(),
}
@ -578,12 +578,15 @@ impl DocumentCloudService for ServerProvider {
impl CollabCloudPluginProvider for ServerProvider {
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>> {
// 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!(
"User authenticator is local, skip create sync plugin for: {}",
context

View File

@ -1,6 +1,6 @@
#![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_database2::DatabaseManager;
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::*;
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 flowy_sqlite::DBConnection;
use lib_infra::async_trait::async_trait;
@ -131,12 +131,12 @@ impl AppFlowyCore {
store_preference.clone(),
));
let server_type = current_server_type();
debug!("🔥runtime:{}, server:{}", runtime, server_type);
let auth_type = current_server_type();
debug!("🔥runtime:{}, server:{}", runtime, auth_type);
let server_provider = Arc::new(ServerProvider::new(
config.clone(),
server_type,
auth_type,
Arc::downgrade(&store_preference),
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>);
impl ServerUserImpl {

View File

@ -1,179 +1,108 @@
use crate::AppFlowyCoreConfig;
use af_plugin::manager::PluginManager;
use arc_swap::ArcSwapOption;
use arc_swap::{ArcSwap, ArcSwapOption};
use dashmap::DashMap;
use flowy_ai::local_ai::controller::LocalAIController;
use flowy_error::{FlowyError, FlowyResult};
use flowy_server::af_cloud::define::{AIUserServiceImpl, LoginUserService};
use flowy_server::af_cloud::AppFlowyCloudServer;
use flowy_server::af_cloud::{
define::{AIUserServiceImpl, LoginUserService},
AppFlowyCloudServer,
};
use flowy_server::local_server::LocalServer;
use flowy_server::{AppFlowyEncryption, AppFlowyServer, EncryptionImpl};
use flowy_server_pub::AuthenticatorType;
use flowy_sqlite::kv::KVStorePreferences;
use flowy_user_pub::entities::*;
use serde_repr::*;
use std::fmt::{Display, Formatter};
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::atomic::{AtomicBool, Ordering};
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 {
config: AppFlowyCoreConfig,
providers: DashMap<Server, Arc<dyn AppFlowyServer>>,
pub(crate) encryption: Arc<dyn AppFlowyEncryption>,
#[allow(dead_code)]
pub(crate) store_preferences: Weak<KVStorePreferences>,
pub(crate) user_enable_sync: AtomicBool,
/// The authenticator type of the user.
authenticator: AtomicU8,
providers: DashMap<AuthType, Arc<dyn AppFlowyServer>>,
auth_type: ArcSwap<AuthType>,
user: Arc<dyn LoginUserService>,
pub(crate) uid: Arc<ArcSwapOption<i64>>,
pub local_ai: Arc<LocalAIController>,
pub uid: Arc<ArcSwapOption<i64>>,
pub user_enable_sync: Arc<AtomicBool>,
pub encryption: Arc<dyn AppFlowyEncryption>,
}
impl ServerProvider {
pub fn new(
config: AppFlowyCoreConfig,
server: Server,
initial_auth: AuthType,
store_preferences: Weak<KVStorePreferences>,
server_user: impl LoginUserService + 'static,
user_service: impl LoginUserService + 'static,
) -> Self {
let user = Arc::new(server_user);
let encryption = EncryptionImpl::new(None);
let user_service = Arc::new(AIUserServiceImpl(user.clone()));
let plugin_manager = Arc::new(PluginManager::new());
let user = Arc::new(user_service);
let auth_type = ArcSwap::from(Arc::new(initial_auth));
let encryption = Arc::new(EncryptionImpl::new(None)) as Arc<dyn AppFlowyEncryption>;
let ai_user = Arc::new(AIUserServiceImpl(user.clone()));
let plugins = Arc::new(PluginManager::new());
let local_ai = Arc::new(LocalAIController::new(
plugin_manager.clone(),
store_preferences.clone(),
user_service.clone(),
plugins,
store_preferences,
ai_user.clone(),
));
Self {
ServerProvider {
config,
providers: DashMap::new(),
user_enable_sync: AtomicBool::new(true),
authenticator: AtomicU8::new(Authenticator::from(server) as u8),
encryption: Arc::new(encryption),
store_preferences,
uid: Default::default(),
encryption,
user_enable_sync: Arc::new(AtomicBool::new(true)),
auth_type,
user,
uid: Default::default(),
local_ai,
}
}
pub fn get_server_type(&self) -> Server {
match Authenticator::from(self.authenticator.load(Ordering::Acquire) as i32) {
Authenticator::Local => Server::Local,
Authenticator::AppFlowyCloud => Server::AppFlowyCloud,
pub fn set_auth_type(&self, new_auth_type: AuthType) {
let old_type = self.get_auth_type();
if old_type != new_auth_type {
self.auth_type.store(Arc::new(new_auth_type));
self.providers.remove(&old_type);
}
}
pub fn set_authenticator(&self, authenticator: Authenticator) {
let old_server_type = self.get_server_type();
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_auth_type(&self) -> AuthType {
*self.auth_type.load_full().as_ref()
}
pub fn get_authenticator(&self) -> Authenticator {
Authenticator::from(self.authenticator.load(Ordering::Acquire) as i32)
}
/// Returns a [AppFlowyServer] trait implementation base on the provider_type.
/// Lazily create or fetch an AppFlowyServer instance
pub fn get_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
let server_type = self.get_server_type();
if let Some(provider) = self.providers.get(&server_type) {
return Ok(provider.value().clone());
let auth_type = self.get_auth_type();
if let Some(entry) = self.providers.get(&auth_type) {
return Ok(entry.clone());
}
let server = match server_type {
Server::Local => {
let server = Arc::new(LocalServer::new(self.user.clone(), self.local_ai.clone()));
Ok::<Arc<dyn AppFlowyServer>, FlowyError>(server)
},
Server::AppFlowyCloud => {
let config = self.config.cloud_config.clone().ok_or_else(|| {
FlowyError::internal().with_context("AppFlowyCloud configuration is missing")
})?;
let server = Arc::new(AppFlowyCloudServer::new(
config,
let server: Arc<dyn AppFlowyServer> = match auth_type {
AuthType::Local => Arc::new(LocalServer::new(self.user.clone(), self.local_ai.clone())),
AuthType::AppFlowyCloud => {
let cfg = self
.config
.cloud_config
.clone()
.ok_or_else(|| FlowyError::internal().with_context("Missing cloud config"))?;
Arc::new(AppFlowyCloudServer::new(
cfg,
self.user_enable_sync.load(Ordering::Acquire),
self.config.device_id.clone(),
self.config.app_version.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)
}
}
impl From<Authenticator> for Server {
fn from(auth_provider: Authenticator) -> Self {
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 {
/// Determine current server type from ENV
pub fn current_server_type() -> AuthType {
match AuthenticatorType::from_env() {
AuthenticatorType::Local => Server::Local,
AuthenticatorType::AppFlowyCloud => Server::AppFlowyCloud,
AuthenticatorType::Local => AuthType::Local,
AuthenticatorType::AppFlowyCloud => AuthType::AppFlowyCloud,
}
}

View File

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

View File

@ -20,7 +20,7 @@ use tokio_stream::wrappers::WatchStream;
use uuid::Uuid;
use crate::entities::{
AuthResponse, Authenticator, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
AuthResponse, AuthType, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
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.
fn set_enable_sync(&self, uid: i64, enable_sync: bool);
/// Sets the authenticator when user sign in or sign up.
///
/// # Arguments
/// * `authenticator`: An `Authenticator` object.
fn set_user_authenticator(&self, authenticator: &Authenticator);
fn set_server_auth_type(&self, auth_type: &AuthType);
fn get_user_authenticator(&self) -> Authenticator;
fn get_server_auth_type(&self) -> AuthType;
/// Sets the network reachability
///

View File

@ -1,3 +1,4 @@
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use chrono::{DateTime, Utc};
@ -32,7 +33,7 @@ pub struct SignInParams {
pub email: String,
pub password: String,
pub name: String,
pub auth_type: Authenticator,
pub auth_type: AuthType,
}
#[derive(Serialize, Deserialize, Default, Debug)]
@ -40,7 +41,7 @@ pub struct SignUpParams {
pub email: String,
pub name: String,
pub password: String,
pub auth_type: Authenticator,
pub auth_type: AuthType,
pub device_id: String,
}
@ -103,7 +104,7 @@ impl UserAuthResponse for AuthResponse {
#[derive(Clone, Debug)]
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>,
/// The user id
@ -180,7 +181,7 @@ pub struct UserProfile {
pub icon_url: String,
pub openai_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.
pub encryption_type: EncryptionType,
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
T: UserAuthResponse,
{
fn from(params: (&T, &Authenticator)) -> Self {
fn from(params: (&T, &AuthType)) -> Self {
let (value, auth_type) = params;
let (icon_url, openai_key, stability_ai_key) = {
value
@ -258,7 +259,7 @@ where
token: value.user_token().unwrap_or_default(),
icon_url,
openai_key,
authenticator: auth_type.clone(),
authenticator: *auth_type,
encryption_type: value.encryption_type(),
stability_ai_key,
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)]
pub enum Authenticator {
pub enum AuthType {
/// It's a local server, we do fake sign in default.
Local = 0,
/// Currently not supported. It will be supported in the future when the
@ -359,28 +360,37 @@ pub enum Authenticator {
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 {
Self::Local
}
}
impl Authenticator {
impl AuthType {
pub fn is_local(&self) -> bool {
matches!(self, Authenticator::Local)
matches!(self, AuthType::Local)
}
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 {
match value {
0 => Authenticator::Local,
1 => Authenticator::AppFlowyCloud,
_ => Authenticator::Local,
0 => AuthType::Local,
1 => AuthType::AppFlowyCloud,
_ => AuthType::Local,
}
}
}

View File

@ -235,20 +235,20 @@ pub enum AuthenticatorPB {
AppFlowyCloud = 2,
}
impl From<Authenticator> for AuthenticatorPB {
fn from(auth_type: Authenticator) -> Self {
impl From<AuthType> for AuthenticatorPB {
fn from(auth_type: AuthType) -> Self {
match auth_type {
Authenticator::Local => AuthenticatorPB::Local,
Authenticator::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud,
AuthType::Local => AuthenticatorPB::Local,
AuthType::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud,
}
}
}
impl From<AuthenticatorPB> for Authenticator {
impl From<AuthenticatorPB> for AuthType {
fn from(pb: AuthenticatorPB) -> Self {
match pb {
AuthenticatorPB::Local => Authenticator::Local,
AuthenticatorPB::AppFlowyCloud => Authenticator::AppFlowyCloud,
AuthenticatorPB::Local => AuthType::Local,
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 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
.sign_in_with_password(&params.email, &params.password)
.await
@ -54,7 +54,7 @@ pub async fn sign_in_with_email_password_handler(
Err(err) => {
manager
.cloud_services
.set_user_authenticator(&old_authenticator);
.set_server_auth_type(&old_authenticator);
return Err(err);
},
}
@ -76,15 +76,13 @@ pub async fn sign_up(
) -> DataResult<UserProfilePB, FlowyError> {
let manager = upgrade_manager(manager)?;
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();
match manager.sign_up(authenticator, BoxAny::new(params)).await {
let prev_auth_type = manager.cloud_services.get_server_auth_type();
match manager.sign_up(auth_type, BoxAny::new(params)).await {
Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
Err(err) => {
manager
.cloud_services
.set_user_authenticator(&prev_authenticator);
manager.cloud_services.set_server_auth_type(&prev_auth_type);
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
// 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();
}
@ -341,7 +339,7 @@ pub async fn oauth_sign_in_handler(
) -> DataResult<UserProfilePB, FlowyError> {
let manager = upgrade_manager(manager)?;
let params = data.into_inner();
let authenticator: Authenticator = params.authenticator.into();
let authenticator: AuthType = params.authenticator.into();
let user_profile = manager
.sign_up(authenticator, BoxAny::new(params.map))
.await?;
@ -355,7 +353,7 @@ pub async fn gen_sign_in_url_handler(
) -> DataResult<SignInUrlPB, FlowyError> {
let manager = upgrade_manager(manager)?;
let params = data.into_inner();
let authenticator: Authenticator = params.authenticator.into();
let authenticator: AuthType = params.authenticator.into();
let sign_in_url = manager
.generate_sign_in_url_with_email(&authenticator, &params.email)
.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)]
#[event_err = "FlowyError"]
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
#[event(input = "SignInPayloadPB", output = "GotrueTokenResponsePB")]
SignInWithEmailPassword = 0,
/// Only use when the [Authenticator] is Local or SelfHosted
/// Only use when the [AuthType] is Local or SelfHosted
/// Creating a new account
#[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
SignUp = 1,
@ -129,7 +129,7 @@ pub enum UserEvent {
OauthSignIn = 10,
/// Get the OAuth callback url
/// Only use when the [Authenticator] is AFCloud
/// Only use when the [AuthType] is AFCloud
#[event(input = "SignInUrlPayloadPB", output = "SignInUrlPB")]
GenerateSignInURL = 11,
@ -165,7 +165,7 @@ pub enum UserEvent {
OpenAnonUser = 26,
/// 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")]
PushRealtimeEvent = 27,
@ -281,19 +281,19 @@ pub enum UserEvent {
#[async_trait]
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.
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.
/// If the user is not signed in, this method will not be called
async fn did_init(
&self,
_user_id: i64,
_user_authenticator: &Authenticator,
_user_authenticator: &AuthType,
_cloud_config: &Option<UserCloudConfig>,
_user_workspace: &UserWorkspace,
_device_id: &str,
_authenticator: &Authenticator,
_authenticator: &AuthType,
) -> FlowyResult<()> {
Ok(())
}
@ -303,7 +303,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
_user_id: i64,
_user_workspace: &UserWorkspace,
_device_id: &str,
_authenticator: &Authenticator,
_authenticator: &AuthType,
) -> FlowyResult<()> {
Ok(())
}
@ -314,7 +314,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
_user_profile: &UserProfile,
_user_workspace: &UserWorkspace,
_device_id: &str,
_authenticator: &Authenticator,
_auth_type: &AuthType,
) -> FlowyResult<()> {
Ok(())
}
@ -326,7 +326,7 @@ pub trait UserStatusCallback: Send + Sync + 'static {
&self,
_user_id: i64,
_user_workspace: &UserWorkspace,
_authenticator: &Authenticator,
_authenticator: &AuthType,
) -> FlowyResult<()> {
Ok(())
}

View File

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

View File

@ -11,7 +11,7 @@ use tracing::{event, instrument};
use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError};
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::util::load_collab;
@ -41,12 +41,12 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration {
&self,
session: &Session,
collab_db: &Arc<CollabKVDB>,
authenticator: &Authenticator,
authenticator: &AuthType,
) -> FlowyResult<()> {
// - 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.
// - 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(());
}
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::schema::user_data_migration_records;
use flowy_sqlite::ConnectionPool;
use flowy_user_pub::entities::Authenticator;
use flowy_user_pub::entities::AuthType;
use flowy_user_pub::session::Session;
use semver::Version;
use tracing::info;
@ -54,7 +54,7 @@ impl UserLocalDataMigration {
pub fn run(
self,
migrations: Vec<Box<dyn UserDataMigration>>,
authenticator: &Authenticator,
authenticator: &AuthType,
app_version: &Version,
) -> FlowyResult<Vec<String>> {
let mut applied_migrations = vec![];
@ -98,7 +98,7 @@ pub trait UserDataMigration {
&self,
user: &Session,
collab_db: &Arc<CollabKVDB>,
authenticator: &Authenticator,
authenticator: &AuthType,
) -> FlowyResult<()>;
}

View File

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

View File

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

View File

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

View File

@ -31,8 +31,8 @@ pub struct UserTable {
}
#[allow(deprecated)]
impl From<(UserProfile, Authenticator)> for UserTable {
fn from(value: (UserProfile, Authenticator)) -> Self {
impl From<(UserProfile, AuthType)> for UserTable {
fn from(value: (UserProfile, AuthType)) -> Self {
let (user_profile, auth_type) = value;
let encryption_type = serde_json::to_string(&user_profile.encryption_type).unwrap_or_default();
UserTable {
@ -62,7 +62,7 @@ impl From<UserTable> for UserProfile {
token: table.token,
icon_url: table.icon_url,
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(),
stability_ai_key: table.stability_ai_key,
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
// 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!(
tracing::Level::INFO,
"Authenticator changed from {:?} to {:?}",
@ -349,9 +349,9 @@ impl UserManager {
pub async fn sign_in(
&self,
params: SignInParams,
authenticator: Authenticator,
authenticator: AuthType,
) -> Result<UserProfile, FlowyError> {
self.cloud_services.set_user_authenticator(&authenticator);
self.cloud_services.set_server_auth_type(&authenticator);
let response: AuthResponse = self
.cloud_services
@ -398,25 +398,25 @@ impl UserManager {
#[tracing::instrument(level = "info", skip(self, params))]
pub async fn sign_up(
&self,
authenticator: Authenticator,
auth_type: AuthType,
params: BoxAny,
) -> Result<UserProfile, FlowyError> {
// sign out the current user if there is one
let migration_user = self.get_migration_user(&authenticator).await;
self.cloud_services.set_user_authenticator(&authenticator);
let migration_user = self.get_migration_user(&auth_type).await;
self.cloud_services.set_server_auth_type(&auth_type);
let auth_service = self.cloud_services.get_user_service()?;
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() {
self.auth_process.lock().await.replace(UserAuthProcess {
user_profile: new_user_profile.clone(),
migration_user,
response,
authenticator,
authenticator: auth_type,
});
} else {
self
.continue_sign_up(&new_user_profile, migration_user, response, &authenticator)
.continue_sign_up(&new_user_profile, migration_user, response, &auth_type)
.await?;
}
Ok(new_user_profile)
@ -450,12 +450,12 @@ impl UserManager {
new_user_profile: &UserProfile,
migration_user: Option<AnonUser>,
response: AuthResponse,
authenticator: &Authenticator,
auth_type: &AuthType,
) -> FlowyResult<()> {
let new_session = Session::from(&response);
self.prepare_user(&new_session).await;
self
.save_auth_data(&response, authenticator, &new_session)
.save_auth_data(&response, auth_type, &new_session)
.await?;
let _ = self
.initial_user_awareness(&new_session, &new_user_profile.authenticator)
@ -469,7 +469,7 @@ impl UserManager {
new_user_profile,
&new_session.user_workspace,
&self.authenticate_user.user_config.device_id,
authenticator,
auth_type,
)
.await?;
@ -493,7 +493,7 @@ impl UserManager {
new_user_profile.uid
);
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?;
self.remove_anon_user();
let _ = self
@ -709,10 +709,10 @@ impl UserManager {
pub(crate) async fn generate_sign_in_url_with_email(
&self,
authenticator: &Authenticator,
authenticator: &AuthType,
email: &str,
) -> 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 url = auth_service.generate_sign_in_url_with_email(email).await?;
@ -726,7 +726,7 @@ impl UserManager {
) -> Result<GotrueTokenResponse, FlowyError> {
self
.cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud);
.set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?;
let response = auth_service.sign_in_with_password(email, password).await?;
Ok(response)
@ -739,7 +739,7 @@ impl UserManager {
) -> Result<(), FlowyError> {
self
.cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud);
.set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?;
auth_service
.sign_in_with_magic_link(email, redirect_to)
@ -754,7 +754,7 @@ impl UserManager {
) -> Result<GotrueTokenResponse, FlowyError> {
self
.cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud);
.set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?;
let response = auth_service.sign_in_with_passcode(email, passcode).await?;
Ok(response)
@ -766,7 +766,7 @@ impl UserManager {
) -> Result<String, FlowyError> {
self
.cloud_services
.set_user_authenticator(&Authenticator::AppFlowyCloud);
.set_server_auth_type(&AuthType::AppFlowyCloud);
let auth_service = self.cloud_services.get_user_service()?;
let url = auth_service
.generate_oauth_url_with_provider(oauth_provider)
@ -778,7 +778,7 @@ impl UserManager {
async fn save_auth_data(
&self,
response: &impl UserAuthResponse,
authenticator: &Authenticator,
authenticator: &AuthType,
session: &Session,
) -> Result<(), FlowyError> {
let user_profile = UserProfile::from((response, authenticator));
@ -798,7 +798,7 @@ impl UserManager {
.authenticate_user
.set_session(Some(session.clone().into()))?;
self
.save_user(uid, (user_profile, authenticator.clone()).into())
.save_user(uid, (user_profile, *authenticator).into())
.await?;
Ok(())
}
@ -827,14 +827,14 @@ impl UserManager {
&self,
old_user: &AnonUser,
_new_user_session: &Session,
authenticator: &Authenticator,
authenticator: &AuthType,
) -> Result<(), FlowyError> {
let old_collab_db = self
.authenticate_user
.database
.get_collab_db(old_user.session.user_id)?;
if authenticator == &Authenticator::AppFlowyCloud {
if authenticator == &AuthType::AppFlowyCloud {
self
.migration_anon_user_on_appflowy_cloud_sign_up(old_user, &old_collab_db)
.await?;
@ -853,10 +853,10 @@ impl UserManager {
}
}
fn current_authenticator() -> Authenticator {
fn current_authenticator() -> AuthType {
match AuthenticatorType::from_env() {
AuthenticatorType::Local => Authenticator::Local,
AuthenticatorType::AppFlowyCloud => Authenticator::AppFlowyCloud,
AuthenticatorType::Local => AuthType::Local,
AuthenticatorType::AppFlowyCloud => AuthType::AppFlowyCloud,
}
}

View File

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

View File

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

View File

@ -1,11 +1,11 @@
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
#[derive(Clone)]
pub struct UserAuthProcess {
pub user_profile: UserProfile,
pub response: AuthResponse,
pub authenticator: Authenticator,
pub authenticator: AuthType,
pub migration_user: Option<AnonUser>,
}