Use /vks/ as prefix for our API.

- Fixes #59.
This commit is contained in:
Justus Winter
2019-02-28 16:57:03 +01:00
parent 765ab569eb
commit 7cd3280bf6
4 changed files with 29 additions and 24 deletions

View File

@@ -27,6 +27,8 @@ setup. The FROM field of the mails can be configured with the `-F` switch.
Usage Usage
----- -----
### HKP
Hagrid implements basic HKP (`op=get` and `op=index`) so tools like GnuPG and Hagrid implements basic HKP (`op=get` and `op=index`) so tools like GnuPG and
OpenKeychain can use it directly. The differences to SKS are OpenKeychain can use it directly. The differences to SKS are
@@ -39,15 +41,17 @@ OpenKeychain can use it directly. The differences to SKS are
Uploading a key via the HKP interface will trigger verification emails to be Uploading a key via the HKP interface will trigger verification emails to be
send. send.
### VKS
Hagrid has it's own URL scheme to fetch keys, verify user IDs and delete keys. Hagrid has it's own URL scheme to fetch keys, verify user IDs and delete keys.
It's meant to be machine readable, but it's not a REST API. The following URLs It's meant to be machine readable, but it's not a REST API. The following URLs
are handled. are handled.
- `GET /by-fingerprint/<FINGERPRINT>` retrieves the key with the given - `GET /vks/by-fingerprint/<FINGERPRINT>` retrieves the key with the given
fingerprint. Hexadecimal digits must be uppercase. fingerprint. Hexadecimal digits must be uppercase.
- `GET /by-keyid/<KEY-ID>` retrieves the key with the given long key - `GET /vks/by-keyid/<KEY-ID>` retrieves the key with the given long key
ID. Hexadecimal digits must be uppercase. ID. Hexadecimal digits must be uppercase.
- `GET /by-email/<URL-encoded user ID>` retrieves the key with the given user - `GET /vks/by-email/<URL-encoded user ID>` retrieves the key with the given user
ID. Only exact matches are accepted. ID. Only exact matches are accepted.
- `GET /vks/verify/<token>` verifies a user ID using a token string send by - `GET /vks/verify/<token>` verifies a user ID using a token string send by
email. email.
@@ -102,12 +106,13 @@ in the above example).
Reverse Proxy Reverse Proxy
------------- -------------
Hagrid is designed to defer lookups to reverse proxy server like Nginx and Hagrid is designed to defer lookups to reverse proxy server like Nginx
Apache. The key database is a set of 3 directories with static files in them. and Apache. The key database is a set of 3 directories with static
The directory structure reflects Hagrids URL scheme. This way, lookups via files in them. The directory structure reflects Hagrids URL
`by-fpr`, `by-email` and `by-kid` can be handled by (multiple) simple HTTP scheme. This way, lookups via `/vks/by-finingerprint`,
server(s). A sample configuration for Nginx is part of the repository `/vks/by-keyid`, and `/vks/by-email` can be handled by (multiple)
(`nginx.conf`). simple HTTP server(s). A sample configuration for Nginx is part of the
repository (`nginx.conf`).
Community Community
--------- ---------

View File

@@ -5,6 +5,6 @@
</p> </p>
<p>You can get it with GnuPG using the following snippet:</p> <p>You can get it with GnuPG using the following snippet:</p>
<pre><code>gpg --fetch-keys <a href="https://{{ domain }}/by-fingerprint/{{ fpr }}">https://{{ domain }}/by-fingerprint/{{ fpr }}</a></code></pre> <pre><code>gpg --fetch-keys <a href="https://{{ domain }}/vks/by-fingerprint/{{ fpr }}">https://{{ domain }}/vks/by-fingerprint/{{ fpr }}</a></code></pre>
</div> </div>
{{/layout}} {{/layout}}

View File

