1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-07 17:03:01 +03:00

Use the new password manager

This commit is contained in:
Quentin Gliech
2022-12-14 15:28:36 +01:00
parent ff2f009b0e
commit 533cabe005
19 changed files with 768 additions and 427 deletions

View File

@@ -13,16 +13,14 @@
// limitations under the License.
use anyhow::Context;
use argon2::Argon2;
use clap::{Parser, ValueEnum};
use mas_config::{DatabaseConfig, RootConfig};
use mas_config::{DatabaseConfig, PasswordsConfig, RootConfig};
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
use mas_router::UrlBuilder;
use mas_storage::{
oauth2::client::{insert_client_from_config, lookup_client, truncate_clients},
user::{
lookup_user_by_username, lookup_user_email, mark_user_email_as_verified, register_user,
set_password,
add_user_password, lookup_user_by_username, lookup_user_email, mark_user_email_as_verified,
},
Clock,
};
@@ -30,6 +28,8 @@ use oauth2_types::scope::Scope;
use rand::SeedableRng;
use tracing::{info, warn};
use crate::util::password_manager_from_config;
#[derive(Parser, Debug)]
pub(super) struct Options {
#[command(subcommand)]
@@ -142,9 +142,6 @@ impl From<&SigningAlgorithm> for JsonWebSignatureAlg {
#[derive(Parser, Debug)]
enum Subcommand {
/// Register a new user
Register { username: String, password: String },
/// Mark email address as verified
VerifyEmail { username: String, email: String },
@@ -196,30 +193,33 @@ impl Options {
let mut rng = rand_chacha::ChaChaRng::from_entropy();
match &self.subcommand {
SC::Register { username, password } => {
let config: DatabaseConfig = root.load_config()?;
let pool = config.connect().await?;
let mut txn = pool.begin().await?;
let hasher = Argon2::default();
let user =
register_user(&mut txn, &mut rng, &clock, hasher, username, password).await?;
txn.commit().await?;
info!(%user.id, %user.username, "User registered");
Ok(())
}
SC::SetPassword { username, password } => {
let config: DatabaseConfig = root.load_config()?;
let pool = config.connect().await?;
let database_config: DatabaseConfig = root.load_config()?;
let passwords_config: PasswordsConfig = root.load_config()?;
let pool = database_config.connect().await?;
let password_manager = password_manager_from_config(&passwords_config).await?;
let mut txn = pool.begin().await?;
let hasher = Argon2::default();
let user = lookup_user_by_username(&mut txn, username)
.await?
.context("User not found")?;
set_password(&mut txn, &mut rng, &clock, hasher, &user, password).await?;
let password = password.as_bytes().to_vec().into();
let (version, hashed_password) = password_manager.hash(&mut rng, password).await?;
add_user_password(
&mut txn,
&mut rng,
&clock,
&user,
version,
hashed_password,
None,
)
.await?;
info!(%user.id, %user.username, "Password changed");
txn.commit().await?;

View File

@@ -20,7 +20,7 @@ use futures_util::stream::{StreamExt, TryStreamExt};
use itertools::Itertools;
use mas_config::RootConfig;
use mas_email::Mailer;
use mas_handlers::{passwords::PasswordManager, AppState, HttpClientFactory, MatrixHomeserver};
use mas_handlers::{AppState, HttpClientFactory, MatrixHomeserver};
use mas_listener::{server::Server, shutdown::ShutdownStream};
use mas_policy::PolicyFactory;
use mas_router::UrlBuilder;
@@ -30,6 +30,8 @@ use mas_templates::Templates;
use tokio::signal::unix::SignalKind;
use tracing::{error, info, log::warn};
use crate::util::password_manager_from_config;
#[derive(Parser, Debug, Default)]
pub(super) struct Options {
/// Automatically apply pending migrations
@@ -168,23 +170,7 @@ 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)?;
let password_manager = password_manager_from_config(&config.passwords).await?;
// Explicitely the config to properly zeroize secret keys
drop(config);