mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2025-11-29 00:23:01 +00:00
feat: define internfaces to create,fetch and rm auth challenges
This commit is contained in:
parent
78de0b266f
commit
c53fe2e3ff
@ -15,6 +15,7 @@ serde = { version = "1", features = ["derive"]}
|
||||
url = { version = "2.2.2", features = ["serde"] }
|
||||
#libmcaptcha = { version = "0.2.2", git = "https://github.com/mCaptcha/libmcaptcha", features = ["minimal"], default-features = false, tag = "0.2.2"}
|
||||
libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
|
||||
uuid = { version = "1.3.3", features = ["v4", "serde"] }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@ -31,7 +31,10 @@
|
||||
//! - [errors](crate::auth): error data structures used in this crate
|
||||
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
||||
//! connection from pool
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use libmcaptcha::defense::Level;
|
||||
|
||||
@ -97,6 +100,64 @@ pub struct NameHash {
|
||||
pub hash: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||
/// Email challenge reason
|
||||
pub enum ChallengeReason {
|
||||
/// challenge created to verify a newly registered user
|
||||
EmailVerification,
|
||||
/// Challenge created to verify a password reset request
|
||||
PasswordReset,
|
||||
}
|
||||
|
||||
impl ChallengeReason {
|
||||
pub fn to_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::EmailVerification => "email_verification",
|
||||
Self::PasswordReset => "password_resset",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for ChallengeReason {
|
||||
fn to_string(&self) -> String {
|
||||
self.to_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ChallengeReason {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
for reason in [Self::PasswordReset, Self::EmailVerification].iter() {
|
||||
if s == reason.to_str() {
|
||||
return Ok(reason.clone());
|
||||
}
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||
/// Email challenge
|
||||
pub struct Challenge {
|
||||
/// challenge unique identifier
|
||||
pub challenge: Uuid,
|
||||
/// reason why the challenge was create
|
||||
pub reason: ChallengeReason,
|
||||
}
|
||||
|
||||
impl Challenge {
|
||||
/// create new Challenge instance for a given reason. Challenge text is auto-generated
|
||||
pub fn new(reason: ChallengeReason) -> Self {
|
||||
let challenge = Uuid::new_v4();
|
||||
Self { challenge, reason }
|
||||
}
|
||||
|
||||
/// Generate new ID (useful when ID clashes)
|
||||
pub fn new_id(&mut self) {
|
||||
self.challenge = Uuid::new_v4();
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
/// mCaptcha's database requirements. To implement support for $Database, kindly implement this
|
||||
/// trait.
|
||||
@ -250,6 +311,15 @@ pub trait MCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase {
|
||||
|
||||
/// fetch PoWConfig confirms
|
||||
async fn fetch_confirm(&self, user: &str, key: &str) -> DBResult<Vec<i64>>;
|
||||
|
||||
/// Record challenge in database
|
||||
async fn new_challenge(&self, challenge: &mut Challenge) -> DBResult<()>;
|
||||
|
||||
/// Record challenge in database
|
||||
async fn fetch_challenge(&self, challenge: &Challenge) -> DBResult<Challenge>;
|
||||
|
||||
/// Delete a challenge from database
|
||||
async fn delete_challenge(&self, challenge: &Challenge) -> DBResult<()>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
|
||||
|
||||
@ -296,3 +296,14 @@ pub async fn database_works<'a, T: MCDatabase>(
|
||||
db.delete_captcha(p.username, p.username).await.unwrap();
|
||||
assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());
|
||||
}
|
||||
|
||||
/// test all challenge routines
|
||||
pub async fn challenges_works<'a, T: MCDatabase>(db: &T) {
|
||||
let mut challenge = Challenge::new(ChallengeReason::PasswordReset);
|
||||
db.new_challenge(&mut challenge).await.unwrap();
|
||||
db.new_challenge(&mut challenge).await.unwrap();
|
||||
let c = db.fetch_challenge(&challenge).await.unwrap();
|
||||
assert_eq!(c, challenge);
|
||||
db.delete_challenge(&challenge).await.unwrap();
|
||||
assert!(db.fetch_challenge(&challenge).await.is_err())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user