Use a base URI instead of a domain.
- Previously, Hagrid assumed https. Using a base URI allows us to specify both protocol and port. This helps with testing. - Fixes #79.
This commit is contained in:
parent
2a9e691e79
commit
c0e2a732fd
|
@ -5,16 +5,16 @@ template_dir = "dist/templates"
|
|||
state_dir = "dist"
|
||||
|
||||
[development]
|
||||
domain = "localhost"
|
||||
base-URI = "http://localhost:8080"
|
||||
from = "noreply@localhost"
|
||||
x-accel-redirect = false
|
||||
|
||||
[staging]
|
||||
domain = "keys.openpgp.org"
|
||||
base-URI = "https://keys.openpgp.org"
|
||||
from = "noreply@keys.openpgp.org"
|
||||
x-accel-redirect = true
|
||||
|
||||
[production]
|
||||
domain = "keys.openpgp.org"
|
||||
base-URI = "https://keys.openpgp.org"
|
||||
from = "noreply@keys.openpgp.org"
|
||||
x-accel-redirect = true
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
<p>
|
||||
Someone, presumably you, requested that your key will no longer
|
||||
be available when searching for you email addresses on
|
||||
<a href="https://{{domain}}">{{domain}}</a>.
|
||||
<a href="{{base_uri}}">{{domain}}</a>.
|
||||
</p>
|
||||
<p>
|
||||
If it was not you, please ignore this email.
|
||||
</p>
|
||||
<p>
|
||||
To de-list your key on {{domain}}, follow this link:
|
||||
To de-list your key on <a href="{{base_uri}}">{{domain}}</a>,
|
||||
follow this link:
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{uri}}">{{uri}}</a>
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
</p>
|
||||
|
||||
<p>You can get it with GnuPG using the following snippet:</p>
|
||||
<pre><code class="snippet">gpg {{ gpg_options }}--fetch-keys <a href="https://{{ domain }}/vks/v1/by-fingerprint/{{ fpr }}">https://{{ domain }}/vks/v1/by-fingerprint/{{ fpr }}</a></code></pre>
|
||||
<pre><code class="snippet">gpg {{ gpg_options }}--fetch-keys <a href="{{base_uri}}/vks/v1/by-fingerprint/{{ fpr }}">{{base_uri}}/vks/v1/by-fingerprint/{{ fpr }}</a></code></pre>
|
||||
</div>
|
||||
{{/layout}}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<body>
|
||||
<p>
|
||||
Someone, presumably you, has uploaded a key
|
||||
to <a href="https://{{domain}}">{{domain}}</a>. The key has the
|
||||
to <a href="{{base_uri}}">{{domain}}</a>. The key has the
|
||||
following fingerprint:
|
||||
</p>
|
||||
<p>
|
||||
|
@ -19,7 +19,7 @@
|
|||
</p>
|
||||
<p>
|
||||
To make your key available when searching for "{{userid}}" on
|
||||
{{domain}}, follow this link:
|
||||
<a href="{{base_uri}}">{{domain}}</a>, follow this link:
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{uri}}">{{uri}}</a>
|
||||
|
|
44
src/mail.rs
44
src/mail.rs
|
@ -1,9 +1,10 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use failure;
|
||||
use handlebars::Handlebars;
|
||||
use lettre::{EmailTransport, SendmailTransport, FileEmailTransport};
|
||||
use lettre_email::EmailBuilder;
|
||||
|
||||
use url;
|
||||
use serde::Serialize;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
|
@ -17,18 +18,21 @@ mod context {
|
|||
pub primary_fp: String,
|
||||
pub uri: String,
|
||||
pub userid: String,
|
||||
pub base_uri: String,
|
||||
pub domain: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct Deletion {
|
||||
pub uri: String,
|
||||
pub base_uri: String,
|
||||
pub domain: String,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Service {
|
||||
from: String,
|
||||
base_uri: String,
|
||||
domain: String,
|
||||
templates: Handlebars,
|
||||
transport: Transport,
|
||||
|
@ -41,26 +45,32 @@ enum Transport {
|
|||
|
||||
impl Service {
|
||||
/// Sends mail via sendmail.
|
||||
pub fn sendmail(from: String, domain: String, templates: Handlebars) -> Self {
|
||||
Self {
|
||||
from: from,
|
||||
domain: domain,
|
||||
templates: templates,
|
||||
transport: Transport::Sendmail,
|
||||
}
|
||||
pub fn sendmail(from: String, base_uri: String, templates: Handlebars)
|
||||
-> Result<Self> {
|
||||
Self::new(from, base_uri, templates, Transport::Sendmail)
|
||||
}
|
||||
|
||||
/// Sends mail by storing it in the given directory.
|
||||
pub fn filemail(from: String, domain: String, templates: Handlebars,
|
||||
pub fn filemail(from: String, base_uri: String, templates: Handlebars,
|
||||
path: PathBuf)
|
||||
-> Self
|
||||
{
|
||||
Self {
|
||||
-> Result<Self> {
|
||||
Self::new(from, base_uri, templates, Transport::Filemail(path))
|
||||
}
|
||||
|
||||
fn new(from: String, base_uri: String, templates: Handlebars,
|
||||
transport: Transport)
|
||||
-> Result<Self> {
|
||||
let domain =
|
||||
url::Url::parse(&base_uri)
|
||||
?.host_str().ok_or_else(|| failure::err_msg("No host in base-URI"))
|
||||
?.to_string();
|
||||
Ok(Self {
|
||||
from: from,
|
||||
base_uri: base_uri,
|
||||
domain: domain,
|
||||
templates: templates,
|
||||
transport: Transport::Filemail(path),
|
||||
}
|
||||
transport: transport,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_verification(&self, tpk: &openpgp::TPK, userid: &Email,
|
||||
|
@ -68,8 +78,9 @@ impl Service {
|
|||
-> Result<()> {
|
||||
let ctx = context::Verification {
|
||||
primary_fp: tpk.fingerprint().to_string(),
|
||||
uri: format!("https://{}/publish/{}", self.domain, token),
|
||||
uri: format!("{}/publish/{}", self.base_uri, token),
|
||||
userid: userid.to_string(),
|
||||
base_uri: self.base_uri.clone(),
|
||||
domain: self.domain.clone(),
|
||||
};
|
||||
|
||||
|
@ -84,7 +95,8 @@ impl Service {
|
|||
pub fn send_confirmation(&self, userids: &[Email], token: &str)
|
||||
-> Result<()> {
|
||||
let ctx = context::Deletion {
|
||||
uri: format!("https://{}/delete/{}", self.domain, token),
|
||||
uri: format!("{}/delete/{}", self.base_uri, token),
|
||||
base_uri: self.base_uri.clone(),
|
||||
domain: self.domain.clone(),
|
||||
};
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ mod templates {
|
|||
pub query: String,
|
||||
pub gpg_options: Option<&'static str>,
|
||||
pub fpr: String,
|
||||
pub domain: String,
|
||||
pub base_uri: String,
|
||||
pub commit: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ pub struct State {
|
|||
public_dir: PathBuf,
|
||||
|
||||
/// XXX
|
||||
domain: String,
|
||||
base_uri: String,
|
||||
|
||||
/// Controls the use of NGINX'es XAccelRedirect feature.
|
||||
x_accel_redirect: bool,
|
||||
|
@ -237,7 +237,7 @@ fn key_to_response<'a>(state: rocket::State<State>,
|
|||
} else {
|
||||
Some("--keyserver-options import-drop-uids ")
|
||||
},
|
||||
domain: state.domain.clone(),
|
||||
base_uri: state.base_uri.clone(),
|
||||
fpr: fp.to_string(),
|
||||
version: env!("VERGEN_SEMVER").to_string(),
|
||||
commit: env!("VERGEN_SHA_SHORT").to_string(),
|
||||
|
@ -448,11 +448,11 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
// State
|
||||
let state_dir: PathBuf = rocket.config().get_str("state_dir")?.into();
|
||||
let public_dir = state_dir.join("public");
|
||||
let domain = rocket.config().get_str("domain")?.to_string();
|
||||
let base_uri = rocket.config().get_str("base-URI")?.to_string();
|
||||
let state = State {
|
||||
state_dir: state_dir,
|
||||
public_dir: public_dir,
|
||||
domain: domain.clone(),
|
||||
base_uri: base_uri.clone(),
|
||||
x_accel_redirect: rocket.config().get_bool("x-accel-redirect")?,
|
||||
};
|
||||
|
||||
|
@ -473,9 +473,9 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
let filemail_into = rocket.config().get_str("filemail_into")
|
||||
.ok().map(|p| PathBuf::from(p));
|
||||
let mail_service = if let Some(path) = filemail_into {
|
||||
mail::Service::filemail(from, domain, handlebars, path)
|
||||
mail::Service::filemail(from, base_uri, handlebars, path)?
|
||||
} else {
|
||||
mail::Service::sendmail(from, domain, handlebars)
|
||||
mail::Service::sendmail(from, base_uri, handlebars)?
|
||||
};
|
||||
|
||||
Ok(rocket
|
||||
|
@ -507,6 +507,9 @@ pub mod tests {
|
|||
use database::*;
|
||||
use super::*;
|
||||
|
||||
/// Fake base URI to use in tests.
|
||||
const BASE_URI: &'static str = "http://local.connection";
|
||||
|
||||
/// Creates a configuration and empty state dir for testing purposes.
|
||||
///
|
||||
/// Note that you need to keep the returned TempDir alive for the
|
||||
|
@ -533,7 +536,7 @@ pub mod tests {
|
|||
root.path().to_str()
|
||||
.ok_or(failure::err_msg("Static path invalid"))?,
|
||||
)
|
||||
.extra("domain", "domain")
|
||||
.extra("base-URI", BASE_URI)
|
||||
.extra("from", "from")
|
||||
.extra("filemail_into", filemail.into_os_string().into_string()
|
||||
.expect("path is valid UTF8"))
|
||||
|
@ -834,9 +837,8 @@ pub mod tests {
|
|||
}
|
||||
|
||||
fn check_mails_and_verify_email(client: &Client, filemail_path: &Path) {
|
||||
let confirm_re =
|
||||
regex::bytes::Regex::new("https://domain(/publish/[^ \t\n]*)")
|
||||
.unwrap();
|
||||
let confirm_re = regex::bytes::Regex::new(
|
||||
&format!("{}(/publish/[^ \t\n]*)", BASE_URI)).unwrap();
|
||||
let confirm_mail = pop_mail(filemail_path).unwrap().unwrap();
|
||||
let confirm_bytes = confirm_mail.message();
|
||||
// eprintln!("{}", String::from_utf8_lossy(&confirm_bytes));
|
||||
|
@ -849,9 +851,8 @@ pub mod tests {
|
|||
}
|
||||
|
||||
fn check_mails_and_confirm_deletion(client: &Client, filemail_path: &Path) {
|
||||
let confirm_re =
|
||||
regex::bytes::Regex::new("https://domain(/delete/[^ \t\n]*)")
|
||||
.unwrap();
|
||||
let confirm_re = regex::bytes::Regex::new(
|
||||
&format!("{}(/delete/[^ \t\n]*)", BASE_URI)).unwrap();
|
||||
let confirm_mail = pop_mail(filemail_path).unwrap().unwrap();
|
||||
let confirm_bytes = confirm_mail.message();
|
||||
// eprintln!("{}", String::from_utf8_lossy(&confirm_bytes));
|
||||
|
|
Loading…
Reference in New Issue