update user

This commit is contained in:
jb-alvarado 2022-06-10 16:12:30 +02:00
parent e59b356128
commit dc50f621e0
5 changed files with 53 additions and 13 deletions

View File

@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::api::utils::GlobalSettings;
// Token lifetime and Secret key are hardcoded for clarity
const JWT_EXPIRATION_MINUTES: i64 = 15;
const JWT_EXPIRATION_MINUTES: i64 = 60;
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Claims {

View File

@ -109,7 +109,7 @@ pub async fn db_connection() -> Result<Pool<Sqlite>, sqlx::Error> {
Ok(conn)
}
pub async fn get_global() -> Result<GlobalSettings, sqlx::Error> {
pub async fn db_global() -> Result<GlobalSettings, sqlx::Error> {
let conn = db_connection().await?;
let query = "SELECT secret FROM global WHERE id = 1";
let result: GlobalSettings = sqlx::query_as(query).fetch_one(&conn).await?;
@ -118,7 +118,7 @@ pub async fn get_global() -> Result<GlobalSettings, sqlx::Error> {
Ok(result)
}
pub async fn get_role(id: &i64) -> Result<String, sqlx::Error> {
pub async fn db_role(id: &i64) -> Result<String, sqlx::Error> {
let conn = db_connection().await?;
let query = "SELECT name FROM roles WHERE id = $1";
let result: Role = sqlx::query_as(query).bind(id).fetch_one(&conn).await?;
@ -150,7 +150,7 @@ pub async fn add_user(
Ok(result)
}
pub async fn get_login(user: &str) -> Result<User, sqlx::Error> {
pub async fn db_login(user: &str) -> Result<User, sqlx::Error> {
let conn = db_connection().await?;
let query = "SELECT id, email, username, password, salt, role_id FROM user WHERE username = $1";
let result: User = sqlx::query_as(query).bind(user).fetch_one(&conn).await?;
@ -158,3 +158,12 @@ pub async fn get_login(user: &str) -> Result<User, sqlx::Error> {
Ok(result)
}
pub async fn db_update_user(id: i64, fields: String) -> Result<SqliteQueryResult, sqlx::Error> {
let conn = db_connection().await?;
let query = format!("UPDATE user SET {fields} WHERE id = $1");
let result: SqliteQueryResult = sqlx::query(&query).bind(id).execute(&conn).await?;
conn.close().await;
Ok(result)
}

View File

@ -9,7 +9,7 @@ pub struct User {
pub email: Option<String>,
pub username: String,
#[sqlx(default)]
#[serde(skip_serializing)]
#[serde(skip_serializing, default = "empty_string")]
pub password: String,
#[sqlx(default)]
#[serde(skip_serializing)]
@ -21,6 +21,10 @@ pub struct User {
pub token: Option<String>,
}
fn empty_string() -> String {
"".to_string()
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct LoginUser {
pub id: i64,

View File

@ -1,13 +1,16 @@
use actix_web::{get, http::StatusCode, post, put, web, Responder};
use actix_web_grants::proc_macro::has_permissions;
use argon2::{password_hash::PasswordHash, Argon2, PasswordVerifier};
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, SaltString},
Argon2, PasswordHasher, PasswordVerifier,
};
use serde::Serialize;
use simplelog::*;
use crate::api::{
auth::{create_jwt, Claims},
errors::ServiceError,
handles::{get_login, get_role},
handles::{db_login, db_role, db_update_user},
models::{LoginUser, User},
};
@ -34,8 +37,32 @@ async fn update_user(
data: web::Json<User>,
) -> Result<impl Responder, ServiceError> {
if user_id.into_inner() == user.id {
println!("{data:?}");
return Ok("Update allow!");
let mut fields = String::new();
if let Some(email) = data.email.clone() {
fields.push_str(format!("email = '{email}'").as_str());
}
if !data.password.is_empty() {
if !fields.is_empty() {
fields.push_str(", ");
}
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
let password_hash = argon2
.hash_password(data.password.clone().as_bytes(), &salt)
.unwrap();
fields.push_str(format!("password = '{}', salt = '{salt}'", password_hash).as_str());
}
if db_update_user(user.id, fields).await.is_ok() {
return Ok("Update Success");
};
return Err(ServiceError::InternalServerError);
}
Err(ServiceError::Unauthorized)
@ -45,7 +72,7 @@ async fn update_user(
/// http://127.0.0.1:8080/auth/login/
#[post("/auth/login/")]
pub async fn login(credentials: web::Json<User>) -> impl Responder {
match get_login(&credentials.username).await {
match db_login(&credentials.username).await {
Ok(mut user) => {
let pass = user.password.clone();
user.password = "".into();
@ -56,7 +83,7 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
.verify_password(credentials.password.as_bytes(), &hash)
.is_ok()
{
let role = get_role(&user.role_id.unwrap_or_default())
let role = db_role(&user.role_id.unwrap_or_default())
.await
.unwrap_or_else(|_| "guest".to_string());
let claims = Claims::new(user.id, user.username.clone(), vec![role.clone()]);

View File

@ -7,7 +7,7 @@ use simplelog::*;
use crate::api::{
args_parse::Args,
handles::{add_user, db_init, get_global},
handles::{add_user, db_global, db_init},
};
#[derive(Debug, sqlx::FromRow)]
@ -17,7 +17,7 @@ pub struct GlobalSettings {
impl GlobalSettings {
async fn new() -> Self {
let global_settings = get_global();
let global_settings = db_global();
match global_settings.await {
Ok(g) => g,