mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2025-11-24 06:25:46 +00:00
feat: log pow performance stats while pow verification
This commit is contained in:
parent
679a35216c
commit
2cf5e48d8e
@ -32,6 +32,27 @@ pub struct ValidationToken {
|
|||||||
pub token: String,
|
pub token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct ApiWork {
|
||||||
|
pub string: String,
|
||||||
|
pub result: String,
|
||||||
|
pub nonce: u64,
|
||||||
|
pub key: String,
|
||||||
|
pub time: Option<u32>,
|
||||||
|
pub worker_type: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ApiWork> for Work {
|
||||||
|
fn from(value: ApiWork) -> Self {
|
||||||
|
Self {
|
||||||
|
string: value.string,
|
||||||
|
nonce: value.nonce,
|
||||||
|
result: value.result,
|
||||||
|
key: value.key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// API keys are mcaptcha actor names
|
// API keys are mcaptcha actor names
|
||||||
|
|
||||||
/// route handler that verifies PoW and issues a solution token
|
/// route handler that verifies PoW and issues a solution token
|
||||||
@ -39,7 +60,7 @@ pub struct ValidationToken {
|
|||||||
#[my_codegen::post(path = "V1_API_ROUTES.pow.verify_pow()")]
|
#[my_codegen::post(path = "V1_API_ROUTES.pow.verify_pow()")]
|
||||||
pub async fn verify_pow(
|
pub async fn verify_pow(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
payload: web::Json<Work>,
|
payload: web::Json<ApiWork>,
|
||||||
data: AppData,
|
data: AppData,
|
||||||
) -> ServiceResult<impl Responder> {
|
) -> ServiceResult<impl Responder> {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
@ -52,8 +73,19 @@ pub async fn verify_pow(
|
|||||||
let ip = "127.0.1.1".into();
|
let ip = "127.0.1.1".into();
|
||||||
|
|
||||||
let key = payload.key.clone();
|
let key = payload.key.clone();
|
||||||
let res = data.captcha.verify_pow(payload.into_inner(), ip).await?;
|
let payload = payload.into_inner();
|
||||||
|
let worker_type = payload.worker_type.clone();
|
||||||
|
let time = payload.time;
|
||||||
|
let (res, difficulty_factor) = data.captcha.verify_pow(payload.into(), ip).await?;
|
||||||
data.stats.record_solve(&data, &key).await?;
|
data.stats.record_solve(&data, &key).await?;
|
||||||
|
if time.is_some() && worker_type.is_some() {
|
||||||
|
let analytics = db_core::CreatePerformanceAnalytics {
|
||||||
|
difficulty_factor,
|
||||||
|
time: time.unwrap(),
|
||||||
|
worker_type: worker_type.unwrap(),
|
||||||
|
};
|
||||||
|
data.db.analysis_save(&key, &analytics).await?;
|
||||||
|
}
|
||||||
let payload = ValidationToken { token: res };
|
let payload = ValidationToken { token: res };
|
||||||
Ok(HttpResponse::Ok().json(payload))
|
Ok(HttpResponse::Ok().json(payload))
|
||||||
}
|
}
|
||||||
@ -81,6 +113,81 @@ pub mod tests {
|
|||||||
verify_pow_works(data).await;
|
verify_pow_works(data).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn verify_analytics_pow_works_pg() {
|
||||||
|
let data = crate::tests::pg::get_data().await;
|
||||||
|
verify_analytics_pow_works(data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn verify_analytics_pow_works_maria() {
|
||||||
|
let data = crate::tests::maria::get_data().await;
|
||||||
|
verify_analytics_pow_works(data).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn verify_analytics_pow_works(data: ArcData) {
|
||||||
|
const NAME: &str = "powanalyticsuser";
|
||||||
|
const PASSWORD: &str = "testingpas";
|
||||||
|
const EMAIL: &str = "powanalyticsuser@a.com";
|
||||||
|
let data = &data;
|
||||||
|
|
||||||
|
delete_user(data, NAME).await;
|
||||||
|
|
||||||
|
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
|
||||||
|
let (_, _signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
|
||||||
|
let 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(
|
||||||
|
&app,
|
||||||
|
post_request!(&get_config_payload, V1_API_ROUTES.pow.get_config)
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(get_config_resp.status(), StatusCode::OK);
|
||||||
|
let config: PoWConfig = test::read_body_json(get_config_resp).await;
|
||||||
|
|
||||||
|
let pow = pow_sha256::ConfigBuilder::default()
|
||||||
|
.salt(config.salt)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
let work = pow
|
||||||
|
.prove_work(&config.string.clone(), config.difficulty_factor)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let work = ApiWork {
|
||||||
|
string: config.string.clone(),
|
||||||
|
result: work.result,
|
||||||
|
nonce: work.nonce,
|
||||||
|
key: token_key.key.clone(),
|
||||||
|
time: Some(100),
|
||||||
|
worker_type: Some("wasm".into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pow_verify_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
post_request!(&work, V1_API_ROUTES.pow.verify_pow).to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(pow_verify_resp.status(), StatusCode::OK);
|
||||||
|
let limit = 50;
|
||||||
|
let offset = 0;
|
||||||
|
let mut analytics = data
|
||||||
|
.db
|
||||||
|
.analytics_fetch(&token_key.key, limit, offset)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(analytics.len(), 1);
|
||||||
|
let a = analytics.pop().unwrap();
|
||||||
|
assert_eq!(a.time, work.time.unwrap());
|
||||||
|
assert_eq!(a.worker_type, work.worker_type.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn verify_pow_works(data: ArcData) {
|
pub async fn verify_pow_works(data: ArcData) {
|
||||||
const NAME: &str = "powverifyusr";
|
const NAME: &str = "powverifyusr";
|
||||||
const PASSWORD: &str = "testingpas";
|
const PASSWORD: &str = "testingpas";
|
||||||
@ -129,6 +236,12 @@ pub mod tests {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(pow_verify_resp.status(), StatusCode::OK);
|
assert_eq!(pow_verify_resp.status(), StatusCode::OK);
|
||||||
|
assert!(data
|
||||||
|
.db
|
||||||
|
.analytics_fetch(&token_key.key, 50, 0)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.is_empty());
|
||||||
|
|
||||||
let string_not_found = test::call_service(
|
let string_not_found = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user