mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2025-03-29 12:48:59 +03:00
cascading delete, mcaptcha add/del and test suite
This commit is contained in:
parent
6be10af6fd
commit
096dcd32e4
8 changed files with 287 additions and 85 deletions
|
@ -1,4 +1,4 @@
|
||||||
CREATE TABLE IF NOT EXISTS mcaptcha_domains (
|
CREATE TABLE IF NOT EXISTS mcaptcha_domains (
|
||||||
name VARCHAR(100) PRIMARY KEY NOT NULL UNIQUE,
|
name VARCHAR(100) PRIMARY KEY NOT NULL UNIQUE,
|
||||||
ID INTEGER references mcaptcha_users(ID) NOT NULL
|
ID INTEGER references mcaptcha_users(ID) ON DELETE CASCADE NOT NULL
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
CREATE TABLE IF NOT EXISTS mcaptcha_config (
|
CREATE TABLE IF NOT EXISTS mcaptcha_config (
|
||||||
config_id SERIAL PRIMARY KEY NOT NULL,
|
config_id SERIAL PRIMARY KEY NOT NULL,
|
||||||
ID INTEGER references mcaptcha_users(ID),
|
domain_name VARCHAR(100) NOT NULL references mcaptcha_domains(name) ON DELETE CASCADE,
|
||||||
key VARCHAR(100) NOT NULL UNIQUE,
|
key VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
name VARCHAR(100) NOT NULL UNIQUE,
|
||||||
duration INTEGER NOT NULL DEFAULT 30
|
duration INTEGER NOT NULL DEFAULT 30
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
CREATE TABLE IF NOT EXISTS mcaptcha_levels (
|
CREATE TABLE IF NOT EXISTS mcaptcha_levels (
|
||||||
config_id INTEGER references mcaptcha_config(config_id),
|
config_id INTEGER references mcaptcha_config(config_id) ON DELETE CASCADE,
|
||||||
difficulty_factor INTEGER NOT NULL,
|
difficulty_factor INTEGER NOT NULL,
|
||||||
visitor_threshold INTEGER NOT NULL,
|
visitor_threshold INTEGER NOT NULL,
|
||||||
level_id SERIAL PRIMARY KEY NOT NULL
|
level_id SERIAL PRIMARY KEY NOT NULL
|
||||||
|
|
|
@ -172,13 +172,15 @@ mod tests {
|
||||||
const NAME: &str = "testuser";
|
const NAME: &str = "testuser";
|
||||||
const PASSWORD: &str = "longpassword";
|
const PASSWORD: &str = "longpassword";
|
||||||
const EMAIL: &str = "testuser1@a.com";
|
const EMAIL: &str = "testuser1@a.com";
|
||||||
|
const SIGNIN: &str = "/api/v1/signin";
|
||||||
|
const SIGNUP: &str = "/api/v1/signup";
|
||||||
|
|
||||||
let mut app = get_app!(data).await;
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
delete_user(NAME, &data).await;
|
delete_user(NAME, &data).await;
|
||||||
|
|
||||||
// 1. Register and signin
|
// 1. Register and signin
|
||||||
let (data, _, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
|
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
let cookies = get_cookie!(signin_resp);
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
|
||||||
// 2. check if duplicate username is allowed
|
// 2. check if duplicate username is allowed
|
||||||
|
@ -187,49 +189,55 @@ mod tests {
|
||||||
password: PASSWORD.into(),
|
password: PASSWORD.into(),
|
||||||
email: EMAIL.into(),
|
email: EMAIL.into(),
|
||||||
};
|
};
|
||||||
let duplicate_user_resp =
|
bad_post_req_test(
|
||||||
test::call_service(&mut app, post_request!(&msg, "/api/v1/signup").to_request()).await;
|
NAME,
|
||||||
assert_eq!(duplicate_user_resp.status(), StatusCode::BAD_REQUEST);
|
PASSWORD,
|
||||||
|
SIGNUP,
|
||||||
|
&msg,
|
||||||
|
ServiceError::UsernameTaken,
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
// 3. sigining in with non-existent user
|
// 3. sigining in with non-existent user
|
||||||
let nonexistantuser = Login {
|
let mut login = Login {
|
||||||
username: "nonexistantuser".into(),
|
username: "nonexistantuser".into(),
|
||||||
password: msg.password.clone(),
|
password: msg.password.clone(),
|
||||||
};
|
};
|
||||||
let userdoesntexist = test::call_service(
|
bad_post_req_test(
|
||||||
&mut app,
|
NAME,
|
||||||
post_request!(&nonexistantuser, "/api/v1/signin").to_request(),
|
PASSWORD,
|
||||||
|
SIGNIN,
|
||||||
|
&login,
|
||||||
|
ServiceError::UsernameNotFound,
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(userdoesntexist.status(), StatusCode::UNAUTHORIZED);
|
|
||||||
let txt: ErrorToResponse = test::read_body_json(userdoesntexist).await;
|
|
||||||
assert_eq!(txt.error, format!("{}", ServiceError::UsernameNotFound));
|
|
||||||
|
|
||||||
// 4. trying to signin with wrong password
|
// 4. trying to signin with wrong password
|
||||||
let wrongpassword = Login {
|
login.username = NAME.into();
|
||||||
username: NAME.into(),
|
login.password = NAME.into();
|
||||||
password: NAME.into(),
|
|
||||||
};
|
bad_post_req_test(
|
||||||
let wrongpassword_resp = test::call_service(
|
NAME,
|
||||||
&mut app,
|
PASSWORD,
|
||||||
post_request!(&wrongpassword, "/api/v1/signin").to_request(),
|
SIGNIN,
|
||||||
|
&login,
|
||||||
|
ServiceError::WrongPassword,
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(wrongpassword_resp.status(), StatusCode::UNAUTHORIZED);
|
|
||||||
let txt: ErrorToResponse = test::read_body_json(wrongpassword_resp).await;
|
|
||||||
assert_eq!(txt.error, format!("{}", ServiceError::WrongPassword));
|
|
||||||
|
|
||||||
// 5. signout
|
// 5. signout
|
||||||
let signout_resp = test::call_service(
|
let signout_resp = test::call_service(
|
||||||
&mut app,
|
&mut app,
|
||||||
post_request!(&wrongpassword, "/api/v1/signout")
|
test::TestRequest::post()
|
||||||
.cookie(cookies.clone())
|
.uri("/api/v1/signout")
|
||||||
|
.cookie(cookies)
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(signout_resp.status(), StatusCode::OK);
|
assert_eq!(signout_resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
delete_user(NAME, &data).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
@ -238,7 +246,12 @@ mod tests {
|
||||||
const PASSWORD: &str = "longpassword2";
|
const PASSWORD: &str = "longpassword2";
|
||||||
const EMAIL: &str = "testuser1@a.com2";
|
const EMAIL: &str = "testuser1@a.com2";
|
||||||
|
|
||||||
let (data, creds, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
|
{
|
||||||
|
let data = Data::new().await;
|
||||||
|
delete_user(NAME, &data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (data, creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
let cookies = get_cookie!(signin_resp);
|
let cookies = get_cookie!(signin_resp);
|
||||||
let mut app = get_app!(data).await;
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
|
@ -251,6 +264,5 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
assert_eq!(delete_user_resp.status(), StatusCode::OK);
|
assert_eq!(delete_user_resp.status(), StatusCode::OK);
|
||||||
delete_user(NAME, &data).await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,18 @@ pub async fn add_domain(
|
||||||
let url = Url::parse(&payload.name)?;
|
let url = Url::parse(&payload.name)?;
|
||||||
if let Some(host) = url.host_str() {
|
if let Some(host) = url.host_str() {
|
||||||
let user = id.identity().unwrap();
|
let user = id.identity().unwrap();
|
||||||
sqlx::query!(
|
let res = sqlx::query!(
|
||||||
"insert into mcaptcha_domains (name, ID) values
|
"insert into mcaptcha_domains (name, ID) values
|
||||||
($1, (select ID from mcaptcha_users where name = ($2) ));",
|
($1, (select ID from mcaptcha_users where name = ($2) ));",
|
||||||
host,
|
host,
|
||||||
user
|
user
|
||||||
)
|
)
|
||||||
.execute(&data.db)
|
.execute(&data.db)
|
||||||
.await?;
|
.await;
|
||||||
Ok(HttpResponse::Ok())
|
match res {
|
||||||
|
Err(e) => Err(dup_error(e, ServiceError::HostnameTaken)),
|
||||||
|
Ok(_) => Ok(HttpResponse::Ok()),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ServiceError::NotAUrl)
|
Err(ServiceError::NotAUrl)
|
||||||
}
|
}
|
||||||
|
@ -72,8 +75,9 @@ pub async fn delete_domain(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct TokenName {
|
pub struct CreateToken {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub domain: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
@ -82,34 +86,60 @@ pub struct TokenKeyPair {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[post("/api/v1/mcaptcha/domain/token/add")]
|
#[post("/api/v1/mcaptcha/domain/token/add")]
|
||||||
//pub async fn add_mcaptcha(
|
pub async fn add_mcaptcha(
|
||||||
// payload: web::Json<Domain>,
|
payload: web::Json<CreateToken>,
|
||||||
// data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
// id: Identity,
|
id: Identity,
|
||||||
//) -> ServiceResult<impl Responder> {
|
) -> ServiceResult<impl Responder> {
|
||||||
// is_authenticated(&id)?;
|
is_authenticated(&id)?;
|
||||||
// let key = get_random(32);
|
let key = get_random(32);
|
||||||
// let res = sqlx::query!(
|
let url = Url::parse(&payload.domain)?;
|
||||||
// "INSERT INTO mcaptcha_config (name, key) VALUES ($1, $2)",
|
println!("got req");
|
||||||
// &payload.name,
|
if let Some(host) = url.host_str() {
|
||||||
// &key,
|
let res = sqlx::query!(
|
||||||
// )
|
"INSERT INTO mcaptcha_config
|
||||||
// .execute(&data.db)
|
(name, key, domain_name)
|
||||||
// .await;
|
VALUES ($1, $2, (
|
||||||
//
|
SELECT name FROM mcaptcha_domains WHERE name = ($3)))",
|
||||||
// match res {
|
&payload.name,
|
||||||
// Err(e) => Err(dup_error(e, ServiceError::UsernameTaken)),
|
&key,
|
||||||
// Ok(_) => {
|
&host,
|
||||||
// let resp = TokenKeyPair {
|
)
|
||||||
// key,
|
.execute(&data.db)
|
||||||
// name: payload.name,
|
.await;
|
||||||
// };
|
|
||||||
//
|
match res {
|
||||||
// Ok(HttpResponse::Ok().json(resp))
|
Err(e) => Err(dup_error(e, ServiceError::TokenNameTaken)),
|
||||||
// }
|
Ok(_) => {
|
||||||
// }
|
let resp = TokenKeyPair {
|
||||||
//}
|
key,
|
||||||
|
name: payload.into_inner().name,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(resp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(ServiceError::NotAUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/api/v1/mcaptcha/domain/token/delete")]
|
||||||
|
pub async fn delete_mcaptcha(
|
||||||
|
payload: web::Json<CreateToken>,
|
||||||
|
data: web::Data<Data>,
|
||||||
|
id: Identity,
|
||||||
|
) -> ServiceResult<impl Responder> {
|
||||||
|
is_authenticated(&id)?;
|
||||||
|
sqlx::query!(
|
||||||
|
"DELETE FROM mcaptcha_config WHERE name = ($1)",
|
||||||
|
&payload.name,
|
||||||
|
)
|
||||||
|
.execute(&data.db)
|
||||||
|
.await?;
|
||||||
|
Ok(HttpResponse::Ok())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_random(len: usize) -> String {
|
fn get_random(len: usize) -> String {
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -141,28 +171,36 @@ mod tests {
|
||||||
const PASSWORD: &str = "longpassworddomain";
|
const PASSWORD: &str = "longpassworddomain";
|
||||||
const EMAIL: &str = "testuserdomain@a.com";
|
const EMAIL: &str = "testuserdomain@a.com";
|
||||||
const DOMAIN: &str = "http://example.com";
|
const DOMAIN: &str = "http://example.com";
|
||||||
|
const ADD_URL: &str = "/api/v1/mcaptcha/domain/add";
|
||||||
|
|
||||||
let (data, _, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
|
{
|
||||||
|
let data = Data::new().await;
|
||||||
|
delete_user(NAME, &data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
|
|
||||||
|
// 1. add domain
|
||||||
|
let (data, _, signin_resp) = add_domain_util(NAME, PASSWORD, DOMAIN).await;
|
||||||
let cookies = get_cookie!(signin_resp);
|
let cookies = get_cookie!(signin_resp);
|
||||||
let mut app = get_app!(data).await;
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
delete_domain_util(DOMAIN, &data).await;
|
let mut domain = Domain {
|
||||||
|
|
||||||
// 1. add domain
|
|
||||||
let domain = Domain {
|
|
||||||
name: DOMAIN.into(),
|
name: DOMAIN.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let add_domain_resp = test::call_service(
|
// 2. duplicate domain
|
||||||
&mut app,
|
bad_post_req_test(
|
||||||
post_request!(&domain, "/api/v1/mcaptcha/domain/add")
|
NAME,
|
||||||
.cookie(cookies.clone())
|
PASSWORD,
|
||||||
.to_request(),
|
ADD_URL,
|
||||||
|
&domain,
|
||||||
|
ServiceError::HostnameTaken,
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(add_domain_resp.status(), StatusCode::OK);
|
|
||||||
|
|
||||||
// 2. delete domain
|
// 3. delete domain
|
||||||
let del_domain_resp = test::call_service(
|
let del_domain_resp = test::call_service(
|
||||||
&mut app,
|
&mut app,
|
||||||
post_request!(&domain, "/api/v1/mcaptcha/domain/delete")
|
post_request!(&domain, "/api/v1/mcaptcha/domain/delete")
|
||||||
|
@ -171,6 +209,85 @@ mod tests {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(del_domain_resp.status(), StatusCode::OK);
|
assert_eq!(del_domain_resp.status(), StatusCode::OK);
|
||||||
delete_user(NAME, &data).await;
|
|
||||||
|
// 4. not a URL test for adding domain
|
||||||
|
domain.name = "testing".into();
|
||||||
|
bad_post_req_test(
|
||||||
|
NAME,
|
||||||
|
PASSWORD,
|
||||||
|
ADD_URL,
|
||||||
|
&domain,
|
||||||
|
ServiceError::NotAUrl,
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn add_mcaptcha_works() {
|
||||||
|
const NAME: &str = "testusermcaptcha";
|
||||||
|
const PASSWORD: &str = "longpassworddomain";
|
||||||
|
const EMAIL: &str = "testusermcaptcha@a.com";
|
||||||
|
const DOMAIN: &str = "http://mcaptcha.example.com";
|
||||||
|
const TOKEN_NAME: &str = "add_mcaptcha_works_token";
|
||||||
|
const ADD_URL: &str = "/api/v1/mcaptcha/domain/token/add";
|
||||||
|
const DEL_URL: &str = "/api/v1/mcaptcha/domain/token/delete";
|
||||||
|
|
||||||
|
{
|
||||||
|
let data = Data::new().await;
|
||||||
|
delete_user(NAME, &data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
|
let (data, _, signin_resp) = add_domain_util(NAME, PASSWORD, DOMAIN).await;
|
||||||
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
|
// 1. add mcaptcha token
|
||||||
|
let mut domain = CreateToken {
|
||||||
|
domain: DOMAIN.into(),
|
||||||
|
name: TOKEN_NAME.into(),
|
||||||
|
};
|
||||||
|
let add_token_resp = test::call_service(
|
||||||
|
&mut app,
|
||||||
|
post_request!(&domain, ADD_URL)
|
||||||
|
.cookie(cookies.clone())
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(add_token_resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
// 2. add duplicate mcaptha
|
||||||
|
bad_post_req_test(
|
||||||
|
NAME,
|
||||||
|
PASSWORD,
|
||||||
|
ADD_URL,
|
||||||
|
&domain,
|
||||||
|
ServiceError::TokenNameTaken,
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// 4. not a URL test for adding domain
|
||||||
|
domain.domain = "testing".into();
|
||||||
|
bad_post_req_test(
|
||||||
|
NAME,
|
||||||
|
PASSWORD,
|
||||||
|
ADD_URL,
|
||||||
|
&domain,
|
||||||
|
ServiceError::NotAUrl,
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
// 4. delete token
|
||||||
|
let del_token = test::call_service(
|
||||||
|
&mut app,
|
||||||
|
post_request!(&domain, DEL_URL)
|
||||||
|
.cookie(cookies.clone())
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(del_token.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,6 @@ pub fn services(cfg: &mut ServiceConfig) {
|
||||||
|
|
||||||
cfg.service(add_domain);
|
cfg.service(add_domain);
|
||||||
cfg.service(delete_domain);
|
cfg.service(delete_domain);
|
||||||
|
cfg.service(add_mcaptcha);
|
||||||
|
cfg.service(delete_mcaptcha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,9 @@ pub enum ServiceError {
|
||||||
/// when the a token name is already taken
|
/// when the a token name is already taken
|
||||||
#[display(fmt = "token name not available")]
|
#[display(fmt = "token name not available")]
|
||||||
TokenNameTaken,
|
TokenNameTaken,
|
||||||
|
/// when the a host name is already taken
|
||||||
|
#[display(fmt = "host name not available")]
|
||||||
|
HostnameTaken,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -97,6 +100,7 @@ impl ResponseError for ServiceError {
|
||||||
|
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
|
println!("{:?}", &self);
|
||||||
match *self {
|
match *self {
|
||||||
ServiceError::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
ServiceError::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
ServiceError::NotAnEmail => StatusCode::BAD_REQUEST,
|
ServiceError::NotAnEmail => StatusCode::BAD_REQUEST,
|
||||||
|
@ -111,6 +115,7 @@ impl ResponseError for ServiceError {
|
||||||
ServiceError::UsernameCaseMappedError => StatusCode::BAD_REQUEST,
|
ServiceError::UsernameCaseMappedError => StatusCode::BAD_REQUEST,
|
||||||
ServiceError::UsernameTaken => StatusCode::BAD_REQUEST,
|
ServiceError::UsernameTaken => StatusCode::BAD_REQUEST,
|
||||||
ServiceError::TokenNameTaken => StatusCode::BAD_REQUEST,
|
ServiceError::TokenNameTaken => StatusCode::BAD_REQUEST,
|
||||||
|
ServiceError::HostnameTaken => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,6 +167,7 @@ impl From<sqlx::Error> for ServiceError {
|
||||||
pub fn dup_error(e: sqlx::Error, dup_error: ServiceError) -> ServiceError {
|
pub fn dup_error(e: sqlx::Error, dup_error: ServiceError) -> ServiceError {
|
||||||
use sqlx::error::Error;
|
use sqlx::error::Error;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
println!("database error: {:?}", &e);
|
||||||
if let Error::Database(err) = e {
|
if let Error::Database(err) = e {
|
||||||
if err.code() == Some(Cow::from("23505")) {
|
if err.code() == Some(Cow::from("23505")) {
|
||||||
dup_error
|
dup_error
|
||||||
|
|
|
@ -3,11 +3,13 @@ use actix_web::{
|
||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
http::{header, StatusCode},
|
http::{header, StatusCode},
|
||||||
};
|
};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::api::v1::auth::{Login, Register};
|
use crate::api::v1::auth::{Login, Register};
|
||||||
use crate::api::v1::services as v1_services;
|
use crate::api::v1::services as v1_services;
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
|
use crate::errors::*;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! get_cookie {
|
macro_rules! get_cookie {
|
||||||
|
@ -17,15 +19,13 @@ macro_rules! get_cookie {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_user(name: &str, data: &Data) {
|
pub async fn delete_user(name: &str, data: &Data) {
|
||||||
let _ = sqlx::query!("DELETE FROM mcaptcha_users WHERE name = ($1)", name,)
|
let r = sqlx::query!("DELETE FROM mcaptcha_users WHERE name = ($1)", name,)
|
||||||
.execute(&data.db)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn delete_domain_util(name: &str, data: &Data) {
|
|
||||||
let _ = sqlx::query!("DELETE FROM mcaptcha_domains WHERE name = ($1)", name,)
|
|
||||||
.execute(&data.db)
|
.execute(&data.db)
|
||||||
.await;
|
.await;
|
||||||
|
println!();
|
||||||
|
println!();
|
||||||
|
println!();
|
||||||
|
println!("Deleting user: {:?}", &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -51,16 +51,20 @@ macro_rules! get_app {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// register and signin utility
|
/// register and signin utility
|
||||||
pub async fn signin_util<'a>(
|
pub async fn register_and_signin<'a>(
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
email: &str,
|
email: &str,
|
||||||
password: &str,
|
password: &str,
|
||||||
) -> (data::Data, Login, ServiceResponse) {
|
) -> (data::Data, Login, ServiceResponse) {
|
||||||
|
register(name, email, password).await;
|
||||||
|
signin(name, password).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// register and signin utility
|
||||||
|
pub async fn register<'a>(name: &'a str, email: &str, password: &str) {
|
||||||
let data = Data::new().await;
|
let data = Data::new().await;
|
||||||
let mut app = get_app!(data).await;
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
delete_user(&name, &data).await;
|
|
||||||
|
|
||||||
// 1. Register
|
// 1. Register
|
||||||
let msg = Register {
|
let msg = Register {
|
||||||
username: name.into(),
|
username: name.into(),
|
||||||
|
@ -70,6 +74,12 @@ pub async fn signin_util<'a>(
|
||||||
let resp =
|
let resp =
|
||||||
test::call_service(&mut app, post_request!(&msg, "/api/v1/signup").to_request()).await;
|
test::call_service(&mut app, post_request!(&msg, "/api/v1/signup").to_request()).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// signin util
|
||||||
|
pub async fn signin<'a>(name: &'a str, password: &str) -> (data::Data, Login, ServiceResponse) {
|
||||||
|
let data = Data::new().await;
|
||||||
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
// 2. signin
|
// 2. signin
|
||||||
let creds = Login {
|
let creds = Login {
|
||||||
|
@ -85,3 +95,57 @@ pub async fn signin_util<'a>(
|
||||||
|
|
||||||
(data, creds, signin_resp)
|
(data, creds, signin_resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// register and signin and domain
|
||||||
|
pub async fn add_domain_util(
|
||||||
|
name: &str,
|
||||||
|
password: &str,
|
||||||
|
domain: &str,
|
||||||
|
) -> (data::Data, Login, ServiceResponse) {
|
||||||
|
use crate::api::v1::mcaptcha::Domain;
|
||||||
|
|
||||||
|
let (data, creds, signin_resp) = signin(name, password).await;
|
||||||
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
|
// 1. add domain
|
||||||
|
let domain = Domain {
|
||||||
|
name: domain.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let add_domain_resp = test::call_service(
|
||||||
|
&mut app,
|
||||||
|
post_request!(&domain, "/api/v1/mcaptcha/domain/add")
|
||||||
|
.cookie(cookies.clone())
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(add_domain_resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
(data, creds, signin_resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// pub duplicate test
|
||||||
|
pub async fn bad_post_req_test<T: Serialize>(
|
||||||
|
name: &str,
|
||||||
|
password: &str,
|
||||||
|
url: &str,
|
||||||
|
payload: &T,
|
||||||
|
dup_err: ServiceError,
|
||||||
|
s: StatusCode,
|
||||||
|
) {
|
||||||
|
let (data, _, signin_resp) = signin(name, password).await;
|
||||||
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
let mut app = get_app!(data).await;
|
||||||
|
|
||||||
|
let dup_token_resp = test::call_service(
|
||||||
|
&mut app,
|
||||||
|
post_request!(&payload, url)
|
||||||
|
.cookie(cookies.clone())
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(dup_token_resp.status(), s);
|
||||||
|
let txt: ErrorToResponse = test::read_body_json(dup_token_resp).await;
|
||||||
|
assert_eq!(txt.error, format!("{}", dup_err));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue