Make a few password-related options public in the config crate

It also adds docs to a few of those options
This commit is contained in:
Quentin Gliech
2025-04-18 18:24:35 +02:00
parent b4a1e5f691
commit a061db35d7
3 changed files with 35 additions and 11 deletions

View File

@@ -38,7 +38,9 @@ pub use self::{
Resource as HttpResource, TlsConfig as HttpTlsConfig, UnixOrTcp,
},
matrix::{HomeserverKind, MatrixConfig},
passwords::{Algorithm as PasswordAlgorithm, PasswordsConfig},
passwords::{
Algorithm as PasswordAlgorithm, HashingScheme as PasswordHashingScheme, PasswordsConfig,
},
policy::PolicyConfig,
rate_limiting::RateLimitingConfig,
secrets::SecretsConfig,

View File

@@ -16,7 +16,7 @@ use crate::ConfigurationSection;
fn default_schemes() -> Vec<HashingScheme> {
vec![HashingScheme {
version: 1,
algorithm: Algorithm::Argon2id,
algorithm: Algorithm::default(),
cost: None,
secret: None,
secret_file: None,
@@ -36,10 +36,14 @@ fn default_minimum_complexity() -> u8 {
pub struct PasswordsConfig {
/// Whether password-based authentication is enabled
#[serde(default = "default_enabled")]
enabled: bool,
pub enabled: bool,
/// The hashing schemes to use for hashing and validating passwords
///
/// The hashing scheme with the highest version number will be used for
/// hashing new passwords.
#[serde(default = "default_schemes")]
schemes: Vec<HashingScheme>,
pub schemes: Vec<HashingScheme>,
/// Score between 0 and 4 determining the minimum allowed password
/// complexity. Scores are based on the ESTIMATED number of guesses
@@ -154,23 +158,30 @@ impl PasswordsConfig {
}
}
/// Parameters for a password hashing scheme
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct HashingScheme {
version: u16,
/// The version of the hashing scheme. They must be unique, and the highest
/// version will be used for hashing new passwords.
pub version: u16,
algorithm: Algorithm,
/// The hashing algorithm to use
pub algorithm: Algorithm,
/// Cost for the bcrypt algorithm
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(default = "default_bcrypt_cost")]
cost: Option<u32>,
pub cost: Option<u32>,
/// An optional secret to use when hashing passwords. This makes it harder
/// to brute-force the passwords in case of a database leak.
#[serde(skip_serializing_if = "Option::is_none")]
secret: Option<String>,
pub secret: Option<String>,
/// Same as `secret`, but read from a file.
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(with = "Option<String>")]
secret_file: Option<Utf8PathBuf>,
pub secret_file: Option<Utf8PathBuf>,
}
#[allow(clippy::unnecessary_wraps)]
@@ -179,13 +190,14 @@ fn default_bcrypt_cost() -> Option<u32> {
}
/// A hashing algorithm
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum Algorithm {
/// bcrypt
Bcrypt,
/// argon2id
#[default]
Argon2id,
/// PBKDF2

View File

@@ -1566,6 +1566,7 @@
"type": "boolean"
},
"schemes": {
"description": "The hashing schemes to use for hashing and validating passwords\n\nThe hashing scheme with the highest version number will be used for hashing new passwords.",
"default": [
{
"version": 1,
@@ -1587,6 +1588,7 @@
}
},
"HashingScheme": {
"description": "Parameters for a password hashing scheme",
"type": "object",
"required": [
"algorithm",
@@ -1594,12 +1596,18 @@
],
"properties": {
"version": {
"description": "The version of the hashing scheme. They must be unique, and the highest version will be used for hashing new passwords.",
"type": "integer",
"format": "uint16",
"minimum": 0.0
},
"algorithm": {
"$ref": "#/definitions/Algorithm"
"description": "The hashing algorithm to use",
"allOf": [
{
"$ref": "#/definitions/Algorithm"
}
]
},
"cost": {
"description": "Cost for the bcrypt algorithm",
@@ -1609,9 +1617,11 @@
"minimum": 0.0
},
"secret": {
"description": "An optional secret to use when hashing passwords. This makes it harder to brute-force the passwords in case of a database leak.",
"type": "string"
},
"secret_file": {
"description": "Same as `secret`, but read from a file.",
"type": "string"
}
}