diff --git a/guard/all.html b/guard/all.html index daef1b24..fe6dfa88 100644 --- a/guard/all.html +++ b/guard/all.html @@ -3,4 +3,4 @@

[] - List of all items

Structs

Enums

Functions

Typedefs

\ No newline at end of file + List of all items

Structs

Enums

Functions

Typedefs

\ No newline at end of file diff --git a/guard/api/v1/auth/index.html b/guard/api/v1/auth/index.html index 0f6e4e1b..2b239849 100644 --- a/guard/api/v1/auth/index.html +++ b/guard/api/v1/auth/index.html @@ -1,7 +1,7 @@ guard::api::v1::auth - Rust

[][src]Module guard::api::v1::auth

Structs

+ Change settings

[][src]Module guard::api::v1::auth

Structs

Login
Password
Register
delete_account
signin
signout
signup

Functions

is_authenticated

Check if user is authenticated

\ No newline at end of file diff --git a/guard/api/v1/fn.services.html b/guard/api/v1/fn.services.html index 41939269..7a306557 100644 --- a/guard/api/v1/fn.services.html +++ b/guard/api/v1/fn.services.html @@ -1,4 +1,4 @@ guard::api::v1::services - Rust

[][src]Function guard::api::v1::services

pub fn services(cfg: &mut ServiceConfig)
\ No newline at end of file + Change settings

[][src]Function guard::api::v1::services

pub fn services(cfg: &mut ServiceConfig)
\ No newline at end of file diff --git a/guard/api/v1/index.html b/guard/api/v1/index.html index c32ba304..65771f42 100644 --- a/guard/api/v1/index.html +++ b/guard/api/v1/index.html @@ -1,6 +1,6 @@ guard::api::v1 - Rust

[][src]Module guard::api::v1

Modules

+ Change settings

[][src]Module guard::api::v1

Modules

auth
mcaptcha

Functions

services
\ No newline at end of file diff --git a/guard/api/v1/mcaptcha/fn.get_random.html b/guard/api/v1/mcaptcha/fn.get_random.html index e46cde0c..e4af1fb3 100644 --- a/guard/api/v1/mcaptcha/fn.get_random.html +++ b/guard/api/v1/mcaptcha/fn.get_random.html @@ -1,4 +1,4 @@ guard::api::v1::mcaptcha::get_random - Rust

[][src]Function guard::api::v1::mcaptcha::get_random

fn get_random(len: usize) -> String
\ No newline at end of file + Change settings

[][src]Function guard::api::v1::mcaptcha::get_random

fn get_random(len: usize) -> String
\ No newline at end of file diff --git a/guard/api/v1/mcaptcha/index.html b/guard/api/v1/mcaptcha/index.html index 7843b45d..2b7b7de6 100644 --- a/guard/api/v1/mcaptcha/index.html +++ b/guard/api/v1/mcaptcha/index.html @@ -1,6 +1,6 @@ guard::api::v1::mcaptcha - Rust

[][src]Module guard::api::v1::mcaptcha

Structs

-
Domain
TokenKeyPair
TokenName
add_domain
delete_domain

Functions

+ Change settings

[][src]Module guard::api::v1::mcaptcha

Structs

+
CreateToken
Domain
TokenKeyPair
add_domain
add_mcaptcha
delete_domain
delete_mcaptcha

Functions

