Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 41af00c

Browse files
Feat: changed hashing algo from sha3 to aragon2
1 parent 97f774c commit 41af00c

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Add migration script here
2+
ALTER TABLE users ADD COLUMN salt TEXT NOT NULL;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Add migration script here
2+
ALTER TABLE users DROP COLUMN salt;

‎src/routes/newsletters.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use actix_web::http::header::{HeaderMap, HeaderValue};
33
use actix_web::http::{header, StatusCode};
44
use actix_web::{web, HttpRequest, HttpResponse, ResponseError};
55
use anyhow::Context;
6+
use argon2::{Algorithm, Argon2, Params, PasswordHash, PasswordVerifier, Version};
67
use secrecy::{ExposeSecret, Secret};
78
use sha3::Digest;
89
use sqlx::PgPool;
@@ -152,21 +153,40 @@ async fn validate_credentials(
152153
credentials: Credentials,
153154
pool: &PgPool,
154155
) -> Result<uuid::Uuid, PublishError> {
155-
let password_hash = sha3::Sha3_256::digest(credentials.password.expose_secret().as_bytes());
156-
let password_hash = format!("{:x}", password_hash);
157-
158-
let user_id: Option<_> = sqlx::query!(
159-
r#"SELECT user_id FROM users WHERE username = 1ドル AND password_hash = 2ドル"#,
156+
let hasher = Argon2::new(
157+
Algorithm::Argon2id,
158+
Version::V0x13,
159+
Params::new(15000, 2, 1, None)
160+
.context("Failed to build Argon2 params")
161+
.map_err(PublishError::UnexpectedError)?,
162+
);
163+
164+
let row: Option<_> = sqlx::query!(
165+
r#"SELECT user_id, password_hash, salt FROM users WHERE username = 1ドル"#,
160166
credentials.username,
161-
password_hash,
162167
)
163168
.fetch_optional(pool)
164169
.await
165170
.context("Failed to perform the query to validate auth credentials")
166171
.map_err(PublishError::UnexpectedError)?;
167172

168-
user_id
169-
.map(|row| row.user_id)
170-
.ok_or_else(|| anyhow::anyhow!("Invalid username or password"))
171-
.map_err(PublishError::AuthError)
173+
let (expected_password_hash, user_id, salt) = match row {
174+
Some(row) => (row.password_hash, row.user_id, row.salt),
175+
None => {
176+
return Err(PublishError::AuthError(anyhow::anyhow!(
177+
"Invalid username or password"
178+
)))
179+
}
180+
};
181+
182+
let expected_password_hash = PasswordHash::new(&expected_password_hash)
183+
.context("Failed to parse hash in PHC string format")
184+
.map_err(PublishError::UnexpectedError)?;
185+
186+
Argon2::default().verify_password(
187+
credentials.password.expose_secret().as_bytes(),
188+
&expected_password_hash,
189+
).context("Failed to verify password").map_err(PublishError::UnexpectedError)?;
190+
191+
Ok(user_id)
172192
}

‎tests/api/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub async fn spawn_app() -> TestApp {
149149
test_user: TestUser::generate(),
150150
};
151151

152-
test_app.test_user.store(&test_app.db_pool).await;
152+
test_app.test_user.store(&test_app.db_pool).await;
153153
test_app
154154
}
155155

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /