188 lines
5.7 KiB
Rust
Raw Normal View History

2021-08-31 17:25:08 +08:00
use super::AUTHORIZED_USERS;
2021-08-23 18:39:10 +08:00
use crate::{
2021-08-24 21:38:53 +08:00
entities::{token::Token, user::UserTable},
2021-08-26 17:58:59 +08:00
sqlx_ext::DBTransaction,
2021-08-31 17:25:08 +08:00
user_service::{hash_password, verify_password, LoggedUser},
2021-08-26 17:58:59 +08:00
workspace_service::user_default::create_default_workspace,
2021-08-23 18:39:10 +08:00
};
2021-08-31 17:25:08 +08:00
2021-08-23 18:39:10 +08:00
use anyhow::Context;
use chrono::Utc;
use flowy_net::{
2021-08-25 17:34:20 +08:00
errors::{ErrorCode, ServerError},
2021-08-23 18:39:10 +08:00
response::FlowyResponse,
};
use flowy_user::{
2021-08-26 17:58:59 +08:00
entities::parser::{UserEmail, UserName, UserPassword},
2021-08-31 23:01:46 +08:00
protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UserDetail},
2021-08-23 18:39:10 +08:00
};
2021-08-29 22:00:42 +08:00
use sqlx::{PgPool, Postgres};
2021-08-23 18:39:10 +08:00
2021-08-31 17:25:08 +08:00
pub async fn sign_in(pool: &PgPool, params: SignInParams) -> Result<SignInResponse, ServerError> {
2021-08-23 23:02:42 +08:00
let email =
UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?;
let password = UserPassword::parse(params.password)
.map_err(|e| ServerError::params_invalid().context(e))?;
2021-08-23 18:39:10 +08:00
let mut transaction = pool
.begin()
.await
.context("Failed to acquire a Postgres connection to sign in")?;
2021-08-23 23:02:42 +08:00
let user = read_user(&mut transaction, &email.0).await?;
2021-08-23 18:39:10 +08:00
transaction
.commit()
.await
.context("Failed to commit SQL transaction to sign in.")?;
2021-08-23 23:02:42 +08:00
match verify_password(&password.0, &user.password) {
2021-08-23 18:39:10 +08:00
Ok(true) => {
2021-08-31 17:56:38 +08:00
let token = Token::create_token(&user.email)?;
let _ = AUTHORIZED_USERS.store_auth(user.email.clone().into(), true)?;
2021-08-26 17:58:59 +08:00
let mut response_data = SignInResponse::default();
response_data.set_uid(user.id.to_string());
response_data.set_name(user.name);
response_data.set_email(user.email);
2021-08-31 17:25:08 +08:00
response_data.set_token(token.clone().into());
2021-08-26 17:58:59 +08:00
2021-08-31 17:25:08 +08:00
Ok(response_data)
2021-08-23 18:39:10 +08:00
},
2021-08-23 23:02:42 +08:00
_ => Err(ServerError::password_not_match()),
2021-08-23 18:39:10 +08:00
}
}
2021-08-31 23:01:46 +08:00
pub async fn sign_out(params: UserToken) -> Result<FlowyResponse, ServerError> {
2021-08-31 17:25:08 +08:00
let _ = AUTHORIZED_USERS.store_auth(LoggedUser::from_token(params.token.clone())?, false)?;
Ok(FlowyResponse::success())
}
2021-08-23 18:39:10 +08:00
pub async fn register_user(
pool: &PgPool,
params: SignUpParams,
) -> Result<FlowyResponse, ServerError> {
2021-08-24 13:10:53 +08:00
let name =
UserName::parse(params.name).map_err(|e| ServerError::params_invalid().context(e))?;
let email =
UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?;
let password = UserPassword::parse(params.password)
.map_err(|e| ServerError::params_invalid().context(e))?;
2021-08-23 18:39:10 +08:00
let mut transaction = pool
.begin()
.await
.context("Failed to acquire a Postgres connection to register user")?;
2021-08-24 13:10:53 +08:00
let _ = is_email_exist(&mut transaction, email.as_ref()).await?;
2021-08-26 17:58:59 +08:00
let response_data = insert_new_user(
2021-08-24 13:10:53 +08:00
&mut transaction,
name.as_ref(),
email.as_ref(),
password.as_ref(),
)
.await
.context("Failed to insert user")?;
2021-08-23 18:39:10 +08:00
2021-08-31 17:56:38 +08:00
let _ = AUTHORIZED_USERS.store_auth(email.as_ref().to_string().into(), true)?;
2021-08-26 17:58:59 +08:00
let _ = create_default_workspace(&mut transaction, response_data.get_uid()).await?;
2021-08-23 18:39:10 +08:00
transaction
.commit()
.await
.context("Failed to commit SQL transaction to register user.")?;
2021-08-26 17:58:59 +08:00
FlowyResponse::success().pb(response_data)
2021-08-23 18:39:10 +08:00
}
2021-08-31 17:25:08 +08:00
pub(crate) async fn get_user_details(
pool: &PgPool,
token: &str,
) -> Result<FlowyResponse, ServerError> {
let logged_user = LoggedUser::from_token(token.to_owned().into())?;
let mut transaction = pool
.begin()
.await
.context("Failed to acquire a Postgres connection to get user detail")?;
let user_table = read_user(&mut transaction, &logged_user.email).await?;
transaction
.commit()
.await
.context("Failed to commit SQL transaction to get user detail.")?;
// update the user active time
let _ = AUTHORIZED_USERS.store_auth(logged_user, true)?;
let mut user_detail = UserDetail::default();
user_detail.set_email(user_table.email);
user_detail.set_name(user_table.name);
user_detail.set_token(token.to_owned());
FlowyResponse::success().pb(user_detail)
}
2021-08-23 18:39:10 +08:00
async fn is_email_exist(
2021-08-26 17:58:59 +08:00
transaction: &mut DBTransaction<'_>,
2021-08-23 18:39:10 +08:00
email: &str,
) -> Result<(), ServerError> {
let result = sqlx::query(r#"SELECT email FROM user_table WHERE email = $1"#)
.bind(email)
.fetch_optional(transaction)
.await
2021-08-23 23:02:42 +08:00
.map_err(|err| ServerError::internal().context(err))?;
2021-08-23 18:39:10 +08:00
match result {
Some(_) => Err(ServerError {
2021-08-23 23:02:42 +08:00
code: ErrorCode::EmailAlreadyExists,
2021-08-23 18:39:10 +08:00
msg: format!("{} already exists", email),
}),
None => Ok(()),
}
}
async fn read_user(
2021-08-26 17:58:59 +08:00
transaction: &mut DBTransaction<'_>,
2021-08-23 18:39:10 +08:00
email: &str,
2021-08-24 21:38:53 +08:00
) -> Result<UserTable, ServerError> {
let user = sqlx::query_as::<Postgres, UserTable>("SELECT * FROM user_table WHERE email = $1")
2021-08-23 18:39:10 +08:00
.bind(email)
.fetch_one(transaction)
.await
2021-08-23 23:02:42 +08:00
.map_err(|err| ServerError::internal().context(err))?;
2021-08-23 18:39:10 +08:00
Ok(user)
}
2021-08-26 17:58:59 +08:00
async fn insert_new_user(
transaction: &mut DBTransaction<'_>,
2021-08-24 13:10:53 +08:00
name: &str,
email: &str,
password: &str,
2021-08-23 18:39:10 +08:00
) -> Result<SignUpResponse, ServerError> {
2021-08-31 17:56:38 +08:00
let token = Token::create_token(email)?;
2021-08-23 18:39:10 +08:00
let uuid = uuid::Uuid::new_v4();
2021-08-24 13:10:53 +08:00
let password = hash_password(password)?;
2021-08-23 18:39:10 +08:00
let _ = sqlx::query!(
r#"
INSERT INTO user_table (id, email, name, create_time, password)
VALUES ($1, $2, $3, $4, $5)
"#,
uuid,
2021-08-24 13:10:53 +08:00
email,
name,
2021-08-23 18:39:10 +08:00
Utc::now(),
password,
2021-08-23 18:39:10 +08:00
)
.execute(transaction)
.await
2021-08-23 23:02:42 +08:00
.map_err(|e| ServerError::internal().context(e))?;
2021-08-23 18:39:10 +08:00
2021-08-26 17:58:59 +08:00
let mut response = SignUpResponse::default();
response.set_uid(uuid.to_string());
response.set_name(name.to_string());
response.set_email(email.to_string());
2021-08-31 17:56:38 +08:00
response.set_token(token.into());
2021-08-23 18:39:10 +08:00
2021-08-26 17:58:59 +08:00
Ok(response)
2021-08-23 18:39:10 +08:00
}