get_random
\ No newline at end of file diff --git a/guard/api/v1/mcaptcha/sidebar-items.js b/guard/api/v1/mcaptcha/sidebar-items.js index 70fe1da3..7d555adb 100644 --- a/guard/api/v1/mcaptcha/sidebar-items.js +++ b/guard/api/v1/mcaptcha/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"fn":[["get_random",""]],"struct":[["Domain",""],["TokenKeyPair",""],["TokenName",""],["add_domain",""],["delete_domain",""]]}); \ No newline at end of file +initSidebarItems({"fn":[["get_random",""]],"struct":[["CreateToken",""],["Domain",""],["TokenKeyPair",""],["add_domain",""],["add_mcaptcha",""],["delete_domain",""],["delete_mcaptcha",""]]}); \ No newline at end of file diff --git a/guard/api/v1/mcaptcha/struct.TokenName.html b/guard/api/v1/mcaptcha/struct.CreateToken.html similarity index 84% rename from guard/api/v1/mcaptcha/struct.TokenName.html rename to guard/api/v1/mcaptcha/struct.CreateToken.html index 5345f12c..2c0db7c2 100644 --- a/guard/api/v1/mcaptcha/struct.TokenName.html +++ b/guard/api/v1/mcaptcha/struct.CreateToken.html @@ -1,15 +1,16 @@ -guard::api::v1::mcaptcha::TokenName - Rust +guard::api::v1::mcaptcha::CreateToken - Rust -

[][src]Struct guard::api::v1::mcaptcha::TokenName

pub struct TokenName {
+

[][src]Struct guard::api::v1::mcaptcha::CreateToken

pub struct CreateToken {
     pub name: String,
+    pub domain: String,
 }

- Fields

name: String

Trait Implementations

impl Clone for TokenName[src]

