kanidmd_core/repl/
config.rs

1use kanidm_lib_crypto::prelude::X509;
2use kanidm_lib_crypto::serialise::x509b64;
3use kanidm_proto::constants::{
4    AUTH_TOKEN_GRACE_WINDOW, DEFAULT_REPLICATION_ADDRESS, DEFAULT_REPLICATION_ORIGIN,
5    DEFAULT_REPL_TASK_POLL_INTERVAL,
6};
7use serde::Deserialize;
8use std::collections::BTreeMap;
9use std::net::SocketAddr;
10use std::str::FromStr;
11use url::Url;
12
13#[derive(Deserialize, Debug, Clone)]
14#[serde(tag = "type")]
15pub enum RepNodeConfig {
16    #[serde(rename = "allow-pull")]
17    AllowPull {
18        #[serde(with = "x509b64")]
19        consumer_cert: X509,
20    },
21    #[serde(rename = "pull")]
22    Pull {
23        #[serde(with = "x509b64")]
24        supplier_cert: X509,
25        #[serde(default)]
26        automatic_refresh: bool,
27    },
28    #[serde(rename = "mutual-pull")]
29    MutualPull {
30        #[serde(with = "x509b64")]
31        partner_cert: X509,
32        #[serde(default)]
33        automatic_refresh: bool,
34    },
35    /*
36    AllowPush {
37    },
38    Push {
39    },
40    */
41}
42
43#[derive(Deserialize, Debug, Clone)]
44pub struct ReplicationConfiguration {
45    /// Defaults to [kanidm_proto::constants::DEFAULT_REPLICATION_ORIGIN]
46    pub origin: Url,
47    /// Defaults to [kanidm_proto::constants::DEFAULT_REPLICATION_ADDRESS]
48    pub bindaddress: SocketAddr,
49    /// Number of seconds between running a replication event. Defaults to
50    /// [kanidm_proto::constants::DEFAULT_REPL_TASK_POLL_INTERVAL] but may
51    /// not exceed [kanidm_proto::constants::AUTH_TOKEN_GRACE_WINDOW].
52    pub task_poll_interval: Option<u64>,
53
54    #[serde(flatten)]
55    pub manual: BTreeMap<Url, RepNodeConfig>,
56}
57
58impl Default for ReplicationConfiguration {
59    fn default() -> Self {
60        // we're using expect here because if we stuff it up, we did it at compile time
61        #[allow(clippy::expect_used)]
62        let origin: Url = Url::from_str(DEFAULT_REPLICATION_ORIGIN)
63            .expect("Failed to parse default replication origin URL");
64        #[allow(clippy::expect_used)]
65        let bindaddress: SocketAddr = DEFAULT_REPLICATION_ADDRESS
66            .parse()
67            .expect("Failed to parse default replication bind address");
68        Self {
69            origin,
70            bindaddress,
71            task_poll_interval: None,
72            manual: BTreeMap::new(),
73        }
74    }
75}
76
77impl ReplicationConfiguration {
78    /// Get the task poll interval, or the default if not set.
79    pub(crate) fn get_task_poll_interval(&self) -> core::time::Duration {
80        let config_poll = core::time::Duration::from_secs(
81            self.task_poll_interval
82                .unwrap_or(DEFAULT_REPL_TASK_POLL_INTERVAL),
83        );
84
85        // Don't allow the replication poll to exceed gracewindow.
86        if config_poll > AUTH_TOKEN_GRACE_WINDOW {
87            AUTH_TOKEN_GRACE_WINDOW
88        } else {
89            config_poll
90        }
91    }
92}