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"] }
|
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 = { 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"] }
|
libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
|
||||||
|
uuid = { version = "1.3.3", features = ["v4", "serde"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
@ -31,7 +31,10 @@
|
|||||||
//! - [errors](crate::auth): error data structures used in this crate
|
//! - [errors](crate::auth): error data structures used in this crate
|
||||||
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
||||||
//! connection from pool
|
//! connection from pool
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub use libmcaptcha::defense::Level;
|
pub use libmcaptcha::defense::Level;
|
||||||
|
|
||||||
@ -97,6 +100,64 @@ pub struct NameHash {
|
|||||||
pub hash: String,
|
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]
|
#[async_trait]
|
||||||
/// mCaptcha's database requirements. To implement support for $Database, kindly implement this
|
/// mCaptcha's database requirements. To implement support for $Database, kindly implement this
|
||||||
/// trait.
|
/// trait.
|
||||||
@ -250,6 +311,15 @@ pub trait MCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase {
|
|||||||
|
|
||||||
/// fetch PoWConfig confirms
|
/// fetch PoWConfig confirms
|
||||||
async fn fetch_confirm(&self, user: &str, key: &str) -> DBResult<Vec<i64>>;
|
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)]
|
#[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();
|
db.delete_captcha(p.username, p.username).await.unwrap();
|
||||||
assert!(!db.captcha_exists(Some(p.username), c.key).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