Don't sign GET requests in private mode
This commit is contained in:
parent
924f5181b6
commit
ac1027ac2a
3 changed files with 44 additions and 38 deletions
|
@ -1,7 +1,7 @@
|
|||
use actix_web::http::Method;
|
||||
use rsa::RsaPrivateKey;
|
||||
|
||||
use crate::config::{Environment, Config};
|
||||
use crate::config::{Config, Instance};
|
||||
use crate::http_signatures::create::{create_http_signature, SignatureError};
|
||||
use crate::models::users::types::User;
|
||||
use crate::utils::crypto::deserialize_private_key;
|
||||
|
@ -29,7 +29,7 @@ pub enum DelivererError {
|
|||
}
|
||||
|
||||
async fn send_activity(
|
||||
config: &Config,
|
||||
instance: &Instance,
|
||||
actor_key: &RsaPrivateKey,
|
||||
actor_key_id: &str,
|
||||
activity_json: &str,
|
||||
|
@ -53,32 +53,29 @@ async fn send_activity(
|
|||
.header("Content-Type", ACTIVITY_CONTENT_TYPE)
|
||||
.body(activity_json.to_owned());
|
||||
|
||||
match config.environment {
|
||||
Environment::Development => {
|
||||
log::info!(
|
||||
"development mode: not sending activity to {}",
|
||||
inbox_url,
|
||||
);
|
||||
},
|
||||
Environment::Production => {
|
||||
// Default timeout is 30s
|
||||
let response = request.send().await?;
|
||||
let response_status = response.status();
|
||||
let response_text = response.text().await?;
|
||||
log::info!(
|
||||
"remote server response: {}",
|
||||
response_text,
|
||||
);
|
||||
if response_status.is_client_error() || response_status.is_server_error() {
|
||||
return Err(DelivererError::HttpError(response_status));
|
||||
}
|
||||
},
|
||||
if instance.is_private {
|
||||
log::info!(
|
||||
"private mode: not sending activity to {}",
|
||||
inbox_url,
|
||||
);
|
||||
} else {
|
||||
// Default timeout is 30s
|
||||
let response = request.send().await?;
|
||||
let response_status = response.status();
|
||||
let response_text = response.text().await?;
|
||||
log::info!(
|
||||
"remote server response: {}",
|
||||
response_text,
|
||||
);
|
||||
if response_status.is_client_error() || response_status.is_server_error() {
|
||||
return Err(DelivererError::HttpError(response_status));
|
||||
};
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn deliver_activity_worker(
|
||||
config: Config,
|
||||
instance: Instance,
|
||||
sender: User,
|
||||
activity: Activity,
|
||||
recipients: Vec<Actor>,
|
||||
|
@ -87,7 +84,7 @@ async fn deliver_activity_worker(
|
|||
let actor_key_id = format!(
|
||||
"{}#main-key",
|
||||
get_actor_url(
|
||||
&config.instance_url(),
|
||||
&instance.url(),
|
||||
&sender.profile.username,
|
||||
),
|
||||
);
|
||||
|
@ -100,7 +97,7 @@ async fn deliver_activity_worker(
|
|||
for inbox_url in inboxes {
|
||||
// TODO: retry on error
|
||||
if let Err(err) = send_activity(
|
||||
&config,
|
||||
&instance,
|
||||
&actor_key,
|
||||
&actor_key_id,
|
||||
&activity_json,
|
||||
|
@ -118,11 +115,11 @@ pub fn deliver_activity(
|
|||
activity: Activity,
|
||||
recipients: Vec<Actor>,
|
||||
) -> () {
|
||||
let config = config.clone();
|
||||
let instance = config.instance();
|
||||
let sender = sender.clone();
|
||||
actix_rt::spawn(async move {
|
||||
deliver_activity_worker(
|
||||
config,
|
||||
instance,
|
||||
sender,
|
||||
activity,
|
||||
recipients,
|
||||
|
|
|
@ -45,19 +45,23 @@ async fn send_request(
|
|||
request_builder = request_builder.query(query_params);
|
||||
};
|
||||
|
||||
let headers = create_http_signature(
|
||||
Method::GET,
|
||||
url,
|
||||
"",
|
||||
&instance.actor_key,
|
||||
&instance.actor_key_id(),
|
||||
)?;
|
||||
if !instance.is_private {
|
||||
// Only public instance can send signed request
|
||||
let headers = create_http_signature(
|
||||
Method::GET,
|
||||
url,
|
||||
"",
|
||||
&instance.actor_key,
|
||||
&instance.actor_key_id(),
|
||||
)?;
|
||||
request_builder = request_builder
|
||||
.header("Host", headers.host)
|
||||
.header("Date", headers.date)
|
||||
.header("Signature", headers.signature);
|
||||
};
|
||||
|
||||
let data = request_builder
|
||||
.header(reqwest::header::ACCEPT, ACTIVITY_CONTENT_TYPE)
|
||||
.header("Host", headers.host)
|
||||
.header("Date", headers.date)
|
||||
.header("Signature", headers.signature)
|
||||
.send().await?
|
||||
.error_for_status()?
|
||||
.text().await?;
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::activitypub::views::get_instance_actor_url;
|
|||
use crate::errors::ConversionError;
|
||||
use crate::utils::crypto::deserialize_private_key;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Environment {
|
||||
Development,
|
||||
Production,
|
||||
|
@ -126,6 +126,7 @@ impl Config {
|
|||
Instance {
|
||||
_url: self.try_instance_url().unwrap(),
|
||||
actor_key: self.try_instance_rsa_key().unwrap(),
|
||||
is_private: self.environment == Environment::Development,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +143,8 @@ pub struct Instance {
|
|||
_url: Url,
|
||||
// Instance actor
|
||||
pub actor_key: RsaPrivateKey,
|
||||
// Private instance won't send signed HTTP requests
|
||||
pub is_private: bool,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
|
@ -200,6 +203,7 @@ mod tests {
|
|||
let instance = Instance {
|
||||
_url: instance_url,
|
||||
actor_key: instance_rsa_key,
|
||||
is_private: true,
|
||||
};
|
||||
|
||||
assert_eq!(instance.url(), "https://example.com");
|
||||
|
@ -213,6 +217,7 @@ mod tests {
|
|||
let instance = Instance {
|
||||
_url: instance_url,
|
||||
actor_key: instance_rsa_key,
|
||||
is_private: true,
|
||||
};
|
||||
|
||||
assert_eq!(instance.url(), "http://1.2.3.4:3777");
|
||||
|
|
Loading…
Reference in a new issue