feat: implement easypwned checks

This commit is contained in:
izzy
2025-05-08 12:09:02 +01:00
parent 31aa0b032f
commit 86788c7e8d
5 changed files with 65 additions and 16 deletions
Generated
+22 -10
View File
@@ -239,7 +239,7 @@ checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
[[package]]
name = "authifier"
version = "1.0.9"
version = "1.0.9-beta.0"
dependencies = [
"async-std",
"async-trait",
@@ -264,6 +264,7 @@ dependencies = [
"schemars",
"serde",
"serde_json",
"sha1",
"totp-lite",
"ulid",
"validator",
@@ -619,9 +620,9 @@ dependencies = [
[[package]]
name = "digest"
version = "0.10.3"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer 0.10.2",
"crypto-common",
@@ -985,7 +986,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest 0.10.3",
"digest 0.10.7",
]
[[package]]
@@ -1315,7 +1316,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582"
dependencies = [
"digest 0.10.3",
"digest 0.10.7",
]
[[package]]
@@ -1592,7 +1593,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271779f35b581956db91a3e55737327a03aa051e90b1c47aeb189508533adfd7"
dependencies = [
"digest 0.10.3",
"digest 0.10.7",
]
[[package]]
@@ -1989,7 +1990,7 @@ dependencies = [
[[package]]
name = "rocket_authifier"
version = "1.0.9"
version = "1.0.9-beta.0"
dependencies = [
"async-std",
"authifier",
@@ -2328,7 +2329,18 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.10.3",
"digest 0.10.7",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.10.7",
]
[[package]]
@@ -2339,7 +2351,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.10.3",
"digest 0.10.7",
]
[[package]]
@@ -2661,7 +2673,7 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc496875d9c8fe9a0ce19e3ee8e8808c60376831a439543f0aac71c9dd129fa"
dependencies = [
"digest 0.10.3",
"digest 0.10.7",
"hmac",
"sha-1 0.10.0",
"sha2",
+2 -1
View File
@@ -1,2 +1,3 @@
[workspace]
members = ["crates/*"]
resolver = "1"
members = ["crates/*"]
+4 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "authifier"
version = "1.0.9"
version = "1.0.9-beta.0"
edition = "2021"
license = "Apache-2.0"
authors = ["Pawel Makles <me@insrt.uk>"]
@@ -21,7 +21,8 @@ pwned100k = []
have_i_been_pwned = []
hcaptcha = ["reqwest"]
shield = ["reqwest"]
default_inbuilts = ["pwned100k", "hcaptcha", "shield"]
easypwned = ["reqwest"]
default_inbuilts = ["pwned100k", "hcaptcha", "shield", "easypwned"]
# default_inbuilts = []
default = ["async-std-runtime", "database-mongodb", "default_inbuilts"]
@@ -41,6 +42,7 @@ async-trait = "0.1.56"
futures = { version = "0.3.21" }
# Serde
sha1 = "0.10.6"
serde_json = { version = "1.0.81" }
iso8601-timestamp = { version = "0.1.10" }
serde = { version = "1.0.116", features = ["derive"] }
+35 -1
View File
@@ -1,5 +1,7 @@
use std::collections::HashSet;
use sha1::Digest;
use crate::{Error, Result};
#[derive(Default, Serialize, Deserialize, Clone)]
@@ -13,12 +15,14 @@ pub enum PasswordScanning {
#[cfg(feature = "pwned100k")]
#[default]
Top100k,
/// easypwned locally-hosted HIBP database API
#[cfg(feature = "easypwned")]
EasyPwned { endpoint: String },
/// Use the Have I Been Pwned? API
#[cfg(feature = "have_i_been_pwned")]
HIBP { api_key: String },
}
#[cfg(feature = "pwned100k")]
lazy_static! {
/// Top 100k compromised passwords
@@ -46,6 +50,36 @@ impl PasswordScanning {
Ok(())
}
}
#[cfg(feature = "easypwned")]
PasswordScanning::EasyPwned { endpoint } => {
let mut hasher = sha1::Sha1::new();
hasher.update(password);
let pwd_hash = hasher.finalize();
#[derive(Deserialize)]
struct EasyPwnedResult {
secure: bool,
}
if let Ok(response) = reqwest::get(format!("{endpoint}/hash/{pwd_hash:#02x}")).await
{
if let Ok(result) = response.json::<EasyPwnedResult>().await {
if result.secure {
Ok(())
} else {
Err(Error::CompromisedPassword)
}
} else if TOP_100K_COMPROMISED.contains(password) {
Err(Error::CompromisedPassword)
} else {
Ok(())
}
} else if TOP_100K_COMPROMISED.contains(password) {
Err(Error::CompromisedPassword)
} else {
Ok(())
}
}
#[cfg(feature = "pwned100k")]
PasswordScanning::Top100k => {
if TOP_100K_COMPROMISED.contains(password) {
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "rocket_authifier"
version = "1.0.9"
version = "1.0.9-beta.0"
edition = "2021"
license = "Apache-2.0"
authors = ["Pawel Makles <me@insrt.uk>"]
@@ -22,7 +22,7 @@ default = []
[dependencies]
# Authifier
authifier = { version = "1.0.9", path = "../authifier", features = [
authifier = { version = "1.0.9-beta.0", path = "../authifier", features = [
"rocket_impl",
"okapi_impl",
] }