tsk-56: API documentation #57
@@ -1,7 +1,7 @@
|
|||||||
pub mod response {
|
pub mod response {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
|
||||||
pub struct TestResult {
|
pub struct TestResult {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
@@ -11,11 +11,28 @@ pub mod endpoint {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use axum::{Extension, Json, http::StatusCode};
|
use axum::{Extension, Json, http::StatusCode};
|
||||||
|
|
||||||
// basic handler that responds with a static string
|
/// Endpoint to hit the root
|
||||||
|
/// basic handler that responds with a static string
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = super::super::endpoints::ROOT,
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Test", body = &str),
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn root() -> &'static str {
|
pub async fn root() -> &'static str {
|
||||||
"Hello, World!"
|
"Hello, World!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint to do a database ping
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = super::super::endpoints::DBTEST,
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Successful ping of the db", body = super::response::TestResult),
|
||||||
|
(status = 400, description = "Failure in pinging the db", body = super::response::TestResult)
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn db_ping(
|
pub async fn db_ping(
|
||||||
Extension(pool): Extension<sqlx::PgPool>,
|
Extension(pool): Extension<sqlx::PgPool>,
|
||||||
) -> (StatusCode, Json<response::TestResult>) {
|
) -> (StatusCode, Json<response::TestResult>) {
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
pub mod request {
|
pub mod request {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod service_login {
|
pub mod service_login {
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub passphrase: String,
|
pub passphrase: String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod refresh_token {
|
pub mod refresh_token {
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
pub access_token: String,
|
pub access_token: String,
|
||||||
}
|
}
|
||||||
@@ -25,14 +25,14 @@ pub mod request {
|
|||||||
pub mod response {
|
pub mod response {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
|
||||||
pub struct Response {
|
pub struct 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 {
|
pub mod service_login {
|
||||||
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub data: Vec<icarus_models::login_result::LoginResult>,
|
pub data: Vec<icarus_models::login_result::LoginResult>,
|
||||||
@@ -40,7 +40,7 @@ pub mod response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod refresh_token {
|
pub mod refresh_token {
|
||||||
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, utoipa::ToSchema)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub data: Vec<icarus_models::login_result::LoginResult>,
|
pub data: Vec<icarus_models::login_result::LoginResult>,
|
||||||
@@ -48,6 +48,7 @@ pub mod response {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Module for login endpoints
|
||||||
pub mod endpoint {
|
pub mod endpoint {
|
||||||
use axum::{Json, http::StatusCode};
|
use axum::{Json, http::StatusCode};
|
||||||
|
|
||||||
@@ -72,6 +73,20 @@ pub mod endpoint {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint to login
|
||||||
|
#[utoipa::path(
|
||||||
|
post,
|
||||||
|
path = super::super::endpoints::LOGIN,
|
||||||
|
request_body(
|
||||||
|
content = request::Request,
|
||||||
|
description = "Data required to login",
|
||||||
|
content_type = "application/json"
|
||||||
|
),
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Successfully logged in", body = response::Response),
|
||||||
|
(status = 404, description = "Could not login with credentials", body = response::Response)
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn login(
|
pub async fn login(
|
||||||
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
||||||
Json(payload): Json<request::Request>,
|
Json(payload): Json<request::Request>,
|
||||||
@@ -115,6 +130,20 @@ pub mod endpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint to login as a service user
|
||||||
|
#[utoipa::path(
|
||||||
|
post,
|
||||||
|
path = super::super::endpoints::SERVICE_LOGIN,
|
||||||
|
request_body(
|
||||||
|
content = request::service_login::Request,
|
||||||
|
description = "Data required to login as a service user",
|
||||||
|
content_type = "application/json"
|
||||||
|
),
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Login successful", body = response::Response),
|
||||||
|
(status = 400, description = "Error logging in with credentials", body = response::Response)
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn service_login(
|
pub async fn service_login(
|
||||||
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
||||||
axum::Json(payload): axum::Json<request::service_login::Request>,
|
axum::Json(payload): axum::Json<request::service_login::Request>,
|
||||||
@@ -154,6 +183,22 @@ pub mod endpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint to retrieve a refresh token
|
||||||
|
#[utoipa::path(
|
||||||
|
post,
|
||||||
|
path = super::super::endpoints::REFRESH_TOKEN,
|
||||||
|
request_body(
|
||||||
|
content = request::refresh_token::Request,
|
||||||
|
description = "Data required to retrieve a refresh token",
|
||||||
|
content_type = "application/json"
|
||||||
|
),
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Refresh token generated", body = response::Response),
|
||||||
|
(status = 400, description = "Error verifying token", body = response::Response),
|
||||||
|
(status = 404, description = "Could not validate token", body = response::Response),
|
||||||
|
(status = 500, description = "Error extracting token", body = response::Response)
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn refresh_token(
|
pub async fn refresh_token(
|
||||||
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
||||||
axum::Json(payload): axum::Json<request::refresh_token::Request>,
|
axum::Json(payload): axum::Json<request::refresh_token::Request>,
|
||||||
|
@@ -6,7 +6,7 @@ use crate::repo;
|
|||||||
pub mod request {
|
pub mod request {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize, utoipa::ToSchema)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
#[serde(skip_serializing_if = "String::is_empty")]
|
#[serde(skip_serializing_if = "String::is_empty")]
|
||||||
pub username: String,
|
pub username: String,
|
||||||
@@ -26,13 +26,28 @@ pub mod request {
|
|||||||
pub mod response {
|
pub mod response {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub data: Vec<icarus_models::user::User>,
|
pub data: Vec<icarus_models::user::User>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Endpoint to register a user
|
||||||
|
#[utoipa::path(
|
||||||
|
post,
|
||||||
|
path = super::endpoints::REGISTER,
|
||||||
|
request_body(
|
||||||
|
content = request::Request,
|
||||||
|
description = "Data required to register",
|
||||||
|
content_type = "application/json"
|
||||||
|
),
|
||||||
|
responses(
|
||||||
|
(status = 201, description = "User created", body = response::Response),
|
||||||
|
(status = 404, description = "User already exists", body = response::Response),
|
||||||
|
(status = 400, description = "Issue creating user", body = response::Response)
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub async fn register_user(
|
pub async fn register_user(
|
||||||
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
axum::Extension(pool): axum::Extension<sqlx::PgPool>,
|
||||||
Json(payload): Json<request::Request>,
|
Json(payload): Json<request::Request>,
|
||||||
|
31
src/main.rs
31
src/main.rs
@@ -19,8 +19,31 @@ mod init {
|
|||||||
Router,
|
Router,
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
};
|
};
|
||||||
|
use utoipa::OpenApi;
|
||||||
|
|
||||||
use crate::callers;
|
use crate::callers;
|
||||||
|
use callers::common as common_callers;
|
||||||
|
use callers::login as login_caller;
|
||||||
|
use callers::register as register_caller;
|
||||||
|
use login_caller::endpoint as login_endpoints;
|
||||||
|
use login_caller::response as login_responses;
|
||||||
|
use register_caller::response as register_responses;
|
||||||
|
|
||||||
|
#[derive(utoipa::OpenApi)]
|
||||||
|
#[openapi(
|
||||||
|
paths(
|
||||||
|
common_callers::endpoint::db_ping, common_callers::endpoint::root,
|
||||||
|
register_caller::register_user,
|
||||||
|
login_endpoints::login, login_endpoints::service_login, login_endpoints::refresh_token
|
||||||
|
),
|
||||||
|
components(schemas(common_callers::response::TestResult,
|
||||||
|
register_responses::Response,
|
||||||
|
login_responses::Response, login_responses::service_login::Response, login_responses::refresh_token::Response)),
|
||||||
|
tags(
|
||||||
|
(name = "Icarus Auth API", description = "Auth API for Icarus API")
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
struct ApiDoc;
|
||||||
|
|
||||||
pub async fn routes() -> Router {
|
pub async fn routes() -> Router {
|
||||||
// build our application with a route
|
// build our application with a route
|
||||||
@@ -58,7 +81,13 @@ mod init {
|
|||||||
|
|
||||||
icarus_auth::db::migrations(&pool).await;
|
icarus_auth::db::migrations(&pool).await;
|
||||||
|
|
||||||
routes().await.layer(axum::Extension(pool))
|
routes()
|
||||||
|
.await
|
||||||
|
.merge(
|
||||||
|
utoipa_swagger_ui::SwaggerUi::new("/swagger-ui")
|
||||||
|
.url("/api-docs/openapi.json", ApiDoc::openapi()),
|
||||||
|
)
|
||||||
|
.layer(axum::Extension(pool))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user