mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 13:29:21 +00:00
Can login user
This commit is contained in:
parent
6f6cd550ea
commit
f0cf3202f4
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -514,6 +514,7 @@ dependencies = [
|
||||
"mailchecker",
|
||||
"mysql",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"serde",
|
||||
"sha1",
|
||||
"yaml-rust",
|
||||
|
@ -17,3 +17,4 @@ encoding_rs = "0.8.23"
|
||||
percent-encoding = "2.1.0"
|
||||
mailchecker = "3.3.6"
|
||||
sha1 = "0.6.0"
|
||||
rand = "0.7.3"
|
@ -5,3 +5,4 @@ pub mod http_request_handler;
|
||||
pub mod api_client;
|
||||
|
||||
pub mod user;
|
||||
pub mod user_token;
|
@ -1,9 +1,12 @@
|
||||
/// User information
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
///! User information
|
||||
///!
|
||||
///! @author Pierre Hubert
|
||||
|
||||
pub type UserID = i64;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct User {
|
||||
pub id: i64,
|
||||
pub id: UserID,
|
||||
pub email: String,
|
||||
pub password: String,
|
||||
pub first_name: String,
|
||||
|
11
src/data/user_token.rs
Normal file
11
src/data/user_token.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::data::user::UserID;
|
||||
|
||||
/// User access token information
|
||||
///
|
||||
/// Author : Pierre Hubert
|
||||
#[derive(Debug)]
|
||||
pub struct UserAccessToken {
|
||||
pub user_id: UserID,
|
||||
pub client_id: u32,
|
||||
pub token: String
|
||||
}
|
@ -5,5 +5,8 @@
|
||||
/// API services tokens table
|
||||
pub const SERVICES_TABLES : &str = "comunic_api_services_tokens";
|
||||
|
||||
/// User access tokens table
|
||||
pub const USER_ACCESS_TOKENS_TABLE: &str = "comunic_api_users_tokens";
|
||||
|
||||
/// User table
|
||||
pub const USERS_TABLE : &str = "utilisateurs";
|
@ -1,6 +1,11 @@
|
||||
use crate::data::api_client::APIClient;
|
||||
use crate::data::error::ResultBoxError;
|
||||
use crate::helpers::user_helper;
|
||||
use crate::data::error::{ExecError, ResultBoxError};
|
||||
use crate::data::user::UserID;
|
||||
use crate::data::user_token::UserAccessToken;
|
||||
use crate::database_structure::USER_ACCESS_TOKENS_TABLE;
|
||||
use crate::helpers::{database, user_helper};
|
||||
use crate::helpers::database::{QueryInfo, InsertQuery};
|
||||
use crate::utils::crypt_utils::{crypt_pass, rand_str};
|
||||
|
||||
/// Account helper
|
||||
///
|
||||
@ -13,9 +18,49 @@ use crate::helpers::user_helper;
|
||||
pub fn login_user(email: &str, password: &str, client: &APIClient) -> ResultBoxError<String> {
|
||||
let user = user_helper::find_user_by_email(email)?;
|
||||
|
||||
// TODO : check user password
|
||||
// Validate user password
|
||||
let password = crypt_pass(password)?;
|
||||
if !user.password.eq(&password) {
|
||||
return Err(ExecError::boxed_new("The user gave an invalid password!"));
|
||||
}
|
||||
|
||||
println!("{:#?}", user);
|
||||
// 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);
|
||||
}
|
||||
|
||||
Ok("d".to_string())
|
||||
|
||||
// Create new login tokens
|
||||
let new_token = UserAccessToken {
|
||||
user_id: user.id,
|
||||
client_id: client.id,
|
||||
token: rand_str(150)
|
||||
};
|
||||
|
||||
// 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)
|
||||
.cond("user_id", user_id.to_string().as_ref())
|
||||
.cond("service_id", client.id.to_string().as_ref()),
|
||||
|res| {
|
||||
Ok(UserAccessToken {
|
||||
user_id: res.get_int64("user_id")?,
|
||||
client_id: res.get_int64("service_id")? as u32,
|
||||
token: res.get_str("token1")?,
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
@ -8,6 +8,7 @@ use mysql::prelude::Queryable;
|
||||
|
||||
use crate::data::config::DatabaseConfig;
|
||||
use crate::data::error::{ExecError, ResultBoxError};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Database access helper
|
||||
///
|
||||
@ -225,3 +226,61 @@ pub fn query<E, F: Fn(&RowResult) -> ProcessRowResult<E>>(info: QueryInfo, proce
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Structure used to execute a insert query
|
||||
pub struct InsertQuery {
|
||||
pub table : String,
|
||||
pub values: HashMap<String, mysql::Value>,
|
||||
}
|
||||
|
||||
impl InsertQuery {
|
||||
|
||||
/// Construct a new InsertQuery instance
|
||||
pub fn new(table: &str) -> InsertQuery {
|
||||
InsertQuery {
|
||||
table: table.to_string(),
|
||||
values: HashMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a string
|
||||
pub fn add_str(mut self, key: &str, value: &str) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value));
|
||||
self
|
||||
}
|
||||
|
||||
/// Add an integer
|
||||
pub fn add_i64(mut self, key: &str, value: i64) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_u32(mut self, key: &str, value: u32) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Insert a new entry into the database
|
||||
pub fn insert(query: InsertQuery) -> ResultBoxError<()> {
|
||||
|
||||
// Collect keys
|
||||
let keys = query.values
|
||||
.keys()
|
||||
.map(|f|f.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let query_sql = format!(
|
||||
"INSERT INTO {} ({}) VALUES({})",
|
||||
query.table,
|
||||
keys.join(", "),
|
||||
keys.iter().map(|_| "?").collect::<Vec<&str>>().join(", ")
|
||||
);
|
||||
|
||||
get_connection()?.exec_drop(
|
||||
query_sql,
|
||||
query.values.values().collect::<Vec<&mysql::Value>>()
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -5,6 +5,8 @@
|
||||
extern crate sha1;
|
||||
|
||||
use crate::data::error::{ResultBoxError, ExecError};
|
||||
use rand::{thread_rng, Rng};
|
||||
use rand::distributions::Alphanumeric;
|
||||
|
||||
/// Generate a new sha1 string
|
||||
///
|
||||
@ -45,3 +47,19 @@ pub fn crypt_pass(pass: &str) -> ResultBoxError<String> {
|
||||
|
||||
Ok(String::from_utf8(result.stdout)?)
|
||||
}
|
||||
|
||||
/// Generate a random string of a given size
|
||||
///
|
||||
/// ```
|
||||
/// use comunic_server::utils::crypt_utils::rand_str;
|
||||
///
|
||||
/// let size = 10;
|
||||
/// let rand = rand_str(size);
|
||||
/// assert_eq!(size, rand.len());
|
||||
/// ```
|
||||
pub fn rand_str(len: usize) -> String {
|
||||
thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(len)
|
||||
.collect()
|
||||
}
|
Loading…
Reference in New Issue
Block a user