@@ -1,22 +1,22 @@
# this routing file is included in the hagrid http block # this routing file is included in the hagrid http block
# it is assumed that hagrid runs on localhost:8080 # it is assumed that hagrid runs on localhost:8080
location /by-email/ { location /vks/by-email/ {
rewrite "^/by-email/([^/]{2})([^/]*)$" /by-email/$1/$2 break; rewrite "^/vks/by-email/([^/]{2})([^/]*)$" /by-email/$1/$2 break;
default_type application/pgp-keys; default_type application/pgp-keys;
add_header Content-Disposition 'attachment; filename="$1$2.asc"'; add_header Content-Disposition 'attachment; filename="$1$2.asc"';
try_files /$uri =404; try_files /$uri =404;
} }
location /by-fingerprint/ { location /vks/by-fingerprint/ {
rewrite ^/by-fingerprint/(0x)?([^/][^/])(..*)$ /by-fingerprint/$2$3 break; rewrite ^/vks/by-fingerprint/(0x)?([^/][^/])(..*)$ /vks/by-fingerprint/$2$3 break;
default_type application/pgp-keys; default_type application/pgp-keys;
add_header Content-Disposition 'attachment; filename="$2$3.asc"'; add_header Content-Disposition 'attachment; filename="$2$3.asc"';
try_files /by-fpr/$2/$3 @fallback; try_files /by-fpr/$2/$3 @fallback;
} }
location /by-keyid/ { location /vks/by-keyid/ {
rewrite ^/by-keyid/(0x)?([^/][^/])(.*)$ /by-keyid/$2$3 break; rewrite ^/vks/by-keyid/(0x)?([^/][^/])(.*)$ /vks/by-keyid/$2$3 break;
default_type application/pgp-keys; default_type application/pgp-keys;
add_header Content-Disposition 'attachment; filename="$2$3.asc"'; add_header Content-Disposition 'attachment; filename="$2$3.asc"';
try_files /by-keyid/$2/$3 @fallback; try_files /by-keyid/$2/$3 @fallback;
@@ -33,14 +33,14 @@ location /pks/lookup {
if ($args ~ "^op=get&options=mr&?search=(0x)?([A-F0-9]{2})([A-F0-9]{14})$") { if ($args ~ "^op=get&options=mr&?search=(0x)?([A-F0-9]{2})([A-F0-9]{14})$") {
set $dir $2; set $dir $2;
set $file $3; set $file $3;
rewrite . /by-keyid/$dir/$file; rewrite . /vks/by-keyid/$dir/$file;
} }
# gpg --receive-keys <FINGERPRINT> # gpg --receive-keys <FINGERPRINT>
if ($args ~ "^op=get&options=mr&?search=(0x)?([A-F0-9]{2})([A-F0-9]{38})$") { if ($args ~ "^op=get&options=mr&?search=(0x)?([A-F0-9]{2})([A-F0-9]{38})$") {
set $dir $2; set $dir $2;
set $file $3; set $file $3;
rewrite . /by-fingerprint/$dir/$file; rewrite . /vks/by-fingerprint/$dir/$file;
} }
# gpg --locate-key <EMAIL> # gpg --locate-key <EMAIL>
@@ -48,7 +48,7 @@ location /pks/lookup {
set $dir $1; set $dir $1;
set $local $2; set $local $2;
set $horst $4; set $horst $4;
rewrite . /by-email/$dir/$local%40$horst; rewrite . /vks/by-email/$dir/$local%40$horst;
} }
proxy_pass http://127.0.0.1:8080; proxy_pass http://127.0.0.1:8080;

View File

@@ -351,7 +351,7 @@ fn key_to_hkp_index<'a>(armored: String) -> MyResponse {
} }
#[get("/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 maybe_key = match Fingerprint::from_str(&fpr) {
Ok(ref fpr) => db.by_fpr(fpr), Ok(ref fpr) => db.by_fpr(fpr),
@@ -365,7 +365,7 @@ fn by_fingerprint(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>,
} }
} }
#[get("/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 maybe_key = match Email::from_str(&email) {
Ok(ref email) => db.by_email(email), Ok(ref email) => db.by_email(email),
@@ -380,7 +380,7 @@ fn by_email(db: rocket::State<Polymorphic>, domain: rocket::State<Domain>, email
} }
} }
#[get("/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 maybe_key = match KeyID::from_str(&kid) {
Ok(ref key) => db.by_kid(key), Ok(ref key) => db.by_kid(key),
@@ -811,8 +811,8 @@ mod tests {
assert_eq!(tpk_.userids().count(), 0); assert_eq!(tpk_.userids().count(), 0);
} }
check_mr_response(&client, &format!("/by-keyid/{}", keyid), &tpk); check_mr_response(&client, &format!("/vks/by-keyid/{}", keyid), &tpk);
check_mr_response(&client, &format!("/by-fingerprint/{}", fp), &tpk); check_mr_response(&client, &format!("/vks/by-fingerprint/{}", fp), &tpk);
check_mr_response( check_mr_response(
&client, &client,
&format!("/pks/lookup?op=get&options=mr&search={}", fp), &format!("/pks/lookup?op=get&options=mr&search={}", fp),