mas_config/sections/
matrix.rs

1// Copyright 2024 New Vector Ltd.
2// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
3//
4// SPDX-License-Identifier: AGPL-3.0-only
5// Please see LICENSE in the repository root for full details.
6
7use rand::{
8    Rng,
9    distributions::{Alphanumeric, DistString},
10};
11use schemars::JsonSchema;
12use serde::{Deserialize, Serialize};
13use serde_with::serde_as;
14use url::Url;
15
16use super::ConfigurationSection;
17
18fn default_homeserver() -> String {
19    "localhost:8008".to_owned()
20}
21
22fn default_endpoint() -> Url {
23    Url::parse("http://localhost:8008/").unwrap()
24}
25
26/// The kind of homeserver it is.
27#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Default)]
28#[serde(rename_all = "snake_case")]
29pub enum HomeserverKind {
30    /// Homeserver is Synapse
31    #[default]
32    Synapse,
33
34    /// Homeserver is Synapse, in read-only mode
35    ///
36    /// This is meant for testing rolling out Matrix Authentication Service with
37    /// no risk of writing data to the homeserver.
38    SynapseReadOnly,
39}
40
41/// Configuration related to the Matrix homeserver
42#[serde_as]
43#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
44pub struct MatrixConfig {
45    /// The kind of homeserver it is.
46    #[serde(default)]
47    pub kind: HomeserverKind,
48
49    /// The server name of the homeserver.
50    #[serde(default = "default_homeserver")]
51    pub homeserver: String,
52
53    /// Shared secret to use for calls to the admin API
54    pub secret: String,
55
56    /// The base URL of the homeserver's client API
57    #[serde(default = "default_endpoint")]
58    pub endpoint: Url,
59}
60
61impl ConfigurationSection for MatrixConfig {
62    const PATH: Option<&'static str> = Some("matrix");
63}
64
65impl MatrixConfig {
66    pub(crate) fn generate<R>(mut rng: R) -> Self
67    where
68        R: Rng + Send,
69    {
70        Self {
71            kind: HomeserverKind::default(),
72            homeserver: default_homeserver(),
73            secret: Alphanumeric.sample_string(&mut rng, 32),
74            endpoint: default_endpoint(),
75        }
76    }
77
78    pub(crate) fn test() -> Self {
79        Self {
80            kind: HomeserverKind::default(),
81            homeserver: default_homeserver(),
82            secret: "test".to_owned(),
83            endpoint: default_endpoint(),
84        }
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use figment::{
91        Figment, Jail,
92        providers::{Format, Yaml},
93    };
94
95    use super::*;
96
97    #[test]
98    fn load_config() {
99        Jail::expect_with(|jail| {
100            jail.create_file(
101                "config.yaml",
102                r"
103                    matrix:
104                      homeserver: matrix.org
105                      secret: test
106                ",
107            )?;
108
109            let config = Figment::new()
110                .merge(Yaml::file("config.yaml"))
111                .extract_inner::<MatrixConfig>("matrix")?;
112
113            assert_eq!(&config.homeserver, "matrix.org");
114            assert_eq!(&config.secret, "test");
115
116            Ok(())
117        });
118    }
119}