diff --git a/migrations/20210310122154_mcaptcha_users.sql b/migrations/20210310122154_mcaptcha_users.sql
index 28a9c24f..09a59c35 100644
--- a/migrations/20210310122154_mcaptcha_users.sql
+++ b/migrations/20210310122154_mcaptcha_users.sql
@@ -1,6 +1,7 @@
CREATE TABLE IF NOT EXISTS mcaptcha_users (
name VARCHAR(100) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
+ secret varchar(50) NOT NULL UNIQUE,
password TEXT NOT NULL,
ID SERIAL PRIMARY KEY NOT NULL
);
diff --git a/src/api/v1/auth.rs b/src/api/v1/auth.rs
index 4ca818d4..39cc8656 100644
--- a/src/api/v1/auth.rs
+++ b/src/api/v1/auth.rs
@@ -14,12 +14,14 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+use std::borrow::Cow;
use actix_identity::Identity;
use actix_web::{post, web, HttpResponse, Responder};
use log::debug;
use serde::{Deserialize, Serialize};
+use super::mcaptcha::get_random;
use crate::errors::*;
use crate::Data;
@@ -49,19 +51,53 @@ pub async fn signup(
let username = data.creds.username(&payload.username)?;
let hash = data.creds.password(&payload.password)?;
data.creds.email(Some(&payload.email))?;
- let res = sqlx::query!(
- "INSERT INTO mcaptcha_users (name , password, email) VALUES ($1, $2, $3)",
+
+ let mut secret;
+
+ loop {
+ secret = get_random(32);
+ let res = add_user_helper(&username, &hash, &payload.email, &secret, &data).await;
+ if res.is_ok() {
+ break;
+ } else {
+ if let Err(sqlx::Error::Database(err)) = res {
+ if err.code() == Some(Cow::from("23505")) {
+ let msg = err.message();
+ if msg.contains("mcaptcha_users_name_key") {
+ Err(ServiceError::UsernameTaken)?;
+ } else if msg.contains("mcaptcha_users_secret_key") {
+ continue;
+ } else {
+ Err(ServiceError::InternalServerError)?;
+ }
+ } else {
+ Err(sqlx::Error::Database(err))?;
+ }
+ };
+ }
+ }
+ Ok(HttpResponse::Ok())
+}
+
+pub async fn add_user_helper(
+ username: &str,
+ hash: &str,
+ email: &str,
+ secret: &str,
+ data: &Data,
+) -> Result<(), sqlx::Error> {
+ sqlx::query!(
+ "INSERT INTO mcaptcha_users
+ (name , password, email, secret) VALUES ($1, $2, $3, $4)",
username,
hash,
- &payload.email
+ email,
+ //get_random(32),
+ secret,
)
.execute(&data.db)
- .await;
-
- match res {
- Err(e) => Err(dup_error(e, ServiceError::UsernameTaken)),
- Ok(_) => Ok(HttpResponse::Ok()),
- }
+ .await?;
+ Ok(())
}
#[post("/api/v1/signin")]
diff --git a/src/errors.rs b/src/errors.rs
index e573334c..bb061b04 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -204,7 +204,9 @@ impl From for ServiceError {
pub fn dup_error(e: sqlx::Error, dup_error: ServiceError) -> ServiceError {
use sqlx::error::Error;
use std::borrow::Cow;
+ // println!("sqlx:Error: {:#?}", &e);
if let Error::Database(err) = e {
+ // println!("Database Error: {:#?}", &err);
if err.code() == Some(Cow::from("23505")) {
dup_error
} else {