Accept Delete(Person) activities if HTTP signature is correct
This commit is contained in:
parent
b95d409010
commit
c89ee4fd7b
|
@ -163,16 +163,6 @@ pub async fn receive_activity(
|
||||||
request: &HttpRequest,
|
request: &HttpRequest,
|
||||||
activity_raw: &Value,
|
activity_raw: &Value,
|
||||||
) -> Result<(), HttpError> {
|
) -> Result<(), HttpError> {
|
||||||
let signer = verify_http_signature(config, db_client, request).await.map_err(|err| {
|
|
||||||
log::warn!("invalid signature: {}", err);
|
|
||||||
HttpError::AuthError("invalid signature")
|
|
||||||
})?;
|
|
||||||
let signer_id = signer.actor_id(&config.instance_url());
|
|
||||||
log::debug!("activity signed by {}", signer_id);
|
|
||||||
if config.blocked_instances.iter().any(|instance| signer.acct.contains(instance)) {
|
|
||||||
return Err(HttpError::ValidationError("instance is blocked".into()));
|
|
||||||
};
|
|
||||||
|
|
||||||
let activity: Activity = serde_json::from_value(activity_raw.clone())
|
let activity: Activity = serde_json::from_value(activity_raw.clone())
|
||||||
.map_err(|_| ValidationError("invalid activity"))?;
|
.map_err(|_| ValidationError("invalid activity"))?;
|
||||||
let activity_type = activity.activity_type.clone();
|
let activity_type = activity.activity_type.clone();
|
||||||
|
@ -180,6 +170,25 @@ pub async fn receive_activity(
|
||||||
let maybe_object_type = activity.object.get("type")
|
let maybe_object_type = activity.object.get("type")
|
||||||
.and_then(|val| val.as_str())
|
.and_then(|val| val.as_str())
|
||||||
.unwrap_or("Unknown");
|
.unwrap_or("Unknown");
|
||||||
|
|
||||||
|
let signer = match verify_http_signature(config, db_client, request).await {
|
||||||
|
Ok(signer) => signer,
|
||||||
|
Err(error) => {
|
||||||
|
let object_id = get_object_id(activity.object)?;
|
||||||
|
if activity_type == DELETE && activity.actor == object_id {
|
||||||
|
// Ignore Delete(Person) activities without HTTP signatures
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
log::warn!("invalid signature: {}", error);
|
||||||
|
return Err(HttpError::AuthError("invalid signature"));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let signer_id = signer.actor_id(&config.instance_url());
|
||||||
|
log::debug!("activity signed by {}", signer_id);
|
||||||
|
if config.blocked_instances.iter().any(|instance| signer.acct.contains(instance)) {
|
||||||
|
return Err(HttpError::ValidationError("instance is blocked".into()));
|
||||||
|
};
|
||||||
|
|
||||||
let object_type = match (activity_type.as_str(), maybe_object_type) {
|
let object_type = match (activity_type.as_str(), maybe_object_type) {
|
||||||
(ACCEPT, FOLLOW) => {
|
(ACCEPT, FOLLOW) => {
|
||||||
require_actor_signature(&activity.actor, &signer_id)?;
|
require_actor_signature(&activity.actor, &signer_id)?;
|
||||||
|
|
|
@ -24,7 +24,6 @@ use super::collections::{
|
||||||
};
|
};
|
||||||
use super::constants::ACTIVITY_CONTENT_TYPE;
|
use super::constants::ACTIVITY_CONTENT_TYPE;
|
||||||
use super::receiver::receive_activity;
|
use super::receiver::receive_activity;
|
||||||
use super::vocabulary::DELETE;
|
|
||||||
|
|
||||||
pub fn get_actor_url(instance_url: &str, username: &str) -> String {
|
pub fn get_actor_url(instance_url: &str, username: &str) -> String {
|
||||||
format!("{}/users/{}", instance_url, username)
|
format!("{}/users/{}", instance_url, username)
|
||||||
|
@ -109,13 +108,7 @@ async fn inbox(
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
log::debug!("received activity: {}", activity);
|
log::debug!("received activity: {}", activity);
|
||||||
let activity_type = activity["type"].as_str().unwrap_or("Unknown");
|
let activity_type = activity["type"].as_str().unwrap_or("Unknown");
|
||||||
if activity_type == DELETE && activity["actor"] == activity["object"] {
|
log::info!("received in {}: {}", request.uri().path(), activity_type);
|
||||||
// Ignore Delete(Person) activities and skip signature verification
|
|
||||||
log::info!("received in {}: Delete(Person)", request.uri().path());
|
|
||||||
return Ok(HttpResponse::Ok().finish());
|
|
||||||
} else {
|
|
||||||
log::info!("received in {}: {}", request.uri().path(), activity_type);
|
|
||||||
};
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
// Store mutex guard in a variable to prevent it from being dropped immediately
|
// Store mutex guard in a variable to prevent it from being dropped immediately
|
||||||
let _guard = inbox_mutex.lock().await;
|
let _guard = inbox_mutex.lock().await;
|
||||||
|
|
Loading…
Reference in a new issue