hkp: send "upload" email template on second upload of a key via hkp

This commit is contained in:
Vincent Breitmoser 2020-08-01 14:05:07 +02:00
parent 8a983547fd
commit 1199294543
4 changed files with 123 additions and 14 deletions

26
dist/email-templates/upload.htm.hbs vendored Normal file
View File

@ -0,0 +1,26 @@
<!doctype html>
<html lang="{{lang}}">
<head>
<meta charset=utf-8>
<title>Your key upload on {{domain}}</title>
</head>
<body>
<p>
Hi,
<p>
This is an automated message from <a href="{{base_uri}}" style="text-decoration:none; color: #333">{{domain}}</a>.
If you didn't upload your key there, please ignore this message.
<p>
OpenPGP key: <tt>{{primary_fp}}</tt>
<p>
This key was just uploaded to keys.openpgp.org. If you want to allow others to find this key by e-mail address, please follow this link:
<p>
<a rel="nofollow" href="{{uri}}">{{uri}}</a>
<p>
You can find more info at <a href="{{base_uri}}/about">{{domain}}/about</a>.
<p>
<a href="{{base_uri}}">{{base_uri}}</a><br />
distributing OpenPGP keys since 2019
</body>
</html>

18
dist/email-templates/upload.txt.hbs vendored Normal file
View File

@ -0,0 +1,18 @@
Hi,
This is an automated message from {{domain}}.
If you didn't upload your key, please ignore this message.
OpenPGP key: {{primary_fp}}
This key was just uploaded to keys.openpgp.org. If you want to allow
others to find this key by e-mail address, please follow this link:
{{uri}}
You can find more info at {{base_uri}}/about
--
{{ base_uri }}
distributing OpenPGP keys since 2019

View File

@ -148,6 +148,32 @@ impl Service {
)
}
pub fn send_upload(
&self,
base_uri: &str,
tpk_name: String,
userid: &Email,
token: &str
) -> Result<()> {
let ctx = context::Welcome {
lang: "en".to_owned(),
primary_fp: tpk_name,
uri: format!("{}/upload/{}", base_uri, token),
base_uri: base_uri.to_owned(),
domain: self.domain.clone(),
};
counters::inc_mail_sent("upload", userid);
self.send(
&vec![userid],
&format!("Your key upload on {domain}", domain = self.domain),
"upload",
"en",
ctx,
)
}
pub fn send_welcome(
&self,
base_uri: &str,

View File

@ -1,6 +1,7 @@
use std::fmt;
use std::time::SystemTime;
use std::collections::HashMap;
use rocket::Data;
use rocket::Outcome;
@ -20,6 +21,7 @@ use crate::web;
use crate::mail;
use crate::web::{HagridState, RequestOrigin, MyResponse, vks_web};
use crate::web::vks::response::UploadResponse;
use crate::web::vks::response::EmailStatus;
#[derive(Debug)]
pub enum Hkp {
@ -48,7 +50,6 @@ impl<'a, 'r> FromRequest<'a, 'r> for Hkp {
fn from_request(request: &'a Request<'r>) -> request::Outcome<Hkp, ()> {
use std::str::FromStr;
use rocket::request::FormItems;
use std::collections::HashMap;
let query = request.uri().query().unwrap_or("");
let fields = FormItems::from(query)
@ -141,12 +142,8 @@ pub fn pks_add_form(
data: Data,
) -> MyResponse {
match vks_web::process_post_form(&db, &tokens_stateless, &rate_limiter, &i18n, data) {
Ok(UploadResponse::Ok { is_new_key, key_fpr, primary_uid, token, .. }) => {
let msg = if is_new_key && send_welcome_mail(&request_origin, &mail_service, key_fpr, primary_uid, token) {
format!("Upload successful. This is a new key, a welcome email has been sent.")
} else {
format!("Upload successful. Please note that identity information will only be published after verification. See {baseuri}/about/usage#gnupg-upload", baseuri = request_origin.get_base_uri())
};
Ok(UploadResponse::Ok { is_new_key, key_fpr, primary_uid, token, status, .. }) => {
let msg = pks_add_ok(&request_origin, &mail_service, &rate_limiter, token, status, is_new_key, key_fpr, primary_uid);
MyResponse::plain(msg)
}
Ok(_) => {
@ -157,19 +154,61 @@ pub fn pks_add_form(
}
}
fn pks_add_ok(
request_origin: &RequestOrigin,
mail_service: &mail::Service,
rate_limiter: &RateLimiter,
token: String,
status: HashMap<String, EmailStatus>,
is_new_key: bool,
key_fpr: String,
primary_uid: Option<Email>,
) -> String {
if primary_uid.is_none() {
return format!("Upload successful. Please note that identity information will only be published after verification. See {baseuri}/about/usage#gnupg-upload", baseuri = request_origin.get_base_uri())
}
let primary_uid = primary_uid.unwrap();
if is_new_key {
if send_welcome_mail(&request_origin, &mail_service, key_fpr, primary_uid, token) {
return format!("Upload successful. This is a new key, a welcome email has been sent.");
}
return format!("Upload successful. Please note that identity information will only be published after verification. See {baseuri}/about/usage#gnupg-upload", baseuri = request_origin.get_base_uri())
}
let has_unverified = status.iter().any(|(_, v)| *v == EmailStatus::Unpublished);
if !has_unverified {
return format!("Upload successful.");
}
// We send this out on the *second* time the key is uploaded (within one ratelimit period).
let uploaded_repeatedly = !rate_limiter.action_perform(format!("hkp-upload-{}", &key_fpr));
if uploaded_repeatedly && rate_limiter.action_perform(format!("hkp-upload-sent-{}", &primary_uid)) {
if send_upload_mail(&request_origin, &mail_service, key_fpr, primary_uid, token) {
return format!("Upload successful. An upload information email has been sent.");
}
}
return format!("Upload successful. Please note that identity information will only be published after verification. See {baseuri}/about/usage#gnupg-upload", baseuri = request_origin.get_base_uri())
}
fn send_upload_mail(
request_origin: &RequestOrigin,
mail_service: &mail::Service,
fpr: String,
primary_uid: Email,
token: String,
) -> bool {
mail_service.send_upload(request_origin.get_base_uri(), fpr, &primary_uid, &token).is_ok()
}
fn send_welcome_mail(
request_origin: &RequestOrigin,
mail_service: &mail::Service,
fpr: String,
primary_uid: Option<Email>,
primary_uid: Email,
token: String,
) -> bool {
if let Some(primary_uid) = primary_uid {
mail_service.send_welcome(
request_origin.get_base_uri(), fpr, &primary_uid, &token).is_ok()
} else {
false
}
mail_service.send_welcome(request_origin.get_base_uri(), fpr, &primary_uid, &token).is_ok()
}
#[get("/pks/lookup")]