pow get config

This commit is contained in:
realaravinth 2021-04-10 17:00:54 +05:30
parent f80bb8dd2e
commit e76dd8014c
No known key found for this signature in database
GPG key ID: AD9F0F08E855ED88
6 changed files with 222 additions and 187 deletions

148
Cargo.lock generated
View file

@ -60,26 +60,6 @@ dependencies = [
"trust-dns-resolver",
]
[[package]]
name = "actix-files"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d031468a7859f71674e5531bd05137e0ea5de05ec9a917314330b88c582e2e0a"
dependencies = [
"actix-service",
"actix-web",
"bitflags",
"bytes 0.5.6",
"derive_more",
"futures-core",
"futures-util",
"log",
"mime",
"mime_guess",
"percent-encoding",
"v_htmlescape",
]
[[package]]
name = "actix-http"
version = "2.2.0"
@ -405,7 +385,7 @@ checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877"
dependencies = [
"getrandom 0.2.2",
"once_cell",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -607,15 +587,6 @@ dependencies = [
"libc",
]
[[package]]
name = "buf-min"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "881e704e61d0fb41d7c6c9ae2bd790eb8c13dc974ae102fb98c788b4fdea4349"
dependencies = [
"bytes 0.6.0",
]
[[package]]
name = "build_const"
version = "0.2.1"
@ -640,12 +611,6 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16"
[[package]]
name = "bytes"
version = "1.0.1"
@ -773,7 +738,7 @@ dependencies = [
"rand 0.8.3",
"sha2",
"time 0.2.26",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -1169,9 +1134,9 @@ dependencies = [
[[package]]
name = "futures"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
dependencies = [
"futures-channel",
"futures-core",
@ -1184,9 +1149,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
dependencies = [
"futures-core",
"futures-sink",
@ -1194,15 +1159,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
[[package]]
name = "futures-executor"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
dependencies = [
"futures-core",
"futures-task",
@ -1211,15 +1176,15 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
[[package]]
name = "futures-macro"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
dependencies = [
"proc-macro-hack",
"proc-macro2",
@ -1229,21 +1194,21 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
[[package]]
name = "futures-task"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
[[package]]
name = "futures-util"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
dependencies = [
"futures-channel",
"futures-core",
@ -1275,7 +1240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -1315,7 +1280,6 @@ name = "guard"
version = "0.1.0"
dependencies = [
"actix",
"actix-files",
"actix-http",
"actix-identity",
"actix-rt",
@ -1323,7 +1287,7 @@ dependencies = [
"argon2-creds",
"cache-buster",
"config",
"derive_builder 0.9.0",
"derive_builder 0.10.0",
"derive_more",
"futures",
"lazy_static",
@ -1647,12 +1611,14 @@ dependencies = [
[[package]]
name = "m_captcha"
version = "0.1.3"
source = "git+https://github.com/mCaptcha/mCaptcha?branch=master#61ee89aee3e421ed7b3292bb3ad71c7e01a40b05"
source = "git+https://github.com/mCaptcha/mCaptcha?branch=master#2d120d6791d8a32e7b3e31a7c5f1b54e3b35f9ef"
dependencies = [
"actix",
"derive_builder 0.9.0",
"derive_more",
"log",
"pow_sha256",
"pretty_env_logger",
"rand 0.8.3",
"serde 1.0.125",
"serde_json",
@ -1819,16 +1785,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "nom"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
dependencies = [
"memchr",
"version_check 0.1.5",
]
[[package]]
name = "nom"
version = "5.1.2"
@ -1837,7 +1793,7 @@ checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -1850,7 +1806,7 @@ dependencies = [
"funty",
"lexical-core",
"memchr",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -2083,7 +2039,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -2094,7 +2050,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -2369,7 +2325,7 @@ dependencies = [
"itoap",
"ryu",
"sailfish-macros",
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -2714,7 +2670,7 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
dependencies = [
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -2912,7 +2868,7 @@ dependencies = [
"standback",
"stdweb",
"time-macros",
"version_check 0.9.3",
"version_check",
"winapi 0.3.9",
]
@ -3112,7 +3068,7 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check 0.9.3",
"version_check",
]
[[package]]
@ -3185,38 +3141,6 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
[[package]]
name = "v_escape"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccca9e73c678b882900cbaec16dae4d3662ace5a17774ac45af04e0f3988fafa"
dependencies = [
"buf-min",
"v_escape_derive",
]
[[package]]
name = "v_escape_derive"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c860ad1273f4eee7006cee05db20c9e60e5d24cba024a32e1094aa8e574f3668"
dependencies = [
"nom 4.2.3",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "v_htmlescape"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db00c903248abee8499af60bf20d242e7882335bbbffd2614915184cbb207402"
dependencies = [
"cfg-if 1.0.0",
"v_escape",
]
[[package]]
name = "validator"
version = "0.13.0"
@ -3256,12 +3180,6 @@ version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad9680608df133af2c1ddd5eaf1ddce91d60d61b6bc51494ef326458365a470a"
[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[[package]]
name = "version_check"
version = "0.9.3"

View file

@ -27,12 +27,11 @@ actix = "0.10"
actix-identity = "0.3"
actix-http = "2.2"
actix-rt = "1"
actix-files = "0.4"
mime_guess = "2.0.3"
rust-embed = "5.9.0"
cache-buster = { version = "0.1", git = "https://github.com/realaravinth/cache-buster" }
futures = "0.3"
futures = "0.3.14"
sqlx = { version = "0.4.0", features = [ "runtime-actix-rustls", "postgres" ] }
argon2-creds = { version = "0.2", git = "https://github.com/realaravinth/argon2-creds", commit = "61f2d1d" }
@ -40,12 +39,12 @@ argon2-creds = { version = "0.2", git = "https://github.com/realaravinth/argon2-
config = "0.11"
validator = { version = "0.13", features = ["derive"]}
derive_builder = "0.9"
derive_builder = "0.10"
derive_more = "0.99"
serde = "1"
serde_json = "1"
serde_yaml = "0.8"
serde_yaml = "0.8.17"
url = "2.2"
@ -63,8 +62,8 @@ rand = "0.8"
sailfish = "0.3.2"
[build-dependencies]
serde_yaml = "0.8"
serde_yaml = "0.8.17"
serde_json = "1"
yaml-rust = "0.4"
yaml-rust = "0.4.5"
cache-buster = { version = "0.1", git = "https://github.com/realaravinth/cache-buster" }
mime = "0.3.16"

View file

@ -176,15 +176,15 @@ pub async fn get_levels(
Ok(HttpResponse::Ok().json(levels))
}
#[derive(Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Levels {
levels: I32Levels,
}
#[derive(Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct I32Levels {
difficulty_factor: i32,
visitor_threshold: i32,
pub difficulty_factor: i32,
pub visitor_threshold: i32,
}
async fn get_levels_util(key: &str, username: &str, data: &Data) -> ServiceResult<Vec<I32Levels>> {
@ -224,25 +224,16 @@ mod tests {
const DEL_URL: &str = "/api/v1/mcaptcha/levels/delete";
const GET_URL: &str = "/api/v1/mcaptcha/levels/get";
let l1 = Level {
difficulty_factor: 50,
visitor_threshold: 50,
};
let l2 = Level {
difficulty_factor: 500,
visitor_threshold: 500,
};
let levels = vec![l1, l2];
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, key) = add_token_util(NAME, PASSWORD).await;
let (data, _, signin_resp, key) = add_levels_util(NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let mut app = get_app!(data).await;
/*
let add_level = AddLevels {
levels: levels.clone(),
@ -258,8 +249,12 @@ mod tests {
)
.await;
assert_eq!(add_token_resp.status(), StatusCode::OK);
*/
// 2. get level
let levels = vec![L1, L2];
let get_level_resp = test::call_service(
&mut app,
post_request!(&key, GET_URL)

View file

@ -15,11 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use actix::prelude::*;
use actix_identity::Identity;
use actix_web::{post, web, HttpResponse, Responder};
use m_captcha::{defense::LevelBuilder, master::AddSiteBuilder, DefenseBuilder, MCaptchaBuilder};
use serde::{Deserialize, Serialize};
use super::{get_random, is_authenticated};
use super::duration::GetDurationResp;
use super::is_authenticated;
use super::levels::I32Levels;
use crate::errors::*;
use crate::Data;
@ -51,9 +55,134 @@ pub async fn get_config(
.fetch_one(&data.db)
.await?;
if let Some(x) = res.exists {
println!("{}", x);
if res.exists.is_none() {
return Err(ServiceError::TokenNotFound);
}
let payload = payload.into_inner();
match res.exists {
Some(true) => {
();
match data.captcha.get_pow(payload.key.clone()).await {
Some(config) => Ok(HttpResponse::Ok().json(config)),
None => {
init_mcaptcha(&data, &payload.key).await?;
let config = data
.captcha
.get_pow(payload.key)
.await
.expect("mcaptcha should be initialized and ready to go");
Ok(HttpResponse::Ok().json(config))
}
}
}
Some(false) => Err(ServiceError::TokenNotFound),
None => Err(ServiceError::TokenNotFound),
}
}
async fn init_mcaptcha(data: &Data, key: &str) -> ServiceResult<()> {
// get levels
let levels_fut = sqlx::query_as!(
I32Levels,
"SELECT difficulty_factor, visitor_threshold FROM mcaptcha_levels WHERE
config_id = (
SELECT config_id FROM mcaptcha_config WHERE key = ($1)
);",
&key,
)
.fetch_all(&data.db);
// get duration
let duration_fut = sqlx::query_as!(
GetDurationResp,
"SELECT duration FROM mcaptcha_config
WHERE key = $1",
&key,
)
.fetch_one(&data.db);
//let (levels, duration) = futures::try_join!(levels_fut, duration_fut).await?;
let (levels, duration) = futures::try_join!(levels_fut, duration_fut)?;
// build defense
let mut defense = DefenseBuilder::default();
for level in levels.iter() {
let level = LevelBuilder::default()
.visitor_threshold(level.visitor_threshold as u32)
.difficulty_factor(level.difficulty_factor as u32)
.unwrap()
.build()
.unwrap();
defense.add_level(level).unwrap();
}
Ok(HttpResponse::Ok())
let defense = defense.build()?;
// create captcha
let mcaptcha = MCaptchaBuilder::default()
.defense(defense)
// leaky bucket algorithm's emission interval
.duration(duration.duration as u64)
// .cache(cache)
.build()
.unwrap()
.start();
// add captcha to master
let msg = AddSiteBuilder::default()
.id(key.into())
.addr(mcaptcha.clone())
.build()
.unwrap();
data.captcha.master.send(msg).await.unwrap();
Ok(())
}
#[cfg(test)]
mod tests {
use actix_web::http::{header, StatusCode};
use actix_web::test;
use m_captcha::pow::PoWConfig;
use super::*;
use crate::api::v1::services as v1_services;
use crate::tests::*;
use crate::*;
#[actix_rt::test]
async fn get_pow_config_works() {
const NAME: &str = "powusrworks";
const PASSWORD: &str = "testingpas";
const EMAIL: &str = "randomuser@a.com";
const GET_URL: &str = "/api/v1/mcaptcha/pow/config";
// const UPDATE_URL: &str = "/api/v1/mcaptcha/domain/token/duration/update";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let mut app = get_app!(data).await;
let get_config_payload = GetConfigPayload {
key: token_key.key.clone(),
};
// update and check changes
let get_config_resp = test::call_service(
&mut app,
post_request!(&get_config_payload, GET_URL)
.cookie(cookies.clone())
.to_request(),
)
.await;
assert_eq!(get_config_resp.status(), StatusCode::OK);
let config: PoWConfig = test::read_body_json(get_config_resp).await;
assert_eq!(config.difficulty_factor, L1.difficulty_factor);
}
}

View file

@ -16,7 +16,6 @@
*/
use std::env;
use actix_files::Files;
use actix_identity::{CookieIdentityPolicy, IdentityService};
use actix_web::{
client::Client, error::InternalError, http::StatusCode, middleware, web::JsonConfig, App,

View file

@ -3,10 +3,12 @@ use actix_web::{
dev::ServiceResponse,
http::{header, StatusCode},
};
use m_captcha::defense::Level;
use serde::Serialize;
use super::*;
use crate::api::v1::auth::{Login, Register};
use crate::api::v1::mcaptcha::levels::AddLevels;
use crate::api::v1::mcaptcha::mcaptcha::MCaptchaDetails;
use crate::api::v1::services as v1_services;
use crate::data::Data;
@ -97,54 +99,9 @@ pub async fn signin<'a>(name: &'a str, password: &str) -> (data::Data, Login, Se
)
.await;
assert_eq!(signin_resp.status(), StatusCode::OK);
(data, creds, signin_resp)
}
///// register and signin and domain
///// bypasses domain verification, use with care
//pub async fn add_domain_util(
// name: &str,
// password: &str,
// domain: &str,
//) -> (data::Data, Login, ServiceResponse) {
// use crate::api::v1::mcaptcha::domains::Domain;
// use url::Url;
//
// 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 add_domain = Domain {
// name: domain.into(),
// };
//
// let add_domain_resp = test::call_service(
// &mut app,
// post_request!(&add_domain, "/api/v1/mcaptcha/domain/add")
// .cookie(cookies.clone())
// .to_request(),
// )
// .await;
// assert_eq!(add_domain_resp.status(), StatusCode::OK);
//
// // verification work around
// let url = Url::parse(domain).unwrap();
// let host = url.host_str().unwrap();
// sqlx::query!(
// "INSERT INTO mcaptcha_domains_verified (name, owner_id) VALUES
// ($1, (SELECT ID from mcaptcha_users WHERE name = $2))",
// &host,
// &name
// )
// .execute(&data.db)
// .await
// .unwrap();
//
// (data, creds, signin_resp)
//}
pub async fn add_token_util(
name: &str,
password: &str,
@ -167,7 +124,7 @@ pub async fn add_token_util(
)
.await;
// let status = add_token_resp.status();
// let txt: ErrorToResponse = test::read_body_json(add_token_resp).await;
// let txt: errortoresponse = test::read_body_json(add_token_resp).await;
// println!("{:?}", txt.error);
//
assert_eq!(add_token_resp.status(), StatusCode::OK);
@ -202,3 +159,41 @@ pub async fn bad_post_req_test<T: Serialize>(
let txt: ErrorToResponse = test::read_body_json(dup_token_resp).await;
assert_eq!(txt.error, format!("{}", dup_err));
}
pub const L1: Level = Level {
difficulty_factor: 50,
visitor_threshold: 50,
};
pub const L2: Level = Level {
difficulty_factor: 500,
visitor_threshold: 500,
};
pub async fn add_levels_util(
name: &str,
password: &str,
) -> (data::Data, Login, ServiceResponse, MCaptchaDetails) {
const ADD_URL: &str = "/api/v1/mcaptcha/levels/add";
let (data, creds, signin_resp, token_key) = add_token_util(name, password).await;
let cookies = get_cookie!(signin_resp);
let mut app = get_app!(data).await;
let levels = vec![L1, L2];
let add_level = AddLevels {
levels: levels.clone(),
key: token_key.key.clone(),
};
// 1. add level
let add_token_resp = test::call_service(
&mut app,
post_request!(&add_level, ADD_URL)
.cookie(cookies.clone())
.to_request(),
)
.await;
assert_eq!(add_token_resp.status(), StatusCode::OK);
(data, creds, signin_resp, token_key)
}