Skip to content

Commit 02bce97

Browse files
authored
Merge pull request #803 from umccr/feat/filemanager-swagger
feat(filemanager): deployable swagger ui
2 parents 1b7ee2a + c799243 commit 02bce97

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

lib/workload/stateless/stacks/filemanager/deploy/stack.ts

+20-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import { StringParameter } from 'aws-cdk-lib/aws-ssm';
99
import { ProviderFunction } from '../../../../components/provider-function';
1010
import { ApiGatewayConstruct, ApiGatewayConstructProps } from '../../../../components/api-gateway';
1111
import { IQueue, Queue } from 'aws-cdk-lib/aws-sqs';
12-
import { HttpMethod, HttpRoute, HttpRouteKey } from 'aws-cdk-lib/aws-apigatewayv2';
12+
import {
13+
HttpMethod,
14+
HttpNoneAuthorizer,
15+
HttpRoute,
16+
HttpRouteKey,
17+
} from 'aws-cdk-lib/aws-apigatewayv2';
1318
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';
1419
import { InventoryFunction } from './constructs/functions/inventory';
1520
import { NamedLambdaRole } from '../../../../components/named-lambda-role';
@@ -150,24 +155,31 @@ export class Filemanager extends Stack {
150155
const apiGateway = new ApiGatewayConstruct(this, 'ApiGateway', props.apiGatewayCognitoProps);
151156
const httpApi = apiGateway.httpApi;
152157

153-
const apiIntegration = new HttpLambdaIntegration('ApiIntegration', apiLambda.function);
158+
const integration = new HttpLambdaIntegration('ApiIntegration', apiLambda.function);
159+
160+
new HttpRoute(this, 'GetSchemaHttpRoute', {
161+
httpApi,
162+
integration,
163+
authorizer: new HttpNoneAuthorizer(),
164+
routeKey: HttpRouteKey.with(`/schema/{proxy+}`, HttpMethod.GET),
165+
});
154166

155167
new HttpRoute(this, 'GetHttpRoute', {
156-
httpApi: httpApi,
157-
integration: apiIntegration,
168+
httpApi,
169+
integration,
158170
routeKey: HttpRouteKey.with('/{proxy+}', HttpMethod.GET),
159171
});
160172

161173
new HttpRoute(this, 'PatchHttpRoute', {
162-
httpApi: httpApi,
163-
integration: apiIntegration,
174+
httpApi,
175+
integration,
164176
authorizer: apiGateway.authStackHttpLambdaAuthorizer,
165177
routeKey: HttpRouteKey.with('/{proxy+}', HttpMethod.PATCH),
166178
});
167179

168180
new HttpRoute(this, 'PostHttpRoute', {
169-
httpApi: httpApi,
170-
integration: apiIntegration,
181+
httpApi,
182+
integration,
171183
authorizer: apiGateway.authStackHttpLambdaAuthorizer,
172184
routeKey: HttpRouteKey.with('/{proxy+}', HttpMethod.POST),
173185
});

lib/workload/stateless/stacks/filemanager/filemanager-api-server/src/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use filemanager::error::Result;
2020
use filemanager::handlers::init_tracing_with_format;
2121
use filemanager::handlers::Format::Pretty;
2222
use filemanager::queries::EntriesBuilder;
23+
use filemanager::routes::openapi::SWAGGER_UI_PATH;
2324
use filemanager::routes::{router, AppState};
2425

2526
/// Run the filemanager API server locally to explore the API.
@@ -115,8 +116,7 @@ async fn main() -> Result<()> {
115116
.with_key_divisor(key_divisor)
116117
.with_shuffle(shuffle)
117118
.build(state.database_client())
118-
.await
119-
.unwrap();
119+
.await?;
120120
}
121121

122122
if args.migrate {
@@ -132,7 +132,7 @@ async fn main() -> Result<()> {
132132
let docs = Uri::builder()
133133
.scheme("http")
134134
.authority(local_addr.to_string())
135-
.path_and_query("/swagger-ui")
135+
.path_and_query(SWAGGER_UI_PATH)
136136
.build()
137137
.map_err(|err| IoError(io::Error::other(err)))?;
138138

lib/workload/stateless/stacks/filemanager/filemanager/src/routes/error.rs

+16
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ pub enum ErrorStatusCode {
7474
example = json!({"message": "JSON Error: parsing json"}),
7575
)]
7676
BadRequest(ErrorResponse),
77+
#[response(
78+
status = UNAUTHORIZED,
79+
description = "the request lacked valid authentication credentials",
80+
example = json!({"message": "Unauthorized"}),
81+
)]
82+
Unauthorized(ErrorResponse),
83+
#[response(
84+
status = FORBIDDEN,
85+
description = "the request lacked valid permissions for the resource",
86+
example = json!({"message": "Forbidden"}),
87+
)]
88+
Forbidden(ErrorResponse),
7789
}
7890

