diff --git a/db/db-core/src/lib.rs b/db/db-core/src/lib.rs index ad9a78b..5639a24 100644 --- a/db/db-core/src/lib.rs +++ b/db/db-core/src/lib.rs @@ -168,17 +168,6 @@ pub struct Repository { pub import: bool, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -/// represents a DNS challenge -pub struct Challenge { - /// url of the forge instance - pub url: String, - /// key of TXT record - pub key: String, - /// value of TXT record - pub value: String, -} - #[async_trait] /// Starchart's database requirements. To implement support for $Database, kindly implement this /// trait. @@ -186,18 +175,6 @@ pub trait SCDatabase: std::marker::Send + std::marker::Sync + CloneSPDatabase { /// ping DB async fn ping(&self) -> bool; - /// check if a DNS challenge exists - async fn dns_challenge_exists(&self, key: &str) -> DBResult; - - /// create DNS challenge - async fn create_dns_challenge(&self, challenge: &Challenge) -> DBResult<()>; - - /// get DNS challenge - async fn get_dns_challenge(&self, key: &str) -> DBResult; - - /// delete DNS challenge - async fn delete_dns_challenge(&self, key: &str) -> DBResult<()>; - /// create forge instance async fn create_forge_instance(&self, f: &CreateForge) -> DBResult<()>; diff --git a/db/db-sqlx-sqlite/sqlx-data.json b/db/db-sqlx-sqlite/sqlx-data.json index 6f38c5a..fabbfef 100644 --- a/db/db-sqlx-sqlite/sqlx-data.json +++ b/db/db-sqlx-sqlite/sqlx-data.json @@ -18,6 +18,108 @@ }, "query": "SELECT ID FROM starchart_forges WHERE hostname = $1" }, + "0fbcc736f60b14d55fbd88031a2929d04de02f5244345c2bc0f0e58d4c29cb14": { + "describe": { + "columns": [ + { + "name": "html_url", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "profile_photo_html_url", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "imported", + "ordinal": 2, + "type_info": "Bool" + } + ], + "nullable": [ + false, + true, + false + ], + "parameters": { + "Right": 2 + } + }, + "query": "SELECT html_url, profile_photo_html_url, imported FROM starchart_users WHERE username = $1 AND \n hostname_id = (SELECT ID FROM starchart_forges WHERE hostname = $2)" + }, + "1b88e5b97fd62fe5036ea3c87c90315f8d368542a8f2e12a0d542d1317a612db": { + "describe": { + "columns": [ + { + "name": "hostname", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "last_crawl_on", + "ordinal": 1, + "type_info": "Int64" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "imported", + "ordinal": 3, + "type_info": "Bool" + } + ], + "nullable": [ + false, + true, + false, + false + ], + "parameters": { + "Right": 2 + } + }, + "query": "SELECT\n hostname,\n last_crawl_on,\n starchart_forge_type.name,\n imported\n FROM\n starchart_forges\n INNER JOIN\n starchart_forge_type\n ON\n starchart_forges.forge_type = starchart_forge_type.id\n ORDER BY\n starchart_forges.ID\n LIMIT $1 OFFSET $2;\n " + }, + "1d98f7afc772f43fb7131131517f831ec9add25ec3f66881143d6d9baa9e2cc6": { + "describe": { + "columns": [ + { + "name": "hostname", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "last_crawl_on", + "ordinal": 1, + "type_info": "Int64" + }, + { + "name": "imported", + "ordinal": 2, + "type_info": "Bool" + }, + { + "name": "name", + "ordinal": 3, + "type_info": "Text" + } + ], + "nullable": [ + false, + true, + false, + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "SELECT \n hostname,\n last_crawl_on,\n imported,\n starchart_forge_type.name\n FROM\n starchart_forges\n INNER JOIN\n starchart_forge_type\n ON\n starchart_forges.forge_type = starchart_forge_type.id\n WHERE\n hostname = $1;\n " + }, "2afb17ba3753aa440465a836b46b7a1466f25791cfc4d0acdd38bc2755ae3e86": { "describe": { "columns": [ @@ -54,6 +156,16 @@ }, "query": "SELECT ID FROM starchart_forge_type WHERE name = $1" }, + "338fb30307071e6df9efee6a68697c60e579d7b2332630bce401c0e7186a642a": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Right": 7 + } + }, + "query": "INSERT INTO \n starchart_users (\n hostname_id, username, html_url,\n profile_photo_html_url, added_on, last_crawl_on, imported\n ) \n VALUES (\n (SELECT ID FROM starchart_forges WHERE hostname = $1), $2, $3, $4, $5, $6, $7)" + }, "364c8e3d147318b864fd28ad284f225aaace9479b5cf0428fb97f0e5689e248d": { "describe": { "columns": [], @@ -92,17 +204,7 @@ }, "query": "SELECT ID FROM starchart_repositories\n WHERE \n name = $1\n AND\n owner_id = ( SELECT ID FROM starchart_users WHERE username = $2)\n AND\n hostname_id = (SELECT ID FROM starchart_forges WHERE hostname = $3)" }, - "76f49b3e5e0c6d16daeb09afca427cbf29cd477bd647fee04c2067f7f898721a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Right": 1 - } - }, - "query": "DELETE FROM starchart_dns_challenges WHERE key = $1" - }, - "80106a5fde0077375453d6170948330cc89dee997c2b8ad1d98b0799702eddc4": { + "78e53b067f8706f326fe06d184f8d94dd2c1869f89706e88afa9a0b19717229c": { "describe": { "columns": [ { @@ -139,6 +241,11 @@ "name": "website", "ordinal": 6, "type_info": "Text" + }, + { + "name": "imported", + "ordinal": 7, + "type_info": "Bool" } ], "nullable": [ @@ -148,85 +255,16 @@ true, false, false, - true + true, + false ], "parameters": { "Right": 2 } }, - "query": " SELECT \n\t\tstarchart_forges.hostname,\n\t\tstarchart_users.username,\n\t\tstarchart_repositories.name,\n\t\tstarchart_repositories.description,\n\t\tstarchart_repositories.html_url,\n starchart_repositories.ID,\n\t\tstarchart_repositories.website\nFROM\n\tstarchart_repositories\nINNER JOIN\n\tstarchart_forges\nON\n\tstarchart_repositories.hostname_id = starchart_forges.id\nINNER JOIN\n\tstarchart_users\nON\n\tstarchart_repositories.owner_id = starchart_users.id\nORDER BY\n\tstarchart_repositories.ID\nLIMIT $1 OFFSET $2\n;" + "query": "SELECT \n starchart_forges.hostname,\n starchart_users.username,\n starchart_repositories.name,\n starchart_repositories.description,\n starchart_repositories.html_url,\n starchart_repositories.ID,\n starchart_repositories.website,\n starchart_repositories.imported\n FROM\n starchart_repositories\n INNER JOIN\n starchart_forges\n ON\n starchart_repositories.hostname_id = starchart_forges.id\n INNER JOIN\n starchart_users\n ON\n starchart_repositories.owner_id = starchart_users.id\n ORDER BY\n starchart_repositories.ID\n LIMIT $1 OFFSET $2\n ;" }, - "891a09656a04fdabfbf51b15204e224221cea8d30782170d3d8503c9275b3d58": { - "describe": { - "columns": [ - { - "name": "key", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "value", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "hostname", - "ordinal": 2, - "type_info": "Text" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "SELECT key, value, hostname FROM starchart_dns_challenges WHERE key = $1" - }, - "8c78e074d78291f9d3c4ef3526bae00cb356591edad79a7fb1f20aa7bb681216": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Right": 3 - } - }, - "query": "INSERT INTO\n starchart_forges (hostname, verified_on, forge_type ) \n VALUES ($1, $2, (SELECT ID FROM starchart_forge_type WHERE name = $3))" - }, - "a4e02e0fafe95a6e21347607f5f69a06f592c3624775feadaaf5fa5b4285815d": { - "describe": { - "columns": [ - { - "name": "hostname", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "last_crawl_on", - "ordinal": 1, - "type_info": "Int64" - }, - { - "name": "name", - "ordinal": 2, - "type_info": "Text" - } - ], - "nullable": [ - false, - true, - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "SELECT \n\t\thostname,\n\t\tlast_crawl_on,\n\t\tstarchart_forge_type.name\n FROM\n starchart_forges\n INNER JOIN\n starchart_forge_type\n ON\n starchart_forges.forge_type = starchart_forge_type.id\n WHERE\n hostname = $1;\n " - }, - "a75419ce6d1248944a7bdd63ddadd6f1017a27b8490fb2746a0f7a5d35ce889a": { + "9978a056397522cf1375900bb00c55bc17685dcc9cb22127b21a24b194a1e536": { "describe": { "columns": [], "nullable": [], @@ -234,25 +272,7 @@ "Right": 4 } }, - "query": "INSERT INTO\n starchart_dns_challenges (hostname, value, key, created ) \n VALUES ($1, $2, $3, $4);" - }, - "a77477b2f3c383c2c3e849e8aef47dab411f6c8f9cfe5cb6f850e28314eb1a47": { - "describe": { - "columns": [ - { - "name": "ID", - "ordinal": 0, - "type_info": "Int64" - } - ], - "nullable": [ - false - ], - "parameters": { - "Right": 1 - } - }, - "query": "SELECT ID FROM starchart_dns_challenges WHERE key = $1" + "query": "INSERT INTO\n starchart_forges (hostname, verified_on, forge_type, imported) \n VALUES ($1, $2, (SELECT ID FROM starchart_forge_type WHERE name = $3), $4)" }, "a81dd4b5df666e22fac211092e7b8425d838dd9023aa2b17659352f30831944d": { "describe": { @@ -272,55 +292,15 @@ }, "query": "SELECT ID FROM starchart_users WHERE username = $1 AND \n hostname_id = (SELECT ID FROM starchart_forges WHERE hostname = $2)" }, - "b4985ad11fafa367302ca9c0126b95bc70f6ae387f9de649aabb2ef424f676db": { + "ca22e5f6e7065cf2d4ffdbfac0084f9871de8cd9073d470cbf7eac2de2a73c47": { "describe": { "columns": [], "nullable": [], "parameters": { - "Right": 6 + "Right": 9 } }, - "query": "INSERT INTO \n starchart_users (\n hostname_id, username, html_url,\n profile_photo_html_url, added_on, last_crawl_on\n ) \n VALUES (\n (SELECT ID FROM starchart_forges WHERE hostname = $1), $2, $3, $4, $5, $6)" - }, - "c0439c4b2d683c516bd29780cd1e39a7bc75adaebdb450b864eb0b424f401b0c": { - "describe": { - "columns": [ - { - "name": "hostname", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "last_crawl_on", - "ordinal": 1, - "type_info": "Int64" - }, - { - "name": "name", - "ordinal": 2, - "type_info": "Text" - } - ], - "nullable": [ - false, - true, - false - ], - "parameters": { - "Right": 2 - } - }, - "query": "SELECT\n\t\thostname,\n\t\tlast_crawl_on,\n\t\tstarchart_forge_type.name\n FROM\n starchart_forges\n INNER JOIN\n starchart_forge_type\n ON\n starchart_forges.forge_type = starchart_forge_type.id\n ORDER BY\n starchart_forges.ID\n LIMIT $1 OFFSET $2;\n " - }, - "e00c8a8b0dbeb4a89a673864055c137365c2ae7bc5daf677bdacb20f21d0fcb2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Right": 8 - } - }, - "query": "INSERT INTO \n starchart_repositories (\n hostname_id, owner_id, name, description, html_url, website, created, last_crawl\n )\n VALUES (\n (SELECT ID FROM starchart_forges WHERE hostname = $1),\n (SELECT ID FROM starchart_users WHERE username = $2),\n $3, $4, $5, $6, $7, $8\n );" + "query": "INSERT INTO \n starchart_repositories (\n hostname_id, owner_id, name, description, html_url, website, created,\n last_crawl, imported\n )\n VALUES (\n (SELECT ID FROM starchart_forges WHERE hostname = $1),\n (SELECT ID FROM starchart_users WHERE username = $2),\n $3, $4, $5, $6, $7, $8, $9\n );" }, "e30ccfaa6aeda8cf30a2b3e9134abd0c0420441c5ed05189c3be605b1405c8e9": { "describe": { @@ -369,29 +349,5 @@ } }, "query": "DELETE FROM starchart_forges WHERE hostname = ($1)" - }, - "fbf6dd6bc2bc6121e080903fc9d6d9031b177acacf64fa92b7b52bd79f8fe89c": { - "describe": { - "columns": [ - { - "name": "html_url", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "profile_photo_html_url", - "ordinal": 1, - "type_info": "Text" - } - ], - "nullable": [ - false, - true - ], - "parameters": { - "Right": 2 - } - }, - "query": "SELECT html_url, profile_photo_html_url FROM starchart_users WHERE username = $1 AND \n hostname_id = (SELECT ID FROM starchart_forges WHERE hostname = $2)" } } \ No newline at end of file diff --git a/db/db-sqlx-sqlite/src/lib.rs b/db/db-sqlx-sqlite/src/lib.rs index f1aa5e5..5627ad5 100644 --- a/db/db-sqlx-sqlite/src/lib.rs +++ b/db/db-sqlx-sqlite/src/lib.rs @@ -439,69 +439,6 @@ impl SCDatabase for Database { Ok(()) } - async fn dns_challenge_exists(&self, key: &str) -> DBResult { - match sqlx::query!( - "SELECT ID FROM starchart_dns_challenges WHERE key = $1", - key - ) - .fetch_one(&self.pool) - .await - { - Ok(_) => Ok(true), - Err(Error::RowNotFound) => Ok(false), - Err(e) => Err(DBError::DBError(Box::new(e).into())), - } - } - - async fn get_dns_challenge(&self, key: &str) -> DBResult { - struct InnerChallenge { - hostname: String, - key: String, - value: String, - } - let res = sqlx::query_as!( - InnerChallenge, - "SELECT key, value, hostname FROM starchart_dns_challenges WHERE key = $1", - key - ) - .fetch_one(&self.pool) - .await - .map_err(|e| DBError::DBError(Box::new(e)))?; - let res = Challenge { - url: res.hostname, - key: res.key, - value: res.value, - }; - Ok(res) - } - - async fn delete_dns_challenge(&self, key: &str) -> DBResult<()> { - sqlx::query!("DELETE FROM starchart_dns_challenges WHERE key = $1", key) - .execute(&self.pool) - .await - .map_err(map_register_err)?; - Ok(()) - } - - /// create DNS challenge - async fn create_dns_challenge(&self, challenge: &Challenge) -> DBResult<()> { - let now = now_unix_time_stamp(); - sqlx::query!( - "INSERT INTO - starchart_dns_challenges (hostname, value, key, created ) - VALUES ($1, $2, $3, $4);", - challenge.url, - challenge.value, - challenge.key, - now, - ) - .execute(&self.pool) - .await - .map_err(map_register_err)?; - - Ok(()) - } - /// Get all repositories async fn get_all_repositories(&self, offset: u32, limit: u32) -> DBResult> { #[allow(non_snake_case)] diff --git a/src/pages/auth/add.rs b/src/pages/auth/add.rs index c164fbf..2f7ec30 100644 --- a/src/pages/auth/add.rs +++ b/src/pages/auth/add.rs @@ -23,12 +23,10 @@ use std::cell::RefCell; use tera::Context; use url::Url; -use db_core::prelude::*; - use crate::errors::ServiceResult; use crate::pages::errors::*; use crate::settings::Settings; -use crate::verify::TXTChallenge; +use crate::verify::{Challenge, TXTChallenge}; use crate::*; pub use crate::pages::*; @@ -88,37 +86,28 @@ pub fn services(cfg: &mut web::ServiceConfig) { pub async fn add_submit( payload: web::Form, ctx: WebCtx, - db: WebDB, ) -> PageResult { async fn _add_submit( payload: &AddChallengePayload, ctx: &ArcCtx, - db: &BoxDB, ) -> ServiceResult { let url_hostname = Url::parse(&payload.hostname).unwrap(); - let key = TXTChallenge::get_challenge_txt_key(ctx, &url_hostname); - if db.dns_challenge_exists(&key).await? { - let value = db.get_dns_challenge(&key).await?.value; - Ok(TXTChallenge { key, value }) - } else { - let challenge = TXTChallenge::new(ctx, &url_hostname); + let challenge = TXTChallenge::new(ctx, &url_hostname); - let c = Challenge { - key: challenge.key, - value: challenge.value, - url: url_hostname.to_string(), - }; - db.create_dns_challenge(&c).await?; + let c = Challenge { + key: challenge.key, + value: challenge.value, + url: url_hostname.to_string(), + }; - let challenge = TXTChallenge { - key: c.key, - value: c.value, - }; - Ok(challenge) - } + let challenge = TXTChallenge { + key: c.key, + value: c.value, + }; + Ok(challenge) } - let challenge = _add_submit(&payload, &ctx, &db) + let challenge = _add_submit(&payload, &ctx) .await .map_err(|e| PageError::new(AddChallenge::new(&ctx.settings, Some(&payload)), e))?; @@ -173,11 +162,6 @@ mod tests { }; println!("{}", payload.hostname); - let hostname = Url::parse(&payload.hostname).unwrap(); - let key = TXTChallenge::get_challenge_txt_key(&ctx, &hostname); - - db.delete_dns_challenge(&key).await.unwrap(); - assert!(!db.dns_challenge_exists(&key).await.unwrap()); let resp = test::call_service( &app, @@ -190,10 +174,6 @@ mod tests { } assert_eq!(resp.status(), StatusCode::FOUND); - assert!(db.dns_challenge_exists(&key).await.unwrap()); - - let challenge = db.get_dns_challenge(&key).await.unwrap().value; - // replay config let resp = test::call_service( &app, @@ -202,8 +182,5 @@ mod tests { .await; assert_eq!(resp.status(), StatusCode::FOUND); - - assert!(db.dns_challenge_exists(&key).await.unwrap()); - assert_eq!(challenge, db.get_dns_challenge(&key).await.unwrap().value); } } diff --git a/src/pages/auth/verify.rs b/src/pages/auth/verify.rs index 9f5061f..688b1f0 100644 --- a/src/pages/auth/verify.rs +++ b/src/pages/auth/verify.rs @@ -23,12 +23,9 @@ use std::cell::RefCell; use tera::Context; use url::Url; -use db_core::prelude::*; - -use crate::errors::ServiceResult; use crate::pages::errors::*; use crate::settings::Settings; -use crate::verify::TXTChallenge; +use crate::verify::{Challenge, TXTChallenge}; use crate::*; pub use crate::pages::*; @@ -50,7 +47,7 @@ impl CtxError for VerifyChallenge { #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct VerifyChallengePayload { - pub hostname: String, + pub hostname: Url, } impl VerifyChallenge { @@ -78,19 +75,14 @@ impl VerifyChallenge { #[get(path = "PAGES.auth.verify")] pub async fn get_verify( ctx: WebCtx, - db: WebDB, query: web::Query, ) -> PageResult { - let payload = query.into_inner(); - let value = _get_challenge(&payload, &db).await.map_err(|e| { - let challenge = Challenge { - key: payload.hostname, - value: "".into(), - url: "".into(), - }; - - PageError::new(VerifyChallenge::new(&ctx.settings, &challenge), e) - })?; + let challenge = TXTChallenge::new(&ctx, &query.hostname); + let value = Challenge { + key: challenge.key, + value: challenge.value, + url: query.hostname.to_string(), + }; let login = VerifyChallenge::page(&ctx.settings, &value); let html = ContentType::html(); @@ -102,11 +94,6 @@ pub fn services(cfg: &mut web::ServiceConfig) { cfg.service(submit_verify); } -async fn _get_challenge(payload: &VerifyChallengePayload, db: &BoxDB) -> ServiceResult { - let value = db.get_dns_challenge(&payload.hostname).await?; - Ok(value) -} - #[post(path = "PAGES.auth.verify")] pub async fn submit_verify( payload: web::Form, @@ -115,31 +102,15 @@ pub async fn submit_verify( federate: WebFederate, ) -> PageResult { let payload = payload.into_inner(); - let value = _get_challenge(&payload, &db).await.map_err(|e| { - let challenge = Challenge { - key: payload.hostname.clone(), - value: "".into(), - url: "".into(), - }; - - PageError::new(VerifyChallenge::new(&ctx.settings, &challenge), e) - })?; - - let challenge = TXTChallenge { - key: payload.hostname, - value: value.value, - }; + let challenge = TXTChallenge::new(&ctx, &payload.hostname); match challenge.verify_txt().await { Ok(true) => { - let _ = db.delete_dns_challenge(&challenge.key).await; - let ctx = ctx.clone(); let federate = federate.clone(); let db = db.clone(); let fut = async move { - ctx.crawl(&Url::parse(&value.url).unwrap(), &db, &federate) - .await; + ctx.crawl(&payload.hostname, &db, &federate).await; }; tokio::spawn(fut); diff --git a/src/verify.rs b/src/verify.rs index a1c37a4..616720d 100644 --- a/src/verify.rs +++ b/src/verify.rs @@ -22,10 +22,20 @@ use trust_dns_resolver::{ }; use url::Url; -use crate::utils::get_random; use crate::ArcCtx; -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +/// represents a DNS challenge +pub struct Challenge { + /// url of the forge instance + pub url: String, + /// key of TXT record + pub key: String, + /// value of TXT record + pub value: String, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct TXTChallenge { pub key: String, pub value: String, @@ -49,7 +59,7 @@ impl TXTChallenge { pub fn new(ctx: &ArcCtx, hostname: &Url) -> Self { let key = Self::get_challenge_txt_key(ctx, hostname); - let value = get_random(VALUES_LEN); + let value = ctx.settings.server.domain.clone(); Self { key, value } }