2020-06-29 15:53:39 +02:00
|
|
|
use crate::constants::database_tables_names::{USER_ACCESS_TOKENS_TABLE, USERS_TABLE};
|
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;
|
|
|
|
use crate::helpers::{database, user_helper};
|
2020-06-26 08:58:00 +02:00
|
|
|
use crate::helpers::database::{DeleteQuery, InsertQuery, QueryInfo};
|
2020-05-24 16:35:54 +02:00
|
|
|
use crate::utils::crypt_utils::{crypt_pass, rand_str};
|
2020-06-29 15:53:39 +02:00
|
|
|
use crate::utils::date_utils::time;
|
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
|
2020-06-25 10:08:34 +02:00
|
|
|
if let Ok(token) = get_client_tokens(&user.id, client) {
|
2020-05-24 16:35:54 +02:00
|
|
|
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 {
|
2020-06-25 10:08:34 +02:00
|
|
|
user_id: user.id.clone(),
|
2020-05-24 16:35:54 +02:00
|
|
|
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)
|
2020-06-25 10:08:34 +02:00
|
|
|
.add_user_id("user_id", &new_token.user_id)
|
2020-05-24 16:35:54 +02:00
|
|
|
.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
|
2020-06-25 10:08:34 +02:00
|
|
|
fn get_client_tokens(user_id: &UserID, client: &APIClient) -> ResultBoxError<UserAccessToken> {
|
2020-05-24 16:35:54 +02:00
|
|
|
database::query_row(
|
|
|
|
QueryInfo::new(USER_ACCESS_TOKENS_TABLE)
|
2020-06-25 10:08:34 +02:00
|
|
|
.cond_user_id("user_id", user_id)
|
2020-05-24 16:39:48 +02:00
|
|
|
.cond_u32("service_id", client.id),
|
2020-05-24 16:35:54 +02:00
|
|
|
|res| {
|
|
|
|
Ok(UserAccessToken {
|
2020-06-25 10:08:34 +02:00
|
|
|
user_id: res.get_user_id("user_id")?,
|
2020-05-24 16:35:54 +02:00
|
|
|
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-06-25 10:08:34 +02:00
|
|
|
|res| res.get_user_id("user_id"),
|
2020-05-24 17:57:47 +02:00
|
|
|
)
|
2020-05-24 19:19:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Destroy a given user login tokens
|
2020-06-25 10:08:34 +02:00
|
|
|
pub fn destroy_login_tokens(id: &UserID, client: &APIClient) -> ResultBoxError<()> {
|
2020-05-24 19:19:07 +02:00
|
|
|
database::delete(DeleteQuery::new(USER_ACCESS_TOKENS_TABLE)
|
|
|
|
.cond_u32("service_id", client.id)
|
2020-06-25 10:08:34 +02:00
|
|
|
.cond_user_id("user_id", id)
|
2020-05-24 19:19:07 +02:00
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(())
|
2020-06-26 08:58:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check out whether a virtual directory is taken by a user or not
|
|
|
|
pub fn check_user_directory_availability(dir: &str, user_id: Option<UserID>) -> ResultBoxError<bool> {
|
|
|
|
let found_user = user_helper::find_user_by_virtual_directory(dir);
|
|
|
|
|
|
|
|
match (found_user, user_id) {
|
|
|
|
|
|
|
|
// A user was found, but we did not specify a user
|
|
|
|
(Ok(_), None) => Ok(false),
|
|
|
|
|
|
|
|
// A user was found, and we specified a user ID, we check if the IDs are the same
|
|
|
|
(Ok(user), Some(id)) => Ok(user.id == id),
|
|
|
|
|
|
|
|
// No user was found, virtual directory is considered as available
|
|
|
|
(Err(_), _) => Ok(true)
|
|
|
|
}
|
2020-06-29 15:53:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Update the last activity of a user
|
|
|
|
pub fn update_last_activity(user_id: &UserID) -> ResultBoxError {
|
|
|
|
database::UpdateInfo::new(USERS_TABLE)
|
|
|
|
.cond_user_id("ID", user_id)
|
|
|
|
.set_u64("last_activity", time())
|
|
|
|
.exec()
|
2020-05-23 19:17:48 +02:00
|
|
|
}
|