event_map.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. use std::sync::Arc;
  2. use strum_macros::Display;
  3. use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
  4. use flowy_error::FlowyResult;
  5. use lib_dispatch::prelude::*;
  6. use lib_infra::box_any::BoxAny;
  7. use lib_infra::future::{to_fut, Fut, FutureResult};
  8. use crate::entities::{SignInResponse, SignUpResponse, UpdateUserProfileParams, UserProfile};
  9. use crate::event_handler::*;
  10. use crate::services::AuthType;
  11. use crate::{errors::FlowyError, services::UserSession};
  12. pub fn init(user_session: Arc<UserSession>) -> AFPlugin {
  13. AFPlugin::new()
  14. .name("Flowy-User")
  15. .state(user_session)
  16. .event(UserEvent::SignIn, sign_in)
  17. .event(UserEvent::SignUp, sign_up)
  18. .event(UserEvent::InitUser, init_user_handler)
  19. .event(UserEvent::GetUserProfile, get_user_profile_handler)
  20. .event(UserEvent::SignOut, sign_out)
  21. .event(UserEvent::UpdateUserProfile, update_user_profile_handler)
  22. .event(UserEvent::CheckUser, check_user_handler)
  23. .event(UserEvent::SetAppearanceSetting, set_appearance_setting)
  24. .event(UserEvent::GetAppearanceSetting, get_appearance_setting)
  25. .event(UserEvent::GetUserSetting, get_user_setting)
  26. .event(UserEvent::ThirdPartyAuth, third_party_auth_handler)
  27. }
  28. pub(crate) struct DefaultUserStatusCallback;
  29. impl UserStatusCallback for DefaultUserStatusCallback {
  30. fn auth_type_did_changed(&self, _auth_type: AuthType) {}
  31. fn did_sign_in(&self, _user_id: i64, _workspace_id: &str) -> Fut<FlowyResult<()>> {
  32. to_fut(async { Ok(()) })
  33. }
  34. fn did_sign_up(&self, _is_new: bool, _user_profile: &UserProfile) -> Fut<FlowyResult<()>> {
  35. to_fut(async { Ok(()) })
  36. }
  37. fn did_expired(&self, _token: &str, _user_id: i64) -> Fut<FlowyResult<()>> {
  38. to_fut(async { Ok(()) })
  39. }
  40. }
  41. pub trait UserStatusCallback: Send + Sync + 'static {
  42. fn auth_type_did_changed(&self, auth_type: AuthType);
  43. fn did_sign_in(&self, user_id: i64, workspace_id: &str) -> Fut<FlowyResult<()>>;
  44. fn did_sign_up(&self, is_new: bool, user_profile: &UserProfile) -> Fut<FlowyResult<()>>;
  45. fn did_expired(&self, token: &str, user_id: i64) -> Fut<FlowyResult<()>>;
  46. }
  47. /// The user cloud service provider.
  48. /// The provider can be supabase, firebase, aws, or any other cloud service.
  49. pub trait UserCloudServiceProvider: Send + Sync + 'static {
  50. fn set_auth_type(&self, auth_type: AuthType);
  51. fn get_auth_service(&self) -> Result<Arc<dyn UserAuthService>, FlowyError>;
  52. }
  53. impl<T> UserCloudServiceProvider for Arc<T>
  54. where
  55. T: UserCloudServiceProvider,
  56. {
  57. fn set_auth_type(&self, auth_type: AuthType) {
  58. (**self).set_auth_type(auth_type)
  59. }
  60. fn get_auth_service(&self) -> Result<Arc<dyn UserAuthService>, FlowyError> {
  61. (**self).get_auth_service()
  62. }
  63. }
  64. #[derive(Clone, Debug)]
  65. pub struct UserCredentials {
  66. /// Currently, the token is only used when the [AuthType] is SelfHosted
  67. pub token: Option<String>,
  68. /// The user id
  69. pub uid: Option<i64>,
  70. /// The user id
  71. pub uuid: Option<String>,
  72. }
  73. impl UserCredentials {
  74. pub fn from_uid(uid: i64) -> Self {
  75. Self {
  76. token: None,
  77. uid: Some(uid),
  78. uuid: None,
  79. }
  80. }
  81. pub fn from_uuid(uuid: String) -> Self {
  82. Self {
  83. token: None,
  84. uid: None,
  85. uuid: Some(uuid),
  86. }
  87. }
  88. pub fn new(token: Option<String>, uid: Option<i64>, uuid: Option<String>) -> Self {
  89. Self { token, uid, uuid }
  90. }
  91. }
  92. /// Provide the generic interface for the user cloud service
  93. /// The user cloud service is responsible for the user authentication and user profile management
  94. pub trait UserAuthService: Send + Sync {
  95. /// Sign up a new account.
  96. /// The type of the params is defined the this trait's implementation.
  97. /// Use the `unbox_or_error` of the [BoxAny] to get the params.
  98. fn sign_up(&self, params: BoxAny) -> FutureResult<SignUpResponse, FlowyError>;
  99. /// Sign in an account
  100. /// The type of the params is defined the this trait's implementation.
  101. fn sign_in(&self, params: BoxAny) -> FutureResult<SignInResponse, FlowyError>;
  102. /// Sign out an account
  103. fn sign_out(&self, token: Option<String>) -> FutureResult<(), FlowyError>;
  104. /// Using the user's token to update the user information
  105. fn update_user(
  106. &self,
  107. credential: UserCredentials,
  108. params: UpdateUserProfileParams,
  109. ) -> FutureResult<(), FlowyError>;
  110. /// Get the user information using the user's token or uid
  111. /// return None if the user is not found
  112. fn get_user_profile(
  113. &self,
  114. credential: UserCredentials,
  115. ) -> FutureResult<Option<UserProfile>, FlowyError>;
  116. fn check_user(&self, credential: UserCredentials) -> FutureResult<(), FlowyError>;
  117. }
  118. #[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
  119. #[event_err = "FlowyError"]
  120. pub enum UserEvent {
  121. /// Only use when the [AuthType] is Local or SelfHosted
  122. /// Logging into an account using a register email and password
  123. #[event(input = "SignInPayloadPB", output = "UserProfilePB")]
  124. SignIn = 0,
  125. /// Only use when the [AuthType] is Local or SelfHosted
  126. /// Creating a new account
  127. #[event(input = "SignUpPayloadPB", output = "UserProfilePB")]
  128. SignUp = 1,
  129. /// Logging out fo an account
  130. #[event(input = "SignOutPB")]
  131. SignOut = 2,
  132. /// Update the user information
  133. #[event(input = "UpdateUserProfilePayloadPB")]
  134. UpdateUserProfile = 3,
  135. /// Get the user information
  136. #[event(output = "UserProfilePB")]
  137. GetUserProfile = 4,
  138. /// Check the user current session is valid or not
  139. #[event(output = "UserProfilePB")]
  140. CheckUser = 5,
  141. /// Initialize resources for the current user after launching the application
  142. #[event()]
  143. InitUser = 6,
  144. /// Change the visual elements of the interface, such as theme, font and more
  145. #[event(input = "AppearanceSettingsPB")]
  146. SetAppearanceSetting = 7,
  147. /// Get the appearance setting
  148. #[event(output = "AppearanceSettingsPB")]
  149. GetAppearanceSetting = 8,
  150. /// Get the settings of the user, such as the user storage folder
  151. #[event(output = "UserSettingPB")]
  152. GetUserSetting = 9,
  153. #[event(input = "ThirdPartyAuthPB", output = "UserProfilePB")]
  154. ThirdPartyAuth = 10,
  155. }