moved mcaptcha into embedded

This commit is contained in:
Aravinth Manivannan 2021-06-03 19:40:45 +05:30
parent e7dd8bff63
commit cc88c69fc6
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
8 changed files with 168 additions and 122 deletions

View file

@ -1,5 +1,9 @@
## 0.1.4 ## 0.1.4
## Added:
- `Master` trait: provides methods to manage mcaptcha
## Changed: ## Changed:
- `PoWConfig` has an extra field to send internal `PoW` salt to clients. - `PoWConfig` has an extra field to send internal `PoW` salt to clients.
@ -11,9 +15,14 @@
- `master::Master` is moved to `master::embedded::master` in preparation - `master::Master` is moved to `master::embedded::master` in preparation
for Redis based implementation. for Redis based implementation.
- `crate::mcaptcha` is moved to `master::embedded::mcaptcha` in preparation - `crate::mcaptcha` is moved to `master::embedded::counter` in preparation
for Redis based implementation. for Redis based implementation.
- `AddSite` message for `Master` now requires an instance of
`crate::master::MCaptcha`. In the case of
`crate::master::embedded::master`, it automatically starts `Counter`
actor.
## 0.1.3 ## 0.1.3
## Added ## Added

View file

@ -1,6 +1,7 @@
use libmcaptcha::{ use libmcaptcha::{
cache::{messages::VerifyCaptchaResult, HashCache}, cache::{messages::VerifyCaptchaResult, HashCache},
master::embedded::master::{AddSiteBuilder, Master}, master::embedded::master::Master,
master::AddSiteBuilder,
pow::{ConfigBuilder, Work}, pow::{ConfigBuilder, Work},
system::SystemBuilder, system::SystemBuilder,
DefenseBuilder, LevelBuilder, MCaptchaBuilder, DefenseBuilder, LevelBuilder, MCaptchaBuilder,
@ -75,8 +76,7 @@ async fn main() -> std::io::Result<()> {
.duration(30) .duration(30)
// .cache(cache) // .cache(cache)
.build() .build()
.unwrap() .unwrap();
.start();
// unique value identifying an MCaptcha actor // unique value identifying an MCaptcha actor
let mcaptcha_name = "batsense.net"; let mcaptcha_name = "batsense.net";
@ -84,7 +84,7 @@ async fn main() -> std::io::Result<()> {
// add MCaptcha to Master // add MCaptcha to Master
let msg = AddSiteBuilder::default() let msg = AddSiteBuilder::default()
.id(mcaptcha_name.into()) .id(mcaptcha_name.into())
.addr(mcaptcha.clone()) .mcaptcha(mcaptcha)
.build() .build()
.unwrap(); .unwrap();
system.master.send(msg).await.unwrap(); system.master.send(msg).await.unwrap();

View file

@ -48,7 +48,8 @@
//! ```rust //! ```rust
//! use libmcaptcha::{ //! use libmcaptcha::{
//! cache::{messages::VerifyCaptchaResult, HashCache}, //! cache::{messages::VerifyCaptchaResult, HashCache},
//! master::embedded::master::{AddSiteBuilder, Master}, //! master::embedded::master:: Master,
//! master::AddSiteBuilder,
//! pow::{ConfigBuilder, Work}, //! pow::{ConfigBuilder, Work},
//! system::SystemBuilder, //! system::SystemBuilder,
//! DefenseBuilder, LevelBuilder, MCaptchaBuilder, //! DefenseBuilder, LevelBuilder, MCaptchaBuilder,
@ -123,8 +124,7 @@
//! .duration(30) //! .duration(30)
//! // .cache(cache) //! // .cache(cache)
//! .build() //! .build()
//! .unwrap() //! .unwrap();
//! .start();
//! //!
//! // unique value identifying an MCaptcha actor //! // unique value identifying an MCaptcha actor
//! let mcaptcha_name = "batsense.net"; //! let mcaptcha_name = "batsense.net";
@ -132,7 +132,7 @@
//! // add MCaptcha to Master //! // add MCaptcha to Master
//! let msg = AddSiteBuilder::default() //! let msg = AddSiteBuilder::default()
//! .id(mcaptcha_name.into()) //! .id(mcaptcha_name.into())
//! .addr(mcaptcha.clone()) //! .mcaptcha(mcaptcha)
//! .build() //! .build()
//! .unwrap(); //! .unwrap();
//! system.master.send(msg).await.unwrap(); //! system.master.send(msg).await.unwrap();
@ -196,4 +196,5 @@ mod utils;
pub use crate::cache::hashcache::HashCache; pub use crate::cache::hashcache::HashCache;
pub use defense::{Defense, DefenseBuilder, LevelBuilder}; pub use defense::{Defense, DefenseBuilder, LevelBuilder};
pub use master::embedded::mcaptcha::{MCaptcha, MCaptchaBuilder}; pub use master::embedded::counter::Counter;
pub use master::MCaptchaBuilder;

View file

@ -15,11 +15,17 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//! MCaptcha actor module that manages defense levels //! Counter actor module that manages defense levels
//! //!
//! ## Usage: //! ## Usage:
//! ```rust //! ```rust
//! use libmcaptcha::{master::embedded::mcaptcha::AddVisitor, MCaptchaBuilder, cache::HashCache, LevelBuilder, DefenseBuilder}; //! use libmcaptcha::{
//! master::embedded::counter::{Counter, AddVisitor},
//! master::MCaptchaBuilder,
//! cache::HashCache,
//! LevelBuilder,
//! DefenseBuilder
//! };
//! // traits from actix needs to be in scope for starting actor //! // traits from actix needs to be in scope for starting actor
//! use actix::prelude::*; //! use actix::prelude::*;
//! //!
@ -55,18 +61,20 @@
//! .build() //! .build()
//! .unwrap(); //! .unwrap();
//! //!
//! // create and start MCaptcha actor //! // create and start Counter actor
//! //let cache = HashCache::default().start(); //! //let cache = HashCache::default().start();
//! let mcaptcha = MCaptchaBuilder::default() //! let mcaptcha = MCaptchaBuilder::default()
//! .defense(defense) //! .defense(defense)
//! // leaky bucket algorithm's emission interval //! // leaky bucket algorithm's emission interval
//! .duration(30) //! .duration(30)
//! .build() //! .build()
//! .unwrap() //! .unwrap();
//! .start(); //!
//! let counter: Counter = mcaptcha.into();
//! let counter = counter.start();
//! //!
//! // increment count when user visits protected routes //! // increment count when user visits protected routes
//! mcaptcha.send(AddVisitor).await.unwrap(); //! counter.send(AddVisitor).await.unwrap();
//! //!
//! Ok(()) //! Ok(())
//! } //! }
@ -78,72 +86,29 @@ use std::time::Duration;
use actix::dev::*; use actix::dev::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::master::MCaptcha;
defense::Defense, use crate::{defense::Defense, master::AddVisitorResult};
errors::{CaptchaError, CaptchaResult},
master::AddVisitorResult,
};
/// Builder for [MCaptcha]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MCaptchaBuilder {
visitor_threshold: u32,
defense: Option<Defense>,
duration: Option<u64>,
}
impl Default for MCaptchaBuilder {
fn default() -> Self {
MCaptchaBuilder {
visitor_threshold: 0,
defense: None,
duration: None,
}
}
}
/// This struct represents the mCaptcha state and is used /// This struct represents the mCaptcha state and is used
/// to configure leaky-bucket lifetime and manage defense /// to configure leaky-bucket lifetime and manage defense
#[derive(Clone, Serialize, Deserialize, Debug)] #[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MCaptcha { pub struct Counter {
visitor_threshold: u32, visitor_threshold: u32,
defense: Defense, defense: Defense,
duration: u64, duration: u64,
} }
impl From<MCaptcha> for Counter {
impl MCaptchaBuilder { fn from(m: MCaptcha) -> Counter {
/// set defense let m = Counter {
pub fn defense(&mut self, d: Defense) -> &mut Self { duration: m.duration,
self.defense = Some(d); defense: m.defense,
self visitor_threshold: m.visitor_threshold,
}
/// set duration
pub fn duration(&mut self, d: u64) -> &mut Self {
self.duration = Some(d);
self
}
/// Builds new [MCaptcha]
pub fn build(&mut self) -> CaptchaResult<MCaptcha> {
if self.duration.is_none() {
Err(CaptchaError::PleaseSetValue("duration".into()))
} else if self.defense.is_none() {
Err(CaptchaError::PleaseSetValue("defense".into()))
} else if self.duration <= Some(0) {
Err(CaptchaError::CaptchaDurationZero)
} else {
let m = MCaptcha {
duration: self.duration.unwrap(),
defense: self.defense.clone().unwrap(),
visitor_threshold: self.visitor_threshold,
}; };
Ok(m) m
}
} }
} }
impl MCaptcha { impl Counter {
/// increments the visitor count by one /// increments the visitor count by one
pub fn add_visitor(&mut self) { pub fn add_visitor(&mut self) {
self.visitor_threshold += 1; self.visitor_threshold += 1;
@ -166,12 +131,12 @@ impl MCaptcha {
self.defense.get_difficulty() self.defense.get_difficulty()
} }
/// get [MCaptcha]'s lifetime /// get [Counter]'s lifetime
pub fn get_duration(&self) -> u64 { pub fn get_duration(&self) -> u64 {
self.duration self.duration
} }
} }
impl Actor for MCaptcha { impl Actor for Counter {
type Context = Context<Self>; type Context = Context<Self>;
} }
@ -180,7 +145,7 @@ impl Actor for MCaptcha {
#[rtype(result = "()")] #[rtype(result = "()")]
struct DeleteVisitor; struct DeleteVisitor;
impl Handler<DeleteVisitor> for MCaptcha { impl Handler<DeleteVisitor> for Counter {
type Result = (); type Result = ();
fn handle(&mut self, _msg: DeleteVisitor, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, _msg: DeleteVisitor, _ctx: &mut Self::Context) -> Self::Result {
self.decrement_visitor(); self.decrement_visitor();
@ -194,7 +159,7 @@ impl Handler<DeleteVisitor> for MCaptcha {
pub struct AddVisitor; pub struct AddVisitor;
impl AddVisitorResult { impl AddVisitorResult {
fn new(m: &MCaptcha) -> Self { fn new(m: &Counter) -> Self {
AddVisitorResult { AddVisitorResult {
duration: m.get_duration(), duration: m.get_duration(),
difficulty_factor: m.get_difficulty(), difficulty_factor: m.get_difficulty(),
@ -202,7 +167,7 @@ impl AddVisitorResult {
} }
} }
impl Handler<AddVisitor> for MCaptcha { impl Handler<AddVisitor> for Counter {
type Result = MessageResult<AddVisitor>; type Result = MessageResult<AddVisitor>;
fn handle(&mut self, _: AddVisitor, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, _: AddVisitor, ctx: &mut Self::Context) -> Self::Result {
@ -228,7 +193,7 @@ impl Handler<AddVisitor> for MCaptcha {
#[rtype(result = "u32")] #[rtype(result = "u32")]
pub struct GetCurrentVisitorCount; pub struct GetCurrentVisitorCount;
impl Handler<GetCurrentVisitorCount> for MCaptcha { impl Handler<GetCurrentVisitorCount> for Counter {
type Result = MessageResult<GetCurrentVisitorCount>; type Result = MessageResult<GetCurrentVisitorCount>;
fn handle(&mut self, _: GetCurrentVisitorCount, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, _: GetCurrentVisitorCount, _ctx: &mut Self::Context) -> Self::Result {
@ -236,12 +201,12 @@ impl Handler<GetCurrentVisitorCount> for MCaptcha {
} }
} }
/// Message to stop [MCaptcha] /// Message to stop [Counter]
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct Stop; pub struct Stop;
impl Handler<Stop> for MCaptcha { impl Handler<Stop> for Counter {
type Result = (); type Result = ();
fn handle(&mut self, _: Stop, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, _: Stop, ctx: &mut Self::Context) -> Self::Result {
@ -253,6 +218,8 @@ impl Handler<Stop> for MCaptcha {
pub mod tests { pub mod tests {
use super::*; use super::*;
use crate::defense::*; use crate::defense::*;
use crate::errors::*;
use crate::master::MCaptchaBuilder;
// constants for testing // constants for testing
// (visitor count, level) // (visitor count, level)
@ -260,7 +227,7 @@ pub mod tests {
pub const LEVEL_2: (u32, u32) = (500, 500); pub const LEVEL_2: (u32, u32) = (500, 500);
pub const DURATION: u64 = 5; pub const DURATION: u64 = 5;
type MyActor = Addr<MCaptcha>; type MyActor = Addr<Counter>;
pub fn get_defense() -> Defense { pub fn get_defense() -> Defense {
DefenseBuilder::default() DefenseBuilder::default()
@ -286,13 +253,17 @@ pub mod tests {
.unwrap() .unwrap()
} }
async fn race(addr: Addr<MCaptcha>, count: (u32, u32)) { async fn race(addr: Addr<Counter>, count: (u32, u32)) {
for _ in 0..count.0 as usize - 1 { for _ in 0..count.0 as usize - 1 {
let _ = addr.send(AddVisitor).await.unwrap(); let _ = addr.send(AddVisitor).await.unwrap();
} }
} }
pub fn get_counter() -> MCaptcha { pub fn get_counter() -> Counter {
get_mcaptcha().into()
}
pub fn get_mcaptcha() -> MCaptcha {
MCaptchaBuilder::default() MCaptchaBuilder::default()
.defense(get_defense()) .defense(get_defense())
.duration(DURATION) .duration(DURATION)

View file

@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//! [Master] actor module that manages [MCaptcha] actors //! [Master] actor module that manages [Counter] actors
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
use std::time::Duration; use std::time::Duration;
@ -23,30 +23,28 @@ use std::time::Duration;
//use actix::clock::sleep; //use actix::clock::sleep;
use actix::clock::delay_for; use actix::clock::delay_for;
use actix::dev::*; use actix::dev::*;
use derive_builder::Builder;
use log::info; use log::info;
use super::mcaptcha::MCaptcha; use super::counter::Counter;
use crate::master::AddVisitor;
use crate::master::Master as MasterTrait; use crate::master::Master as MasterTrait;
use crate::master::{AddSite, AddVisitor};
/// This Actor manages the [MCaptcha] actors. /// This Actor manages the [Counter] actors.
/// A service can have several [MCaptcha] actors with /// A service can have several [Counter] actors with
/// varying [Defense][crate::defense::Defense] configurations /// varying [Defense][crate::defense::Defense] configurations
/// so a "master" actor is needed to manage them all /// so a "master" actor is needed to manage them all
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct Master { pub struct Master {
sites: BTreeMap<String, (Option<()>, Addr<MCaptcha>)>, sites: BTreeMap<String, (Option<()>, Addr<Counter>)>,
gc: u64, gc: u64,
} }
impl MasterTrait for Master {} impl MasterTrait for Master {}
impl Master { impl Master {
/// add [MCaptcha] actor to [Master] /// add [Counter] actor to [Master]
pub fn add_site(&mut self, details: AddSite) { pub fn add_site(&mut self, addr: Addr<Counter>, id: String) {
self.sites self.sites.insert(id, (None, addr.to_owned()));
.insert(details.id, (None, details.addr.to_owned()));
} }
/// create new master /// create new master
@ -58,8 +56,8 @@ impl Master {
} }
} }
/// get [MCaptcha] actor from [Master] /// get [Counter] actor from [Master]
pub fn get_site<'a, 'b>(&'a mut self, id: &'b str) -> Option<Addr<MCaptcha>> { pub fn get_site<'a, 'b>(&'a mut self, id: &'b str) -> Option<Addr<Counter>> {
let mut r = None; let mut r = None;
if let Some((read_val, addr)) = self.sites.get_mut(id) { if let Some((read_val, addr)) = self.sites.get_mut(id) {
r = Some(addr.clone()); r = Some(addr.clone());
@ -68,7 +66,7 @@ impl Master {
r r
} }
/// remvoes [MCaptcha] actor from [Master] /// remvoes [Counter] actor from [Master]
pub fn rm_site(&mut self, id: &str) { pub fn rm_site(&mut self, id: &str) {
self.sites.remove(id); self.sites.remove(id);
} }
@ -99,7 +97,7 @@ impl Handler<AddVisitor> for Master {
let fut = async move { let fut = async move {
let config = addr let config = addr
.unwrap() .unwrap()
.send(super::mcaptcha::AddVisitor) .send(super::counter::AddVisitor)
.await .await
.unwrap(); .unwrap();
@ -112,9 +110,9 @@ impl Handler<AddVisitor> for Master {
} }
} }
/// Message to get an [MCaptcha] actor from master /// Message to get an [Counter] actor from master
#[derive(Message)] #[derive(Message)]
#[rtype(result = "Option<Addr<MCaptcha>>")] #[rtype(result = "Option<Addr<Counter>>")]
pub struct GetSite(pub String); pub struct GetSite(pub String);
impl Handler<GetSite> for Master { impl Handler<GetSite> for Master {
@ -130,7 +128,7 @@ impl Handler<GetSite> for Master {
} }
} }
/// Message to clean up master of [MCaptcha] actors with zero visitor count /// Message to clean up master of [Counter] actors with zero visitor count
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct CleanUp; pub struct CleanUp;
@ -145,7 +143,7 @@ impl Handler<CleanUp> for Master {
info!("init master actor cleanup up"); info!("init master actor cleanup up");
let task = async move { let task = async move {
for (id, (new, addr)) in sites.iter() { for (id, (new, addr)) in sites.iter() {
use super::mcaptcha::{GetCurrentVisitorCount, Stop}; use super::counter::{GetCurrentVisitorCount, Stop};
let visitor_count = addr.send(GetCurrentVisitorCount).await.unwrap(); let visitor_count = addr.send(GetCurrentVisitorCount).await.unwrap();
println!("{}", visitor_count); println!("{}", visitor_count);
if visitor_count == 0 && new.is_some() { if visitor_count == 0 && new.is_some() {
@ -165,7 +163,7 @@ impl Handler<CleanUp> for Master {
} }
} }
/// Message to delete [MCaptcha] actor /// Message to delete [Counter] actor
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct RemoveSite(pub String); pub struct RemoveSite(pub String);
@ -178,43 +176,38 @@ impl Handler<RemoveSite> for Master {
} }
} }
/// Message to add an [MCaptcha] actor to [Master]
#[derive(Message, Builder)]
#[rtype(result = "()")]
pub struct AddSite {
pub id: String,
pub addr: Addr<MCaptcha>,
}
impl Handler<AddSite> for Master { impl Handler<AddSite> for Master {
type Result = (); type Result = ();
fn handle(&mut self, m: AddSite, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, m: AddSite, _ctx: &mut Self::Context) -> Self::Result {
self.add_site(m); let counter: Counter = m.mcaptcha.into();
let addr = counter.start();
self.add_site(addr, m.id);
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::master::embedded::mcaptcha::tests::*; use crate::master::embedded::counter::tests::*;
use crate::master::AddSiteBuilder;
#[actix_rt::test] #[actix_rt::test]
async fn master_actor_works() { async fn master_actor_works() {
let addr = Master::new(1).start(); let addr = Master::new(1).start();
let id = "yo"; let id = "yo";
let mcaptcha = get_counter().start(); let mcaptcha = get_mcaptcha();
let msg = AddSiteBuilder::default() let msg = AddSiteBuilder::default()
.id(id.into()) .id(id.into())
.addr(mcaptcha.clone()) .mcaptcha(mcaptcha.clone())
.build() .build()
.unwrap(); .unwrap();
addr.send(msg).await.unwrap(); addr.send(msg).await.unwrap();
let mcaptcha_addr = addr.send(GetSite(id.into())).await.unwrap(); let mcaptcha_addr = addr.send(GetSite(id.into())).await.unwrap();
assert_eq!(mcaptcha_addr, Some(mcaptcha)); assert!(mcaptcha_addr.is_some());
let addr_doesnt_exist = addr.send(GetSite("a".into())).await.unwrap(); let addr_doesnt_exist = addr.send(GetSite("a".into())).await.unwrap();
assert!(addr_doesnt_exist.is_none()); assert!(addr_doesnt_exist.is_none());

View file

@ -16,5 +16,5 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
pub mod counter;
pub mod master; pub mod master;
pub mod mcaptcha;

View file

@ -19,12 +19,18 @@
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use actix::dev::*; use actix::dev::*;
use derive_builder::Builder;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod embedded; pub mod embedded;
use crate::defense::Defense;
use crate::errors::*;
/// 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 Master: actix::Actor + actix::Handler<AddVisitor> {} pub trait Master: actix::Actor + actix::Handler<AddVisitor> + actix::Handler<AddSite> {}
//+ actix::Handler<AddSite>
/// Message to add visitor to an [MCaptcha] actor /// Message to add visitor to an [MCaptcha] actor
#[derive(Message)] #[derive(Message)]
@ -39,3 +45,68 @@ pub struct AddVisitorResult {
pub duration: u64, pub duration: u64,
pub difficulty_factor: u32, pub difficulty_factor: u32,
} }
/// Message to add an [Counter] actor to [Master]
#[derive(Message, Builder)]
#[rtype(result = "()")]
pub struct AddSite {
pub id: String,
pub mcaptcha: MCaptcha,
}
/// Builder for [MCaptcha]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MCaptchaBuilder {
visitor_threshold: u32,
defense: Option<Defense>,
duration: Option<u64>,
}
impl Default for MCaptchaBuilder {
fn default() -> Self {
MCaptchaBuilder {
visitor_threshold: 0,
defense: None,
duration: None,
}
}
}
impl MCaptchaBuilder {
/// set defense
pub fn defense(&mut self, d: Defense) -> &mut Self {
self.defense = Some(d);
self
}
/// set duration
pub fn duration(&mut self, d: u64) -> &mut Self {
self.duration = Some(d);
self
}
/// Builds new [MCaptcha]
pub fn build(self: &mut MCaptchaBuilder) -> CaptchaResult<MCaptcha> {
if self.duration.is_none() {
Err(CaptchaError::PleaseSetValue("duration".into()))
} else if self.defense.is_none() {
Err(CaptchaError::PleaseSetValue("defense".into()))
} else if self.duration <= Some(0) {
Err(CaptchaError::CaptchaDurationZero)
} else {
let m = MCaptcha {
duration: self.duration.unwrap(),
defense: self.defense.clone().unwrap(),
visitor_threshold: self.visitor_threshold,
};
Ok(m)
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MCaptcha {
visitor_threshold: u32,
defense: Defense,
duration: u64,
}

View file

@ -42,7 +42,8 @@ where
+ ToEnvelope<T, CacheResult> + ToEnvelope<T, CacheResult>
+ ToEnvelope<T, VerifyCaptchaResult>, + ToEnvelope<T, VerifyCaptchaResult>,
X: Master, X: Master,
<X as actix::Actor>::Context: ToEnvelope<X, crate::master::AddVisitor>, <X as actix::Actor>::Context:
ToEnvelope<X, crate::master::AddVisitor> + ToEnvelope<X, crate::master::AddSite>,
{ {
/// utility function to get difficulty factor of site `id` and cache it /// utility function to get difficulty factor of site `id` and cache it
pub async fn get_pow(&self, id: String) -> Option<PoWConfig> { pub async fn get_pow(&self, id: String) -> Option<PoWConfig> {
@ -123,21 +124,21 @@ mod tests {
use super::System; use super::System;
use super::*; use super::*;
use crate::cache::HashCache; use crate::cache::HashCache;
use crate::master::embedded::counter::tests::*;
use crate::master::embedded::master::Master; use crate::master::embedded::master::Master;
use crate::master::embedded::master::*; use crate::master::*;
use crate::master::embedded::mcaptcha::tests::*;
const MCAPTCHA_NAME: &str = "batsense.net"; const MCAPTCHA_NAME: &str = "batsense.net";
async fn boostrap_system(gc: u64) -> System<HashCache, Master> { async fn boostrap_system(gc: u64) -> System<HashCache, Master> {
let master = Master::new(gc).start(); let master = Master::new(gc).start();
let mcaptcha = get_counter().start(); let mcaptcha = get_mcaptcha();
let pow = get_config(); let pow = get_config();
let cache = HashCache::default().start(); let cache = HashCache::default().start();
let msg = AddSiteBuilder::default() let msg = AddSiteBuilder::default()
.id(MCAPTCHA_NAME.into()) .id(MCAPTCHA_NAME.into())
.addr(mcaptcha.clone()) .mcaptcha(mcaptcha)
.build() .build()
.unwrap(); .unwrap();