diff --git a/src/origin/descr.rs b/src/origin/descr.rs index 6e0acc8..a525a15 100644 --- a/src/origin/descr.rs +++ b/src/origin/descr.rs @@ -7,6 +7,7 @@ use sha2::{Digest, Sha256}; /// A unique description of an origin, from where a domain might be served. pub enum Descr { Git { url: String, branch_name: String }, + Proxy { url: String }, } impl Descr { @@ -25,6 +26,10 @@ impl Descr { h_update(url); h_update(branch_name); } + Descr::Proxy { url } => { + h_update("proxy"); + h_update(url); + } } h.finalize().encode_hex::() diff --git a/src/origin/git.rs b/src/origin/git.rs index 3f4b6d9..b466e3b 100644 --- a/src/origin/git.rs +++ b/src/origin/git.rs @@ -56,15 +56,24 @@ impl FSStore { format!("origin/{branch_name}") } + fn deconstruct_descr(descr: &origin::Descr) -> (&str, &str) { + if let origin::Descr::Git { + ref url, + ref branch_name, + } = descr + { + (url, branch_name) + } else { + panic!("non git descr passed in") + } + } + fn create_repo_snapshot( &self, repo: gix::Repository, descr: &origin::Descr, ) -> Result { - let origin::Descr::Git { - ref branch_name, .. - } = descr; - + let (_, branch_name) = Self::deconstruct_descr(descr); let branch_ref = self.branch_ref(branch_name); let commit_object_id = repo @@ -148,10 +157,7 @@ impl FSStore { fs::create_dir_all(repo_path) .map_unexpected_while(|| format!("creating {}", repo_path.display()))?; - let origin::Descr::Git { - ref url, - ref branch_name, - } = descr; + let (url, branch_name) = Self::deconstruct_descr(descr); let (repo, _) = gix::prepare_clone_bare(url.clone(), repo_path) .map_err(|e| match e { diff --git a/src/service/http.rs b/src/service/http.rs index 0828b42..bc5368c 100644 --- a/src/service/http.rs +++ b/src/service/http.rs @@ -257,8 +257,7 @@ impl<'svc> Service { } let settings: domain::Settings = match args.flat_domain_settings.try_into() { - Ok(Some(settings)) => settings, - Ok(None) => return self.render_error_page(400, "no domain settings provided"), + Ok(settings) => settings, Err(e) => { return self .render_error_page(400, format!("invalid domain settings: {e}").as_str()) @@ -280,11 +279,19 @@ impl<'svc> Service { _ => false, }); + let flat_domain_settings = match settings.try_into() { + Ok(s) => s, + Err(e) => { + return self + .internal_error(format!("failed to flatten domains settings: {e}").as_str()) + } + }; + self.render_page( "/domain_init.html", Data { domain: args.domain, - flat_domain_settings: settings.into(), + flat_domain_settings, dns_records: &self.config.dns_records, challenge_token: settings_hash, @@ -300,8 +307,7 @@ impl<'svc> Service { } let settings: domain::Settings = match args.flat_domain_settings.try_into() { - Ok(Some(settings)) => settings, - Ok(None) => return self.render_error_page(400, "no domain settings provided"), + Ok(settings) => settings, Err(e) => { return self .render_error_page(400, format!("invalid domain settings: {e}").as_str()) diff --git a/src/service/util.rs b/src/service/util.rs index 80961eb..695d735 100644 --- a/src/service/util.rs +++ b/src/service/util.rs @@ -1,49 +1,58 @@ -use std::convert::{From, TryFrom}; +use std::convert::TryFrom; use serde::{Deserialize, Serialize}; -use crate::{domain, origin}; +use crate::{domain, error::unexpected, origin}; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Default)] pub struct FlatDomainSettings { domain_setting_origin_descr_kind: Option, + domain_setting_origin_descr_git_url: Option, domain_setting_origin_descr_git_branch_name: Option, + + domain_setting_origin_descr_proxy_url: Option, } -impl TryFrom for Option { +impl TryFrom for domain::Settings { type Error = String; fn try_from(v: FlatDomainSettings) -> Result { - match v + let origin_descr = match v .domain_setting_origin_descr_kind .unwrap_or("".to_string()) .as_str() { - "" => Ok(None), - "git" => Ok(Some(domain::Settings { - origin_descr: origin::Descr::Git { - url: v - .domain_setting_origin_descr_git_url - .ok_or("domain_setting_origin_descr_git_url missing")?, - branch_name: v - .domain_setting_origin_descr_git_branch_name - .ok_or("domain_setting_origin_descr_git_branch_name missing")?, - }, - })), + "git" => Ok(origin::Descr::Git { + url: v + .domain_setting_origin_descr_git_url + .ok_or("missing domain_setting_origin_descr_git_url")?, + branch_name: v + .domain_setting_origin_descr_git_branch_name + .ok_or("missing domain_setting_origin_descr_git_branch_name")?, + }), + "" => Err("missing domain_setting_origin_descr_kind".to_string()), _ => Err("invalid domain_setting_origin_descr_kind".to_string()), - } + }?; + + Ok(Self { origin_descr }) } } -impl From for FlatDomainSettings { - fn from(v: domain::Settings) -> Self { +impl TryFrom for FlatDomainSettings { + type Error = unexpected::Error; + + fn try_from(v: domain::Settings) -> Result { match v.origin_descr { - origin::Descr::Git { url, branch_name } => FlatDomainSettings { + origin::Descr::Git { url, branch_name } => Ok(FlatDomainSettings { domain_setting_origin_descr_kind: Some("git".to_string()), domain_setting_origin_descr_git_url: Some(url), domain_setting_origin_descr_git_branch_name: Some(branch_name), - }, + ..Default::default() + }), + origin::Descr::Proxy { .. } => Err(unexpected::Error::from( + "proxy origins not supported for forms", + )), } } }