Skip to main content

headless_lms_server/
openapi.rs

1use utoipa::{
2    Modify, OpenApi,
3    openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme},
4};
5
6#[derive(OpenApi)]
7#[openapi(
8    nest(
9        (path = "/api/v0/cms", api = crate::controllers::cms::CmsRoutesApiDoc),
10        (path = "/api/v0/files", api = crate::controllers::files::CmsFilesApiDoc)
11    ),
12    // The CMS serves the block validator that headless-lms calls; its types come from here.
13    components(schemas(
14        headless_lms_mcp::validator::ValidateBlocksRequest,
15        headless_lms_mcp::validator::ValidateBlocksResponse,
16        headless_lms_mcp::validator::BlockSchemas
17    )),
18    info(
19        title = "CMS API",
20        version = "0.1.0"
21    )
22)]
23pub struct CmsApiDoc;
24
25#[derive(OpenApi)]
26#[openapi(
27    nest(
28        (
29            path = "/api/v0/main-frontend",
30            api = crate::controllers::main_frontend::MainFrontendRoutesApiDoc
31        ),
32        (path = "/api/v0/files", api = crate::controllers::files::FilesApiDoc)
33    ),
34    components(schemas(
35        headless_lms_models::suspected_cheaters::SuspectedCheaterStatus
36    )),
37    tags(
38        (name = "glossary", description = "Glossary endpoints used by main-frontend")
39    ),
40    info(
41        title = "Main Frontend API",
42        version = "0.1.0"
43    )
44)]
45pub struct MainFrontendApiDoc;
46
47#[derive(OpenApi)]
48#[openapi(
49    nest(
50        (
51            path = "/api/v0/course-material",
52            api = crate::controllers::course_material::CourseMaterialRoutesApiDoc
53        )
54    ),
55    components(schemas(
56        headless_lms_models::teacher_grading_decisions::TeacherDecisionType
57    )),
58    info(
59        title = "Course Material API",
60        version = "0.1.0"
61    )
62)]
63pub struct CourseMaterialApiDoc;
64
65#[derive(OpenApi)]
66#[openapi(
67    nest((path = "/api/v0/auth", api = crate::controllers::auth::AuthRoutesApiDoc)),
68    info(
69        title = "Auth API",
70        version = "0.1.0"
71    )
72)]
73pub struct AuthApiDoc;
74
75#[derive(OpenApi)]
76#[openapi(
77    nest((path = "/api/v0/errors", api = crate::controllers::errors::ErrorsRoutesApiDoc)),
78    info(
79        title = "Errors API",
80        version = "0.1.0"
81    )
82)]
83pub struct ErrorsApiDoc;
84
85/// Declares the single `bearer_auth` HTTP bearer scheme that every
86/// `/api/v0/exercise-services/client` operation references.
87struct ExerciseServicesClientSecurityAddon;
88
89impl Modify for ExerciseServicesClientSecurityAddon {
90    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
91        let components = openapi.components.get_or_insert_with(Default::default);
92        components.add_security_scheme(
93            "bearer_auth",
94            SecurityScheme::Http(
95                HttpBuilder::new()
96                    .scheme(HttpAuthScheme::Bearer)
97                    .description(Some(
98                        "Access token passed as an HTTP bearer token in the Authorization header.",
99                    ))
100                    .build(),
101            ),
102        );
103    }
104}
105
106#[derive(OpenApi)]
107#[openapi(
108    nest((path = "/api/v0/exercise-services/client", api = crate::controllers::exercise_services::client::ExerciseServicesClientRoutesApiDoc)),
109    modifiers(&ExerciseServicesClientSecurityAddon),
110    info(
111        title = "Exercise Services Client API",
112        version = "0.1.0"
113    )
114)]
115pub struct ExerciseServicesClientApiDoc;