parent
946f0dd7e5
commit
d38b80f26d
|
@ -36,8 +36,7 @@ OpenKeychain can use it directly. The differences to SKS are
|
|||
- only exact matches for user IDs are returned (i.e. `exact=on` is
|
||||
always assumed),
|
||||
- `op=index` returns either one or no keys,
|
||||
- all packets that aren't public keys, user IDs or signatures are filtered out,
|
||||
- Uploading a key via the HKP interface is not supported.
|
||||
- all packets that aren't public keys, user IDs or signatures are filtered out.
|
||||
|
||||
### VKS
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ mod queries {
|
|||
use rocket::http::hyper::header::ContentDisposition;
|
||||
|
||||
#[derive(Responder)]
|
||||
enum MyResponse {
|
||||
pub enum MyResponse {
|
||||
#[response(status = 200, content_type = "html")]
|
||||
Success(Template),
|
||||
#[response(status = 200, content_type = "plain")]
|
||||
|
@ -638,6 +638,7 @@ fn rocket_factory(rocket: rocket::Rocket, db: Polymorphic) -> rocket::Rocket {
|
|||
by_keyid,
|
||||
// HKP
|
||||
lookup,
|
||||
upload::pks_add,
|
||||
upload::vks_publish,
|
||||
upload::vks_publish_submit,
|
||||
// verification & deletion
|
||||
|
@ -953,6 +954,61 @@ mod tests {
|
|||
&tpk);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hkp() {
|
||||
let (tmpdir, config) = configuration().unwrap();
|
||||
let filemail_into = tmpdir.path().join("filemail");
|
||||
|
||||
// eprintln!("LEAKING: {:?}", tmpdir);
|
||||
// ::std::mem::forget(tmpdir);
|
||||
|
||||
let db = Polymorphic::Filesystem(
|
||||
Filesystem::new(config.root().unwrap().to_path_buf()).unwrap());
|
||||
let rocket = rocket_factory(rocket::custom(config), db);
|
||||
let client = Client::new(rocket).expect("valid rocket instance");
|
||||
|
||||
// Generate a key and upload it.
|
||||
let (tpk, _) = TPKBuilder::autocrypt(
|
||||
None, Some("foo@invalid.example.com".into()))
|
||||
.generate().unwrap();
|
||||
|
||||
// Prepare to /pks/add
|
||||
let mut armored = Vec::new();
|
||||
{
|
||||
use sequoia_openpgp::armor::{Writer, Kind};
|
||||
let mut w = Writer::new(&mut armored, Kind::PublicKey, &[])
|
||||
.unwrap();
|
||||
tpk.serialize(&mut w).unwrap();
|
||||
}
|
||||
let mut post_data = String::from("keytext=");
|
||||
for enc in url::form_urlencoded::byte_serialize(&armored) {
|
||||
post_data.push_str(enc);
|
||||
}
|
||||
|
||||
// Add!
|
||||
let mut response = client.post("/pks/add")
|
||||
.body(post_data.as_bytes())
|
||||
.header(ContentType::Form)
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let body = response.body_string().unwrap();
|
||||
eprintln!("response: {}", body);
|
||||
|
||||
// Check that we do not get a confirmation mail.
|
||||
let confirm_mail = pop_mail(filemail_into.as_path()).unwrap();
|
||||
assert!(confirm_mail.is_none());
|
||||
|
||||
// We should not be able to look it up by email address.
|
||||
check_null_responses_by_email(&client, "foo@invalid.example.com");
|
||||
|
||||
// And check that we can get it back via the machine readable
|
||||
// interface.
|
||||
check_mr_responses_by_fingerprint(&client, &tpk, 0);
|
||||
|
||||
// And check that we can see the human-readable result page.
|
||||
check_hr_responses_by_fingerprint(&client, &tpk);
|
||||
}
|
||||
|
||||
/// Returns and removes the first mail it finds from the given
|
||||
/// directory.
|
||||
fn pop_mail(dir: &Path) -> Result<Option<SimpleSendableEmail>> {
|
||||
|
|
|
@ -18,6 +18,8 @@ use web::Domain;
|
|||
|
||||
use std::io::Read;
|
||||
|
||||
use super::MyResponse;
|
||||
|
||||
mod template {
|
||||
#[derive(Serialize)]
|
||||
pub struct Upload {
|
||||
|
@ -83,16 +85,26 @@ pub fn vks_publish_submit(
|
|||
db: State<Polymorphic>, cont_type: &ContentType, data: Data,
|
||||
mail_service: State<mail::Service>, domain: State<Domain>,
|
||||
) -> Flash<Redirect> {
|
||||
match do_upload_hkp(db, cont_type, data, mail_service, domain) {
|
||||
match do_upload_hkp(db, cont_type, data, Some(mail_service), domain) {
|
||||
Ok(ok) => ok,
|
||||
Err(err) => Flash::error(Redirect::to("/vks/v1/publish?err"), err.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/pks/add", data = "<data>")]
|
||||
pub fn pks_add(db: State<Polymorphic>, cont_type: &ContentType, data: Data,
|
||||
domain: State<Domain>)
|
||||
-> MyResponse {
|
||||
match do_upload_hkp(db, cont_type, data, None, domain) {
|
||||
Ok(_) => MyResponse::plain("Ok".into()),
|
||||
Err(err) => MyResponse::ise(err),
|
||||
}
|
||||
}
|
||||
|
||||
// signature requires the request to have a `Content-Type`
|
||||
fn do_upload_hkp(
|
||||
db: State<Polymorphic>, cont_type: &ContentType, data: Data,
|
||||
mail_service: State<mail::Service>, domain: State<Domain>,
|
||||
mail_service: Option<State<mail::Service>>, domain: State<Domain>,
|
||||
) -> Result<Flash<Redirect>> {
|
||||
if cont_type.is_form_data() {
|
||||
// multipart/form-data
|
||||
|
@ -142,7 +154,7 @@ fn do_upload_hkp(
|
|||
|
||||
fn process_upload(
|
||||
boundary: &str, data: Data, db: &Polymorphic,
|
||||
mail_service: State<mail::Service>,
|
||||
mail_service: Option<State<mail::Service>>,
|
||||
domain: &str,
|
||||
) -> Result<Flash<Redirect>> {
|
||||
// saves all fields, any field longer than 10kB goes to a temporary directory
|
||||
|
@ -159,10 +171,9 @@ fn process_upload(
|
|||
}
|
||||
}
|
||||
|
||||
fn process_multipart(
|
||||
entries: Entries, db: &Polymorphic, mail_service: State<mail::Service>,
|
||||
domain: &str,
|
||||
) -> Result<Flash<Redirect>> {
|
||||
fn process_multipart(entries: Entries, db: &Polymorphic,
|
||||
mail_service: Option<State<mail::Service>>,
|
||||
domain: &str) -> Result<Flash<Redirect>> {
|
||||
match entries.fields.get("keytext") {
|
||||
Some(ent) if ent.len() == 1 => {
|
||||
let reader = ent[0].data.readable()?;
|
||||
|
@ -175,7 +186,7 @@ fn process_multipart(
|
|||
}
|
||||
|
||||
fn process_key<R>(
|
||||
reader: R, db: &Polymorphic, mail_service: State<mail::Service>,
|
||||
reader: R, db: &Polymorphic, mail_service: Option<State<mail::Service>>,
|
||||
domain: &str,
|
||||
) -> Result<Flash<Redirect>>
|
||||
where
|
||||
|
@ -188,13 +199,15 @@ where
|
|||
let tokens = db.merge_or_publish(tpk)?;
|
||||
let mut results: Vec<String> = vec!();
|
||||
|
||||
for (email,token) in tokens {
|
||||
mail_service.send_verification(
|
||||
&email,
|
||||
&token,
|
||||
domain,
|
||||
)?;
|
||||
results.push(email.to_string());
|
||||
if let Some(mail_service) = mail_service {
|
||||
for (email, token) in tokens {
|
||||
mail_service.send_verification(
|
||||
&email,
|
||||
&token,
|
||||
domain,
|
||||
)?;
|
||||
results.push(email.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let json = serde_json::to_string(&results).unwrap();
|
||||
|
|
Loading…
Reference in New Issue