add gpg/curl shortcut
This commit is contained in:
parent
6b916f6556
commit
f8b6fab897
|
@ -70,6 +70,7 @@ code.snippet {
|
|||
}
|
||||
|
||||
blockquote {
|
||||
font-family: monospace;
|
||||
background: #f9f9f9;
|
||||
border-left: 10px solid #ccc;
|
||||
margin: 1.5em 10px;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Error: {{internal_error}}
|
|
@ -31,26 +31,48 @@
|
|||
</p>
|
||||
|
||||
<h2 style="margin-left: 3%;"><img src="/assets/img/gnupg.svg" style="display: inline; height: 2em; vertical-align: -30%; padding-right: 10px;" /> GnuPG</h2>
|
||||
<p>
|
||||
To configure GnuPG to use <span class="brand">keys.openpgp.org</span>
|
||||
as keyserver, add this line to your <tt>gpg.conf</tt> file:
|
||||
<blockquote>
|
||||
keyserver hkps://keys.openpgp.org
|
||||
</blockquote>
|
||||
Alternatively, commands can be run with an extra parameter
|
||||
<tt>--keyserver keys.openpgp.org</tt>.
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
To locate the key of a user, by email address:
|
||||
<blockquote>gpg --locate-keys user@example.net</blockquote>
|
||||
</li>
|
||||
<li>To refresh all your keys (e.g. new revocation certificates and subkeys):
|
||||
<blockquote>gpg --refresh</blockquote>
|
||||
</li>
|
||||
</ul>
|
||||
To configure GnuPG to use <span class="brand">keys.openpgp.org</span>
|
||||
as keyserver, add this line to your <tt>gpg.conf</tt> file:
|
||||
<blockquote>
|
||||
keyserver hkps://keys.openpgp.org
|
||||
</blockquote>
|
||||
|
||||
<h3>Retrieving keys</h3>
|
||||
<ul>
|
||||
<li>
|
||||
To locate the key of a user, by email address:
|
||||
<blockquote>gpg --locate-keys user@example.net</blockquote>
|
||||
</li>
|
||||
<li>To refresh all your keys (e.g. new revocation certificates and subkeys):
|
||||
<blockquote>gpg --refresh</blockquote>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Uploading your key</h3>
|
||||
<p>
|
||||
Keys can be uploaded with GnuPG's <tt>--send-keys</tt> command, but
|
||||
identity information can't be verified that way to make the key
|
||||
searchable by e-mail address (<a href="/about">what's that?</a>).
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
You can try this shortcut for uploading your key, which outputs
|
||||
a direct link to the verification page:
|
||||
<blockquote>
|
||||
gpg --export your_address@example.net | curl -T - {{base_uri}}
|
||||
</blockquote>
|
||||
</li>
|
||||
<li>
|
||||
Alternatively, you can export them to a file and enter that into the
|
||||
<a href="/upload" target="_blank">upload</a> page:
|
||||
<blockquote>
|
||||
gpg --export your_address@example.net > my_key.pub
|
||||
</blockquote>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 style="margin-left: 3%;">Others</h2>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -148,6 +148,23 @@ mod templates {
|
|||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct About {
|
||||
pub base_uri: String,
|
||||
pub commit: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
impl About {
|
||||
pub fn new(base_uri: impl Into<String>) -> Self {
|
||||
Self {
|
||||
base_uri: base_uri.into(),
|
||||
version: env!("VERGEN_SEMVER").to_string(),
|
||||
commit: env!("VERGEN_SHA_SHORT").to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl General {
|
||||
pub fn new(error: Option<String>) -> Self {
|
||||
Self {
|
||||
|
@ -280,8 +297,8 @@ fn faq() -> Template {
|
|||
}
|
||||
|
||||
#[get("/about/usage")]
|
||||
fn usage() -> Template {
|
||||
Template::render("about/usage", templates::General::default())
|
||||
fn usage(state: rocket::State<HagridState>) -> Template {
|
||||
Template::render("about/usage", templates::About::new(state.base_uri.as_ref()))
|
||||
}
|
||||
|
||||
#[get("/about/privacy")]
|
||||
|
@ -323,6 +340,8 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
vks_web::request_verify_form,
|
||||
vks_web::request_verify_form_data,
|
||||
vks_web::verify_confirm,
|
||||
vks_web::quick_upload,
|
||||
vks_web::quick_upload_proceed,
|
||||
// HKP
|
||||
hkp::pks_lookup,
|
||||
hkp::pks_add_form,
|
||||
|
@ -733,6 +752,23 @@ pub mod tests {
|
|||
assert_eq!(response.status(), Status::BadRequest);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upload_curl_shortcut() {
|
||||
let (_tmpdir, client) = client().unwrap();
|
||||
|
||||
let (tpk, _) = TPKBuilder::autocrypt(
|
||||
None, Some("foo@invalid.example.com".into()))
|
||||
.generate().unwrap();
|
||||
|
||||
let mut tpk_serialized = Vec::new();
|
||||
tpk.serialize(&mut tpk_serialized).unwrap();
|
||||
|
||||
let _token = vks_publish_shortcut_get_token(&client, &tpk_serialized);
|
||||
|
||||
check_mr_responses_by_fingerprint(&client, &tpk, 0);
|
||||
check_null_responses_by_email(&client, "foo@invalid.example.com");
|
||||
}
|
||||
|
||||
/// Asserts that the given URI 404s.
|
||||
pub fn check_null_response(client: &Client, uri: &str) {
|
||||
let response = client.get(uri).dispatch();
|
||||
|
@ -891,7 +927,6 @@ pub mod tests {
|
|||
assert!(response.body_string().unwrap().contains("pending"));
|
||||
}
|
||||
|
||||
|
||||
fn check_mails_and_verify_email(client: &Client, filemail_path: &Path) {
|
||||
let pattern = format!("{}(/verify/[^ \t\n]*)", BASE_URI);
|
||||
let confirm_uri = pop_mail_capture_pattern(filemail_path, &pattern);
|
||||
|
@ -980,6 +1015,21 @@ pub mod tests {
|
|||
.dispatch()
|
||||
}
|
||||
|
||||
fn vks_publish_shortcut_get_token<'a>(client: &'a Client, data: &[u8]) -> String {
|
||||
let mut response = client.put("/")
|
||||
.body(data)
|
||||
.dispatch();
|
||||
let response_body = response.body_string().unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert!(response_body.contains("Key successfully uploaded"));
|
||||
|
||||
let pattern = format!("{}/upload/([^ \t\n]*)", BASE_URI);
|
||||
let capture_re = regex::bytes::Regex::new(&pattern).unwrap();
|
||||
let capture_content = capture_re .captures(response_body.as_bytes()).unwrap()
|
||||
.get(1).unwrap().as_bytes();
|
||||
String::from_utf8_lossy(capture_content).to_string()
|
||||
}
|
||||
|
||||
fn vks_publish_json_get_token<'a>(client: &'a Client, data: &[u8]) -> String {
|
||||
let mut response = client.post("/vks/v1/upload")
|
||||
.header(ContentType::JSON)
|
||||
|
|
|
@ -12,7 +12,7 @@ use rocket::Data;
|
|||
use database::{KeyDatabase, StatefulTokens};
|
||||
use mail;
|
||||
use tokens;
|
||||
use web::MyResponse;
|
||||
use web::{HagridState,MyResponse};
|
||||
use rate_limiter::RateLimiter;
|
||||
|
||||
use std::io::Read;
|
||||
|
@ -87,11 +87,30 @@ mod template {
|
|||
}
|
||||
|
||||
impl MyResponse {
|
||||
fn upload_response_quick(response: UploadResponse, base_uri: &str) -> Self {
|
||||
match response {
|
||||
UploadResponse::Ok { token, key_fpr: _, is_revoked: _, status: _ } => {
|
||||
let uri = uri!(quick_upload_proceed: token);
|
||||
let text = format!(
|
||||
"Key successfully uploaded. Proceed here:\n{}{}\n",
|
||||
base_uri,
|
||||
uri
|
||||
);
|
||||
MyResponse::plain(text)
|
||||
},
|
||||
UploadResponse::OkMulti { key_fprs } =>
|
||||
MyResponse::plain(format!("Uploaded {} keys.\n", key_fprs.len())),
|
||||
UploadResponse::Error(error) => MyResponse::bad_request(
|
||||
"500-plain", failure::err_msg(error)),
|
||||
}
|
||||
}
|
||||
|
||||
fn upload_response(response: UploadResponse) -> Self {
|
||||
match response {
|
||||
UploadResponse::Ok { token, key_fpr, is_revoked, status } =>
|
||||
Self::upload_ok(token, key_fpr, is_revoked, status),
|
||||
UploadResponse::OkMulti { key_fprs } => Self::upload_ok_multi(key_fprs),
|
||||
UploadResponse::OkMulti { key_fprs } =>
|
||||
Self::upload_ok_multi(key_fprs),
|
||||
UploadResponse::Error(error) => MyResponse::bad_request(
|
||||
"upload/upload", failure::err_msg(error)),
|
||||
}
|
||||
|
@ -191,6 +210,44 @@ pub fn upload_post_form_data(
|
|||
process_upload(&db, &tokens_stateless, &rate_limiter, data, boundary)
|
||||
}
|
||||
|
||||
#[put("/", data = "<data>")]
|
||||
pub fn quick_upload(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
tokens_stateless: rocket::State<tokens::Service>,
|
||||
rate_limiter: rocket::State<RateLimiter>,
|
||||
state: rocket::State<HagridState>,
|
||||
data: Data,
|
||||
) -> MyResponse {
|
||||
use std::io::Cursor;
|
||||
|
||||
let mut buf = Vec::default();
|
||||
if let Err(error) = std::io::copy(&mut data.open().take(UPLOAD_LIMIT), &mut buf) {
|
||||
return MyResponse::bad_request("500-plain", failure::err_msg(error));
|
||||
}
|
||||
|
||||
MyResponse::upload_response_quick(vks::process_key(
|
||||
&db,
|
||||
&tokens_stateless,
|
||||
&rate_limiter,
|
||||
Cursor::new(buf)), &state.base_uri)
|
||||
}
|
||||
|
||||
#[get("/upload/<token>", rank = 2)]
|
||||
pub fn quick_upload_proceed(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
token_stateful: rocket::State<StatefulTokens>,
|
||||
token_stateless: rocket::State<tokens::Service>,
|
||||
mail_service: rocket::State<mail::Service>,
|
||||
rate_limiter: rocket::State<RateLimiter>,
|
||||
token: String,
|
||||
) -> MyResponse {
|
||||
let result = vks::request_verify(
|
||||
db, token_stateful, token_stateless, mail_service,
|
||||
rate_limiter, token, vec!());
|
||||
MyResponse::upload_response(result)
|
||||
}
|
||||
|
||||
|
||||
#[post("/upload/submit", format = "application/x-www-form-urlencoded", data = "<data>")]
|
||||
pub fn upload_post_form(
|
||||
db: rocket::State<KeyDatabase>,
|
||||
|
|
Loading…
Reference in New Issue