2021-07-11 15:33:19 +08:00
|
|
|
use flowy_database::{
|
|
|
|
query_dsl::*,
|
|
|
|
schema::{user_table, user_table::dsl},
|
|
|
|
DBConnection,
|
|
|
|
ExpressionMethods,
|
2021-07-13 23:08:20 +08:00
|
|
|
UserDatabaseConnection,
|
2021-07-10 16:27:20 +08:00
|
|
|
};
|
2021-07-11 15:33:19 +08:00
|
|
|
use flowy_infra::kv::KVStore;
|
2021-07-10 16:27:20 +08:00
|
|
|
use lazy_static::lazy_static;
|
2021-07-14 23:00:58 +08:00
|
|
|
use std::sync::{Arc, RwLock};
|
2021-07-10 16:27:20 +08:00
|
|
|
|
2021-07-11 15:33:19 +08:00
|
|
|
use crate::{
|
2021-07-14 21:12:52 +08:00
|
|
|
entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
|
2021-07-11 21:54:55 +08:00
|
|
|
errors::{ErrorBuilder, UserError, UserErrorCode},
|
2021-07-15 08:46:16 +08:00
|
|
|
event::UserEvent::GetStatus,
|
2021-07-14 21:12:52 +08:00
|
|
|
services::user_session::{database::UserDB, user_server::UserServer},
|
|
|
|
sql_tables::{User, UserChangeset},
|
2021-07-11 15:33:19 +08:00
|
|
|
};
|
2021-07-15 08:46:16 +08:00
|
|
|
use flowy_dispatch::prelude::{Data, EventDispatch, ModuleRequest};
|
|
|
|
use std::convert::TryFrom;
|
2021-07-11 15:33:19 +08:00
|
|
|
|
2021-07-10 16:27:20 +08:00
|
|
|
pub struct UserSessionConfig {
|
|
|
|
root_dir: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UserSessionConfig {
|
|
|
|
pub fn new(root_dir: &str) -> Self {
|
|
|
|
Self {
|
|
|
|
root_dir: root_dir.to_owned(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct UserSession {
|
|
|
|
database: UserDB,
|
|
|
|
config: UserSessionConfig,
|
2021-07-14 23:00:58 +08:00
|
|
|
server: Arc<dyn UserServer + Send + Sync>,
|
2021-07-10 16:27:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UserSession {
|
2021-07-14 23:00:58 +08:00
|
|
|
pub fn new<R>(config: UserSessionConfig, server: Arc<R>) -> Self
|
2021-07-10 16:27:20 +08:00
|
|
|
where
|
2021-07-11 15:33:19 +08:00
|
|
|
R: 'static + UserServer + Send + Sync,
|
2021-07-10 16:27:20 +08:00
|
|
|
{
|
|
|
|
let db = UserDB::new(&config.root_dir);
|
|
|
|
Self {
|
|
|
|
database: db,
|
|
|
|
config,
|
2021-07-14 23:00:58 +08:00
|
|
|
server,
|
2021-07-10 16:27:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-11 15:33:19 +08:00
|
|
|
pub async fn sign_in(&self, params: SignInParams) -> Result<User, UserError> {
|
|
|
|
let user = self.server.sign_in(params)?;
|
|
|
|
let _ = set_current_user_id(Some(user.id.clone()))?;
|
|
|
|
self.save_user(user)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn sign_up(&self, params: SignUpParams) -> Result<User, UserError> {
|
|
|
|
let user = self.server.sign_up(params)?;
|
|
|
|
let _ = set_current_user_id(Some(user.id.clone()))?;
|
|
|
|
self.save_user(user)
|
|
|
|
}
|
|
|
|
|
2021-07-11 17:38:03 +08:00
|
|
|
pub async fn sign_out(&self) -> Result<(), UserError> {
|
|
|
|
let user_id = self.current_user_id()?;
|
|
|
|
let conn = self.get_db_connection()?;
|
2021-07-11 21:54:55 +08:00
|
|
|
let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&user_id))).execute(&*conn)?;
|
2021-07-11 17:38:03 +08:00
|
|
|
|
|
|
|
match self.server.sign_out(&user_id) {
|
|
|
|
Ok(_) => {},
|
|
|
|
Err(_) => {},
|
|
|
|
}
|
|
|
|
let _ = self.database.close_user_db()?;
|
2021-07-11 15:33:19 +08:00
|
|
|
let _ = set_current_user_id(None)?;
|
2021-07-11 17:38:03 +08:00
|
|
|
|
|
|
|
Ok(())
|
2021-07-11 15:33:19 +08:00
|
|
|
}
|
|
|
|
|
2021-07-14 21:12:52 +08:00
|
|
|
pub async fn update_user(&self, params: UpdateUserParams) -> Result<UserDetail, UserError> {
|
|
|
|
let changeset = UserChangeset::new(params);
|
|
|
|
let conn = self.get_db_connection()?;
|
|
|
|
diesel_update_table!(user_table, changeset, conn);
|
|
|
|
|
|
|
|
let user_detail = self.current_user_detail()?;
|
|
|
|
Ok(user_detail)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn current_user_detail(&self) -> Result<UserDetail, UserError> {
|
2021-07-11 17:38:03 +08:00
|
|
|
let user_id = self.current_user_id()?;
|
2021-07-11 15:33:19 +08:00
|
|
|
let conn = self.get_db_connection()?;
|
|
|
|
|
|
|
|
let user = dsl::user_table
|
2021-07-11 17:38:03 +08:00
|
|
|
.filter(user_table::id.eq(&user_id))
|
2021-07-11 15:33:19 +08:00
|
|
|
.first::<User>(&*conn)?;
|
|
|
|
|
2021-07-11 17:38:03 +08:00
|
|
|
match self.server.get_user_info(&user_id) {
|
|
|
|
Ok(_user_detail) => {
|
|
|
|
// TODO: post latest user_detail to upper layer
|
|
|
|
},
|
|
|
|
Err(_e) => {
|
|
|
|
// log::debug!("Get user details failed. {:?}", e);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-07-11 15:33:19 +08:00
|
|
|
Ok(UserDetail::from(user))
|
|
|
|
}
|
|
|
|
|
2021-07-10 16:27:20 +08:00
|
|
|
pub fn get_db_connection(&self) -> Result<DBConnection, UserError> {
|
2021-07-14 21:12:52 +08:00
|
|
|
let user_id = get_current_user_id()?;
|
|
|
|
self.database.get_connection(&user_id)
|
|
|
|
}
|
|
|
|
|
2021-07-15 08:46:16 +08:00
|
|
|
pub fn set_current_workspace() {
|
|
|
|
unimplemented!()
|
|
|
|
|
|
|
|
// let request = SignInRequest {
|
|
|
|
// email: valid_email(),
|
|
|
|
// password: valid_password(),
|
|
|
|
// };
|
|
|
|
//
|
|
|
|
// let user_detail = Tester::<UserError>::new(SignIn)
|
|
|
|
// .request(request)
|
|
|
|
// .sync_send()
|
|
|
|
// .parse::<UserDetail>();
|
|
|
|
//
|
|
|
|
// user_detail
|
|
|
|
}
|
|
|
|
|
2021-07-14 21:12:52 +08:00
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn get_current_workspace(&self) -> Result<String, UserError> {
|
2021-07-15 08:46:16 +08:00
|
|
|
// let response = EventDispatch::sync_send(ModuleRequest::new(GetStatus));
|
|
|
|
// let user_detail =
|
|
|
|
// <Data<UserDetail>>::try_from(response.payload).unwrap().into_inner();
|
2021-07-14 21:12:52 +08:00
|
|
|
let user_id = get_current_user_id()?;
|
|
|
|
let conn = self.get_db_connection()?;
|
|
|
|
|
|
|
|
let workspace = dsl::user_table
|
|
|
|
.filter(user_table::id.eq(&user_id))
|
|
|
|
.select(user_table::workspace)
|
|
|
|
.first::<String>(&*conn)?;
|
|
|
|
|
|
|
|
Ok(workspace)
|
2021-07-10 16:27:20 +08:00
|
|
|
}
|
2021-07-11 15:33:19 +08:00
|
|
|
}
|
2021-07-10 16:27:20 +08:00
|
|
|
|
2021-07-11 15:33:19 +08:00
|
|
|
impl UserSession {
|
|
|
|
fn save_user(&self, user: User) -> Result<User, UserError> {
|
2021-07-10 16:27:20 +08:00
|
|
|
let conn = self.get_db_connection()?;
|
2021-07-11 21:54:55 +08:00
|
|
|
let _ = diesel::insert_into(user_table::table)
|
2021-07-10 16:27:20 +08:00
|
|
|
.values(user.clone())
|
|
|
|
.execute(&*conn)?;
|
|
|
|
|
|
|
|
Ok(user)
|
|
|
|
}
|
2021-07-11 17:38:03 +08:00
|
|
|
|
|
|
|
fn current_user_id(&self) -> Result<String, UserError> {
|
|
|
|
match KVStore::get_str(USER_ID_DISK_CACHE_KEY) {
|
2021-07-11 21:54:55 +08:00
|
|
|
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
2021-07-11 17:38:03 +08:00
|
|
|
Some(user_id) => Ok(user_id),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-13 23:08:20 +08:00
|
|
|
impl UserDatabaseConnection for UserSession {
|
|
|
|
fn get_connection(&self) -> Result<DBConnection, String> {
|
|
|
|
self.get_db_connection().map_err(|e| format!("{:?}", e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-11 17:38:03 +08:00
|
|
|
const USER_ID_DISK_CACHE_KEY: &str = "user_id";
|
|
|
|
lazy_static! {
|
|
|
|
pub static ref CURRENT_USER_ID: RwLock<Option<String>> = RwLock::new(None);
|
|
|
|
}
|
2021-07-14 21:12:52 +08:00
|
|
|
|
|
|
|
pub(crate) fn get_current_user_id() -> Result<String, UserError> {
|
2021-07-11 21:54:55 +08:00
|
|
|
let read_guard = CURRENT_USER_ID.read().map_err(|e| {
|
|
|
|
ErrorBuilder::new(UserErrorCode::ReadCurrentIdFailed)
|
|
|
|
.error(e)
|
|
|
|
.build()
|
|
|
|
})?;
|
2021-07-11 17:38:03 +08:00
|
|
|
|
|
|
|
let mut user_id = (*read_guard).clone();
|
|
|
|
// explicitly drop the read_guard in case of dead lock
|
|
|
|
drop(read_guard);
|
|
|
|
|
|
|
|
if user_id.is_none() {
|
|
|
|
user_id = KVStore::get_str(USER_ID_DISK_CACHE_KEY);
|
|
|
|
*(CURRENT_USER_ID.write().unwrap()) = user_id.clone();
|
|
|
|
}
|
|
|
|
|
2021-07-14 21:12:52 +08:00
|
|
|
if user_id.is_none() {
|
|
|
|
return Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build());
|
|
|
|
}
|
|
|
|
|
|
|
|
match user_id {
|
|
|
|
None => Err(ErrorBuilder::new(UserErrorCode::UserNotLoginYet).build()),
|
|
|
|
Some(user_id) => Ok(user_id),
|
|
|
|
}
|
2021-07-11 17:38:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn set_current_user_id(user_id: Option<String>) -> Result<(), UserError> {
|
|
|
|
KVStore::set_str(
|
|
|
|
USER_ID_DISK_CACHE_KEY,
|
|
|
|
user_id.clone().unwrap_or("".to_owned()),
|
|
|
|
);
|
|
|
|
|
2021-07-11 21:54:55 +08:00
|
|
|
let mut current_user_id = CURRENT_USER_ID.write().map_err(|e| {
|
|
|
|
ErrorBuilder::new(UserErrorCode::WriteCurrentIdFailed)
|
|
|
|
.error(e)
|
|
|
|
.build()
|
|
|
|
})?;
|
2021-07-11 17:38:03 +08:00
|
|
|
*current_user_id = user_id;
|
|
|
|
Ok(())
|
2021-07-10 16:27:20 +08:00
|
|
|
}
|