mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2024-12-18 14:06:37 +00:00
Extract db query into its own function.
This commit is contained in:
parent
4695dfebf4
commit
db0ebb4828
1 changed files with 24 additions and 17 deletions
|
@ -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)?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue