Skip to main content

auth_oidc/
module.rs

1use crate::migrations::AUTH_OIDC_MIGRATIONS;
2use platform_core::AppContext;
3use platform_http::ApiOpenApiRouter;
4use platform_module::{
5    ConsoleArea, ConsoleNavigation, ConsolePackage, ConsoleSurface, ConsoleWorkspaceRef,
6    HostLinkedModule, LinkedBinding, LinkedHttpContribution, Module, ModuleHttpMethod,
7    ModuleHttpRoute, ModuleManifest,
8};
9
10pub const MODULE_NAME: &str = "auth-oidc";
11
12fn auth_workspace() -> ConsoleWorkspaceRef {
13    ConsoleWorkspaceRef {
14        id: "auth".to_owned(),
15        label: "Auth".to_owned(),
16        icon: Some("shield".to_owned()),
17    }
18}
19
20pub fn http_routes() -> Vec<ModuleHttpRoute> {
21    vec![
22        ModuleHttpRoute {
23            method: ModuleHttpMethod::Get,
24            path: "/.well-known/openid-configuration".to_owned(),
25            capability: None,
26            operation: None,
27            display_name: Some("OIDC Provider Metadata".to_owned()),
28            story_title: Some("OIDC Discovery".to_owned()),
29        },
30        ModuleHttpRoute {
31            method: ModuleHttpMethod::Get,
32            path: "/.well-known/jwks.json".to_owned(),
33            capability: None,
34            operation: None,
35            display_name: Some("OIDC JSON Web Key Set".to_owned()),
36            story_title: Some("OIDC JWKS".to_owned()),
37        },
38        ModuleHttpRoute {
39            method: ModuleHttpMethod::Get,
40            path: "/oauth/authorize".to_owned(),
41            capability: None,
42            operation: None,
43            display_name: Some("OIDC Authorization".to_owned()),
44            story_title: Some("OIDC Authorization".to_owned()),
45        },
46        ModuleHttpRoute {
47            method: ModuleHttpMethod::Post,
48            path: "/oauth/token".to_owned(),
49            capability: None,
50            operation: None,
51            display_name: Some("OIDC Token Exchange".to_owned()),
52            story_title: Some("OIDC Token Exchange".to_owned()),
53        },
54    ]
55}
56
57pub fn console_surfaces() -> Vec<ConsoleSurface> {
58    vec![ConsoleSurface {
59        name: "oidc-provider".to_owned(),
60        label: "OIDC Provider".to_owned(),
61        area: ConsoleArea::Data,
62        route: "/data/auth/providers/oidc".to_owned(),
63        package: ConsolePackage {
64            name: "@lenso/auth-provider-console".to_owned(),
65            export: "authProviderConsoleModule".to_owned(),
66        },
67        icon: Some("shield".to_owned()),
68        required_capabilities: Vec::new(),
69        navigation: Some(ConsoleNavigation {
70            workspace: auth_workspace(),
71            group: None,
72            order: Some(83),
73        }),
74    }]
75}
76
77pub fn manifest() -> ModuleManifest {
78    ModuleManifest::builder(MODULE_NAME)
79        .dependencies(vec![auth::module::MODULE_NAME.to_owned()])
80        .http_routes(http_routes())
81        .console(console_surfaces())
82        .build()
83}
84
85pub fn merge_http(base: ApiOpenApiRouter) -> ApiOpenApiRouter {
86    base.merge(crate::routes::router())
87}
88
89pub fn binding() -> LinkedBinding {
90    LinkedBinding::builder()
91        .http(LinkedHttpContribution {
92            public_prefixes: &["/.well-known/", "/oauth/"],
93            merge: merge_http,
94        })
95        .build()
96}
97
98pub fn module(_ctx: &AppContext) -> Module {
99    Module::linked(manifest(), binding())
100}
101
102pub fn linked_module() -> HostLinkedModule {
103    HostLinkedModule::linked(MODULE_NAME, manifest, module, AUTH_OIDC_MIGRATIONS)
104}
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109    use platform_module::{ModuleManifestLintSeverity, ModuleSource, lint_module_manifest};
110
111    #[test]
112    fn manifest_declares_oidc_routes() {
113        let manifest = manifest();
114
115        assert_eq!(manifest.name, MODULE_NAME);
116        assert_eq!(manifest.http_routes, http_routes());
117        assert_eq!(manifest.console, console_surfaces());
118
119        let lints = lint_module_manifest(ModuleSource::Linked, &manifest);
120        assert!(
121            lints
122                .iter()
123                .all(|lint| lint.severity == ModuleManifestLintSeverity::Ok),
124            "auth-oidc manifest should not have warning/error lints: {lints:?}"
125        );
126    }
127}