1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

Split the full config with partial configs used by some sub-commands

This commit is contained in:
Quentin Gliech
2023-06-26 17:03:16 +02:00
parent dec9310a32
commit 8c42563e61
18 changed files with 135 additions and 23 deletions

View File

@ -15,7 +15,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use clap::Parser; use clap::Parser;
use mas_config::{ConfigurationSection, RootConfig}; use mas_config::{ConfigurationSection, RootConfig, SyncConfig};
use mas_storage::{ use mas_storage::{
upstream_oauth2::UpstreamOAuthProviderRepository, Repository, RepositoryAccess, SystemClock, upstream_oauth2::UpstreamOAuthProviderRepository, Repository, RepositoryAccess, SystemClock,
}; };
@ -142,7 +142,7 @@ async fn sync(root: &super::Options, prune: bool, dry_run: bool) -> anyhow::Resu
let mut rng = rand_chacha::ChaChaRng::from_entropy(); let mut rng = rand_chacha::ChaChaRng::from_entropy();
let clock = SystemClock::default(); let clock = SystemClock::default();
let config: RootConfig = root.load_config()?; let config: SyncConfig = root.load_config()?;
let encrypter = config.secrets.encrypter(); let encrypter = config.secrets.encrypter();
let pool = database_from_config(&config.database).await?; let pool = database_from_config(&config.database).await?;
let mut repo = PgRepository::from_pool(&pool).await?.boxed(); let mut repo = PgRepository::from_pool(&pool).await?.boxed();

View File