 /*
 * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
@@ -432,13 +444,15 @@
         const NAME: &str = "testuser";
         const PASSWORD: &str = "longpassword";
         const EMAIL: &str = "testuser1@a.com";
+        const SIGNIN: &str = "/api/v1/signin";
+        const SIGNUP: &str = "/api/v1/signup";
 
         let mut app = get_app!(data).await;
 
         delete_user(NAME, &data).await;
 
         // 1. Register and signin
-        let (data, _, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
+        let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
         let cookies = get_cookie!(signin_resp);
 
         // 2. check if duplicate username is allowed
@@ -447,49 +461,55 @@
             password: PASSWORD.into(),
             email: EMAIL.into(),
         };
-        let duplicate_user_resp =
-            test::call_service(&mut app, post_request!(&msg, "/api/v1/signup").to_request()).await;
-        assert_eq!(duplicate_user_resp.status(), StatusCode::BAD_REQUEST);
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            SIGNUP,
+            &msg,
+            ServiceError::UsernameTaken,
+            StatusCode::BAD_REQUEST,
+        )
+        .await;
 
         // 3. sigining in with non-existent user
-        let nonexistantuser = Login {
+        let mut login = Login {
             username: "nonexistantuser".into(),
             password: msg.password.clone(),
         };
-        let userdoesntexist = test::call_service(
-            &mut app,
-            post_request!(&nonexistantuser, "/api/v1/signin").to_request(),
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            SIGNIN,
+            &login,
+            ServiceError::UsernameNotFound,
+            StatusCode::UNAUTHORIZED,
         )
         .await;
-        assert_eq!(userdoesntexist.status(), StatusCode::UNAUTHORIZED);
-        let txt: ErrorToResponse = test::read_body_json(userdoesntexist).await;
-        assert_eq!(txt.error, format!("{}", ServiceError::UsernameNotFound));
 
         // 4. trying to signin with wrong password
-        let wrongpassword = Login {
-            username: NAME.into(),
-            password: NAME.into(),
-        };
-        let wrongpassword_resp = test::call_service(
-            &mut app,
-            post_request!(&wrongpassword, "/api/v1/signin").to_request(),
+        login.username = NAME.into();
+        login.password = NAME.into();
+
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            SIGNIN,
+            &login,
+            ServiceError::WrongPassword,
+            StatusCode::UNAUTHORIZED,
         )
         .await;
-        assert_eq!(wrongpassword_resp.status(), StatusCode::UNAUTHORIZED);
-        let txt: ErrorToResponse = test::read_body_json(wrongpassword_resp).await;
-        assert_eq!(txt.error, format!("{}", ServiceError::WrongPassword));
 
         // 5. signout
         let signout_resp = test::call_service(
             &mut app,
-            post_request!(&wrongpassword, "/api/v1/signout")
-                .cookie(cookies.clone())
+            test::TestRequest::post()
+                .uri("/api/v1/signout")
+                .cookie(cookies)
                 .to_request(),
         )
         .await;
         assert_eq!(signout_resp.status(), StatusCode::OK);
-
-        delete_user(NAME, &data).await;
     }
 
     #[actix_rt::test]
@@ -498,7 +518,12 @@
         const PASSWORD: &str = "longpassword2";
         const EMAIL: &str = "testuser1@a.com2";
 
-        let (data, creds, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
+        {
+            let data = Data::new().await;
+            delete_user(NAME, &data).await;
+        }
+
+        let (data, creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
         let cookies = get_cookie!(signin_resp);
         let mut app = get_app!(data).await;
 
@@ -511,7 +536,6 @@
         .await;
 
         assert_eq!(delete_user_resp.status(), StatusCode::OK);
-        delete_user(NAME, &data).await;
     }
 }
 
diff --git a/src/guard/api/v1/mcaptcha.rs.html b/src/guard/api/v1/mcaptcha.rs.html index ee95bc54..a28ab09b 100644 --- a/src/guard/api/v1/mcaptcha.rs.html +++ b/src/guard/api/v1/mcaptcha.rs.html @@ -177,6 +177,123 @@ 174 175 176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293
 /*
 * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
@@ -219,15 +336,18 @@
     let url = Url::parse(&payload.name)?;
     if let Some(host) = url.host_str() {
         let user = id.identity().unwrap();
-        sqlx::query!(
+        let res = sqlx::query!(
             "insert into mcaptcha_domains (name, ID) values  
             ($1, (select ID from mcaptcha_users where name = ($2) ));",
             host,
             user
         )
         .execute(&data.db)
-        .await?;
-        Ok(HttpResponse::Ok())
+        .await;
+        match res {
+            Err(e) => Err(dup_error(e, ServiceError::HostnameTaken)),
+            Ok(_) => Ok(HttpResponse::Ok()),
+        }
     } else {
         Err(ServiceError::NotAUrl)
     }
@@ -252,8 +372,9 @@
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
-pub struct TokenName {
+pub struct CreateToken {
     pub name: String,
+    pub domain: String,
 }
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
@@ -262,34 +383,60 @@
     pub key: String,
 }
 
-//#[post("/api/v1/mcaptcha/domain/token/add")]
-//pub async fn add_mcaptcha(
-//    payload: web::Json<Domain>,
-//    data: web::Data<Data>,
-//    id: Identity,
-//) -> ServiceResult<impl Responder> {
-//    is_authenticated(&id)?;
-//    let key = get_random(32);
-//    let res = sqlx::query!(
-//        "INSERT INTO mcaptcha_config (name, key) VALUES ($1, $2)",
-//        &payload.name,
-//        &key,
-//    )
-//    .execute(&data.db)
-//    .await;
-//
-//    match res {
-//        Err(e) => Err(dup_error(e, ServiceError::UsernameTaken)),
-//        Ok(_) => {
-//            let resp = TokenKeyPair {
-//                key,
-//                name: payload.name,
-//            };
-//
-//            Ok(HttpResponse::Ok().json(resp))
-//        }
-//    }
-//}
+#[post("/api/v1/mcaptcha/domain/token/add")]
+pub async fn add_mcaptcha(
+    payload: web::Json<CreateToken>,
+    data: web::Data<Data>,
+    id: Identity,
+) -> ServiceResult<impl Responder> {
+    is_authenticated(&id)?;
+    let key = get_random(32);
+    let url = Url::parse(&payload.domain)?;
+    println!("got req");
+    if let Some(host) = url.host_str() {
+        let res = sqlx::query!(
+            "INSERT INTO mcaptcha_config 
+        (name, key, domain_name)
+        VALUES ($1, $2, (
+                SELECT name FROM mcaptcha_domains WHERE name = ($3)))",
+            &payload.name,
+            &key,
+            &host,
+        )
+        .execute(&data.db)
+        .await;
+
+        match res {
+            Err(e) => Err(dup_error(e, ServiceError::TokenNameTaken)),
+            Ok(_) => {
+                let resp = TokenKeyPair {
+                    key,
+                    name: payload.into_inner().name,
+                };
+
+                Ok(HttpResponse::Ok().json(resp))
+            }
+        }
+    } else {
+        Err(ServiceError::NotAUrl)
+    }
+}
+
+#[post("/api/v1/mcaptcha/domain/token/delete")]
+pub async fn delete_mcaptcha(
+    payload: web::Json<CreateToken>,
+    data: web::Data<Data>,
+    id: Identity,
+) -> ServiceResult<impl Responder> {
+    is_authenticated(&id)?;
+    sqlx::query!(
+        "DELETE FROM mcaptcha_config WHERE name = ($1)",
+        &payload.name,
+    )
+    .execute(&data.db)
+    .await?;
+    Ok(HttpResponse::Ok())
+}
 
 fn get_random(len: usize) -> String {
     use std::iter;
@@ -321,28 +468,36 @@
         const PASSWORD: &str = "longpassworddomain";
         const EMAIL: &str = "testuserdomain@a.com";
         const DOMAIN: &str = "http://example.com";
+        const ADD_URL: &str = "/api/v1/mcaptcha/domain/add";
 
-        let (data, _, signin_resp) = signin_util(NAME, EMAIL, PASSWORD).await;
+        {
+            let data = Data::new().await;
+            delete_user(NAME, &data).await;
+        }
+
+        register_and_signin(NAME, EMAIL, PASSWORD).await;
+
+        // 1. add domain
+        let (data, _, signin_resp) = add_domain_util(NAME, PASSWORD, DOMAIN).await;
         let cookies = get_cookie!(signin_resp);
         let mut app = get_app!(data).await;
 
-        delete_domain_util(DOMAIN, &data).await;
-
-        // 1. add domain
-        let domain = Domain {
+        let mut domain = Domain {
             name: DOMAIN.into(),
         };
 
-        let add_domain_resp = test::call_service(
-            &mut app,
-            post_request!(&domain, "/api/v1/mcaptcha/domain/add")
-                .cookie(cookies.clone())
-                .to_request(),
+        // 2. duplicate domain
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            ADD_URL,
+            &domain,
+            ServiceError::HostnameTaken,
+            StatusCode::BAD_REQUEST,
         )
         .await;
-        assert_eq!(add_domain_resp.status(), StatusCode::OK);
 
-        // 2. delete domain
+        // 3. delete domain
         let del_domain_resp = test::call_service(
             &mut app,
             post_request!(&domain, "/api/v1/mcaptcha/domain/delete")
@@ -351,7 +506,86 @@
         )
         .await;
         assert_eq!(del_domain_resp.status(), StatusCode::OK);
-        delete_user(NAME, &data).await;
+
+        // 4. not a URL test for adding domain
+        domain.name = "testing".into();
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            ADD_URL,
+            &domain,
+            ServiceError::NotAUrl,
+            StatusCode::BAD_REQUEST,
+        )
+        .await;
+    }
+
+    #[actix_rt::test]
+    async fn add_mcaptcha_works() {
+        const NAME: &str = "testusermcaptcha";
+        const PASSWORD: &str = "longpassworddomain";
+        const EMAIL: &str = "testusermcaptcha@a.com";
+        const DOMAIN: &str = "http://mcaptcha.example.com";
+        const TOKEN_NAME: &str = "add_mcaptcha_works_token";
+        const ADD_URL: &str = "/api/v1/mcaptcha/domain/token/add";
+        const DEL_URL: &str = "/api/v1/mcaptcha/domain/token/delete";
+
+        {
+            let data = Data::new().await;
+            delete_user(NAME, &data).await;
+        }
+
+        register_and_signin(NAME, EMAIL, PASSWORD).await;
+        let (data, _, signin_resp) = add_domain_util(NAME, PASSWORD, DOMAIN).await;
+        let cookies = get_cookie!(signin_resp);
+        let mut app = get_app!(data).await;
+
+        // 1. add mcaptcha token
+        let mut domain = CreateToken {
+            domain: DOMAIN.into(),
+            name: TOKEN_NAME.into(),
+        };
+        let add_token_resp = test::call_service(
+            &mut app,
+            post_request!(&domain, ADD_URL)
+                .cookie(cookies.clone())
+                .to_request(),
+        )
+        .await;
+        assert_eq!(add_token_resp.status(), StatusCode::OK);
+
+        // 2. add duplicate mcaptha
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            ADD_URL,
+            &domain,
+            ServiceError::TokenNameTaken,
+            StatusCode::BAD_REQUEST,
+        )
+        .await;
+
+        // 4. not a URL test for adding domain
+        domain.domain = "testing".into();
+        bad_post_req_test(
+            NAME,
+            PASSWORD,
+            ADD_URL,
+            &domain,
+            ServiceError::NotAUrl,
+            StatusCode::BAD_REQUEST,
+        )
+        .await;
+
+        // 4. delete token
+        let del_token = test::call_service(
+            &mut app,
+            post_request!(&domain, DEL_URL)
+                .cookie(cookies.clone())
+                .to_request(),
+        )
+        .await;
+        assert_eq!(del_token.status(), StatusCode::OK);
     }
 }
 
diff --git a/src/guard/api/v1/mod.rs.html b/src/guard/api/v1/mod.rs.html index 3b68ebf5..6dd6e971 100644 --- a/src/guard/api/v1/mod.rs.html +++ b/src/guard/api/v1/mod.rs.html @@ -35,6 +35,8 @@ 32 33 34 +35 +36
 /*
 * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
@@ -69,6 +71,8 @@
 
     cfg.service(add_domain);
     cfg.service(delete_domain);
+    cfg.service(add_mcaptcha);
+    cfg.service(delete_mcaptcha);
 }
 
\ No newline at end of file diff --git a/src/guard/errors.rs.html b/src/guard/errors.rs.html index 72a9fa08..6ac0202e 100644 --- a/src/guard/errors.rs.html +++ b/src/guard/errors.rs.html @@ -178,6 +178,12 @@ 175 176 177 +178 +179 +180 +181 +182 +183
 /*
 * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
@@ -257,6 +263,9 @@
     /// when the a token name is already taken
     #[display(fmt = "token name not available")]
     TokenNameTaken,
+    /// when the a host name is already taken
+    #[display(fmt = "host name not available")]
+    HostnameTaken,
 }
 
 #[derive(Serialize, Deserialize)]
@@ -278,6 +287,7 @@
 
     #[cfg(not(tarpaulin_include))]
     fn status_code(&self) -> StatusCode {
+        println!("{:?}", &self);
         match *self {
             ServiceError::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR,
             ServiceError::NotAnEmail => StatusCode::BAD_REQUEST,
@@ -292,6 +302,7 @@
             ServiceError::UsernameCaseMappedError => StatusCode::BAD_REQUEST,
             ServiceError::UsernameTaken => StatusCode::BAD_REQUEST,
             ServiceError::TokenNameTaken => StatusCode::BAD_REQUEST,
+            ServiceError::HostnameTaken => StatusCode::BAD_REQUEST,
         }
     }
 }
@@ -343,6 +354,7 @@
 pub fn dup_error(e: sqlx::Error, dup_error: ServiceError) -> ServiceError {
     use sqlx::error::Error;
     use std::borrow::Cow;
+    println!("database error: {:?}", &e);
     if let Error::Database(err) = e {
         if err.code() == Some(Cow::from("23505")) {
             dup_error