You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Load the configuration from a common Figment instance
This should avoid loading the same files multiple times. It should also make it easier to do post-processing on the configuration, like validation. This does deprecate one undocumented feature: the ability to override some fields during the configuration generation using environment variables.
This commit is contained in:
@ -21,7 +21,7 @@ anyhow.workspace = true
|
||||
|
||||
camino = { workspace = true, features = ["serde1"] }
|
||||
chrono.workspace = true
|
||||
figment = { version = "0.10.15", features = ["env", "yaml", "test"] }
|
||||
figment.workspace = true
|
||||
ipnetwork = { version = "0.20.0", features = ["serde", "schemars"] }
|
||||
schemars.workspace = true
|
||||
ulid.workspace = true
|
||||
|
@ -201,7 +201,10 @@ impl ConfigurationSection for ClientsConfig {
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use figment::Jail;
|
||||
use figment::{
|
||||
providers::{Format, Yaml},
|
||||
Figment, Jail,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -249,7 +252,9 @@ mod tests {
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let config = ClientsConfig::load_from_file("config.yaml")?;
|
||||
let config = Figment::new()
|
||||
.merge(Yaml::file("config.yaml"))
|
||||
.extract_inner::<ClientsConfig>("clients")?;
|
||||
|
||||
assert_eq!(config.0.len(), 5);
|
||||
|
||||
|
@ -164,7 +164,10 @@ impl ConfigurationSection for DatabaseConfig {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use figment::Jail;
|
||||
use figment::{
|
||||
providers::{Format, Yaml},
|
||||
Figment, Jail,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -179,7 +182,9 @@ mod tests {
|
||||
",
|
||||
)?;
|
||||
|
||||
let config = DatabaseConfig::load_from_file("config.yaml")?;
|
||||
let config = Figment::new()
|
||||
.merge(Yaml::file("config.yaml"))
|
||||
.extract_inner::<DatabaseConfig>("database")?;
|
||||
|
||||
assert_eq!(
|
||||
config.options,
|
||||
|
@ -76,7 +76,10 @@ impl ConfigurationSection for MatrixConfig {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use figment::Jail;
|
||||
use figment::{
|
||||
providers::{Format, Yaml},
|
||||
Figment, Jail,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -92,10 +95,12 @@ mod tests {
|
||||
",
|
||||
)?;
|
||||
|
||||
let config = MatrixConfig::load_from_file("config.yaml")?;
|
||||
let config = Figment::new()
|
||||
.merge(Yaml::file("config.yaml"))
|
||||
.extract_inner::<MatrixConfig>("matrix")?;
|
||||
|
||||
assert_eq!(config.homeserver, "matrix.org".to_owned());
|
||||
assert_eq!(config.secret, "test".to_owned());
|
||||
assert_eq!(&config.homeserver, "matrix.org");
|
||||
assert_eq!(&config.secret, "test");
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
@ -12,14 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use anyhow::Context;
|
||||
use async_trait::async_trait;
|
||||
use camino::Utf8Path;
|
||||
use figment::{
|
||||
error::Error as FigmentError,
|
||||
providers::{Env, Format, Serialized, Yaml},
|
||||
Figment, Profile,
|
||||
};
|
||||
use figment::{error::Error as FigmentError, Figment};
|
||||
use rand::Rng;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
@ -35,64 +29,13 @@ pub trait ConfigurationSection: Sized + DeserializeOwned + Serialize {
|
||||
where
|
||||
R: Rng + Send;
|
||||
|
||||
/// Generate a sample configuration and override it with environment
|
||||
/// variables.
|
||||
///
|
||||
/// This is what backs the `config generate` subcommand, allowing to
|
||||
/// programmatically generate a configuration file, e.g.
|
||||
///
|
||||
/// ```sh
|
||||
/// export MAS_OAUTH2_ISSUER=https://example.com/
|
||||
/// export MAS_HTTP_ADDRESS=127.0.0.1:1234
|
||||
/// matrix-authentication-service config generate
|
||||
/// ```
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the configuration could not be generated or if the
|
||||
/// existing configuration could not be loaded
|
||||
async fn load_and_generate<R>(rng: R) -> anyhow::Result<Self>
|
||||
where
|
||||
R: Rng + Send,
|
||||
{
|
||||
let base = Self::generate(rng)
|
||||
.await
|
||||
.context("could not generate configuration")?;
|
||||
|
||||
Figment::new()
|
||||
.merge(Serialized::from(&base, Profile::Default))
|
||||
.merge(Env::prefixed("MAS_").split("_"))
|
||||
.extract_inner(Self::path())
|
||||
.context("could not load configuration")
|
||||
}
|
||||
|
||||
/// Load configuration from a list of files and environment variables.
|
||||
/// Extract configuration from a Figment instance.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the configuration could not be loaded
|
||||
fn load_from_files<P>(paths: &[P]) -> Result<Self, FigmentError>
|
||||
where
|
||||
P: AsRef<Utf8Path>,
|
||||
{
|
||||
let base = Figment::new().merge(Env::prefixed("MAS_").split("_"));
|
||||
|
||||
paths
|
||||
.iter()
|
||||
.fold(base, |f, path| f.merge(Yaml::file(path.as_ref())))
|
||||
.extract_inner(Self::path())
|
||||
}
|
||||
|
||||
/// Load configuration from a file and environment variables.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the configuration could not be loaded
|
||||
fn load_from_file<P>(path: P) -> Result<Self, FigmentError>
|
||||
where
|
||||
P: AsRef<Utf8Path>,
|
||||
{
|
||||
Self::load_from_files(&[path])
|
||||
fn extract(figment: &Figment) -> Result<Self, FigmentError> {
|
||||
figment.extract_inner(Self::path())
|
||||
}
|
||||
|
||||
/// Generate config used in unit tests
|
||||
|
Reference in New Issue
Block a user