support_kit/deployments/
security_control.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use rustls_acme::{axum::AxumAcceptor, caches::DirCache, AcmeConfig};
use tokio_stream::StreamExt;

#[derive(Debug, Default, bon::Builder)]
pub struct SecurityControl {
    config: super::SecurityConfig,
}

impl SecurityControl {
    pub fn new(deployment: &super::DeploymentConfig) -> Self {
        Self::builder().config(deployment.security.clone()).build()
    }

    pub async fn init(&self) -> Option<AxumAcceptor> {
        match &self.config {
            super::SecurityConfig::Acme {
                domains,
                emails,
                cache,
                production,
                ..
            } => {
                let mut state = AcmeConfig::new(domains)
                    .contact(emails.iter().map(|email| format!("mailto:{email}")))
                    .cache_option(cache.clone().map(DirCache::new))
                    .directory_lets_encrypt(*production)
                    .state();

                let acceptor = state.axum_acceptor(state.default_rustls_config());

                tokio::spawn(async move {
                    loop {
                        match state.next().await.unwrap() {
                            Ok(ok) => tracing::info!("tls certification event: {:?}", ok),
                            Err(err) => {
                                tracing::error!("tls certification error: {:?}", err)
                            }
                        }
                    }
                });

                Some(acceptor)
            }
            _ => None,
        }
    }
}