Docs authorization for protected routes
This commit is contained in:
parent
bc3469fa88
commit
2673f48ade
3
TODO.md
3
TODO.md
@ -4,7 +4,8 @@ Tasks that have been completed in commits before this one have been omitted from
|
||||
|
||||
- [x] /video PUT route
|
||||
- [x] /channel PUT route
|
||||
- [x] OpenAPI documentation
|
||||
- [x] OpenAPI docs
|
||||
- [x] Add authorization for protected routes in API docs
|
||||
|
||||
## Planned features
|
||||
|
||||
|
24
src/doc.rs
24
src/doc.rs
@ -1,4 +1,10 @@
|
||||
use utoipa::OpenApi;
|
||||
use utoipa::{
|
||||
Modify, OpenApi,
|
||||
openapi::{
|
||||
Components,
|
||||
security::{ApiKey, ApiKeyValue, SecurityScheme},
|
||||
},
|
||||
};
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
// Because apparently the OpenApi macro can't import these on its own
|
||||
@ -36,10 +42,24 @@ use crate::routes::{
|
||||
info(
|
||||
title = "Almond API",
|
||||
description = "Interface to archive YouTube videos."
|
||||
)
|
||||
),
|
||||
modifiers(&SecurityAddon),
|
||||
)]
|
||||
struct ApiDoc;
|
||||
|
||||
struct SecurityAddon;
|
||||
|
||||
impl Modify for SecurityAddon {
|
||||
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
|
||||
let components = openapi.components.get_or_insert_with(Components::default);
|
||||
|
||||
components.add_security_scheme(
|
||||
"authKey",
|
||||
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description("almond-api-key", "The API key/password that must be sent at the request header for protected routes."))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn docs_router() -> SwaggerUi {
|
||||
SwaggerUi::new("/docs").url("/api-doc/openapi.json", ApiDoc::openapi())
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ pub struct UploadChannelQuery {
|
||||
}
|
||||
|
||||
/// Upload a channel's metadata to the database
|
||||
#[utoipa::path(post, path = "/channel", request_body = UploadChannelQuery, params(("url" = String, Query), ("almond-api-key" = String, description = "API key")), tags = ["channel"], responses((status = 200, description = "Channel already exists, skipping"), (status = 201, description = "Channel uploaded successfully"), (status = 400, description = "Bad request, likely a malformed URL"), (status = 401, description = "Unauthorized"), (status = 500, description = "Failed to upload channel to database")))]
|
||||
#[utoipa::path(post, path = "/channel", request_body = UploadChannelQuery, params(("url" = String, Query)), tags = ["channel"], responses((status = 200, description = "Channel already exists, skipping"), (status = 201, description = "Channel uploaded successfully"), (status = 400, description = "Bad request, likely a malformed URL"), (status = 401, description = "Unauthorized"), (status = 500, description = "Failed to upload channel to database")), security(("authKey" = [])))]
|
||||
pub async fn upload_channel(
|
||||
State(state): State<Instance>,
|
||||
Query(query): Query<UploadChannelQuery>,
|
||||
@ -177,7 +177,7 @@ pub async fn upload_channel(
|
||||
}
|
||||
|
||||
/// Update an existing channel from the database
|
||||
#[utoipa::path(put, path = "/channel/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["channel"], responses((status = 204, description = "Channel updated successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to update channel from database")))]
|
||||
#[utoipa::path(put, path = "/channel/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["channel"], responses((status = 204, description = "Channel updated successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to update channel from database")), security(("authKey" = [])))]
|
||||
pub async fn update_channel(State(state): State<Instance>, Path(id): Path<String>) -> StatusCode {
|
||||
match sqlx::query_as!(Channel, "SELECT * FROM channel WHERE youtube_id = ?", id)
|
||||
.fetch_optional(&state.pool)
|
||||
@ -222,7 +222,7 @@ pub async fn update_channel(State(state): State<Instance>, Path(id): Path<String
|
||||
}
|
||||
|
||||
/// Delete a channel from the database
|
||||
#[utoipa::path(delete, path = "/channel/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["channel"], responses((status = 204, description = "Channel deleted successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to delete channel from database")))]
|
||||
#[utoipa::path(delete, path = "/channel/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["channel"], responses((status = 204, description = "Channel deleted successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to delete channel from database")), security(("authKey" = [])))]
|
||||
pub async fn delete_channel(State(state): State<Instance>, Path(id): Path<String>) -> StatusCode {
|
||||
match sqlx::query!("DELETE FROM channel WHERE youtube_id = ?", id)
|
||||
.fetch_optional(&state.pool)
|
||||
|
@ -85,7 +85,7 @@ pub struct UploadVideoQuery {
|
||||
}
|
||||
|
||||
/// Upload a video to the database
|
||||
#[utoipa::path(post, path = "/video", request_body = UploadVideoQuery, params(("url" = String, Query), ("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 200, description = "Video already exists, skipping"), (status = 201, description = "Video uploaded successfully"), (status = 400, description = "Bad request, likely a malformed URL"), (status = 401, description = "Unauthorized"), (status = 500, description = "Failed to upload video to database")))]
|
||||
#[utoipa::path(post, path = "/video", request_body = UploadVideoQuery, params(("url" = String, Query), ("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 200, description = "Video already exists, skipping"), (status = 201, description = "Video uploaded successfully"), (status = 400, description = "Bad request, likely a malformed URL"), (status = 401, description = "Unauthorized"), (status = 500, description = "Failed to upload video to database")), security(("authKey" = [])))]
|
||||
pub async fn upload_video(
|
||||
State(state): State<Instance>,
|
||||
Query(query): Query<UploadVideoQuery>,
|
||||
@ -162,7 +162,7 @@ pub async fn upload_video(
|
||||
}
|
||||
|
||||
/// Update an existing video from the database
|
||||
#[utoipa::path(put, path = "/video/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 204, description = "Video updated successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to update video from database")))]
|
||||
#[utoipa::path(put, path = "/video/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 204, description = "Video updated successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to update video from database")), security(("authKey" = [])))]
|
||||
pub async fn update_video(State(state): State<Instance>, Path(id): Path<String>) -> StatusCode {
|
||||
match sqlx::query_as!(Video, "SELECT * FROM video WHERE youtube_id = ?", id)
|
||||
.fetch_optional(&state.pool)
|
||||
@ -205,7 +205,7 @@ pub async fn update_video(State(state): State<Instance>, Path(id): Path<String>)
|
||||
}
|
||||
|
||||
/// Delete a video from the database
|
||||
#[utoipa::path(delete, path = "/video/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 204, description = "Video deleted successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to delete video from database")))]
|
||||
#[utoipa::path(delete, path = "/video/{id}", params(("almond-api-key" = String, description = "API key")), tags = ["video"], responses((status = 204, description = "Video deleted successfully"), (status = 404, description = "Video with specified ID not found"), (status = 500, description = "Failed to delete video from database")), security(("authKey" = [])))]
|
||||
pub async fn delete_video(State(state): State<Instance>, Path(id): Path<String>) -> StatusCode {
|
||||
match sqlx::query!("DELETE FROM video WHERE youtube_id = ?", id)
|
||||
.fetch_optional(&state.pool)
|
||||
|
Loading…
x
Reference in New Issue
Block a user