tsk-50: Added service login endpoint

This commit is contained in:
2025-08-02 16:21:02 -04:00
parent c31743eed1
commit 3aa75b16b6
3 changed files with 83 additions and 0 deletions

View File

@@ -6,6 +6,13 @@ pub mod request {
pub username: String,
pub password: String,
}
pub mod service_login {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct Request {
pub passphrase: String,
}
}
}
pub mod response {
@@ -16,6 +23,14 @@ pub mod response {
pub message: String,
pub data: Vec<icarus_models::login_result::LoginResult>,
}
pub mod service_login {
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
pub struct Response {
pub message: String,
pub data: Vec<icarus_models::login_result::LoginResult>,
}
}
}
pub mod endpoint {
@@ -79,4 +94,37 @@ pub mod endpoint {
}
}
}
pub async fn service_login(axum::Extension(pool): axum::Extension<sqlx::PgPool>, axum::Json(payload): axum::Json<request::service_login::Request>)
-> (axum::http::StatusCode, axum::Json<response::service_login::Response>) {
let mut response = response::service_login::Response::default();
match repo::service::valid_passphrase(&pool, &payload.passphrase).await {
Ok((id, _passphrase, _date_created)) => {
let key = icarus_envy::environment::get_secret_key().await;
let (token_literal, duration) = token_stuff::create_service_token(&key).unwrap();
if token_stuff::verify_token(&key, &token_literal) {
let login_result = icarus_models::login_result::LoginResult {
id: id,
username: String::from("service"),
token: token_literal,
token_type: String::from(icarus_models::token::TOKEN_TYPE),
expiration: duration,
};
response.data.push(login_result);
response.message = String::from("Successful");
(axum::http::StatusCode::OK, axum::Json(response))
} else {
(axum::http::StatusCode::OK, axum::Json(response))
}
}
Err(err) => {
response.message = err.to_string();
(axum::http::StatusCode::BAD_REQUEST, axum::Json(response))
}
}
}
}

View File

@@ -195,3 +195,29 @@ pub mod salt {
}
}
}
pub mod service {
use sqlx::Row;
pub async fn valid_passphrase(pool: &sqlx::PgPool, passphrase: &String) -> Result<(uuid::Uuid, String, time::OffsetDateTime), sqlx::Error> {
let result = sqlx::query(
r#"
SELECT * FROM "passphrase" WHERE passphrase = $1
"#
)
.bind(passphrase)
.fetch_one(pool)
.await;
match result {
Ok(row) => {
let id: uuid::Uuid = row.try_get("id")?;
let passphrase: String = row.try_get("passphrase")?;
let date_created: Option<time::OffsetDateTime> = row.try_get("date_created")?;
Ok((id, passphrase, date_created.unwrap()))
}
Err(err) => Err(err)
}
}
}

View File

@@ -29,6 +29,15 @@ pub fn create_token(provided_key: &String) -> Result<(String, i64), josekit::Jos
icarus_models::token::create_token(provided_key, &resource, time::Duration::hours(4))
}
pub fn create_service_token(provided: &String) -> Result<(String, i64), josekit::JoseError> {
let resource = icarus_models::token::TokenResource {
message: String::from("Service random"),
issuer: String::from(ISSUER),
audiences: vec![String::from(AUDIENCE)],
};
icarus_models::token::create_token(provided, &resource, time::Duration::hours(1))
}
pub fn verify_token(key: &String, token: &String) -> bool {
let ver = Hs256.verifier_from_bytes(key.as_bytes()).unwrap();
let (payload, _header) = jwt::decode_with_verifier(token, &ver).unwrap();