static_authn_plugin/
module.rs1use std::sync::{Arc, OnceLock};
4
5use async_trait::async_trait;
6use authn_resolver_sdk::{AuthNResolverPluginClient, AuthNResolverPluginSpecV1};
7use modkit::Module;
8use modkit::client_hub::ClientScope;
9use modkit::context::ModuleCtx;
10use modkit::gts::BaseModkitPluginV1;
11use tracing::info;
12use types_registry_sdk::{RegisterResult, TypesRegistryClient};
13
14use crate::config::StaticAuthNPluginConfig;
15use crate::domain::Service;
16
17#[modkit::module(
26 name = "static-authn-plugin",
27 deps = ["types-registry"]
28)]
29pub struct StaticAuthNPlugin {
30 service: OnceLock<Arc<Service>>,
31}
32
33impl Default for StaticAuthNPlugin {
34 fn default() -> Self {
35 Self {
36 service: OnceLock::new(),
37 }
38 }
39}
40
41#[async_trait]
42impl Module for StaticAuthNPlugin {
43 async fn init(&self, ctx: &ModuleCtx) -> anyhow::Result<()> {
44 info!("Initializing {} module", Self::MODULE_NAME);
45
46 let cfg: StaticAuthNPluginConfig = ctx.config()?;
48 if matches!(cfg.mode, crate::config::AuthNMode::AcceptAll) {
49 tracing::warn!(
50 "Static AuthN plugin is running in `accept_all` mode \u{2014} \
51 all bearer tokens will be accepted with a hardcoded identity. \
52 Do NOT use this mode in production."
53 );
54 }
55
56 info!(
57 vendor = %cfg.vendor,
58 priority = cfg.priority,
59 mode = ?cfg.mode,
60 token_count = cfg.tokens.len(),
61 "Loaded plugin configuration"
62 );
63
64 let instance_id = AuthNResolverPluginSpecV1::gts_make_instance_id(
66 "hyperspot.builtin.static_authn_resolver.plugin.v1",
67 );
68
69 let registry = ctx.client_hub().get::<dyn TypesRegistryClient>()?;
71 let instance = BaseModkitPluginV1::<AuthNResolverPluginSpecV1> {
72 id: instance_id.clone(),
73 vendor: cfg.vendor.clone(),
74 priority: cfg.priority,
75 properties: AuthNResolverPluginSpecV1,
76 };
77 let instance_json = serde_json::to_value(&instance)?;
78
79 let results = registry.register(vec![instance_json]).await?;
80 RegisterResult::ensure_all_ok(&results)?;
81
82 let service = Arc::new(Service::from_config(&cfg));
84 self.service
85 .set(service.clone())
86 .map_err(|_| anyhow::anyhow!("{} module already initialized", Self::MODULE_NAME))?;
87
88 let api: Arc<dyn AuthNResolverPluginClient> = service;
90 ctx.client_hub()
91 .register_scoped::<dyn AuthNResolverPluginClient>(
92 ClientScope::gts_id(&instance_id),
93 api,
94 );
95
96 info!(instance_id = %instance_id, "{} module initialized successfully", Self::MODULE_NAME);
97 Ok(())
98 }
99}