From b597c0b965b128887ac1a19e0fa2b27ebcea7a43 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Fri, 9 Apr 2021 17:28:04 +0530 Subject: [PATCH] extending Save to cache captcha responses --- CHANGELOG.md | 10 +++++ Cargo.lock | 89 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++ src/cache/hashcache.rs | 42 ++++++++++++-------- src/cache/mod.rs | 12 +++--- src/master.rs | 3 +- src/system.rs | 11 +++--- 7 files changed, 141 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc58722..0ca9811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ ## Fixed - a bug in `mCaptcha/pow_sha256` was causing errors in PoW computation +## Changed +- `Cache` became `CachePoW` (`HashCache` extension) +- `Retrieve` became `RetrievePoW`(`HashCache` extension) +- `DeleteString` became `DeletePoW` (`HashCache` extension) +- `Save` trait now requires three new message impls (`HashCache` extension_ + +## Added +- `HashCache` was extended to store captcha responses + + ## 0.1.2 ## Changed - actix upgraded to `0.11` diff --git a/Cargo.lock b/Cargo.lock index 7881d96..9d8e6f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,15 @@ dependencies = [ "syn", ] +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + [[package]] name = "async-trait" version = "0.1.48" @@ -87,6 +96,17 @@ dependencies = [ "syn", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -341,6 +361,19 @@ dependencies = [ "syn", ] +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "fnv" version = "1.0.7" @@ -499,6 +532,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -615,7 +657,9 @@ dependencies = [ "actix-rt", "derive_builder 0.9.0", "derive_more", + "log", "pow_sha256", + "pretty_env_logger", "rand 0.8.3", "serde", "serde_json", @@ -806,6 +850,16 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + [[package]] name = "proc-macro2" version = "1.0.26" @@ -920,6 +974,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" + [[package]] name = "resolv-conf" version = "0.7.0" @@ -1041,6 +1112,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.24" @@ -1260,6 +1340,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 2064e0a..6422bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ actix = "0.10" serde = "1.0.114" serde_json = "1" +pretty_env_logger = "0.4" +log = "0.4" + derive_builder = "0.9" derive_more = "0.99" diff --git a/src/cache/hashcache.rs b/src/cache/hashcache.rs index 6ab6cdb..fa7d333 100644 --- a/src/cache/hashcache.rs +++ b/src/cache/hashcache.rs @@ -26,12 +26,16 @@ use crate::errors::*; #[derive(Clone, Default)] /// cache datastructure implementing [Save] -pub struct HashCache(HashMap); +pub struct HashCache { + difficulty_map: HashMap, + result_map: HashMap, +} impl HashCache { // save [PoWConfig] to cache - fn save(&mut self, config: Cache) -> CaptchaResult<()> { - self.0.insert(config.string, config.difficulty_factor); + fn save(&mut self, config: CachePoW) -> CaptchaResult<()> { + self.difficulty_map + .insert(config.string, config.difficulty_factor); Ok(()) } @@ -46,7 +50,7 @@ impl HashCache { // delete [PoWConfig] from cache fn remove(&mut self, string: &str) -> Option { - self.0.remove(string) + self.difficulty_map.remove(string) } } @@ -57,15 +61,15 @@ impl Actor for HashCache { } /// cache a PoWConfig -impl Handler for HashCache { - type Result = MessageResult; - fn handle(&mut self, msg: Cache, ctx: &mut Self::Context) -> Self::Result { +impl Handler for HashCache { + type Result = MessageResult; + fn handle(&mut self, msg: CachePoW, 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 = DeleteString(msg.string.clone()); + let del_msg = DeletePoW(msg.string.clone()); let duration: Duration = Duration::new(msg.duration.clone(), 0); let wait_for = async move { @@ -81,18 +85,18 @@ impl Handler for HashCache { } /// Delte a PoWConfig -impl Handler for HashCache { - type Result = MessageResult; - fn handle(&mut self, msg: DeleteString, _ctx: &mut Self::Context) -> Self::Result { +impl Handler for HashCache { + type Result = MessageResult; + fn handle(&mut self, msg: DeletePoW, _ctx: &mut Self::Context) -> Self::Result { self.remove(&msg.0); MessageResult(Ok(())) } } /// Retrive PoW difficulty_factor for a PoW string -impl Handler for HashCache { - type Result = MessageResult; - fn handle(&mut self, msg: Retrive, _ctx: &mut Self::Context) -> Self::Result { +impl Handler for HashCache { + type Result = MessageResult; + fn handle(&mut self, msg: RetrivePoW, _ctx: &mut Self::Context) -> Self::Result { MessageResult(self.retrive(msg.0)) } } @@ -127,18 +131,22 @@ mod tests { duration: DURATION, }; let string = pow.string.clone(); - let msg = Cache::new(&pow, &visitor_result); + let msg = CachePoW::new(&pow, &visitor_result); addr.send(msg).await.unwrap().unwrap(); - let cache_difficulty_factor = addr.send(Retrive(string.clone())).await.unwrap().unwrap(); + let cache_difficulty_factor = addr + .send(RetrivePoW(string.clone())) + .await + .unwrap() + .unwrap(); assert_eq!(DIFFICULTY_FACTOR, cache_difficulty_factor.unwrap()); let duration: Duration = Duration::new(5, 0); //sleep(DURATION + DURATION).await; delay_for(duration + duration).await; - let expired_string = addr.send(Retrive(string)).await.unwrap().unwrap(); + let expired_string = addr.send(RetrivePoW(string)).await.unwrap().unwrap(); assert_eq!(None, expired_string); } } diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 0c32b37..c5d270a 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -24,7 +24,7 @@ pub mod hashcache; /// Describes actor handler trait impls that are required by a cache implementation pub trait Save: - actix::Actor + actix::Handler + actix::Handler + actix::Handler + actix::Actor + actix::Handler + actix::Handler + actix::Handler { } pub mod messages { @@ -40,15 +40,15 @@ pub mod messages { /// Message to cache PoW difficulty factor and string #[derive(Message, Serialize, Deserialize, Builder)] #[rtype(result = "CaptchaResult<()>")] - pub struct Cache { + pub struct CachePoW { pub string: String, pub difficulty_factor: u32, pub duration: u64, } - impl Cache { + impl CachePoW { pub fn new(p: &PoWConfig, v: &AddVisitorResult) -> Self { - CacheBuilder::default() + CachePoWBuilder::default() .string(p.string.clone()) .difficulty_factor(v.difficulty_factor) .duration(v.duration) @@ -61,11 +61,11 @@ pub mod messages { /// string from the cache #[derive(Message)] #[rtype(result = "CaptchaResult>")] - pub struct Retrive(pub String); + pub struct RetrivePoW(pub String); /// Message to delete cached PoW difficulty factor and string /// when they expire #[derive(Message)] #[rtype(result = "CaptchaResult<()>")] - pub struct DeleteString(pub String); + pub struct DeletePoW(pub String); } diff --git a/src/master.rs b/src/master.rs index 46e1e21..28aa02a 100644 --- a/src/master.rs +++ b/src/master.rs @@ -23,6 +23,7 @@ use std::time::Duration; use actix::clock::delay_for; use actix::dev::*; use derive_builder::Builder; +use log::info; use crate::mcaptcha::MCaptcha; @@ -111,7 +112,7 @@ impl Handler for Master { let sites = self.sites.clone(); let gc = self.gc; let master = ctx.address(); - println!("init cleanup up"); + info!("init master actor cleanup up"); let task = async move { for (id, (new, addr)) in sites.iter() { use crate::mcaptcha::{GetCurrentVisitorCount, Stop}; diff --git a/src/system.rs b/src/system.rs index 55344b7..de87bf4 100644 --- a/src/system.rs +++ b/src/system.rs @@ -37,11 +37,12 @@ pub struct System { impl System where T: Save, - ::Context: ToEnvelope + ToEnvelope, + ::Context: + ToEnvelope + ToEnvelope, { /// utility function to get difficulty factor of site `id` and cache it pub async fn get_pow(&self, id: String) -> Option { - use crate::cache::messages::Cache; + use crate::cache::messages::CachePoW; use crate::master::GetSite; use crate::mcaptcha::AddVisitor; @@ -52,17 +53,17 @@ where let mcaptcha = site_addr.unwrap().send(AddVisitor).await.unwrap(); let pow_config = PoWConfig::new(mcaptcha.difficulty_factor); - let cache_msg = Cache::new(&pow_config, &mcaptcha); + let cache_msg = CachePoW::new(&pow_config, &mcaptcha); self.cache.send(cache_msg).await.unwrap().unwrap(); Some(pow_config) } /// utility function to verify [Work] pub async fn verify_pow(&self, work: Work) -> CaptchaResult { - use crate::cache::messages::Retrive; + use crate::cache::messages::RetrivePoW; let string = work.string.clone(); - let msg = Retrive(string.clone()); + let msg = RetrivePoW(string.clone()); let pow: PoW = work.into(); let difficulty = self.cache.send(msg).await.unwrap()?;