mail: use base_uri from RequestOrigin
This will cause outgoing emails to contain onion addresses for backlinks to the server, if the request comes via onion service.
This commit is contained in:
parent
36a016c15b
commit
65df904cd0
14
src/mail.rs
14
src/mail.rs
|
@ -31,7 +31,6 @@ mod context {
|
|||
|
||||
pub struct Service {
|
||||
from: Mailbox,
|
||||
base_uri: String,
|
||||
domain: String,
|
||||
templates: Handlebars,
|
||||
transport: Transport,
|
||||
|
@ -65,21 +64,20 @@ impl Service {
|
|||
?.to_string();
|
||||
Ok(Self {
|
||||
from: from.parse().unwrap(),
|
||||
base_uri: base_uri,
|
||||
domain: domain,
|
||||
templates: templates,
|
||||
transport: transport,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_verification(&self, tpk_name: String, userid: &Email,
|
||||
pub fn send_verification(&self, base_uri: &str, tpk_name: String, userid: &Email,
|
||||
token: &str)
|
||||
-> Result<()> {
|
||||
let ctx = context::Verification {
|
||||
primary_fp: tpk_name,
|
||||
uri: format!("{}/verify/{}", self.base_uri, token),
|
||||
uri: format!("{}/verify/{}", base_uri, token),
|
||||
userid: userid.to_string(),
|
||||
base_uri: self.base_uri.clone(),
|
||||
base_uri: base_uri.to_owned(),
|
||||
domain: self.domain.clone(),
|
||||
};
|
||||
|
||||
|
@ -91,12 +89,12 @@ impl Service {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn send_manage_token(&self, tpk_name: String, recipient: &Email,
|
||||
pub fn send_manage_token(&self, base_uri: &str, tpk_name: String, recipient: &Email,
|
||||
link_path: &str) -> Result<()> {
|
||||
let ctx = context::Manage {
|
||||
primary_fp: tpk_name,
|
||||
uri: format!("{}{}", self.base_uri, link_path),
|
||||
base_uri: self.base_uri.clone(),
|
||||
uri: format!("{}{}", base_uri, link_path),
|
||||
base_uri: base_uri.to_owned(),
|
||||
domain: self.domain.clone(),
|
||||
};
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ pub fn vks_manage_key(
|
|||
#[post("/manage", data="<request>")]
|
||||
pub fn vks_manage_post(
|
||||
db: State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
rate_limiter: rocket::State<RateLimiter>,
|
||||
request: Form<forms::ManageRequest>,
|
||||
|
@ -153,7 +154,8 @@ pub fn vks_manage_post(
|
|||
let token = token_service.create(&StatelessVerifyToken { fpr });
|
||||
let link_path = uri!(vks_manage_key: token).to_string();
|
||||
|
||||
if let Err(e) = mail_service.send_manage_token(fpr_text, &email, &link_path) {
|
||||
let base_uri = request_origin.get_base_uri();
|
||||
if let Err(e) = mail_service.send_manage_token(base_uri, fpr_text, &email, &link_path) {
|
||||
return MyResponse::ise(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -796,6 +796,44 @@ pub mod tests {
|
|||
assert_eq!(response.status(), Status::BadRequest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upload_verify_onion() {
|
||||
let (tmpdir, client) = client().unwrap();
|
||||
let filemail_into = tmpdir.path().join("filemail");
|
||||
|
||||
// Generate a key and upload it.
|
||||
let (tpk, _) = TPKBuilder::autocrypt(
|
||||
None, Some("foo@invalid.example.com"))
|
||||
.generate().unwrap();
|
||||
|
||||
let mut tpk_serialized = Vec::new();
|
||||
tpk.serialize(&mut tpk_serialized).unwrap();
|
||||
let token = vks_publish_submit_get_token(&client, &tpk_serialized);
|
||||
|
||||
// Check the verification link
|
||||
let encoded = ::url::form_urlencoded::Serializer::new(String::new())
|
||||
.append_pair("token", &token)
|
||||
.append_pair("address", "foo@invalid.example.com")
|
||||
.finish();
|
||||
|
||||
let response = client.post("/upload/request-verify")
|
||||
.header(ContentType::Form)
|
||||
.header(Header::new("X-Is-Onion", "true"))
|
||||
.body(encoded.as_bytes())
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
|
||||
// Now check for the verification mail.
|
||||
let pattern = format!("{}(/verify/[^ \t\n]*)", BASE_URI_ONION);
|
||||
let confirm_uri = pop_mail_capture_pattern(&filemail_into, &pattern);
|
||||
|
||||
let response = client.get(&confirm_uri).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
|
||||
assert_consistency(client.rocket());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn upload_curl_shortcut() {
|
||||
let (_tmpdir, client) = client().unwrap();
|
||||
|
|
|
@ -5,6 +5,7 @@ use database::types::{Fingerprint,Email};
|
|||
use mail;
|
||||
use tokens::{self, StatelessSerializable};
|
||||
use rate_limiter::RateLimiter;
|
||||
use web::RequestOrigin;
|
||||
|
||||
use sequoia_openpgp::TPK;
|
||||
|
||||
|
@ -167,6 +168,7 @@ fn process_key_single(
|
|||
|
||||
pub fn request_verify(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
|
@ -197,7 +199,7 @@ pub fn request_verify(
|
|||
for email in emails_requested {
|
||||
let rate_limit_ok = rate_limiter.action_perform(format!("verify-{}", &email));
|
||||
if rate_limit_ok {
|
||||
if send_verify_email(&mail_service, &token_stateful, &verify_state.fpr, &email).is_err() {
|
||||
if send_verify_email(&request_origin, &mail_service, &token_stateful, &verify_state.fpr, &email).is_err() {
|
||||
return UploadResponse::err(&format!("error sending email to {}", &email));
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +219,7 @@ fn check_tpk_state(
|
|||
}
|
||||
|
||||
fn send_verify_email(
|
||||
request_origin: &RequestOrigin,
|
||||
mail_service: &mail::Service,
|
||||
token_stateful: &StatefulTokens,
|
||||
fpr: &Fingerprint,
|
||||
|
@ -227,6 +230,7 @@ fn send_verify_email(
|
|||
let token_verify = token_stateful.new_token("verify", token_str.as_bytes())?;
|
||||
|
||||
mail_service.send_verification(
|
||||
request_origin.get_base_uri(),
|
||||
fpr.to_string(),
|
||||
&email,
|
||||
&token_verify,
|
||||
|
|
|
@ -96,6 +96,7 @@ pub fn upload_fallback(
|
|||
#[post("/vks/v1/request-verify", format = "json", data="<data>")]
|
||||
pub fn request_verify_json(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
|
@ -105,7 +106,7 @@ pub fn request_verify_json(
|
|||
let data = json_or_error(data)?;
|
||||
let json::VerifyRequest { token, addresses } = data.into_inner();
|
||||
let result = vks::request_verify(
|
||||
db, token_stateful, token_stateless, mail_service,
|
||||
db, request_origin, token_stateful, token_stateless, mail_service,
|
||||
rate_limiter, token, addresses);
|
||||
upload_ok_json(result)
|
||||
}
|
||||
|
|
|
@ -290,6 +290,7 @@ pub fn quick_upload(
|
|||
#[get("/upload/<token>", rank = 2)]
|
||||
pub fn quick_upload_proceed(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
|
@ -297,7 +298,7 @@ pub fn quick_upload_proceed(
|
|||
token: String,
|
||||
) -> MyResponse {
|
||||
let result = vks::request_verify(
|
||||
db, token_stateful, token_stateless, mail_service,
|
||||
db, request_origin, token_stateful, token_stateless, mail_service,
|
||||
rate_limiter, token, vec!());
|
||||
MyResponse::upload_response(result)
|
||||
}
|
||||
|
@ -388,6 +389,7 @@ fn process_multipart(
|
|||
#[post("/upload/request-verify", format = "application/x-www-form-urlencoded", data="<request>")]
|
||||
pub fn request_verify_form(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
|
@ -396,7 +398,7 @@ pub fn request_verify_form(
|
|||
) -> MyResponse {
|
||||
let forms::VerifyRequest { token, address } = request.into_inner();
|
||||
let result = vks::request_verify(
|
||||
db, token_stateful, token_stateless, mail_service,
|
||||
db, request_origin, token_stateful, token_stateless, mail_service,
|
||||
rate_limiter, token, vec!(address));
|
||||
MyResponse::upload_response(result)
|
||||
}
|
||||
|
@ -404,6 +406,7 @@ pub fn request_verify_form(
|
|||
#[post("/upload/request-verify", format = "multipart/form-data", data="<request>")]
|
||||
pub fn request_verify_form_data(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
request_origin: RequestOrigin,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
|
@ -412,7 +415,7 @@ pub fn request_verify_form_data(
|
|||
) -> MyResponse {
|
||||
let forms::VerifyRequest { token, address } = request.into_inner();
|
||||
let result = vks::request_verify(
|
||||
db, token_stateful, token_stateless, mail_service,
|
||||
db, request_origin, token_stateful, token_stateless, mail_service,
|
||||
rate_limiter, token, vec!(address));
|
||||
MyResponse::upload_response(result)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue