2020-05-23 19:17:48 +02:00
|
|
|
use crate::data::api_client::APIClient;
|
2020-05-24 16:35:54 +02:00
|
|
|
use crate::data::error::{ExecError, ResultBoxError};
|
|
|
|
use crate::data::user::UserID;
|
|
|
|
use crate::data::user_token::UserAccessToken;
|
2020-05-26 17:51:11 +02:00
|
|
|
use crate::constants::database_tables_names::USER_ACCESS_TOKENS_TABLE;
|
2020-05-24 16:35:54 +02:00
|
|
|
use crate::helpers::{database, user_helper};
|
2020-05-24 19:19:07 +02:00
|
|
|
use crate::helpers::database::{QueryInfo, InsertQuery, DeleteQuery};
|
2020-05-24 16:35:54 +02:00
|
|
|
use crate::utils::crypt_utils::{crypt_pass, rand_str};
|
2020-05-23 19:17:48 +02:00
|
|
|
|
|
|
|
/// Account helper
|
|
|
|
///
|
|
|
|
/// @author Pierre Hubert
|
|
|
|
|
|
|
|
/// Attempt to sign-in user
|
|
|
|
///
|
|
|
|
/// In this version of the api, we consider that there is only one login token required
|
|
|
|
/// This is why I returns just a simple string, the token created for the user in case of success
|
|
|
|
pub fn login_user(email: &str, password: &str, client: &APIClient) -> ResultBoxError<String> {
|
|
|
|
let user = user_helper::find_user_by_email(email)?;
|
|
|
|
|
2020-05-24 16:35:54 +02:00
|
|
|
// Validate user password
|
|
|
|
let password = crypt_pass(password)?;
|
|
|
|
if !user.password.eq(&password) {
|
|
|
|
return Err(ExecError::boxed_new("The user gave an invalid password!"));
|
|
|
|
}
|
2020-05-23 19:17:48 +02:00
|
|
|
|
2020-05-24 16:35:54 +02:00
|
|
|
// Check if we already have a login token for this user
|
|
|
|
if let Ok(token) = get_client_tokens(user.id, client) {
|
|
|
|
return Ok(token.token);
|
|
|
|
}
|
2020-05-23 19:17:48 +02:00
|
|
|
|
2020-05-24 16:35:54 +02:00
|
|
|
|
|
|
|
// Create new login tokens
|
|
|
|
let new_token = UserAccessToken {
|
|
|
|
user_id: user.id,
|
|
|
|
client_id: client.id,
|
2020-05-24 17:57:47 +02:00
|
|
|
token: rand_str(150),
|
2020-05-24 16:35:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Save it
|
|
|
|
database::insert(
|
|
|
|
InsertQuery::new(USER_ACCESS_TOKENS_TABLE)
|
|
|
|
.add_i64("user_id", new_token.user_id)
|
|
|
|
.add_u32("service_id", client.id)
|
|
|
|
.add_str("token1", &new_token.token)
|
|
|
|
.add_str("token2", "dummy_data")
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(new_token.token)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get user login tokens
|
|
|
|
fn get_client_tokens(user_id: UserID, client: &APIClient) -> ResultBoxError<UserAccessToken> {
|
|
|
|
database::query_row(
|
|
|
|
QueryInfo::new(USER_ACCESS_TOKENS_TABLE)
|
2020-05-24 16:39:48 +02:00
|
|
|
.cond_i64("user_id", user_id)
|
|
|
|
.cond_u32("service_id", client.id),
|
2020-05-24 16:35:54 +02:00
|
|
|
|res| {
|
|
|
|
Ok(UserAccessToken {
|
|
|
|
user_id: res.get_int64("user_id")?,
|
|
|
|
client_id: res.get_int64("service_id")? as u32,
|
|
|
|
token: res.get_str("token1")?,
|
|
|
|
})
|
|
|
|
},
|
|
|
|
)
|
2020-05-24 17:57:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Find a user ID based on login token
|
|
|
|
pub fn get_user_by_login_token(token: &str, client: &APIClient) -> ResultBoxError<UserID> {
|
|
|
|
database::query_row(
|
|
|
|
QueryInfo::new(USER_ACCESS_TOKENS_TABLE)
|
|
|
|
.cond_u32("service_id", client.id)
|
2020-05-24 18:02:19 +02:00
|
|
|
.cond("token1", token)
|
|
|
|
.add_field("user_id"),
|
2020-05-24 17:57:47 +02:00
|
|
|
|res| res.get_int64("user_id"),
|
|
|
|
)
|
2020-05-24 19:19:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Destroy a given user login tokens
|
|
|
|
pub fn destroy_login_tokens(id: UserID, client: &APIClient) -> ResultBoxError<()> {
|
|
|
|
|
|
|
|
database::delete(DeleteQuery::new(USER_ACCESS_TOKENS_TABLE)
|
|
|
|
.cond_u32("service_id", client.id)
|
|
|
|
.cond_i64("user_id", id)
|
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(())
|
2020-05-23 19:17:48 +02:00
|
|
|
}
|