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
Password schemes configuration
This commit is contained in:
@ -20,7 +20,7 @@ use futures_util::stream::{StreamExt, TryStreamExt};
|
||||
use itertools::Itertools;
|
||||
use mas_config::RootConfig;
|
||||
use mas_email::Mailer;
|
||||
use mas_handlers::{AppState, HttpClientFactory, MatrixHomeserver};
|
||||
use mas_handlers::{passwords::PasswordManager, AppState, HttpClientFactory, MatrixHomeserver};
|
||||
use mas_listener::{server::Server, shutdown::ShutdownStream};
|
||||
use mas_policy::PolicyFactory;
|
||||
use mas_router::UrlBuilder;
|
||||
@ -168,6 +168,24 @@ impl Options {
|
||||
|
||||
let listeners_config = config.http.listeners.clone();
|
||||
|
||||
let password_manager = config
|
||||
.passwords
|
||||
.load()
|
||||
.await
|
||||
.context("failed to load the password schemes")?
|
||||
.into_iter()
|
||||
.map(|(version, algorithm, secret)| {
|
||||
use mas_handlers::passwords::Hasher;
|
||||
let hasher = match algorithm {
|
||||
mas_config::PasswordAlgorithm::Pbkdf2 => Hasher::pbkdf2(secret),
|
||||
mas_config::PasswordAlgorithm::Bcrypt { cost } => Hasher::bcrypt(cost, secret),
|
||||
mas_config::PasswordAlgorithm::Argon2id => Hasher::argon2id(secret),
|
||||
};
|
||||
|
||||
(version, hasher)
|
||||
});
|
||||
let password_manager = PasswordManager::new(password_manager)?;
|
||||
|
||||
// Explicitely the config to properly zeroize secret keys
|
||||
drop(config);
|
||||
|
||||
@ -199,6 +217,7 @@ impl Options {
|
||||
policy_factory,
|
||||
graphql_schema,
|
||||
http_client_factory,
|
||||
password_manager,
|
||||
};
|
||||
|
||||
let mut fd_manager = listenfd::ListenFd::from_env();
|
||||
|
@ -23,6 +23,7 @@ mod database;
|
||||
mod email;
|
||||
mod http;
|
||||
mod matrix;
|
||||
mod passwords;
|
||||
mod policy;
|
||||
mod secrets;
|
||||
mod telemetry;
|
||||
@ -38,6 +39,7 @@ pub use self::{
|
||||
Resource as HttpResource, TlsConfig as HttpTlsConfig, UnixOrTcp,
|
||||
},
|
||||
matrix::MatrixConfig,
|
||||
passwords::{Algorithm as PasswordAlgorithm, PasswordsConfig},
|
||||
policy::PolicyConfig,
|
||||
secrets::SecretsConfig,
|
||||
telemetry::{
|
||||
@ -82,6 +84,10 @@ pub struct RootConfig {
|
||||
/// Application secrets
|
||||
pub secrets: SecretsConfig,
|
||||
|
||||
/// Configuration related to user passwords
|
||||
#[serde(default)]
|
||||
pub passwords: PasswordsConfig,
|
||||
|
||||
/// Configuration related to the homeserver
|
||||
#[serde(default)]
|
||||
pub matrix: MatrixConfig,
|
||||
@ -109,6 +115,7 @@ impl ConfigurationSection<'_> for RootConfig {
|
||||
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?,
|
||||
@ -122,6 +129,7 @@ impl ConfigurationSection<'_> for RootConfig {
|
||||
database: DatabaseConfig::test(),
|
||||
telemetry: TelemetryConfig::test(),
|
||||
templates: TemplatesConfig::test(),
|
||||
passwords: PasswordsConfig::test(),
|
||||
csrf: CsrfConfig::test(),
|
||||
email: EmailConfig::test(),
|
||||
secrets: SecretsConfig::test(),
|
||||
|
@ -23,7 +23,7 @@ use mas_router::UrlBuilder;
|
||||
use mas_templates::Templates;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::MatrixHomeserver;
|
||||
use crate::{passwords::PasswordManager, MatrixHomeserver};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
@ -37,6 +37,7 @@ pub struct AppState {
|
||||
pub policy_factory: Arc<PolicyFactory>,
|
||||
pub graphql_schema: mas_graphql::Schema,
|
||||
pub http_client_factory: HttpClientFactory,
|
||||
pub password_manager: PasswordManager,
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for PgPool {
|
||||
@ -92,8 +93,15 @@ impl FromRef<AppState> for Arc<PolicyFactory> {
|
||||
input.policy_factory.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for HttpClientFactory {
|
||||
fn from_ref(input: &AppState) -> Self {
|
||||
input.http_client_factory.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for PasswordManager {
|
||||
fn from_ref(input: &AppState) -> Self {
|
||||
input.password_manager.clone()
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use pbkdf2::Pbkdf2;
|
||||
use rand::{CryptoRng, Rng, RngCore, SeedableRng};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
pub type SchemeVersion = u32;
|
||||
pub type SchemeVersion = u16;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PasswordManager {
|
||||
|
@ -128,6 +128,22 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"passwords": {
|
||||
"description": "Configuration related to user passwords",
|
||||
"default": {
|
||||
"schemes": [
|
||||
{
|
||||
"algorithm": "argon2id",
|
||||
"version": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PasswordsConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"policy": {
|
||||
"description": "Configuration related to the OPA policies",
|
||||
"default": {
|
||||
@ -647,6 +663,74 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"HashingScheme": {
|
||||
"description": "A hashing algorithm",
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "bcrypt",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"algorithm"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"bcrypt"
|
||||
]
|
||||
},
|
||||
"cost": {
|
||||
"description": "Hashing cost",
|
||||
"default": 12,
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "argon2id",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"algorithm"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"argon2id"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "PBKDF2",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"algorithm"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"pbkdf2"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"HttpConfig": {
|
||||
"description": "Configuration related to the web server",
|
||||
"type": "object",
|
||||
@ -1209,6 +1293,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"PasswordsConfig": {
|
||||
"description": "User password hashing config",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"schemes": {
|
||||
"default": [
|
||||
{
|
||||
"algorithm": "argon2id",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/HashingScheme"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"PolicyConfig": {
|
||||
"description": "Application secrets",
|
||||
"type": "object",
|
||||
|
Reference in New Issue
Block a user