HTTP signature when sending activites
This commit is contained in:
parent
3d442e70ee
commit
3cf6836095
|
@ -808,6 +808,7 @@ dependencies = [
|
||||||
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"hyper 0.11.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -3,11 +3,12 @@ authors = ["Bat' <baptiste@gelez.xyz>"]
|
||||||
name = "plume"
|
name = "plume"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.9.1"
|
base64 = "0.9"
|
||||||
bcrypt = "0.2"
|
bcrypt = "0.2"
|
||||||
dotenv = "*"
|
dotenv = "*"
|
||||||
heck = "0.3.0"
|
heck = "0.3.0"
|
||||||
hex = "0.3"
|
hex = "0.3"
|
||||||
|
hyper = "*"
|
||||||
lazy_static = "*"
|
lazy_static = "*"
|
||||||
openssl = "0.10.6"
|
openssl = "0.10.6"
|
||||||
reqwest = "0.8"
|
reqwest = "0.8"
|
||||||
|
@ -29,3 +30,4 @@ version = "*"
|
||||||
[dependencies.rocket_contrib]
|
[dependencies.rocket_contrib]
|
||||||
features = ["tera_templates", "json"]
|
features = ["tera_templates", "json"]
|
||||||
version = "*"
|
version = "*"
|
||||||
|
"
|
||||||
|
|
|
@ -5,6 +5,7 @@ use serde_json;
|
||||||
use BASE_URL;
|
use BASE_URL;
|
||||||
use activity_pub::{activity_pub, ActivityPub, context, ap_url};
|
use activity_pub::{activity_pub, ActivityPub, context, ap_url};
|
||||||
use activity_pub::activity::Activity;
|
use activity_pub::activity::Activity;
|
||||||
|
use activity_pub::request;
|
||||||
use activity_pub::sign::*;
|
use activity_pub::sign::*;
|
||||||
use models::instance::Instance;
|
use models::instance::Instance;
|
||||||
|
|
||||||
|
@ -85,8 +86,12 @@ pub trait Actor: Sized {
|
||||||
let mut act = act.serialize();
|
let mut act = act.serialize();
|
||||||
act["@context"] = context();
|
act["@context"] = context();
|
||||||
let signed = act.sign(sender, conn);
|
let signed = act.sign(sender, conn);
|
||||||
|
|
||||||
let res = Client::new()
|
let res = Client::new()
|
||||||
.post(&self.compute_inbox(conn)[..])
|
.post(&self.compute_inbox(conn)[..])
|
||||||
|
.headers(request::headers())
|
||||||
|
.header(request::signature(sender, request::headers, conn))
|
||||||
|
.header(request::digest(signed.to_string()))
|
||||||
.body(signed.to_string())
|
.body(signed.to_string())
|
||||||
.send();
|
.send();
|
||||||
match res {
|
match res {
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub mod actor;
|
||||||
pub mod inbox;
|
pub mod inbox;
|
||||||
pub mod object;
|
pub mod object;
|
||||||
pub mod outbox;
|
pub mod outbox;
|
||||||
|
pub mod request;
|
||||||
pub mod sign;
|
pub mod sign;
|
||||||
pub mod webfinger;
|
pub mod webfinger;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
use base64;
|
||||||
|
use diesel::PgConnection;
|
||||||
|
use hex;
|
||||||
|
use openssl::hash::{Hasher, MessageDigest};
|
||||||
|
use openssl::sha::sha256;
|
||||||
|
use reqwest::header::{Date, Headers, UserAgent};
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use activity_pub::sign::Signer;
|
||||||
|
|
||||||
|
const USER_AGENT: &'static str = "Plume/0.1.0";
|
||||||
|
|
||||||
|
header! {
|
||||||
|
(Signature, "Signature") => [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
header! {
|
||||||
|
(Digest, "Digest") => [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn headers() -> Headers {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
headers.set(UserAgent::new(USER_AGENT));
|
||||||
|
headers.set(Date(SystemTime::now().into()));
|
||||||
|
headers
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signature<S: Signer>(signer: S, headers: Headers, conn: &PgConnection) -> Signature {
|
||||||
|
let signed_string = headers.iter().map(|h| format!("{}: {}", h.name().to_lowercase(), h.value_string())).collect::<Vec<String>>().join("\n");
|
||||||
|
let signed_headers = headers.iter().map(|h| h.name().to_string()).collect::<Vec<String>>().join(" ").to_lowercase();
|
||||||
|
|
||||||
|
let data = signer.sign(signed_string);
|
||||||
|
let sign = hex::encode(sha256(&data[..]));
|
||||||
|
|
||||||
|
Signature(format!(
|
||||||
|
"keyId=\"{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers}\",signature=\"#{signature}\"",
|
||||||
|
key_id = signer.get_key_id(conn),
|
||||||
|
signed_headers = signed_headers,
|
||||||
|
signature = sign
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn digest(body: String) -> Digest {
|
||||||
|
let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap();
|
||||||
|
hasher.update(&body.into_bytes()[..]);
|
||||||
|
let res = base64::encode(&hasher.finish().unwrap());
|
||||||
|
Digest(format!("SHA-256={}", res))
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ extern crate chrono;
|
||||||
extern crate heck;
|
extern crate heck;
|
||||||
extern crate hex;
|
extern crate hex;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
extern crate hyper;
|
||||||
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
extern crate dotenv;
|
extern crate dotenv;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
Loading…
Reference in New Issue