impl new Save for hashcache
This commit is contained in:
parent
b597c0b965
commit
9f4429aee9
2 changed files with 164 additions and 17 deletions
146
src/cache/hashcache.rs
vendored
146
src/cache/hashcache.rs
vendored
|
@ -33,15 +33,15 @@ pub struct HashCache {
|
||||||
|
|
||||||
impl HashCache {
|
impl HashCache {
|
||||||
// save [PoWConfig] to cache
|
// save [PoWConfig] to cache
|
||||||
fn save(&mut self, config: CachePoW) -> CaptchaResult<()> {
|
fn save_pow_config(&mut self, config: CachePoW) -> CaptchaResult<()> {
|
||||||
self.difficulty_map
|
self.difficulty_map
|
||||||
.insert(config.string, config.difficulty_factor);
|
.insert(config.string, config.difficulty_factor);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrive [PoWConfig] from cache. Deletes config post retrival
|
// retrive [PoWConfig] from cache. Deletes config post retrival
|
||||||
fn retrive(&mut self, string: String) -> CaptchaResult<Option<u32>> {
|
fn retrive_pow_config(&mut self, string: String) -> CaptchaResult<Option<u32>> {
|
||||||
if let Some(difficulty_factor) = self.remove(&string) {
|
if let Some(difficulty_factor) = self.remove_pow_config(&string) {
|
||||||
Ok(Some(difficulty_factor.to_owned()))
|
Ok(Some(difficulty_factor.to_owned()))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -49,9 +49,33 @@ impl HashCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete [PoWConfig] from cache
|
// delete [PoWConfig] from cache
|
||||||
fn remove(&mut self, string: &str) -> Option<u32> {
|
fn remove_pow_config(&mut self, string: &str) -> Option<u32> {
|
||||||
self.difficulty_map.remove(string)
|
self.difficulty_map.remove(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save captcha result
|
||||||
|
fn save_captcha_result(&mut self, res: CacheResult) -> CaptchaResult<()> {
|
||||||
|
self.result_map.insert(res.result, res.key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify captcha result
|
||||||
|
fn verify_captcha_result(&mut self, challenge: VerifyCaptchaResult) -> CaptchaResult<bool> {
|
||||||
|
if let Some(captcha_id) = self.remove_cache_result(&challenge.result) {
|
||||||
|
if captcha_id == challenge.key {
|
||||||
|
return Ok(true);
|
||||||
|
} else {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete cache result
|
||||||
|
fn remove_cache_result(&mut self, string: &str) -> Option<String> {
|
||||||
|
self.result_map.remove(string)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Save for HashCache {}
|
impl Save for HashCache {}
|
||||||
|
@ -80,7 +104,7 @@ impl Handler<CachePoW> for HashCache {
|
||||||
.into_actor(self);
|
.into_actor(self);
|
||||||
ctx.spawn(wait_for);
|
ctx.spawn(wait_for);
|
||||||
|
|
||||||
MessageResult(self.save(msg))
|
MessageResult(self.save_pow_config(msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +112,7 @@ impl Handler<CachePoW> for HashCache {
|
||||||
impl Handler<DeletePoW> for HashCache {
|
impl Handler<DeletePoW> for HashCache {
|
||||||
type Result = MessageResult<DeletePoW>;
|
type Result = MessageResult<DeletePoW>;
|
||||||
fn handle(&mut self, msg: DeletePoW, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: DeletePoW, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
self.remove(&msg.0);
|
self.remove_pow_config(&msg.0);
|
||||||
MessageResult(Ok(()))
|
MessageResult(Ok(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +121,51 @@ impl Handler<DeletePoW> for HashCache {
|
||||||
impl Handler<RetrivePoW> for HashCache {
|
impl Handler<RetrivePoW> for HashCache {
|
||||||
type Result = MessageResult<RetrivePoW>;
|
type Result = MessageResult<RetrivePoW>;
|
||||||
fn handle(&mut self, msg: RetrivePoW, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: RetrivePoW, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
MessageResult(self.retrive(msg.0))
|
MessageResult(self.retrive_pow_config(msg.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// cache PoW result
|
||||||
|
impl Handler<CacheResult> for HashCache {
|
||||||
|
type Result = MessageResult<CacheResult>;
|
||||||
|
fn handle(&mut self, msg: CacheResult, ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
//use actix::clock::sleep;
|
||||||
|
use actix::clock::delay_for;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
let addr = ctx.address();
|
||||||
|
let del_msg = DeleteCaptchaResult {
|
||||||
|
result: msg.result.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let duration: Duration = Duration::new(msg.duration.clone(), 0);
|
||||||
|
let wait_for = async move {
|
||||||
|
//sleep(duration).await;
|
||||||
|
delay_for(duration).await;
|
||||||
|
addr.send(del_msg).await.unwrap().unwrap();
|
||||||
|
}
|
||||||
|
.into_actor(self);
|
||||||
|
ctx.spawn(wait_for);
|
||||||
|
|
||||||
|
MessageResult(self.save_captcha_result(msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delte a PoWConfig
|
||||||
|
impl Handler<DeleteCaptchaResult> for HashCache {
|
||||||
|
type Result = MessageResult<DeleteCaptchaResult>;
|
||||||
|
fn handle(&mut self, msg: DeleteCaptchaResult, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
self.remove_cache_result(&msg.result);
|
||||||
|
MessageResult(Ok(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrive PoW difficulty_factor for a PoW string
|
||||||
|
impl Handler<VerifyCaptchaResult> for HashCache {
|
||||||
|
type Result = MessageResult<VerifyCaptchaResult>;
|
||||||
|
fn handle(&mut self, msg: VerifyCaptchaResult, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
// MessageResult(self.retrive(msg.0))
|
||||||
|
MessageResult(self.verify_captcha_result(msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,18 +175,18 @@ mod tests {
|
||||||
use crate::mcaptcha::AddVisitorResult;
|
use crate::mcaptcha::AddVisitorResult;
|
||||||
use crate::pow::PoWConfig;
|
use crate::pow::PoWConfig;
|
||||||
|
|
||||||
async fn sleep(time: u64) {
|
// async fn sleep(time: u64) {
|
||||||
//use actix::clock::sleep;
|
// //use actix::clock::sleep;
|
||||||
use actix::clock::delay_for;
|
// use actix::clock::delay_for;
|
||||||
use std::time::Duration;
|
// use std::time::Duration;
|
||||||
|
|
||||||
let duration: Duration = Duration::new(time, 0);
|
// let duration: Duration = Duration::new(time, 0);
|
||||||
//sleep(duration).await;
|
// //sleep(duration).await;
|
||||||
delay_for(duration).await;
|
// delay_for(duration).await;
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn hashcache_works() {
|
async fn hashcache_pow_cache_works() {
|
||||||
use actix::clock::delay_for;
|
use actix::clock::delay_for;
|
||||||
use actix::clock::Duration;
|
use actix::clock::Duration;
|
||||||
|
|
||||||
|
@ -149,4 +217,50 @@ mod tests {
|
||||||
let expired_string = addr.send(RetrivePoW(string)).await.unwrap().unwrap();
|
let expired_string = addr.send(RetrivePoW(string)).await.unwrap().unwrap();
|
||||||
assert_eq!(None, expired_string);
|
assert_eq!(None, expired_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn hashcache_result_cache_works() {
|
||||||
|
use actix::clock::delay_for;
|
||||||
|
use actix::clock::Duration;
|
||||||
|
|
||||||
|
const DURATION: u64 = 5;
|
||||||
|
const KEY: &str = "a";
|
||||||
|
const RES: &str = "b";
|
||||||
|
let addr = HashCache::default().start();
|
||||||
|
// send value to cache
|
||||||
|
// send another value to cache for auto delete
|
||||||
|
// verify_captcha_result
|
||||||
|
// delete
|
||||||
|
// wait for timeout and verify_captcha_result against second value
|
||||||
|
|
||||||
|
let add_cache = CacheResult {
|
||||||
|
key: KEY.into(),
|
||||||
|
result: RES.into(),
|
||||||
|
duration: DURATION,
|
||||||
|
};
|
||||||
|
|
||||||
|
addr.send(add_cache).await.unwrap().unwrap();
|
||||||
|
|
||||||
|
let verify_msg = VerifyCaptchaResult {
|
||||||
|
key: KEY.into(),
|
||||||
|
result: RES.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(addr.send(verify_msg).await.unwrap().unwrap());
|
||||||
|
|
||||||
|
let verify_msg = VerifyCaptchaResult {
|
||||||
|
key: "cz".into(),
|
||||||
|
result: RES.into(),
|
||||||
|
};
|
||||||
|
assert!(!addr.send(verify_msg).await.unwrap().unwrap());
|
||||||
|
|
||||||
|
let duration: Duration = Duration::new(5, 0);
|
||||||
|
delay_for(duration + duration).await;
|
||||||
|
|
||||||
|
let verify_msg = VerifyCaptchaResult {
|
||||||
|
key: KEY.into(),
|
||||||
|
result: RES.into(),
|
||||||
|
};
|
||||||
|
assert!(!addr.send(verify_msg).await.unwrap().unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
35
src/cache/mod.rs
vendored
35
src/cache/mod.rs
vendored
|
@ -24,7 +24,13 @@ pub mod hashcache;
|
||||||
|
|
||||||
/// Describes actor handler trait impls that are required by a cache implementation
|
/// Describes actor handler trait impls that are required by a cache implementation
|
||||||
pub trait Save:
|
pub trait Save:
|
||||||
actix::Actor + actix::Handler<RetrivePoW> + actix::Handler<CachePoW> + actix::Handler<DeletePoW>
|
actix::Actor
|
||||||
|
+ actix::Handler<RetrivePoW>
|
||||||
|
+ actix::Handler<CachePoW>
|
||||||
|
+ actix::Handler<DeletePoW>
|
||||||
|
+ actix::Handler<CacheResult>
|
||||||
|
+ actix::Handler<VerifyCaptchaResult>
|
||||||
|
+ actix::Handler<DeleteCaptchaResult>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
pub mod messages {
|
pub mod messages {
|
||||||
|
@ -68,4 +74,31 @@ pub mod messages {
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "CaptchaResult<()>")]
|
#[rtype(result = "CaptchaResult<()>")]
|
||||||
pub struct DeletePoW(pub String);
|
pub struct DeletePoW(pub String);
|
||||||
|
|
||||||
|
/// Message to cache captcha result and the captcha key for which
|
||||||
|
/// it was generated
|
||||||
|
#[derive(Message, Serialize, Deserialize, Builder)]
|
||||||
|
#[rtype(result = "CaptchaResult<()>")]
|
||||||
|
pub struct CacheResult {
|
||||||
|
pub result: String,
|
||||||
|
// key is Captcha identifier
|
||||||
|
pub key: String,
|
||||||
|
pub duration: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Message to verify captcha result against
|
||||||
|
/// the stored captcha key
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "CaptchaResult<bool>")]
|
||||||
|
pub struct VerifyCaptchaResult {
|
||||||
|
pub result: String,
|
||||||
|
pub key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Message to delete cached capthca result when it expires
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "CaptchaResult<()>")]
|
||||||
|
pub struct DeleteCaptchaResult {
|
||||||
|
pub result: String,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue