Extract db query into its own function.

This commit is contained in:
Luca Palmieri 2021-08-30 13:56:34 +02:00
parent 4695dfebf4
commit db0ebb4828

View file

@ -84,38 +84,45 @@ fn basic_authentication(headers: &HeaderMap) -> Result<Credentials, anyhow::Erro
Ok(Credentials { username, password })
}
async fn validate_credentials(
credentials: Credentials,
#[tracing::instrument(name = "Get stored credentials", skip(username, pool))]
async fn get_stored_credentials(
username: &str,
pool: &PgPool,
) -> Result<uuid::Uuid, PublishError> {
let row: Option<_> = sqlx::query!(
) -> Result<Option<(uuid::Uuid, String)>, anyhow::Error> {
let row = sqlx::query!(
r#"
SELECT user_id, password_hash
FROM users
WHERE username = $1
"#,
credentials.username,
username,
)
.fetch_optional(pool)
.await
.context("Failed to performed a query to retrieve stored credentials.")
.map_err(PublishError::UnexpectedError)?;
.context("Failed to performed a query to retrieve stored credentials.")?
.map(|row| (row.user_id, row.password_hash));
Ok(row)
}
let (expected_password_hash, user_id) = match row {
Some(row) => (row.password_hash, row.user_id),
None => {
return Err(PublishError::AuthError(anyhow::anyhow!(
"Unknown username."
)))
}
};
#[tracing::instrument(name = "Validate credentials", skip(credentials, pool))]
async fn validate_credentials(
credentials: Credentials,
pool: &PgPool,
) -> Result<uuid::Uuid, PublishError> {
let (user_id, expected_password_hash) = get_stored_credentials(&credentials.username, &pool)
.await
.map_err(PublishError::UnexpectedError)?
.ok_or_else(|| PublishError::AuthError(anyhow::anyhow!("Unknown username.")))?;
let expected_password_hash = PasswordHash::new(&expected_password_hash)
.context("Failed to parse hash in PHC string format.")
.map_err(PublishError::UnexpectedError)?;
Argon2::default()
.verify_password(credentials.password.as_bytes(), &expected_password_hash)
tracing::info_span!("Verify password hash")
.in_scope(|| {
Argon2::default()
.verify_password(credentials.password.as_bytes(), &expected_password_hash)
})
.context("Invalid password.")
.map_err(PublishError::AuthError)?;