mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
feat: impl auth challenges interfaces for mariadb
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge_reason (
|
||||||
|
id INT auto_increment,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
name VARCHAR(40) NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS mcaptcha_challenge (
|
||||||
|
id INT auto_increment,
|
||||||
|
PRIMARY KEY(id),
|
||||||
|
reason INT NOT NULL,
|
||||||
|
challenge_id varchar(40) NOT NULL UNIQUE,
|
||||||
|
received timestamp NOT NULL DEFAULT now(),
|
||||||
|
|
||||||
|
CONSTRAINT `fk_mcaptcha_mcaptcha_challenge_reason`
|
||||||
|
FOREIGN KEY (reason)
|
||||||
|
REFERENCES mcaptcha_challenge_reason (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
|
||||||
|
);
|
||||||
@@ -1,5 +1,15 @@
|
|||||||
{
|
{
|
||||||
"db": "MySQL",
|
"db": "MySQL",
|
||||||
|
"04e79a67bc8c1b18eca95fc4d2602ed5dd41b6d864796f034540efec3da05fa8": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT IGNORE INTO\n mcaptcha_challenge_reason (name)\n VALUES (?)"
|
||||||
|
},
|
||||||
"1367dceb151a766a901b5dd771d0b75d0bc61d2fef17a94a90c8ffa0065e2c44": {
|
"1367dceb151a766a901b5dd771d0b75d0bc61d2fef17a94a90c8ffa0065e2c44": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -199,6 +209,16 @@
|
|||||||
},
|
},
|
||||||
"query": "UPDATE mcaptcha_users set name = ?\n WHERE name = ?"
|
"query": "UPDATE mcaptcha_users set name = ?\n WHERE name = ?"
|
||||||
},
|
},
|
||||||
|
"6a31a6745dc005449f742b516979f195674848222b16c72c48da553a379a4e6f": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "INSERT INTO mcaptcha_challenge (challenge_id, received, reason)\n VALUES (?, ?, (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?));\n "
|
||||||
|
},
|
||||||
"6d1b6e5e58ca2ba285cab7b050bbdc43de1f3e46cf7d420bc95c124a1c7c9d1f": {
|
"6d1b6e5e58ca2ba285cab7b050bbdc43de1f3e46cf7d420bc95c124a1c7c9d1f": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
@@ -332,6 +352,31 @@
|
|||||||
},
|
},
|
||||||
"query": "insert into mcaptcha_users \n (name , password, email, secret) values (?, ?, ?, ?)"
|
"query": "insert into mcaptcha_users \n (name , password, email, secret) values (?, ?, ?, ?)"
|
||||||
},
|
},
|
||||||
|
"900a1f8c30fed90f8e56f88c4d0a2e81a7ea6af24d90c3a76764ee411b01af73": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": {
|
||||||
|
"char_set": 63,
|
||||||
|
"flags": {
|
||||||
|
"bits": 515
|
||||||
|
},
|
||||||
|
"max_size": 11,
|
||||||
|
"type": "Long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "SELECT id\n FROM mcaptcha_challenge\n WHERE\n challenge_id = ?\n AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);"
|
||||||
|
},
|
||||||
"9c435148ed5655e79dd1e73e3566ce23b7c6d38edcedbb988c95813c5da893ed": {
|
"9c435148ed5655e79dd1e73e3566ce23b7c6d38edcedbb988c95813c5da893ed": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
@@ -873,6 +918,16 @@
|
|||||||
},
|
},
|
||||||
"query": "SELECT name, password FROM mcaptcha_users WHERE email = ?"
|
"query": "SELECT name, password FROM mcaptcha_users WHERE email = ?"
|
||||||
},
|
},
|
||||||
|
"f47c05c0a7da41a2176f08a44c6c945dabb84558a4d09369b6108bfce8b9d2bf": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "DELETE\n FROM mcaptcha_challenge\n WHERE\n challenge_id = ?\n AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);"
|
||||||
|
},
|
||||||
"fc717ff0827ccfaa1cc61a71cc7f71c348ebb03d35895c54b011c03121ad2385": {
|
"fc717ff0827ccfaa1cc61a71cc7f71c348ebb03d35895c54b011c03121ad2385": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
|||||||
@@ -95,6 +95,22 @@ impl Migrate for Database {
|
|||||||
.run(&self.pool)
|
.run(&self.pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
|
||||||
|
for reason in [
|
||||||
|
ChallengeReason::EmailVerification,
|
||||||
|
ChallengeReason::PasswordReset,
|
||||||
|
] {
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT IGNORE INTO
|
||||||
|
mcaptcha_challenge_reason (name)
|
||||||
|
VALUES (?)",
|
||||||
|
reason.to_str()
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| DBError::DBError(Box::new(e)))?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,6 +911,73 @@ impl MCDatabase for Database {
|
|||||||
|
|
||||||
Ok(Date::dates_to_unix(records))
|
Ok(Date::dates_to_unix(records))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn new_challenge(&self, challenge: &mut Challenge) -> DBResult<()> {
|
||||||
|
let now = now_unix_time_stamp();
|
||||||
|
loop {
|
||||||
|
let res = sqlx::query!(
|
||||||
|
"INSERT INTO mcaptcha_challenge (challenge_id, received, reason)
|
||||||
|
VALUES (?, ?, (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?));
|
||||||
|
",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
now,
|
||||||
|
challenge.reason.to_str()
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
if let Err(Error::Database(err)) = res {
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
if err.code() == Some(Cow::from("23505")) {
|
||||||
|
let msg = err.message();
|
||||||
|
if msg.contains("for key 'challenge_id'") {
|
||||||
|
challenge.new_id();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Record challenge in database
|
||||||
|
async fn fetch_challenge(&self, challenge: &Challenge) -> DBResult<Challenge> {
|
||||||
|
struct C {
|
||||||
|
id: i32,
|
||||||
|
}
|
||||||
|
sqlx::query_as!(
|
||||||
|
C,
|
||||||
|
"SELECT id
|
||||||
|
FROM mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = ?
|
||||||
|
AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await
|
||||||
|
.map_err(map_register_err)?;
|
||||||
|
Ok(challenge.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete a challenge from database
|
||||||
|
async fn delete_challenge(&self, challenge: &Challenge) -> DBResult<()> {
|
||||||
|
let _ = sqlx::query!(
|
||||||
|
"DELETE
|
||||||
|
FROM mcaptcha_challenge
|
||||||
|
WHERE
|
||||||
|
challenge_id = ?
|
||||||
|
AND reason = (SELECT id FROM mcaptcha_challenge_reason WHERE name = ?);",
|
||||||
|
&challenge.challenge.to_string(),
|
||||||
|
challenge.reason.to_str(),
|
||||||
|
)
|
||||||
|
.execute(&self.pool)
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -89,4 +89,5 @@ async fn everyting_works() {
|
|||||||
description: CAPTCHA_DESCRIPTION,
|
description: CAPTCHA_DESCRIPTION,
|
||||||
};
|
};
|
||||||
database_works(&db, &p, &c, &LEVELS, &TRAFFIC_PATTERN, &ADD_NOTIFICATION).await;
|
database_works(&db, &p, &c, &LEVELS, &TRAFFIC_PATTERN, &ADD_NOTIFICATION).await;
|
||||||
|
challenges_works(&db).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user