7991
impl From<QueryRejection> for ErrorStatusCode {
@@ -117,6 +129,8 @@ impl Display for ErrorStatusCode {
117129
ErrorStatusCode::BadRequest(err) => Display::fmt(err, f),
118130
ErrorStatusCode::NotFound(err) => Display::fmt(err, f),
119131
ErrorStatusCode::InternalServerError(err) => Display::fmt(err, f),
132+
ErrorStatusCode::Forbidden(err) => Display::fmt(err, f),
133+
ErrorStatusCode::Unauthorized(err) => Display::fmt(err, f),
120134
ErrorStatusCode::Rejection(_, message) => Display::fmt(message, f),
121135
}
122136
}
@@ -130,6 +144,8 @@ impl IntoResponse for ErrorStatusCode {
130144
(StatusCode::INTERNAL_SERVER_ERROR, extract::Json(err))
131145
}
132146
ErrorStatusCode::NotFound(err) => (StatusCode::NOT_FOUND, extract::Json(err)),
147+
ErrorStatusCode::Forbidden(err) => (StatusCode::NOT_FOUND, extract::Json(err)),
148+
ErrorStatusCode::Unauthorized(err) => (StatusCode::NOT_FOUND, extract::Json(err)),
133149
ErrorStatusCode::Rejection(status, err) => (
134150
StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
135151
extract::Json(err),

lib/workload/stateless/stacks/filemanager/filemanager/src/routes/openapi.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ use crate::routes::pagination::*;
2020
use crate::routes::presign::ContentDisposition;
2121
use crate::routes::update::*;
2222

23+
/// The path to the swagger ui.
24+
pub const SWAGGER_UI_PATH: &str = "/schema/swagger-ui";
25+
2326
/// A newtype equivalent to a `DateTime` with a time zone.
2427
#[derive(ToSchema)]
2528
#[schema(value_type = DateTime, format = DateTime)]
@@ -102,7 +105,7 @@ impl Modify for SecurityAddon {
102105

103106
/// Create the swagger ui endpoint.
104107
pub fn swagger_ui() -> SwaggerUi {
105-
SwaggerUi::new("/swagger-ui").url("/schema/openapi.json", ApiDoc::openapi())
108+
SwaggerUi::new(SWAGGER_UI_PATH).url("/schema/openapi.json", ApiDoc::openapi())
106109
}
107110

108111
#[cfg(test)]
@@ -113,6 +116,7 @@ mod tests {
113116
use sqlx::PgPool;
114117
use tower::util::ServiceExt;
115118

119+
use super::*;
116120
use crate::database::aws::migration::tests::MIGRATOR;
117121
use crate::routes::router;
118122
use crate::routes::AppState;
@@ -123,7 +127,7 @@ mod tests {
123127
let response = app
124128
.oneshot(
125129
Request::builder()
126-
.uri("/swagger-ui")
130+
.uri(SWAGGER_UI_PATH)
127131
.body(Body::empty())
128132
.unwrap(),
129133
)

0 commit comments

Comments
 (0)