Rename domain::Domain to domain::Settings, finished renaming it everywhere

This commit is contained in:
Brian Picciano 2023-07-16 14:38:48 +02:00
parent 5a4ff4ca65
commit 5dd2e756cc
8 changed files with 134 additions and 134 deletions

View File

@ -18,11 +18,11 @@ use sha2::{Digest, Sha256};
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
/// Defines how a domain will behave when it is accessed. These are configured by the owner of the
/// domain during setup.
pub struct Domain {
pub struct Settings {
pub origin_descr: origin::Descr,
}
impl Domain {
impl Settings {
pub fn hash(&self) -> Result<String, unexpected::Error> {
let mut h = Sha256::new();
serde_json::to_writer(&mut h, self).or_unexpected()?;

View File

@ -30,7 +30,7 @@ pub struct ConfigACME {
#[derive(Deserialize)]
pub struct BuiltinDomain {
#[serde(flatten)]
pub domain: domain::Domain,
pub settings: domain::Settings,
pub public: bool,
}

View File

@ -7,7 +7,7 @@ use std::sync;
use tokio_util::sync::CancellationToken;
#[derive(thiserror::Error, Debug)]
pub enum GetConfigError {
pub enum GetSettingsError {
#[error("not found")]
NotFound,
@ -15,11 +15,11 @@ pub enum GetConfigError {
Unexpected(#[from] unexpected::Error),
}
impl From<store::GetError> for GetConfigError {
fn from(e: store::GetError) -> GetConfigError {
impl From<store::GetError> for GetSettingsError {
fn from(e: store::GetError) -> GetSettingsError {
match e {
store::GetError::NotFound => GetConfigError::NotFound,
store::GetError::Unexpected(e) => GetConfigError::Unexpected(e),
store::GetError::NotFound => GetSettingsError::NotFound,
store::GetError::Unexpected(e) => GetSettingsError::Unexpected(e),
}
}
}
@ -79,8 +79,8 @@ impl From<store::GetError> for SyncError {
}
#[derive(thiserror::Error, Debug)]
pub enum SyncWithConfigError {
#[error("cannot call SyncWithConfig on builtin domain")]
pub enum SyncWithSettingsError {
#[error("cannot call SyncWithSettings on builtin domain")]
BuiltinDomain,
#[error("invalid url")]
@ -102,36 +102,36 @@ pub enum SyncWithConfigError {
Unexpected(#[from] unexpected::Error),
}
impl From<origin::SyncError> for SyncWithConfigError {
fn from(e: origin::SyncError) -> SyncWithConfigError {
impl From<origin::SyncError> for SyncWithSettingsError {
fn from(e: origin::SyncError) -> SyncWithSettingsError {
match e {
origin::SyncError::InvalidURL => SyncWithConfigError::InvalidURL,
origin::SyncError::InvalidBranchName => SyncWithConfigError::InvalidBranchName,
origin::SyncError::AlreadyInProgress => SyncWithConfigError::AlreadyInProgress,
origin::SyncError::Unexpected(e) => SyncWithConfigError::Unexpected(e),
origin::SyncError::InvalidURL => SyncWithSettingsError::InvalidURL,
origin::SyncError::InvalidBranchName => SyncWithSettingsError::InvalidBranchName,
origin::SyncError::AlreadyInProgress => SyncWithSettingsError::AlreadyInProgress,
origin::SyncError::Unexpected(e) => SyncWithSettingsError::Unexpected(e),
}
}
}
impl From<checker::CheckDomainError> for SyncWithConfigError {
fn from(e: checker::CheckDomainError) -> SyncWithConfigError {
impl From<checker::CheckDomainError> for SyncWithSettingsError {
fn from(e: checker::CheckDomainError) -> SyncWithSettingsError {
match e {
checker::CheckDomainError::ServiceDNSRecordsNotSet => {
SyncWithConfigError::ServiceDNSRecordsNotSet
SyncWithSettingsError::ServiceDNSRecordsNotSet
}
checker::CheckDomainError::ChallengeTokenNotSet => {
SyncWithConfigError::ChallengeTokenNotSet
SyncWithSettingsError::ChallengeTokenNotSet
}
checker::CheckDomainError::Unexpected(e) => SyncWithConfigError::Unexpected(e),
checker::CheckDomainError::Unexpected(e) => SyncWithSettingsError::Unexpected(e),
}
}
}
impl From<store::SetError> for SyncWithConfigError {
fn from(e: store::SetError) -> SyncWithConfigError {
impl From<store::SetError> for SyncWithSettingsError {
fn from(e: store::SetError) -> SyncWithSettingsError {
match e {
store::SetError::BuiltinDomain => SyncWithConfigError::BuiltinDomain,
store::SetError::Unexpected(e) => SyncWithConfigError::Unexpected(e),
store::SetError::BuiltinDomain => SyncWithSettingsError::BuiltinDomain,
store::SetError::Unexpected(e) => SyncWithSettingsError::Unexpected(e),
}
}
}
@ -140,7 +140,7 @@ pub type GetAcmeHttp01ChallengeKeyError = acme::manager::GetHttp01ChallengeKeyEr
//#[mockall::automock]
pub trait Manager: Sync + Send + rustls::server::ResolvesServerCert {
fn get_config(&self, domain: &domain::Name) -> Result<domain::Domain, GetConfigError>;
fn get_settings(&self, domain: &domain::Name) -> Result<domain::Settings, GetSettingsError>;
fn get_file<'store>(
&'store self,
@ -153,11 +153,11 @@ pub trait Manager: Sync + Send + rustls::server::ResolvesServerCert {
domain: domain::Name,
) -> util::BoxFuture<'mgr, Result<(), unexpected::Error>>;
fn sync_with_config<'mgr>(
fn sync_with_settings<'mgr>(
&'mgr self,
domain: domain::Name,
config: domain::Domain,
) -> util::BoxFuture<'mgr, Result<(), SyncWithConfigError>>;
settings: domain::Settings,
) -> util::BoxFuture<'mgr, Result<(), SyncWithSettingsError>>;
fn get_acme_http01_challenge_key(
&self,
@ -235,7 +235,7 @@ impl ManagerImpl {
}
impl Manager for ManagerImpl {
fn get_config(&self, domain: &domain::Name) -> Result<domain::Domain, GetConfigError> {
fn get_settings(&self, domain: &domain::Name) -> Result<domain::Settings, GetSettingsError> {
Ok(self.domain_store.get(domain)?)
}
@ -262,23 +262,21 @@ impl Manager for ManagerImpl {
})
}
fn sync_with_config<'mgr>(
fn sync_with_settings<'mgr>(
&'mgr self,
domain: domain::Name,
config: domain::Domain,
) -> util::BoxFuture<'mgr, Result<(), SyncWithConfigError>> {
settings: domain::Settings,
) -> util::BoxFuture<'mgr, Result<(), SyncWithSettingsError>> {
Box::pin(async move {
let config_hash = config
let hash = settings
.hash()
.or_unexpected_while("calculating config hash")?;
self.domain_checker
.check_domain(&domain, &config_hash)
.await?;
self.domain_checker.check_domain(&domain, &hash).await?;
self.origin_store.sync(&config.origin_descr)?;
self.origin_store.sync(&settings.origin_descr)?;
self.domain_store.set(&domain, &config)?;
self.domain_store.set(&domain, &settings)?;
self.sync_cert(domain).await?;

View File

@ -23,8 +23,8 @@ pub enum SetError {
#[mockall::automock]
pub trait Store {
fn get(&self, domain: &domain::Name) -> Result<domain::Domain, GetError>;
fn set(&self, domain: &domain::Name, config: &domain::Domain) -> Result<(), SetError>;
fn get(&self, domain: &domain::Name) -> Result<domain::Settings, GetError>;
fn set(&self, domain: &domain::Name, settings: &domain::Settings) -> Result<(), SetError>;
fn all_domains(&self) -> Result<Vec<domain::Name>, unexpected::Error>;
}
@ -40,40 +40,40 @@ impl FSStore {
})
}
fn config_dir_path(&self, domain: &domain::Name) -> path::PathBuf {
fn settings_dir_path(&self, domain: &domain::Name) -> path::PathBuf {
self.dir_path.join(domain.as_str())
}
fn config_file_path(&self, domain: &domain::Name) -> path::PathBuf {
self.config_dir_path(domain).join("config.json")
fn settings_file_path(&self, domain: &domain::Name) -> path::PathBuf {
self.settings_dir_path(domain).join("settings.json")
}
}
impl Store for FSStore {
fn get(&self, domain: &domain::Name) -> Result<domain::Domain, GetError> {
let path = self.config_file_path(domain);
let config_file = fs::File::open(path.as_path()).map_err(|e| match e.kind() {
fn get(&self, domain: &domain::Name) -> Result<domain::Settings, GetError> {
let path = self.settings_file_path(domain);
let settings_file = fs::File::open(path.as_path()).map_err(|e| match e.kind() {
io::ErrorKind::NotFound => GetError::NotFound,
_ => e
.into_unexpected_while(format!("opening {}", path.display()))
.into(),
})?;
let config = serde_json::from_reader(config_file)
let settings = serde_json::from_reader(settings_file)
.map_unexpected_while(|| format!("json parsing {}", path.display()))?;
Ok(config)
Ok(settings)
}
fn set(&self, domain: &domain::Name, config: &domain::Domain) -> Result<(), SetError> {
let dir_path = self.config_dir_path(domain);
fn set(&self, domain: &domain::Name, settings: &domain::Settings) -> Result<(), SetError> {
let dir_path = self.settings_dir_path(domain);
fs::create_dir_all(dir_path.as_path())
.map_unexpected_while(|| format!("creating dir {}", dir_path.display()))?;
let file_path = self.config_file_path(domain);
let config_file = fs::File::create(file_path.as_path())
let file_path = self.settings_file_path(domain);
let settings_file = fs::File::create(file_path.as_path())
.map_unexpected_while(|| format!("creating file {}", file_path.display()))?;
serde_json::to_writer(config_file, config)
serde_json::to_writer(settings_file, settings)
.map_unexpected_while(|| format!("writing config to {}", file_path.display()))?;
Ok(())
@ -115,18 +115,18 @@ impl<S: Store> StoreWithBuiltin<S> {
}
impl<S: Store> Store for StoreWithBuiltin<S> {
fn get(&self, domain: &domain::Name) -> Result<domain::Domain, GetError> {
fn get(&self, domain: &domain::Name) -> Result<domain::Settings, GetError> {
if let Some(domain) = self.domains.get(domain) {
return Ok(domain.domain.clone());
return Ok(domain.settings.clone());
}
self.inner.get(domain)
}
fn set(&self, domain: &domain::Name, config: &domain::Domain) -> Result<(), SetError> {
fn set(&self, domain: &domain::Name, settings: &domain::Settings) -> Result<(), SetError> {
if self.domains.get(domain).is_some() {
return Err(SetError::BuiltinDomain);
}
self.inner.set(domain, config)
self.inner.set(domain, settings)
}
fn all_domains(&self) -> Result<Vec<domain::Name>, unexpected::Error> {
@ -154,13 +154,13 @@ mod tests {
#[test]
fn basic() {
let tmp_dir = TempDir::new("domain_config_store").unwrap();
let tmp_dir = TempDir::new("domain_store").unwrap();
let store = FSStore::new(tmp_dir.path()).expect("store created");
let domain = domain::Name::from_str("foo.com").expect("domain parsed");
let config = domain::Domain {
let settings = domain::Settings {
origin_descr: Descr::Git {
url: "bar".to_string(),
branch_name: "baz".to_string(),
@ -169,20 +169,23 @@ mod tests {
assert!(matches!(
store.get(&domain),
Err::<domain::Domain, GetError>(GetError::NotFound)
Err::<domain::Settings, GetError>(GetError::NotFound)
));
store.set(&domain, &config).expect("config set");
assert_eq!(config, store.get(&domain).expect("config retrieved"));
store.set(&domain, &settings).expect("set");
assert_eq!(settings, store.get(&domain).expect("settings retrieved"));
let new_config = domain::Domain {
let new_settings = domain::Settings {
origin_descr: Descr::Git {
url: "BAR".to_string(),
branch_name: "BAZ".to_string(),
},
};
store.set(&domain, &new_config).expect("config set");
assert_eq!(new_config, store.get(&domain).expect("config retrieved"));
store.set(&domain, &new_settings).expect("set");
assert_eq!(
new_settings,
store.get(&domain).expect("settings retrieved")
);
}
}

View File

@ -63,7 +63,7 @@ struct DomainInitArgs {
domain: domain::Name,
#[serde(flatten)]
domain_config: service::util::FlatConfig,
flat_domain_settings: service::util::FlatDomainSettings,
}
#[derive(Deserialize)]
@ -72,7 +72,7 @@ struct DomainSyncArgs {
passphrase: String,
#[serde(flatten)]
domain_config: service::util::FlatConfig,
flat_domain_settings: service::util::FlatDomainSettings,
}
impl<'svc> Service {
@ -220,39 +220,35 @@ impl<'svc> Service {
fn domain_get(&self, args: DomainGetArgs) -> Response<Body> {
#[derive(Serialize)]
struct Response {
struct Data {
domain: domain::Name,
config: Option<domain::Domain>,
settings: Option<domain::Settings>,
}
let config = match self.domain_manager.get_config(&args.domain) {
Ok(config) => Some(config),
Err(domain::manager::GetConfigError::NotFound) => None,
Err(domain::manager::GetConfigError::Unexpected(e)) => {
let settings = match self.domain_manager.get_settings(&args.domain) {
Ok(settings) => Some(settings),
Err(domain::manager::GetSettingsError::NotFound) => None,
Err(domain::manager::GetSettingsError::Unexpected(e)) => {
return self.internal_error(
format!(
"retrieving configuration for domain {}: {}",
&args.domain, e
)
.as_str(),
format!("retrieving settings for domain {}: {}", &args.domain, e).as_str(),
);
}
};
self.render_page(
"/domain.html",
Response {
Data {
domain: args.domain,
config,
settings,
},
)
}
fn domain_init(&self, args: DomainInitArgs) -> Response<Body> {
#[derive(Serialize)]
struct Response<'a> {
struct Data<'a> {
domain: domain::Name,
flat_config: service::util::FlatConfig,
flat_domain_settings: service::util::FlatDomainSettings,
dns_records: &'a [service::ConfigDNSRecord],
challenge_token: String,
@ -260,19 +256,20 @@ impl<'svc> Service {
dns_records_have_cname: bool,
}
let config: domain::Domain = match args.domain_config.try_into() {
Ok(Some(config)) => config,
Ok(None) => return self.render_error_page(400, "domain config is required"),
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"),
Err(e) => {
return self.render_error_page(400, format!("invalid domain config: {e}").as_str())
return self
.render_error_page(400, format!("invalid domain settings: {e}").as_str())
}
};
let config_hash = match config.hash() {
let settings_hash = match settings.hash() {
Ok(hash) => hash,
Err(e) => {
return self.internal_error(
format!("failed to hash domain config {config:?}: {e}").as_str(),
format!("failed to hash domain settings {settings:?}: {e}").as_str(),
)
}
};
@ -285,11 +282,11 @@ impl<'svc> Service {
self.render_page(
"/domain_init.html",
Response {
Data {
domain: args.domain,
flat_config: config.into(),
flat_domain_settings: settings.into(),
dns_records: &self.config.dns_records,
challenge_token: config_hash,
challenge_token: settings_hash,
domain_is_zone_apex,
dns_records_have_cname,
@ -302,42 +299,44 @@ impl<'svc> Service {
return self.render_error_page(401, "Incorrect passphrase");
}
let config: domain::Domain = match args.domain_config.try_into() {
Ok(Some(config)) => config,
Ok(None) => return self.render_error_page(400, "domain config is required"),
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"),
Err(e) => {
return self.render_error_page(400, format!("invalid domain config: {e}").as_str())
return self
.render_error_page(400, format!("invalid domain settings: {e}").as_str())
}
};
let sync_result = self
.domain_manager
.sync_with_config(args.domain.clone(), config)
.sync_with_settings(args.domain.clone(), settings)
.await;
#[derive(Serialize)]
struct Response {
struct Data {
domain: domain::Name,
error_msg: Option<String>,
}
let error_msg = match sync_result {
Ok(_) => None,
Err(domain::manager::SyncWithConfigError::BuiltinDomain) => Some("This domain is not able to be configured, please contact the server administrator.".to_string()),
Err(domain::manager::SyncWithConfigError::InvalidURL) => Some("Fetching the git repository failed, please double check that you input the correct URL.".to_string()),
Err(domain::manager::SyncWithConfigError::InvalidBranchName) => Some("The git repository does not have a branch of the given name, please double check that you input the correct name.".to_string()),
Err(domain::manager::SyncWithConfigError::AlreadyInProgress) => Some("The configuration of your domain is still in progress, please refresh in a few minutes.".to_string()),
Err(domain::manager::SyncWithConfigError::ServiceDNSRecordsNotSet) => Some("None of the expected service DNS records were set on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()),
Err(domain::manager::SyncWithConfigError::ChallengeTokenNotSet) => Some("The TXT record is not set correctly on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()),
Err(domain::manager::SyncWithConfigError::Unexpected(e)) => Some(format!("An unexpected error occurred: {e}")),
Err(domain::manager::SyncWithSettingsError::BuiltinDomain) => Some("This domain is not able to be configured, please contact the server administrator.".to_string()),
Err(domain::manager::SyncWithSettingsError::InvalidURL) => Some("Fetching the git repository failed, please double check that you input the correct URL.".to_string()),
Err(domain::manager::SyncWithSettingsError::InvalidBranchName) => Some("The git repository does not have a branch of the given name, please double check that you input the correct name.".to_string()),
Err(domain::manager::SyncWithSettingsError::AlreadyInProgress) => Some("The configuration of your domain is still in progress, please refresh in a few minutes.".to_string()),
Err(domain::manager::SyncWithSettingsError::ServiceDNSRecordsNotSet) => Some("None of the expected service DNS records were set on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()),
Err(domain::manager::SyncWithSettingsError::ChallengeTokenNotSet) => Some("The TXT record is not set correctly on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()),
Err(domain::manager::SyncWithSettingsError::Unexpected(e)) => Some(format!("An unexpected error occurred: {e}")),
};
let response = Response {
domain: args.domain,
error_msg,
};
self.render_page("/domain_sync.html", response)
self.render_page(
"/domain_sync.html",
Data {
domain: args.domain,
error_msg,
},
)
}
fn domains(&self) -> Response<Body> {

View File

@ -2,7 +2,7 @@
Configure New Domain
</h2>
{{# if data.config }}
{{# if data.settings }}
<p>Your domain <code>{{ data.domain }}</code> is already configured with
Domani. You can see the existing configuration below. If you modify any values
@ -32,7 +32,7 @@ automatically updated too!</p>
<input name="config_origin_descr_git_url"
type="text"
placeholder="https://example.com/some_repo.git"
value="{{ data.config.origin_descr.Git.url }}"
value="{{ data.settings.origin_descr.Git.url }}"
required />
</label>
</p>
@ -43,7 +43,7 @@ automatically updated too!</p>
<input name="config_origin_descr_git_branch_name"
type="text"
placeholder="main / master / etc..."
value="{{ data.config.origin_descr.Git.branch_name }}"
value="{{ data.settings.origin_descr.Git.branch_name }}"
required />
</label>
</p>

View File

@ -5,7 +5,7 @@ administrator of the Domani server:</p>
<form method="{{ form_method }}" action="/domain_sync.html" id="syncForm">
<input name="domain" type="hidden" value="{{ data.domain }}" />
{{ #each data.flat_config }}
{{ #each data.flat_domain_settings }}
<input name="{{ @key }}" type="hidden" value="{{ this }}" />
{{ /each }}

View File

@ -5,44 +5,44 @@ use serde::{Deserialize, Serialize};
use crate::{domain, origin};
#[derive(Serialize, Deserialize)]
pub struct FlatConfig {
config_origin_descr_kind: Option<String>,
config_origin_descr_git_url: Option<String>,
config_origin_descr_git_branch_name: Option<String>,
pub struct FlatDomainSettings {
domain_setting_origin_descr_kind: Option<String>,
domain_setting_origin_descr_git_url: Option<String>,
domain_setting_origin_descr_git_branch_name: Option<String>,
}
impl TryFrom<FlatConfig> for Option<domain::Domain> {
impl TryFrom<FlatDomainSettings> for Option<domain::Settings> {
type Error = String;
fn try_from(v: FlatConfig) -> Result<Self, Self::Error> {
fn try_from(v: FlatDomainSettings) -> Result<Self, Self::Error> {
match v
.config_origin_descr_kind
.domain_setting_origin_descr_kind
.unwrap_or("".to_string())
.as_str()
{
"" => Ok(None),
"git" => Ok(Some(domain::Domain {
"git" => Ok(Some(domain::Settings {
origin_descr: origin::Descr::Git {
url: v
.config_origin_descr_git_url
.ok_or("config_origin_descr_git_url missing")?,
.domain_setting_origin_descr_git_url
.ok_or("domain_setting_origin_descr_git_url missing")?,
branch_name: v
.config_origin_descr_git_branch_name
.ok_or("config_origin_descr_git_branch_name missing")?,
.domain_setting_origin_descr_git_branch_name
.ok_or("domain_setting_origin_descr_git_branch_name missing")?,
},
})),
_ => Err("invalid config_origin_descr_kind".to_string()),
_ => Err("invalid domain_setting_origin_descr_kind".to_string()),
}
}
}
impl From<domain::Domain> for FlatConfig {
fn from(v: domain::Domain) -> Self {
impl From<domain::Settings> for FlatDomainSettings {
fn from(v: domain::Settings) -> Self {
match v.origin_descr {
origin::Descr::Git { url, branch_name } => FlatConfig {
config_origin_descr_kind: Some("git".to_string()),
config_origin_descr_git_url: Some(url),
config_origin_descr_git_branch_name: Some(branch_name),
origin::Descr::Git { url, branch_name } => 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),
},
}
}