diff --git a/Cargo.toml b/Cargo.toml index 45f362c4..7a20ffcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/mCaptcha/mCaptcha" documentation = "https://mcaptcha.org/docs/" license = "AGPLv3 or later version" authors = ["realaravinth "] -edition = "2018" +edition = "2021" default-run = "mcaptcha" build = "build.rs" diff --git a/src/demo.rs b/src/demo.rs index e1965276..17a16176 100644 --- a/src/demo.rs +++ b/src/demo.rs @@ -15,9 +15,11 @@ * along with this program. If not, see . */ use std::time::Duration; +//use std::sync::atomicBool use actix::clock::sleep; use actix::spawn; +use tokio::task::JoinHandle; use crate::api::v1::account::delete::runners::delete_user; use crate::api::v1::account::{username::runners::username_exists, AccountCheckPayload}; @@ -31,52 +33,79 @@ pub const DEMO_USER: &str = "aaronsw"; /// Demo password pub const DEMO_PASSWORD: &str = "password"; -/// register demo user runner -async fn register_demo_user(data: &AppData) -> ServiceResult<()> { - let user_exists_payload = AccountCheckPayload { - val: DEMO_USER.into(), - }; +pub struct DemoUser { + data: AppData, + duration: Duration, + handle: JoinHandle<()>, +} - if !username_exists(&user_exists_payload, data).await?.exists { - let register_payload = Register { - username: DEMO_USER.into(), - password: DEMO_PASSWORD.into(), - confirm_password: DEMO_PASSWORD.into(), - email: None, +impl DemoUser { + pub async fn spawn(data: AppData, duration: Duration) -> ServiceResult { + let handle = Self::run(data.clone(), duration.clone()).await?; + let d = Self { + data, + duration, + handle, }; - log::info!("Registering demo user"); - match register_runner(®ister_payload, data).await { - Err(ServiceError::UsernameTaken) | Ok(_) => Ok(()), - Err(e) => Err(e), + Ok(d) + } + + #[allow(dead_code)] + pub fn abort(&self) { + self.handle.abort(); + } + + /// register demo user runner + async fn register_demo_user(data: &AppData) -> ServiceResult<()> { + let user_exists_payload = AccountCheckPayload { + val: DEMO_USER.into(), + }; + + if !username_exists(&user_exists_payload, &data).await?.exists { + let register_payload = Register { + username: DEMO_USER.into(), + password: DEMO_PASSWORD.into(), + confirm_password: DEMO_PASSWORD.into(), + email: None, + }; + + log::info!("Registering demo user"); + match register_runner(®ister_payload, &data).await { + Err(ServiceError::UsernameTaken) | Ok(_) => Ok(()), + Err(e) => Err(e), + } + } else { + Ok(()) } - } else { + } + + async fn delete_demo_user(data: &AppData) -> ServiceResult<()> { + log::info!("Deleting demo user"); + delete_user(DEMO_USER, &data).await?; Ok(()) } -} -async fn delete_demo_user(data: &AppData) -> ServiceResult<()> { - log::info!("Deleting demo user"); - delete_user(DEMO_USER, data).await?; - Ok(()) -} + pub async fn run( + data: AppData, + duration: Duration, + ) -> ServiceResult> { + Self::register_demo_user(&data).await?; -pub async fn run(data: AppData, duration: Duration) -> ServiceResult<()> { - register_demo_user(&data).await?; - - let fut = async move { - loop { - sleep(duration).await; - if let Err(e) = delete_demo_user(&data).await { - log::error!("Error while deleting demo user: {:?}", e); + let fut = async move { + loop { + sleep(duration).await; + if let Err(e) = Self::delete_demo_user(&data).await { + log::error!("Error while deleting demo user: {:?}", e); + } + if let Err(e) = Self::register_demo_user(&data).await { + log::error!("Error while registering demo user: {:?}", e); + } } - if let Err(e) = register_demo_user(&data).await { - log::error!("Error while registering demo user: {:?}", e); - } - } - }; - spawn(fut); - Ok(()) + }; + let handle = spawn(fut); + Ok(handle) + } } #[cfg(test)] @@ -100,7 +129,7 @@ mod tests { let duration = Duration::from_secs(DURATION); // register works - let _ = register_demo_user(&data).await.unwrap(); + let _ = DemoUser::register_demo_user(&data).await.unwrap(); let payload = AccountCheckPayload { val: DEMO_USER.into(), }; @@ -108,11 +137,11 @@ mod tests { signin(DEMO_USER, DEMO_PASSWORD).await; // deletion works - assert!(super::delete_demo_user(&data).await.is_ok()); + assert!(DemoUser::delete_demo_user(&data).await.is_ok()); assert!(!username_exists(&payload, &data).await.unwrap().exists); // test the runner - run(data, duration).await.unwrap(); + let user = DemoUser::spawn(data, duration).await.unwrap(); let (data_inner, _, signin_resp, token_key) = add_levels_util(DEMO_USER, DEMO_PASSWORD).await; let cookies = get_cookie!(signin_resp); @@ -133,7 +162,7 @@ mod tests { let resp = test::call_service( &app, - post_request!(&token_key, crate::V1_API_ROUTES.captcha.create) + post_request!(&token_key, crate::V1_API_ROUTES.captcha.get) .cookie(cookies) .to_request(), ) @@ -141,5 +170,6 @@ mod tests { assert_eq!(resp.status(), StatusCode::OK); let res_levels: Vec = test::read_body_json(resp).await; assert!(res_levels.is_empty()); + user.abort(); } } diff --git a/src/main.rs b/src/main.rs index 310cf24f..7c28ec41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,7 @@ pub use settings::Settings; use static_assets::FileMap; pub use widget::WIDGET_ROUTES; +use crate::demo::DemoUser; pub use crate::middleware::auth::CheckLogin; lazy_static! { @@ -114,10 +115,14 @@ async fn main() -> std::io::Result<()> { sqlx::migrate!("./migrations/").run(&data.db).await.unwrap(); let data = actix_web::web::Data::new(data); + let mut demo_user: Option = None; + if SETTINGS.allow_demo && SETTINGS.allow_registration { - demo::run(data.clone(), Duration::from_secs(60 * 30)) - .await - .unwrap(); + demo_user = Some( + DemoUser::spawn(data.clone(), Duration::from_secs(60 * 30)) + .await + .unwrap(), + ); } println!("Starting server on: http://{}", SETTINGS.server.get_ip()); @@ -141,7 +146,12 @@ async fn main() -> std::io::Result<()> { .bind(SETTINGS.server.get_ip()) .unwrap() .run() - .await + .await?; + + if let Some(demo_user) = demo_user { + demo_user.abort(); + } + Ok(()) } #[cfg(not(tarpaulin_include))]