mirror of
https://gitlab.com/hagrid-keyserver/hagrid.git
synced 2023-02-13 20:55:02 -05:00
Simplify and optimize lookups.
- This uses the new Database::lookup_primary_fingerprint(..) interface to avoid parsing the TPK if we do not need it. - It also deduplicates some code, simplifying the implementation.
This commit is contained in:
parent
5b17240ae6
commit
f9f4ccb8c1
1 changed files with 44 additions and 69 deletions
109
src/web/mod.rs
109
src/web/mod.rs
|
@ -15,11 +15,9 @@ use handlebars::Handlebars;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use sequoia_openpgp as openpgp;
|
|
||||||
|
|
||||||
mod upload;
|
mod upload;
|
||||||
|
|
||||||
use database::{Database, Polymorphic};
|
use database::{Database, Polymorphic, Query};
|
||||||
use Result;
|
use Result;
|
||||||
use types::{Email, Fingerprint, KeyID};
|
use types::{Email, Fingerprint, KeyID};
|
||||||
use Opt;
|
use Opt;
|
||||||
|
@ -75,7 +73,7 @@ impl MyResponse {
|
||||||
MyResponse::Plain(s)
|
MyResponse::Plain(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key(armored_key: String, fp: &openpgp::Fingerprint) -> Self {
|
pub fn key(armored_key: String, fp: &Fingerprint) -> Self {
|
||||||
use rocket::http::hyper::header::{ContentDisposition, DispositionType,
|
use rocket::http::hyper::header::{ContentDisposition, DispositionType,
|
||||||
DispositionParam, Charset};
|
DispositionParam, Charset};
|
||||||
MyResponse::Key(
|
MyResponse::Key(
|
||||||
|
@ -85,7 +83,7 @@ impl MyResponse {
|
||||||
parameters: vec![
|
parameters: vec![
|
||||||
DispositionParam::Filename(
|
DispositionParam::Filename(
|
||||||
Charset::Us_Ascii, None,
|
Charset::Us_Ascii, None,
|
||||||
(fp.to_hex() + ".asc").into_bytes()),
|
(fp.to_string() + ".asc").into_bytes()),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -133,7 +131,6 @@ mod templates {
|
||||||
pub struct Search {
|
pub struct Search {
|
||||||
pub query: String,
|
pub query: String,
|
||||||
pub fpr: Option<String>,
|
pub fpr: Option<String>,
|
||||||
pub armored: Option<String>,
|
|
||||||
pub domain: Option<String>,
|
pub domain: Option<String>,
|
||||||
pub commit: String,
|
pub commit: String,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
|
@ -238,27 +235,27 @@ impl<'a, 'r> FromRequest<'a, 'r> for queries::Hkp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_to_response<'a>(query: String, domain: String, armored: String,
|
fn key_to_response<'a>(db: rocket::State<Polymorphic>,
|
||||||
|
query_string: String, domain: String,
|
||||||
|
query: Query,
|
||||||
machine_readable: bool) -> MyResponse {
|
machine_readable: bool) -> MyResponse {
|
||||||
use sequoia_openpgp::TPK;
|
let fp = if let Some(fp) = db.lookup_primary_fingerprint(&query) {
|
||||||
use sequoia_openpgp::parse::Parse;
|
fp
|
||||||
use std::convert::TryFrom;
|
} else {
|
||||||
|
return MyResponse::not_found(None, None);
|
||||||
let key = match TPK::from_bytes(armored.as_bytes()) {
|
|
||||||
Ok(key) => key,
|
|
||||||
Err(err) => { return MyResponse::ise(err); }
|
|
||||||
};
|
};
|
||||||
let fpr = key.primary().fingerprint();
|
|
||||||
|
|
||||||
if machine_readable {
|
if machine_readable {
|
||||||
return MyResponse::key(armored, &fpr);
|
return match db.by_fpr(&fp) {
|
||||||
|
Some(armored) => MyResponse::key(armored, &fp.into()),
|
||||||
|
None => MyResponse::not_found(None, None),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = templates::Search{
|
let context = templates::Search{
|
||||||
query: query,
|
query: query_string,
|
||||||
domain: Some(domain),
|
domain: Some(domain),
|
||||||
fpr: Fingerprint::try_from(fpr).unwrap().to_string().into(),
|
fpr: fp.to_string().into(),
|
||||||
armored: armored.into(),
|
|
||||||
version: env!("VERGEN_SEMVER").to_string(),
|
version: env!("VERGEN_SEMVER").to_string(),
|
||||||
commit: env!("VERGEN_SHA_SHORT").to_string(),
|
commit: env!("VERGEN_SHA_SHORT").to_string(),
|
||||||
};
|
};
|
||||||
|
@ -266,12 +263,13 @@ fn key_to_response<'a>(query: String, domain: String, armored: String,
|
||||||
MyResponse::ok("found", context)
|
MyResponse::ok("found", context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_to_hkp_index<'a>(armored: String) -> MyResponse {
|
fn key_to_hkp_index<'a>(db: rocket::State<Polymorphic>, query: Query)
|
||||||
|
-> MyResponse {
|
||||||
use sequoia_openpgp::RevocationStatus;
|
use sequoia_openpgp::RevocationStatus;
|
||||||
use sequoia_openpgp::{parse::Parse, TPK};
|
|
||||||
|
|
||||||
let tpk = match TPK::from_bytes(armored.as_bytes()) {
|
let tpk = match db.lookup(&query) {
|
||||||
Ok(tpk) => tpk,
|
Ok(Some(tpk)) => tpk,
|
||||||
|
Ok(None) => return MyResponse::not_found(None, None), // XXX: This should return 404.
|
||||||
Err(err) => { return MyResponse::ise(err); }
|
Err(err) => { return MyResponse::ise(err); }
|
||||||
};
|
};
|
||||||
let mut out = String::default();
|
let mut out = String::default();
|
||||||
|
@ -353,45 +351,32 @@ fn key_to_hkp_index<'a>(armored: String) -> MyResponse {
|
||||||
|
|
||||||
#[get("/vks/by-fingerprint/<fpr>")]
|
#[get("/vks/by-fingerprint/<fpr>")]
|
||||||
fn by_fingerprint(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, fpr: String) -> MyResponse {
|
fn by_fingerprint(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, fpr: String) -> MyResponse {
|
||||||
let maybe_key = match Fingerprint::from_str(&fpr) {
|
let query = match Fingerprint::from_str(&fpr) {
|
||||||
Ok(ref fpr) => db.by_fpr(fpr),
|
Ok(fpr) => Query::ByFingerprint(fpr),
|
||||||
Err(e) => return MyResponse::ise(e),
|
Err(e) => return MyResponse::ise(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
match maybe_key {
|
key_to_response(db, fpr, domain.0.clone(), query, true)
|
||||||
Some(armored) => key_to_response(fpr, domain.0.clone(), armored,
|
|
||||||
true),
|
|
||||||
None => MyResponse::not_found(None, None),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vks/by-email/<email>")]
|
#[get("/vks/by-email/<email>")]
|
||||||
fn by_email(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, email: String) -> MyResponse {
|
fn by_email(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, email: String) -> MyResponse {
|
||||||
let maybe_key = match Email::from_str(&email) {
|
let query = match Email::from_str(&email) {
|
||||||
Ok(ref email) => db.by_email(email),
|
Ok(email) => Query::ByEmail(email),
|
||||||
Err(e) => return MyResponse::ise(e),
|
Err(e) => return MyResponse::ise(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
match maybe_key {
|
key_to_response(db, email, domain.0.clone(), query, true)
|
||||||
Some(armored) => key_to_response(email, domain.0.clone(), armored,
|
|
||||||
true),
|
|
||||||
None => MyResponse::not_found(None, None),
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vks/by-keyid/<kid>")]
|
#[get("/vks/by-keyid/<kid>")]
|
||||||
fn by_keyid(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, kid: String) -> MyResponse {
|
fn by_keyid(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, kid: String) -> MyResponse {
|
||||||
let maybe_key = match KeyID::from_str(&kid) {
|
let query = match KeyID::from_str(&kid) {
|
||||||
Ok(ref key) => db.by_kid(key),
|
Ok(keyid) => Query::ByKeyID(keyid),
|
||||||
Err(e) => return MyResponse::ise(e),
|
Err(e) => return MyResponse::ise(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
match maybe_key {
|
key_to_response(db, kid, domain.0.clone(), query, true)
|
||||||
Some(armored) => key_to_response(kid, domain.0.clone(), armored,
|
|
||||||
true),
|
|
||||||
None => MyResponse::not_found(None, None),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vks/verify/<token>")]
|
#[get("/vks/verify/<token>")]
|
||||||
|
@ -520,14 +505,15 @@ fn files(file: PathBuf, static_dir: State<StaticDir>) -> Option<NamedFile> {
|
||||||
fn lookup(
|
fn lookup(
|
||||||
db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, key: Option<queries::Hkp>,
|
db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, key: Option<queries::Hkp>,
|
||||||
) -> MyResponse {
|
) -> MyResponse {
|
||||||
let (maybe_key, index, machine_readable) = match key {
|
let query_string = key.as_ref().map(|k| format!("{}", k));
|
||||||
Some(queries::Hkp::Fingerprint { ref fpr, index, machine_readable }) =>
|
let (query, index, machine_readable) = match key {
|
||||||
(db.by_fpr(fpr), index, machine_readable),
|
Some(queries::Hkp::Fingerprint { fpr, index, machine_readable }) =>
|
||||||
Some(queries::Hkp::KeyID { ref keyid, index, machine_readable }) =>
|
(Query::ByFingerprint(fpr), index, machine_readable),
|
||||||
(db.by_kid(keyid), index, machine_readable),
|
Some(queries::Hkp::KeyID { keyid, index, machine_readable }) =>
|
||||||
Some(queries::Hkp::Email { ref email, index }) => {
|
(Query::ByKeyID(keyid), index, machine_readable),
|
||||||
|
Some(queries::Hkp::Email { email, index }) => {
|
||||||
// XXX: Maybe return 501 Not Implemented if machine_readable
|
// XXX: Maybe return 501 Not Implemented if machine_readable
|
||||||
(db.by_email(email), index, false)
|
(Query::ByEmail(email), index, false)
|
||||||
}
|
}
|
||||||
Some(queries::Hkp::Invalid { query: _ }) => {
|
Some(queries::Hkp::Invalid { query: _ }) => {
|
||||||
return MyResponse::not_found(None, None);
|
return MyResponse::not_found(None, None);
|
||||||
|
@ -536,24 +522,13 @@ fn lookup(
|
||||||
return MyResponse::not_found(None, None);
|
return MyResponse::not_found(None, None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let query = format!("{}", key.unwrap());
|
|
||||||
|
|
||||||
match maybe_key {
|
|
||||||
Some(armored) => {
|
|
||||||
if index {
|
if index {
|
||||||
key_to_hkp_index(armored)
|
key_to_hkp_index(db, query)
|
||||||
} else {
|
} else {
|
||||||
key_to_response(query, domain.0.clone(), armored,
|
key_to_response(db,
|
||||||
machine_readable)
|
query_string.expect("key was Some if we made it here"),
|
||||||
}
|
domain.0.clone(), query, machine_readable)
|
||||||
}
|
|
||||||
None => {
|
|
||||||
if index {
|
|
||||||
MyResponse::plain("info:1:0\r\n".into())
|
|
||||||
} else {
|
|
||||||
MyResponse::not_found(None, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue