1use std::sync::{Arc, OnceLock};
4
5use async_trait::async_trait;
6use authn_resolver_sdk::{AuthNResolverClient, AuthNResolverPluginSpecV1};
7use modkit::Module;
8use modkit::context::ModuleCtx;
9use tracing::info;
10use types_registry_sdk::{RegisterResult, TypesRegistryClient};
11
12use crate::config::AuthNResolverConfig;
13use crate::domain::{AuthNResolverLocalClient, Service};
14
15#[modkit::module(
25 name = "authn-resolver",
26 deps = ["types-registry"],
27 capabilities = []
28)]
29pub(crate) struct AuthNResolver {
30 service: OnceLock<Arc<Service>>,
31}
32
33impl Default for AuthNResolver {
34 fn default() -> Self {
35 Self {
36 service: OnceLock::new(),
37 }
38 }
39}
40
41#[async_trait]
42impl Module for AuthNResolver {
43 #[tracing::instrument(skip_all, fields(vendor))]
44 async fn init(&self, ctx: &ModuleCtx) -> anyhow::Result<()> {
45 let cfg: AuthNResolverConfig = ctx.config()?;
46 tracing::Span::current().record("vendor", cfg.vendor.as_str());
47 info!(vendor = %cfg.vendor, "Initializing authn_resolver");
48
49 let registry = ctx.client_hub().get::<dyn TypesRegistryClient>()?;
51 let schema_str = AuthNResolverPluginSpecV1::gts_schema_with_refs_as_string();
52 let schema_json: serde_json::Value = serde_json::from_str(&schema_str)?;
53 let results = registry.register(vec![schema_json]).await?;
54 RegisterResult::ensure_all_ok(&results)?;
55 info!(
56 schema_id = %AuthNResolverPluginSpecV1::gts_schema_id(),
57 "Registered plugin schema in types-registry"
58 );
59
60 let hub = ctx.client_hub();
62 let svc = Arc::new(Service::new(hub, cfg.vendor));
63
64 let api: Arc<dyn AuthNResolverClient> =
66 Arc::new(AuthNResolverLocalClient::new(svc.clone()));
67 ctx.client_hub().register::<dyn AuthNResolverClient>(api);
68
69 self.service
70 .set(svc)
71 .map_err(|_| anyhow::anyhow!("Service already initialized"))?;
72
73 Ok(())
74 }
75}