diff --git a/src/callers/login.rs b/src/callers/login.rs index 9476df5..92b2ad8 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -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, } + + pub mod service_login { + #[derive(Debug, Default, serde::Deserialize, serde::Serialize)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } } pub mod endpoint { @@ -79,4 +94,37 @@ pub mod endpoint { } } } + + pub async fn service_login(axum::Extension(pool): axum::Extension, axum::Json(payload): axum::Json) + -> (axum::http::StatusCode, axum::Json) { + 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)) + } + } + } } diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 52e9e3c..e35b4ea 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -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 = row.try_get("date_created")?; + + Ok((id, passphrase, date_created.unwrap())) + } + Err(err) => Err(err) + } + } +} diff --git a/src/token_stuff/mod.rs b/src/token_stuff/mod.rs index ea2f412..241216a 100644 --- a/src/token_stuff/mod.rs +++ b/src/token_stuff/mod.rs @@ -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();