tsk-50: Create Special endpoint for services to obtain a token #53
@@ -6,6 +6,13 @@ pub mod request {
|
|||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod service_login {
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct Request {
|
||||||
|
pub passphrase: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod response {
|
pub mod response {
|
||||||
@@ -16,6 +23,14 @@ pub mod response {
|
|||||||
pub message: String,
|
pub message: String,
|
||||||
pub data: Vec<icarus_models::login_result::LoginResult>,
|
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 {
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -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))
|
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 {
|
pub fn verify_token(key: &String, token: &String) -> bool {
|
||||||
let ver = Hs256.verifier_from_bytes(key.as_bytes()).unwrap();
|
let ver = Hs256.verifier_from_bytes(key.as_bytes()).unwrap();
|
||||||
let (payload, _header) = jwt::decode_with_verifier(token, &ver).unwrap();
|
let (payload, _header) = jwt::decode_with_verifier(token, &ver).unwrap();
|
||||||
|
Reference in New Issue
Block a user