debt-pirate/api/src/requests/auth/login/handler.rs

105 lines
2.8 KiB
Rust
Raw Normal View History

use std::time::SystemTime;
use axum::{
debug_handler,
2024-10-05 08:09:46 -04:00
extract::State,
response::{IntoResponse, Response},
2024-10-05 08:09:46 -04:00
Json,
};
use http::StatusCode;
use pasetors::{keys::SymmetricKey, version4::V4};
2024-10-05 08:09:46 -04:00
use tracing::debug;
2024-10-05 08:09:46 -04:00
use crate::{
db::{
get_username_and_password_by_username, insert_new_user_auth_token, DbPool,
NewUserAuthTokenEntity, UserIdAndHashedPasswordEntity,
},
models::{ApiResponse, AppError, Session},
requests::{
auth::login::models::{AuthLoginResponse, AuthLoginTokenData},
AppState,
},
services::{
auth_token::{generate_auth_token, generate_session_token},
user_session, verify_password, CachePool,
},
2024-10-05 08:09:46 -04:00
};
use super::models::AuthLoginRequest;
#[debug_handler]
2024-10-05 08:09:46 -04:00
pub async fn auth_login_post_handler(
State(state): State<AppState>,
Json(body): Json<AuthLoginRequest>,
) -> Result<Response, AppError> {
let db_pool = state.db_pool();
let cache_pool = state.cache_pool();
let token_key = state.env().token_key();
auth_login_request(db_pool, cache_pool, token_key, body).await
2024-10-05 08:09:46 -04:00
}
async fn auth_login_request(
db_pool: &DbPool,
cache_pool: &CachePool,
token_key: &SymmetricKey<V4>,
body: AuthLoginRequest,
) -> Result<Response, AppError> {
2024-10-05 08:09:46 -04:00
debug!(?body);
let AuthLoginRequest { username, password } = body;
let UserIdAndHashedPasswordEntity {
id: user_id,
2024-10-05 08:09:46 -04:00
password: hashed_password,
} = get_username_and_password_by_username(db_pool, username).await?;
2024-10-05 08:09:46 -04:00
verify_password(password, hashed_password)?;
let (session_token, session_token_id, session_token_expiration) =
generate_session_token(token_key, user_id);
let (auth_token, auth_token_id, auth_token_expiration) =
generate_auth_token(token_key, user_id);
insert_new_user_auth_token(
db_pool,
NewUserAuthTokenEntity {
user_id,
token_hash: blake3::hash(auth_token_id.as_bytes()),
expires_at: auth_token_expiration,
},
)
.await?;
let session = Session {
user_id,
created_at: SystemTime::now(),
expires_at: auth_token_expiration,
};
let expiration = session_token_expiration
.duration_since(SystemTime::now())
.unwrap();
user_session::store_user_session(cache_pool, session_token_id, session, Some(expiration))
.await?;
let response = AuthLoginResponse {
user_id,
session: AuthLoginTokenData {
token: session_token,
expiration: session_token_expiration,
},
auth: AuthLoginTokenData {
token: auth_token,
expiration: auth_token_expiration,
},
};
Ok((
StatusCode::OK,
ApiResponse::new(response).into_json_response(),
)
.into_response())
}