use actix_web::web;
use utoipa::{
openapi::security::{AuthorizationCode, Flow, OAuth2, Scopes, SecurityScheme},
Modify, OpenApi,
};
use utoipa_swagger_ui::SwaggerUi;
use crate::{
config::auth::Config,
controller::{
base_layer_image, blossoms, config, drawings, guided_tours, layers, map, plant_layer,
plantings, plants, seed, timeline, users,
},
model::{
dto::{
core::{
ActionDtoWrapperDeleteDrawings, ActionDtoWrapperDeleteLayer,
ActionDtoWrapperDeletePlantings, ActionDtoWrapperNewDrawings,
ActionDtoWrapperNewLayer, ActionDtoWrapperNewPlantings,
ActionDtoWrapperUpdateDrawings, ActionDtoWrapperUpdateLayer,
ActionDtoWrapperUpdatePlantings, TimelinePagePlantingsDto,
},
drawings::{
DrawingDto, EllipseProperties, FreeLineProperties, ImageProperties,
LabelTextProperties, PolygonProperties, RectangleProperties,
UpdateAddDateDrawingDto, UpdateNotesDrawingDto, UpdateRemoveDateDrawingDto,
},
layers::LayerDto,
plantings::{
MovePlantingDto, PlantingDto, TransformPlantingDto, UpdateAddDatePlantingDto,
UpdatePlantingDto, UpdatePlantingNoteDto, UpdateRemoveDatePlantingDto,
},
timeline::{TimelineDto, TimelineEntryDto},
BaseLayerImageDto, ConfigDto, Coordinates, GainedBlossomsDto, GuidedToursDto, MapDto,
NewMapDto, NewSeedDto, PageLayerDto, PageMapDto, PagePlantsSummaryDto, PageSeedDto,
PlantsSummaryDto, RelationDto, RelationsDto, SeedDto, UpdateBaseLayerImageDto,
UpdateGuidedToursDto, UpdateMapDto, UsersDto,
},
r#enum::{
privacy_option::PrivacyOption, quality::Quality, quantity::Quantity,
relation_type::RelationType,
},
},
};
#[derive(OpenApi)]
#[openapi(paths(config::get), components(schemas(ConfigDto)))]
struct ConfigApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
seed::find,
seed::find_by_id,
seed::create,
seed::delete_by_id
),
components(
schemas(
PageSeedDto,
SeedDto,
NewSeedDto,
Quality,
Quantity
)
),
modifiers(&SecurityAddon)
)]
struct SeedApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
plants::find,
plants::find_by_id
),
components(
schemas(
PagePlantsSummaryDto,
PlantsSummaryDto
)
),
modifiers(&SecurityAddon)
)]
struct PlantsApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
map::find,
map::find_by_id,
map::create,
map::update
),
components(
schemas(
PageMapDto,
MapDto,
NewMapDto,
UpdateMapDto,
PrivacyOption,
Coordinates
)
),
modifiers(&SecurityAddon)
)]
struct MapApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
layers::find,
layers::find_by_id,
layers::create,
layers::delete
),
components(
schemas(
LayerDto,
PageLayerDto,
ActionDtoWrapperNewLayer,
ActionDtoWrapperUpdateLayer,
ActionDtoWrapperDeleteLayer,
)
),
modifiers(&SecurityAddon)
)]
struct LayerApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
plant_layer::heatmap,
plant_layer::find_relations
),
components(
schemas(
RelationsDto,
RelationDto,
RelationType
)
),
modifiers(&SecurityAddon)
)]
struct PlantLayerApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
base_layer_image::find,
base_layer_image::create,
base_layer_image::update,
base_layer_image::delete
),
components(
schemas(
BaseLayerImageDto,
UpdateBaseLayerImageDto,
)
),
modifiers(&SecurityAddon)
)]
struct BaseLayerImagesApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
plantings::find,
plantings::create,
plantings::update,
plantings::delete
),
components(
schemas(
PlantingDto,
TimelinePagePlantingsDto,
UpdatePlantingDto,
TransformPlantingDto,
MovePlantingDto,
UpdateAddDatePlantingDto,
UpdateRemoveDatePlantingDto,
UpdatePlantingNoteDto,
ActionDtoWrapperNewPlantings,
ActionDtoWrapperUpdatePlantings,
ActionDtoWrapperDeletePlantings,
ActionDtoWrapperDeleteDrawings,
)
),
modifiers(&SecurityAddon)
)]
struct PlantingsApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
users::create
),
components(
schemas(
UsersDto
)
),
modifiers(&SecurityAddon)
)]
struct UsersApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
guided_tours::setup,
guided_tours::find_by_user,
guided_tours::update
),
components(
schemas(
GuidedToursDto,
UpdateGuidedToursDto
)
),
modifiers(&SecurityAddon)
)]
struct GuidedToursApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
blossoms::gain,
),
components(
schemas(
GainedBlossomsDto
)
),
modifiers(&SecurityAddon)
)]
struct BlossomsApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
timeline::get_timeline,
),
components(
schemas(
TimelineEntryDto,
TimelineDto
)
),
modifiers(&SecurityAddon)
)]
struct TimelineApiDoc;
#[derive(OpenApi)]
#[openapi(
paths(
drawings::find,
drawings::create,
drawings::update,
drawings::delete,
),
components(
schemas(
DrawingDto,
RectangleProperties,
EllipseProperties,
FreeLineProperties,
PolygonProperties,
LabelTextProperties,
ImageProperties,
UpdateAddDateDrawingDto,
UpdateRemoveDateDrawingDto,
UpdateNotesDrawingDto,
ActionDtoWrapperNewDrawings,
ActionDtoWrapperUpdateDrawings,
ActionDtoWrapperDeleteDrawings,
)
),
modifiers(&SecurityAddon)
)]
struct DrawingsApiDoc;
pub fn config(cfg: &mut web::ServiceConfig) {
let mut openapi = ConfigApiDoc::openapi();
openapi.merge(SeedApiDoc::openapi());
openapi.merge(PlantsApiDoc::openapi());
openapi.merge(MapApiDoc::openapi());
openapi.merge(LayerApiDoc::openapi());
openapi.merge(PlantLayerApiDoc::openapi());
openapi.merge(BaseLayerImagesApiDoc::openapi());
openapi.merge(PlantingsApiDoc::openapi());
openapi.merge(UsersApiDoc::openapi());
openapi.merge(TimelineApiDoc::openapi());
openapi.merge(DrawingsApiDoc::openapi());
openapi.merge(GuidedToursApiDoc::openapi());
openapi.merge(BlossomsApiDoc::openapi());
cfg.service(SwaggerUi::new("/doc/api/swagger/ui/{_:.*}").url("/doc/api/openapi.json", openapi));
}
struct SecurityAddon;
impl Modify for SecurityAddon {
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
#[allow(clippy::unwrap_used)]
let components = openapi.components.as_mut().unwrap();
let config = &Config::get().openid_configuration;
let oauth2 = OAuth2::new([Flow::AuthorizationCode(AuthorizationCode::new(
config.authorization_endpoint.clone(),
config.token_endpoint.clone(),
Scopes::new(),
))]);
components.add_security_scheme("oauth2", SecurityScheme::OAuth2(oauth2));
}
}