summaryrefslogtreecommitdiff
path: root/src/password.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/password.rs')
-rw-r--r--src/password.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/password.rs b/src/password.rs
new file mode 100644
index 0000000..b14f728
--- /dev/null
+++ b/src/password.rs
@@ -0,0 +1,31 @@
+use argon2::Argon2;
+use password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString};
+use rand_core::OsRng;
+
+#[derive(Debug, sqlx::Type)]
+#[sqlx(transparent)]
+pub struct StoredHash(String);
+
+impl StoredHash {
+ pub fn new(password: &str) -> Result<Self, password_hash::Error> {
+ let salt = SaltString::generate(&mut OsRng);
+ let argon2 = Argon2::default();
+ let hash = argon2
+ .hash_password(password.as_bytes(), &salt)?
+ .to_string();
+ Ok(Self(hash))
+ }
+
+ pub fn verify(&self, password: &str) -> Result<bool, password_hash::Error> {
+ let hash = PasswordHash::new(&self.0)?;
+
+ match Argon2::default().verify_password(password.as_bytes(), &hash) {
+ // Successful authentication, not an error
+ Ok(()) => Ok(true),
+ // Unsuccessful authentication, also not an error
+ Err(password_hash::errors::Error::Password) => Ok(false),
+ // Password validation failed for some other reason, treat as an error
+ Err(err) => Err(err),
+ }
+ }
+}