@ -74,7 +74,7 @@ impl Options {
} }
} }
pub fn load_config<'de, T: ConfigurationSection<'de>>(&self) -> anyhow::Result<T> { pub fn load_config<T: ConfigurationSection>(&self) -> anyhow::Result<T> {
let configs = if self.config.is_empty() { let configs = if self.config.is_empty() {
// Read the MAS_CONFIG environment variable // Read the MAS_CONFIG environment variable
std::env::var("MAS_CONFIG") std::env::var("MAS_CONFIG")

View File

@ -17,7 +17,7 @@ use std::{sync::Arc, time::Duration};
use anyhow::Context; use anyhow::Context;
use clap::Parser; use clap::Parser;
use itertools::Itertools; use itertools::Itertools;
use mas_config::RootConfig; use mas_config::AppConfig;
use mas_handlers::{AppState, HttpClientFactory, MatrixHomeserver}; use mas_handlers::{AppState, HttpClientFactory, MatrixHomeserver};
use mas_listener::{server::Server, shutdown::ShutdownStream}; use mas_listener::{server::Server, shutdown::ShutdownStream};
use mas_matrix_synapse::SynapseConnection; use mas_matrix_synapse::SynapseConnection;
@ -54,7 +54,7 @@ impl Options {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub async fn run(self, root: &super::Options) -> anyhow::Result<()> { pub async fn run(self, root: &super::Options) -> anyhow::Result<()> {
let span = info_span!("cli.run.init").entered(); let span = info_span!("cli.run.init").entered();
let config: RootConfig = root.load_config()?; let config: AppConfig = root.load_config()?;
// Connect to the database // Connect to the database
info!("Connecting to the database"); info!("Connecting to the database");

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
use clap::Parser; use clap::Parser;
use mas_config::RootConfig; use mas_config::AppConfig;
use mas_handlers::HttpClientFactory; use mas_handlers::HttpClientFactory;
use mas_matrix_synapse::SynapseConnection; use mas_matrix_synapse::SynapseConnection;
use mas_router::UrlBuilder; use mas_router::UrlBuilder;
@ -31,7 +31,7 @@ pub(super) struct Options {}
impl Options { impl Options {
pub async fn run(self, root: &super::Options) -> anyhow::Result<()> { pub async fn run(self, root: &super::Options) -> anyhow::Result<()> {
let span = info_span!("cli.worker.init").entered(); let span = info_span!("cli.worker.init").entered();
let config: RootConfig = root.load_config()?; let config: AppConfig = root.load_config()?;
// Connect to the database // Connect to the database
info!("Connecting to the database"); info!("Connecting to the database");

View File

@ -171,7 +171,7 @@ impl DerefMut for ClientsConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for ClientsConfig { impl ConfigurationSection for ClientsConfig {
fn path() -> &'static str { fn path() -> &'static str {
"clients" "clients"
} }

View File

@ -43,7 +43,7 @@ impl Default for CsrfConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for CsrfConfig { impl ConfigurationSection for CsrfConfig {
fn path() -> &'static str { fn path() -> &'static str {
"csrf" "csrf"
} }

View File

@ -145,7 +145,7 @@ pub struct DatabaseConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for DatabaseConfig { impl ConfigurationSection for DatabaseConfig {
fn path() -> &'static str { fn path() -> &'static str {
"database" "database"
} }

View File

@ -124,7 +124,7 @@ impl Default for EmailConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for EmailConfig { impl ConfigurationSection for EmailConfig {
fn path() -> &'static str { fn path() -> &'static str {
"email" "email"
} }

View File

@ -370,7 +370,7 @@ impl Default for HttpConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for HttpConfig { impl ConfigurationSection for HttpConfig {
fn path() -> &'static str { fn path() -> &'static str {
"http" "http"
} }

View File

@ -49,7 +49,7 @@ pub struct MatrixConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for MatrixConfig { impl ConfigurationSection for MatrixConfig {
fn path() -> &'static str { fn path() -> &'static str {
"matrix" "matrix"
} }

View File

@ -106,7 +106,7 @@ pub struct RootConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for RootConfig { impl ConfigurationSection for RootConfig {
fn path() -> &'static str { fn path() -> &'static str {
"" ""
} }
@ -148,3 +148,115 @@ impl ConfigurationSection<'_> for RootConfig {
} }
} }
} }
/// Partial configuration actually used by the server
#[allow(missing_docs)]
#[derive(Debug, Deserialize, Serialize)]
pub struct AppConfig {
#[serde(default)]
pub http: HttpConfig,
#[serde(default)]
pub database: DatabaseConfig,
#[serde(default)]
pub templates: TemplatesConfig,
#[serde(default)]
pub csrf: CsrfConfig,
#[serde(default)]
pub email: EmailConfig,
pub secrets: SecretsConfig,
#[serde(default)]
pub passwords: PasswordsConfig,
pub matrix: MatrixConfig,
#[serde(default)]
pub policy: PolicyConfig,
}
#[async_trait]
impl ConfigurationSection for AppConfig {
fn path() -> &'static str {
""
}
async fn generate<R>(mut rng: R) -> anyhow::Result<Self>
where
R: Rng + Send,
{
Ok(Self {
http: HttpConfig::generate(&mut rng).await?,
database: DatabaseConfig::generate(&mut rng).await?,
templates: TemplatesConfig::generate(&mut rng).await?,
csrf: CsrfConfig::generate(&mut rng).await?,
email: EmailConfig::generate(&mut rng).await?,
passwords: PasswordsConfig::generate(&mut rng).await?,
secrets: SecretsConfig::generate(&mut rng).await?,
matrix: MatrixConfig::generate(&mut rng).await?,
policy: PolicyConfig::generate(&mut rng).await?,
})
}
fn test() -> Self {
Self {
http: HttpConfig::test(),
database: DatabaseConfig::test(),
templates: TemplatesConfig::test(),
passwords: PasswordsConfig::test(),
csrf: CsrfConfig::test(),
email: EmailConfig::test(),
secrets: SecretsConfig::test(),
matrix: MatrixConfig::test(),
policy: PolicyConfig::test(),
}
}
}
/// Partial config used by the `mas-cli config sync` command
#[allow(missing_docs)]
#[derive(Debug, Deserialize, Serialize)]
pub struct SyncConfig {
#[serde(default)]
pub database: DatabaseConfig,
pub secrets: SecretsConfig,
#[serde(default)]
pub clients: ClientsConfig,
#[serde(default)]
pub upstream_oauth2: UpstreamOAuth2Config,
}
#[async_trait]
impl ConfigurationSection for SyncConfig {
fn path() -> &'static str {
""
}
async fn generate<R>(mut rng: R) -> anyhow::Result<Self>
where
R: Rng + Send,
{
Ok(Self {
database: DatabaseConfig::generate(&mut rng).await?,
secrets: SecretsConfig::generate(&mut rng).await?,
clients: ClientsConfig::generate(&mut rng).await?,
upstream_oauth2: UpstreamOAuth2Config::generate(&mut rng).await?,
})
}
fn test() -> Self {
Self {
database: DatabaseConfig::test(),
secrets: SecretsConfig::test(),
clients: ClientsConfig::test(),
upstream_oauth2: UpstreamOAuth2Config::test(),
}
}
}

View File

@ -56,7 +56,7 @@ impl Default for PasswordsConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for PasswordsConfig { impl ConfigurationSection for PasswordsConfig {
fn path() -> &'static str { fn path() -> &'static str {
"passwords" "passwords"
} }

View File

@ -82,7 +82,7 @@ impl Default for PolicyConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for PolicyConfig { impl ConfigurationSection for PolicyConfig {
fn path() -> &'static str { fn path() -> &'static str {
"policy" "policy"
} }

View File

@ -138,7 +138,7 @@ impl SecretsConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for SecretsConfig { impl ConfigurationSection for SecretsConfig {
fn path() -> &'static str { fn path() -> &'static str {
"secrets" "secrets"
} }

View File

@ -287,7 +287,7 @@ pub struct TelemetryConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for TelemetryConfig { impl ConfigurationSection for TelemetryConfig {
fn path() -> &'static str { fn path() -> &'static str {
"telemetry" "telemetry"
} }

View File

@ -48,7 +48,7 @@ impl Default for TemplatesConfig {
} }
#[async_trait] #[async_trait]
impl ConfigurationSection<'_> for TemplatesConfig { impl ConfigurationSection for TemplatesConfig {
fn path() -> &'static str { fn path() -> &'static str {
"templates" "templates"
} }

View File

@ -32,7 +32,7 @@ pub struct UpstreamOAuth2Config {
} }
#[async_trait] #[async_trait]
impl<'a> ConfigurationSection<'a> for UpstreamOAuth2Config { impl ConfigurationSection for UpstreamOAuth2Config {
fn path() -> &'static str { fn path() -> &'static str {
"upstream_oauth2" "upstream_oauth2"
} }

View File

@ -21,12 +21,12 @@ use figment::{
Figment, Profile, Figment, Profile,
}; };
use rand::Rng; use rand::Rng;
use serde::{Deserialize, Serialize}; use serde::{de::DeserializeOwned, Serialize};
#[async_trait] #[async_trait]
/// Trait implemented by all configuration section to help loading specific part /// Trait implemented by all configuration section to help loading specific part
/// of the config and generate the sample config. /// of the config and generate the sample config.
pub trait ConfigurationSection<'a>: Sized + Deserialize<'a> + Serialize { pub trait ConfigurationSection: Sized + DeserializeOwned + Serialize {
/// Specify where this section should live relative to the root. /// Specify where this section should live relative to the root.
fn path() -> &'static str; fn path() -> &'static str;
@ -39,7 +39,7 @@ pub trait ConfigurationSection<'a>: Sized + Deserialize<'a> + Serialize {
/// variables. /// variables.
/// ///
/// This is what backs the `config generate` subcommand, allowing to /// This is what backs the `config generate` subcommand, allowing to
/// programatically generate a configuration file, e.g. /// programmatically generate a configuration file, e.g.
/// ///
/// ```sh /// ```sh
/// export MAS_OAUTH2_ISSUER=https://example.com/ /// export MAS_OAUTH2_ISSUER=https://example.com/