2023-01-30 03:11:19 +00:00
|
|
|
use crate::entities::{UserProfilePB, UserSettingPB};
|
2023-01-31 11:30:48 +00:00
|
|
|
use crate::event_map::UserStatusCallback;
|
2023-04-04 00:41:16 +00:00
|
|
|
|
2022-01-11 05:34:45 +00:00
|
|
|
use crate::{
|
2023-02-13 01:29:49 +00:00
|
|
|
errors::{ErrorCode, FlowyError},
|
|
|
|
event_map::UserCloudService,
|
|
|
|
notification::*,
|
|
|
|
services::database::{UserDB, UserTable, UserTableChangeset},
|
2022-01-11 05:34:45 +00:00
|
|
|
};
|
2023-04-04 00:41:16 +00:00
|
|
|
use collab_persistence::CollabKV;
|
2023-01-31 00:28:31 +00:00
|
|
|
use flowy_sqlite::ConnectionPool;
|
|
|
|
use flowy_sqlite::{
|
2023-02-13 01:29:49 +00:00
|
|
|
kv::KV,
|
|
|
|
query_dsl::*,
|
|
|
|
schema::{user_table, user_table::dsl},
|
|
|
|
DBConnection, ExpressionMethods, UserDatabaseConnection,
|
2021-07-10 08:27:20 +00:00
|
|
|
};
|
2023-04-04 00:41:16 +00:00
|
|
|
|
2022-01-10 15:45:59 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::sync::Arc;
|
2023-01-31 11:30:48 +00:00
|
|
|
use tokio::sync::RwLock;
|
2023-02-13 01:29:49 +00:00
|
|
|
use user_model::{
|
|
|
|
SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
|
|
|
|
};
|
2021-11-09 05:29:31 +00:00
|
|
|
|
2023-04-04 00:41:16 +00:00
|
|
|
// lazy_static! {
|
|
|
|
// static ref ID_GEN: Mutex<UserIDGenerator> = Mutex::new(UserIDGenerator::new(1));
|
|
|
|
// }
|
2021-07-10 08:27:20 +00:00
|
|
|
pub struct UserSessionConfig {
|
2023-02-13 01:29:49 +00:00
|
|
|
root_dir: String,
|
2022-12-20 03:14:42 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
/// Used as the key of `Session` when saving session information to KV.
|
|
|
|
session_cache_key: String,
|
2021-07-10 08:27:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UserSessionConfig {
|
2023-02-13 01:29:49 +00:00
|
|
|
/// The `root_dir` represents as the root of the user folders. It must be unique for each
|
|
|
|
/// users.
|
|
|
|
pub fn new(name: &str, root_dir: &str) -> Self {
|
|
|
|
let session_cache_key = format!("{}_session_cache", name);
|
|
|
|
Self {
|
|
|
|
root_dir: root_dir.to_owned(),
|
|
|
|
session_cache_key,
|
2021-07-10 08:27:20 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-07-10 08:27:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct UserSession {
|
2023-02-13 01:29:49 +00:00
|
|
|
database: UserDB,
|
|
|
|
config: UserSessionConfig,
|
|
|
|
cloud_service: Arc<dyn UserCloudService>,
|
|
|
|
user_status_callback: RwLock<Option<Arc<dyn UserStatusCallback>>>,
|
2021-07-10 08:27:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UserSession {
|
2023-02-13 01:29:49 +00:00
|
|
|
pub fn new(config: UserSessionConfig, cloud_service: Arc<dyn UserCloudService>) -> Self {
|
|
|
|
let db = UserDB::new(&config.root_dir);
|
|
|
|
let user_status_callback = RwLock::new(None);
|
|
|
|
Self {
|
|
|
|
database: db,
|
|
|
|
config,
|
|
|
|
cloud_service,
|
|
|
|
user_status_callback,
|
2021-08-31 15:01:46 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-08-31 15:01:46 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
pub async fn init<C: UserStatusCallback + 'static>(&self, user_status_callback: C) {
|
2023-04-04 00:41:16 +00:00
|
|
|
// if let Some(old_session) = self.get_old_session() {
|
|
|
|
// let uid = ID_GEN.lock().next_id();
|
|
|
|
// let _ = user_status_callback
|
|
|
|
// .will_migrated(&old_session.token, &old_session.user_id, uid)
|
|
|
|
// .await;
|
|
|
|
//
|
|
|
|
// let new_session = Session {
|
|
|
|
// user_id: uid,
|
|
|
|
// token: old_session.token.clone(),
|
|
|
|
// email: old_session.email.clone(),
|
|
|
|
// name: old_session.name.clone(),
|
|
|
|
// };
|
|
|
|
// self.set_session(Some(new_session)).unwrap();
|
|
|
|
//
|
|
|
|
// if let Ok(db) = self.db_connection() {
|
|
|
|
// // Update db
|
|
|
|
// let _ = db.immediate_transaction(|| {
|
|
|
|
// // get the user data
|
|
|
|
// let mut user = dsl::user_table
|
|
|
|
// .filter(user_table::id.eq(&old_session.user_id))
|
|
|
|
// .first::<UserTable>(&*db)?;
|
|
|
|
//
|
|
|
|
// // delete the existing row
|
|
|
|
// let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&old_session.user_id)))
|
|
|
|
// .execute(&*db)?;
|
|
|
|
//
|
|
|
|
// // insert new row
|
|
|
|
// user.id = uid.to_string();
|
|
|
|
// let _ = diesel::insert_into(user_table::table)
|
|
|
|
// .values(user)
|
|
|
|
// .execute(&*db)?;
|
|
|
|
// Ok::<(), FlowyError>(())
|
|
|
|
// });
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
if let Ok(session) = self.get_session() {
|
|
|
|
let _ = user_status_callback
|
2023-04-04 00:41:16 +00:00
|
|
|
.did_sign_in(&session.token, session.user_id)
|
2023-02-13 01:29:49 +00:00
|
|
|
.await;
|
2021-07-11 07:33:19 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
*self.user_status_callback.write().await = Some(Arc::new(user_status_callback));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn db_connection(&self) -> Result<DBConnection, FlowyError> {
|
|
|
|
let user_id = self.get_session()?.user_id;
|
2023-04-04 00:41:16 +00:00
|
|
|
self.database.get_connection(user_id)
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// The caller will be not 'Sync' before of the return value,
|
|
|
|
// PooledConnection<ConnectionManager> is not sync. You can use
|
|
|
|
// db_connection_pool function to require the ConnectionPool that is 'Sync'.
|
|
|
|
//
|
|
|
|
// let pool = self.db_connection_pool()?;
|
|
|
|
// let conn: PooledConnection<ConnectionManager> = pool.get()?;
|
|
|
|
pub fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError> {
|
|
|
|
let user_id = self.get_session()?.user_id;
|
2023-04-04 00:41:16 +00:00
|
|
|
self.database.get_pool(user_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_kv_db(&self) -> Result<Arc<CollabKV>, FlowyError> {
|
|
|
|
let user_id = self.get_session()?.user_id;
|
|
|
|
self.database.get_kv_db(user_id)
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip(self))]
|
|
|
|
pub async fn sign_in(&self, params: SignInParams) -> Result<UserProfile, FlowyError> {
|
|
|
|
if self.is_user_login(¶ms.email) {
|
|
|
|
match self.get_user_profile().await {
|
|
|
|
Ok(profile) => {
|
|
|
|
send_sign_in_notification()
|
|
|
|
.payload::<UserProfilePB>(profile.clone().into())
|
2022-07-04 02:59:08 +00:00
|
|
|
.send();
|
2023-02-13 01:29:49 +00:00
|
|
|
Ok(profile)
|
|
|
|
},
|
|
|
|
Err(err) => Err(err),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let resp = self.cloud_service.sign_in(params).await?;
|
|
|
|
let session: Session = resp.clone().into();
|
|
|
|
self.set_session(Some(session))?;
|
|
|
|
let user_profile: UserProfile = self.save_user(resp.into()).await?.into();
|
|
|
|
let _ = self
|
|
|
|
.user_status_callback
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
.as_ref()
|
|
|
|
.unwrap()
|
2023-04-04 00:41:16 +00:00
|
|
|
.did_sign_in(&user_profile.token, user_profile.id)
|
2023-02-13 01:29:49 +00:00
|
|
|
.await;
|
|
|
|
send_sign_in_notification()
|
|
|
|
.payload::<UserProfilePB>(user_profile.clone().into())
|
|
|
|
.send();
|
|
|
|
Ok(user_profile)
|
2021-07-23 09:30:33 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip(self))]
|
|
|
|
pub async fn sign_up(&self, params: SignUpParams) -> Result<UserProfile, FlowyError> {
|
|
|
|
if self.is_user_login(¶ms.email) {
|
|
|
|
self.get_user_profile().await
|
|
|
|
} else {
|
|
|
|
let resp = self.cloud_service.sign_up(params).await?;
|
|
|
|
let session: Session = resp.clone().into();
|
|
|
|
self.set_session(Some(session))?;
|
|
|
|
let user_table = self.save_user(resp.into()).await?;
|
|
|
|
let user_profile: UserProfile = user_table.into();
|
|
|
|
let _ = self
|
|
|
|
.user_status_callback
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
.as_ref()
|
|
|
|
.unwrap()
|
|
|
|
.did_sign_up(&user_profile)
|
|
|
|
.await;
|
|
|
|
Ok(user_profile)
|
2022-11-11 09:24:10 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tracing::instrument(level = "debug", skip(self))]
|
|
|
|
pub async fn sign_out(&self) -> Result<(), FlowyError> {
|
|
|
|
let session = self.get_session()?;
|
2023-04-04 00:41:16 +00:00
|
|
|
let uid = session.user_id.to_string();
|
|
|
|
let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&uid)))
|
2023-02-13 01:29:49 +00:00
|
|
|
.execute(&*(self.db_connection()?))?;
|
2023-04-04 00:41:16 +00:00
|
|
|
self.database.close_user_db(session.user_id)?;
|
2023-02-13 01:29:49 +00:00
|
|
|
self.set_session(None)?;
|
|
|
|
let _ = self
|
|
|
|
.user_status_callback
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
.as_ref()
|
|
|
|
.unwrap()
|
2023-04-04 00:41:16 +00:00
|
|
|
.did_expired(&session.token, session.user_id)
|
2023-02-13 01:29:49 +00:00
|
|
|
.await;
|
|
|
|
self.sign_out_on_server(&session.token).await?;
|
2022-11-11 09:24:10 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-09-01 08:08:32 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
#[tracing::instrument(level = "debug", skip(self))]
|
|
|
|
pub async fn update_user_profile(
|
|
|
|
&self,
|
|
|
|
params: UpdateUserProfileParams,
|
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let session = self.get_session()?;
|
|
|
|
let changeset = UserTableChangeset::new(params.clone());
|
|
|
|
diesel_update_table!(user_table, changeset, &*self.db_connection()?);
|
|
|
|
|
|
|
|
let user_profile = self.get_user_profile().await?;
|
|
|
|
let profile_pb: UserProfilePB = user_profile.into();
|
|
|
|
send_notification(&session.token, UserNotification::DidUpdateUserProfile)
|
|
|
|
.payload(profile_pb)
|
|
|
|
.send();
|
|
|
|
self.update_user_on_server(&session.token, params).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-12-09 14:28:11 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
pub async fn init_user(&self) -> Result<(), FlowyError> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn check_user(&self) -> Result<UserProfile, FlowyError> {
|
|
|
|
let (user_id, token) = self.get_session()?.into_part();
|
2023-04-04 00:41:16 +00:00
|
|
|
let user_id = user_id.to_string();
|
2023-02-13 01:29:49 +00:00
|
|
|
let user = dsl::user_table
|
|
|
|
.filter(user_table::id.eq(&user_id))
|
|
|
|
.first::<UserTable>(&*(self.db_connection()?))?;
|
|
|
|
|
|
|
|
self.read_user_profile_on_server(&token)?;
|
|
|
|
Ok(user.into())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_user_profile(&self) -> Result<UserProfile, FlowyError> {
|
|
|
|
let (user_id, token) = self.get_session()?.into_part();
|
2023-04-04 00:41:16 +00:00
|
|
|
let user_id = user_id.to_string();
|
2023-02-13 01:29:49 +00:00
|
|
|
let user = dsl::user_table
|
|
|
|
.filter(user_table::id.eq(&user_id))
|
|
|
|
.first::<UserTable>(&*(self.db_connection()?))?;
|
|
|
|
|
|
|
|
self.read_user_profile_on_server(&token)?;
|
|
|
|
Ok(user.into())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn user_dir(&self) -> Result<String, FlowyError> {
|
|
|
|
let session = self.get_session()?;
|
|
|
|
Ok(format!("{}/{}", self.config.root_dir, session.user_id))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn user_setting(&self) -> Result<UserSettingPB, FlowyError> {
|
|
|
|
let user_setting = UserSettingPB {
|
|
|
|
user_folder: self.user_dir()?,
|
|
|
|
};
|
|
|
|
Ok(user_setting)
|
|
|
|
}
|
|
|
|
|
2023-04-04 00:41:16 +00:00
|
|
|
pub fn user_id(&self) -> Result<i64, FlowyError> {
|
2023-02-13 01:29:49 +00:00
|
|
|
Ok(self.get_session()?.user_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn user_name(&self) -> Result<String, FlowyError> {
|
|
|
|
Ok(self.get_session()?.name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn token(&self) -> Result<String, FlowyError> {
|
|
|
|
Ok(self.get_session()?.token)
|
|
|
|
}
|
2021-09-01 08:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UserSession {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn read_user_profile_on_server(&self, _token: &str) -> Result<(), FlowyError> {
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-09-01 08:08:32 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
async fn update_user_on_server(
|
|
|
|
&self,
|
|
|
|
token: &str,
|
|
|
|
params: UpdateUserProfileParams,
|
|
|
|
) -> Result<(), FlowyError> {
|
|
|
|
let server = self.cloud_service.clone();
|
|
|
|
let token = token.to_owned();
|
|
|
|
let _ = tokio::spawn(async move {
|
|
|
|
match server.update_user(&token, params).await {
|
|
|
|
Ok(_) => {},
|
|
|
|
Err(e) => {
|
|
|
|
// TODO: retry?
|
|
|
|
tracing::error!("update user profile failed: {:?}", e);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn sign_out_on_server(&self, token: &str) -> Result<(), FlowyError> {
|
|
|
|
let server = self.cloud_service.clone();
|
|
|
|
let token = token.to_owned();
|
|
|
|
let _ = tokio::spawn(async move {
|
|
|
|
match server.sign_out(&token).await {
|
|
|
|
Ok(_) => {},
|
|
|
|
Err(e) => tracing::error!("Sign out failed: {:?}", e),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn save_user(&self, user: UserTable) -> Result<UserTable, FlowyError> {
|
|
|
|
let conn = self.db_connection()?;
|
|
|
|
let _ = diesel::insert_into(user_table::table)
|
|
|
|
.values(user.clone())
|
|
|
|
.execute(&*conn)?;
|
|
|
|
Ok(user)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_session(&self, session: Option<Session>) -> Result<(), FlowyError> {
|
|
|
|
tracing::debug!("Set user session: {:?}", session);
|
|
|
|
match &session {
|
|
|
|
None => KV::remove(&self.config.session_cache_key)
|
|
|
|
.map_err(|e| FlowyError::new(ErrorCode::Internal, &e))?,
|
|
|
|
Some(session) => KV::set_str(&self.config.session_cache_key, session.clone().into()),
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-09-03 08:43:03 +00:00
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
fn get_session(&self) -> Result<Session, FlowyError> {
|
|
|
|
match KV::get_str(&self.config.session_cache_key) {
|
|
|
|
None => Err(FlowyError::unauthorized()),
|
|
|
|
Some(s) => Ok(Session::from(s)),
|
2021-07-18 15:56:36 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-09-03 08:43:03 +00:00
|
|
|
|
2023-04-04 00:41:16 +00:00
|
|
|
// fn get_old_session(&self) -> Option<OldSession> {
|
|
|
|
// let s = KV::get_str(&self.config.session_cache_key)?;
|
|
|
|
// serde_json::from_str::<OldSession>(&s).ok()
|
|
|
|
// }
|
|
|
|
|
2023-02-13 01:29:49 +00:00
|
|
|
fn is_user_login(&self, email: &str) -> bool {
|
|
|
|
match self.get_session() {
|
|
|
|
Ok(session) => session.email == email,
|
|
|
|
Err(_) => false,
|
2021-09-03 08:43:03 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-08-31 15:01:46 +00:00
|
|
|
}
|
|
|
|
|
2021-09-27 15:23:23 +00:00
|
|
|
pub async fn update_user(
|
2023-02-13 01:29:49 +00:00
|
|
|
_cloud_service: Arc<dyn UserCloudService>,
|
|
|
|
pool: Arc<ConnectionPool>,
|
|
|
|
params: UpdateUserProfileParams,
|
2021-12-14 10:04:51 +00:00
|
|
|
) -> Result<(), FlowyError> {
|
2023-02-13 01:29:49 +00:00
|
|
|
let changeset = UserTableChangeset::new(params);
|
|
|
|
let conn = pool.get()?;
|
|
|
|
diesel_update_table!(user_table, changeset, &*conn);
|
|
|
|
Ok(())
|
2021-07-16 15:18:12 +00:00
|
|
|
}
|
2021-07-11 09:38:03 +00:00
|
|
|
|
2021-07-13 15:08:20 +00:00
|
|
|
impl UserDatabaseConnection for UserSession {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn get_connection(&self) -> Result<DBConnection, String> {
|
|
|
|
self.db_connection().map_err(|e| format!("{:?}", e))
|
|
|
|
}
|
2021-07-13 15:08:20 +00:00
|
|
|
}
|
|
|
|
|
2021-09-01 03:21:42 +00:00
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
|
|
|
struct Session {
|
2023-04-04 00:41:16 +00:00
|
|
|
user_id: i64,
|
2023-02-13 01:29:49 +00:00
|
|
|
token: String,
|
|
|
|
email: String,
|
|
|
|
#[serde(default)]
|
|
|
|
name: String,
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 13:39:53 +00:00
|
|
|
impl std::convert::From<SignInResponse> for Session {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn from(resp: SignInResponse) -> Self {
|
|
|
|
Session {
|
|
|
|
user_id: resp.user_id,
|
|
|
|
token: resp.token,
|
|
|
|
email: resp.email,
|
|
|
|
name: resp.name,
|
2021-12-09 13:39:53 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-12-09 13:39:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<SignUpResponse> for Session {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn from(resp: SignUpResponse) -> Self {
|
|
|
|
Session {
|
|
|
|
user_id: resp.user_id,
|
|
|
|
token: resp.token,
|
|
|
|
email: resp.email,
|
|
|
|
name: resp.name,
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-12-09 13:39:53 +00:00
|
|
|
}
|
2021-09-07 15:30:43 +00:00
|
|
|
|
2021-12-09 13:39:53 +00:00
|
|
|
impl Session {
|
2023-04-04 00:41:16 +00:00
|
|
|
pub fn into_part(self) -> (i64, String) {
|
2023-02-13 01:29:49 +00:00
|
|
|
(self.user_id, self.token)
|
|
|
|
}
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<String> for Session {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn from(s: String) -> Self {
|
|
|
|
match serde_json::from_str(&s) {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
tracing::error!("Deserialize string to Session failed: {:?}", e);
|
|
|
|
Session::default()
|
|
|
|
},
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2021-11-27 11:19:41 +00:00
|
|
|
impl std::convert::From<Session> for String {
|
2023-02-13 01:29:49 +00:00
|
|
|
fn from(session: Session) -> Self {
|
|
|
|
match serde_json::to_string(&session) {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
tracing::error!("Serialize session to string failed: {:?}", e);
|
|
|
|
"".to_string()
|
|
|
|
},
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2023-02-13 01:29:49 +00:00
|
|
|
}
|
2021-09-01 03:21:42 +00:00
|
|
|
}
|
2023-04-04 00:41:16 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
|
|
|
struct OldSession {
|
|
|
|
user_id: String,
|
|
|
|
token: String,
|
|
|
|
email: String,
|
|
|
|
#[serde(default)]
|
|
|
|
name: String,
|
|
|
|
}
|