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}