Define common return type for activity handlers

This commit is contained in:
silverpill 2022-05-30 21:48:41 +00:00
parent 1b1633d0b7
commit 30990c8af6
4 changed files with 36 additions and 27 deletions

View file

@ -1,3 +1,8 @@
use super::fetcher::helpers::ImportError;
// Handlers should return object type if activity has been accepted
// or None if it has been ignored
pub type HandlerResult = Result<Option<&'static str>, ImportError>;
pub mod create_note; pub mod create_note;
pub mod update_note; pub mod update_note;
pub mod update_person; pub mod update_person;

View file

@ -2,28 +2,29 @@ use chrono::Utc;
use tokio_postgres::GenericClient; use tokio_postgres::GenericClient;
use crate::activitypub::activity::Object; use crate::activitypub::activity::Object;
use crate::activitypub::fetcher::helpers::ImportError;
use crate::activitypub::receiver::parse_object_id; use crate::activitypub::receiver::parse_object_id;
use crate::activitypub::vocabulary::NOTE;
use crate::errors::DatabaseError; use crate::errors::DatabaseError;
use crate::models::posts::queries::{ use crate::models::posts::queries::{
get_post_by_object_id, get_post_by_object_id,
update_post, update_post,
}; };
use crate::models::posts::types::PostUpdateData; use crate::models::posts::types::PostUpdateData;
use super::HandlerResult;
use super::create_note::get_note_content; use super::create_note::get_note_content;
pub async fn handle_update_note( pub async fn handle_update_note(
db_client: &mut impl GenericClient, db_client: &mut impl GenericClient,
instance_url: &str, instance_url: &str,
object: Object, object: Object,
) -> Result<(), ImportError> { ) -> HandlerResult {
let post_id = match parse_object_id(instance_url, &object.id) { let post_id = match parse_object_id(instance_url, &object.id) {
Ok(post_id) => post_id, Ok(post_id) => post_id,
Err(_) => { Err(_) => {
let post = match get_post_by_object_id(db_client, &object.id).await { let post = match get_post_by_object_id(db_client, &object.id).await {
Ok(post) => post, Ok(post) => post,
// Ignore Update if post is not found locally // Ignore Update if post is not found locally
Err(DatabaseError::NotFound(_)) => return Ok(()), Err(DatabaseError::NotFound(_)) => return Ok(None),
Err(other_error) => return Err(other_error.into()), Err(other_error) => return Err(other_error.into()),
}; };
post.id post.id
@ -33,5 +34,5 @@ pub async fn handle_update_note(
let updated_at = object.updated.unwrap_or(Utc::now()); let updated_at = object.updated.unwrap_or(Utc::now());
let post_data = PostUpdateData { content, updated_at }; let post_data = PostUpdateData { content, updated_at };
update_post(db_client, &post_id, post_data).await?; update_post(db_client, &post_id, post_data).await?;
Ok(()) Ok(Some(NOTE))
} }

View file

@ -7,6 +7,7 @@ use crate::activitypub::{
actor::Actor, actor::Actor,
fetcher::fetchers::fetch_avatar_and_banner, fetcher::fetchers::fetch_avatar_and_banner,
fetcher::helpers::ImportError, fetcher::helpers::ImportError,
vocabulary::PERSON,
}; };
use crate::errors::ValidationError; use crate::errors::ValidationError;
use crate::models::profiles::queries::{ use crate::models::profiles::queries::{
@ -14,18 +15,20 @@ use crate::models::profiles::queries::{
update_profile, update_profile,
}; };
use crate::models::profiles::types::ProfileUpdateData; use crate::models::profiles::types::ProfileUpdateData;
use super::HandlerResult;
pub async fn handle_update_person( pub async fn handle_update_person(
db_client: &impl GenericClient, db_client: &impl GenericClient,
media_dir: &Path, media_dir: &Path,
activity: Activity, activity: Activity,
) -> Result<(), ImportError> { ) -> HandlerResult {
let actor: Actor = serde_json::from_value(activity.object) let actor: Actor = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid actor data"))?; .map_err(|_| ValidationError("invalid actor data"))?;
if actor.id != activity.actor { if actor.id != activity.actor {
return Err(ValidationError("actor ID mismatch").into()); return Err(ValidationError("actor ID mismatch").into());
}; };
update_actor(db_client, media_dir, actor).await update_actor(db_client, media_dir, actor).await?;
Ok(Some(PERSON))
} }
pub async fn update_actor( pub async fn update_actor(

View file

@ -194,7 +194,7 @@ pub async fn receive_activity(
return Err(HttpError::ValidationError("instance is blocked".into())); return Err(HttpError::ValidationError("instance is blocked".into()));
}; };
let object_type = match (activity_type.as_str(), maybe_object_type) { let maybe_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)?;
let actor_profile = get_profile_by_actor_id(db_client, &activity.actor).await?; let actor_profile = get_profile_by_actor_id(db_client, &activity.actor).await?;
@ -205,7 +205,7 @@ pub async fn receive_activity(
return Err(HttpError::ValidationError("actor is not a target".into())); return Err(HttpError::ValidationError("actor is not a target".into()));
}; };
follow_request_accepted(db_client, &follow_request_id).await?; follow_request_accepted(db_client, &follow_request_id).await?;
FOLLOW Some(FOLLOW)
}, },
(REJECT, FOLLOW) => { (REJECT, FOLLOW) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -217,7 +217,7 @@ pub async fn receive_activity(
return Err(HttpError::ValidationError("actor is not a target".into())); return Err(HttpError::ValidationError("actor is not a target".into()));
}; };
follow_request_rejected(db_client, &follow_request_id).await?; follow_request_rejected(db_client, &follow_request_id).await?;
FOLLOW Some(FOLLOW)
}, },
(CREATE, NOTE | QUESTION | PAGE) => { (CREATE, NOTE | QUESTION | PAGE) => {
let object: Object = serde_json::from_value(activity.object) let object: Object = serde_json::from_value(activity.object)
@ -230,7 +230,7 @@ pub async fn receive_activity(
None None
}; };
import_post(config, db_client, object_id, object_received).await?; import_post(config, db_client, object_id, object_received).await?;
NOTE Some(NOTE)
}, },
(ANNOUNCE, _) => { (ANNOUNCE, _) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -261,7 +261,7 @@ pub async fn receive_activity(
..Default::default() ..Default::default()
}; };
create_post(db_client, &author.id, repost_data).await?; create_post(db_client, &author.id, repost_data).await?;
NOTE Some(NOTE)
}, },
(DELETE, _) => { (DELETE, _) => {
if signer_id != activity.actor { if signer_id != activity.actor {
@ -289,7 +289,7 @@ pub async fn receive_activity(
actix_rt::spawn(async move { actix_rt::spawn(async move {
deletion_queue.process(&config).await; deletion_queue.process(&config).await;
}); });
NOTE Some(NOTE)
}, },
(EMOJI_REACT | LIKE, _) => { (EMOJI_REACT | LIKE, _) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -323,7 +323,7 @@ pub async fn receive_activity(
Err(DatabaseError::AlreadyExists(_)) => return Ok(()), Err(DatabaseError::AlreadyExists(_)) => return Ok(()),
Err(other_error) => return Err(other_error.into()), Err(other_error) => return Err(other_error.into()),
}; };
NOTE Some(NOTE)
}, },
(FOLLOW, _) => { (FOLLOW, _) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -354,7 +354,7 @@ pub async fn receive_activity(
); );
let recipients = vec![source_actor]; let recipients = vec![source_actor];
deliver_activity(config, &target_user, new_activity, recipients); deliver_activity(config, &target_user, new_activity, recipients);
PERSON Some(PERSON)
}, },
(UNDO, FOLLOW) => { (UNDO, FOLLOW) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -371,7 +371,7 @@ pub async fn receive_activity(
Err(DatabaseError::NotFound(_)) => return Ok(()), Err(DatabaseError::NotFound(_)) => return Ok(()),
Err(other_error) => return Err(other_error.into()), Err(other_error) => return Err(other_error.into()),
}; };
FOLLOW Some(FOLLOW)
}, },
(UNDO, _) => { (UNDO, _) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -388,7 +388,7 @@ pub async fn receive_activity(
&reaction.author_id, &reaction.author_id,
&reaction.post_id, &reaction.post_id,
).await?; ).await?;
LIKE Some(LIKE)
}, },
Err(DatabaseError::NotFound(_)) => { Err(DatabaseError::NotFound(_)) => {
// Undo(Announce) // Undo(Announce)
@ -407,7 +407,7 @@ pub async fn receive_activity(
// Can't undo regular post // Can't undo regular post
None => return Err(HttpError::ValidationError("object is not a repost".into())), None => return Err(HttpError::ValidationError("object is not a repost".into())),
}; };
ANNOUNCE Some(ANNOUNCE)
}, },
Err(other_error) => return Err(other_error.into()), Err(other_error) => return Err(other_error.into()),
} }
@ -416,8 +416,7 @@ pub async fn receive_activity(
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
let object: Object = serde_json::from_value(activity.object) let object: Object = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid object"))?; .map_err(|_| ValidationError("invalid object"))?;
handle_update_note(db_client, &config.instance_url(), object).await?; handle_update_note(db_client, &config.instance_url(), object).await?
NOTE
}, },
(UPDATE, PERSON) => { (UPDATE, PERSON) => {
require_actor_signature(&activity.actor, &signer_id)?; require_actor_signature(&activity.actor, &signer_id)?;
@ -425,20 +424,21 @@ pub async fn receive_activity(
db_client, db_client,
&config.media_dir(), &config.media_dir(),
activity, activity,
).await?; ).await?
PERSON
}, },
_ => { _ => {
log::warn!("activity type is not supported: {}", activity_raw); log::warn!("activity type is not supported: {}", activity_raw);
return Ok(()); return Ok(());
}, },
}; };
log::info!( if let Some(object_type) = maybe_object_type {
"processed {}({}) from {}", log::info!(
activity_type, "processed {}({}) from {}",
object_type, activity_type,
activity_actor, object_type,
); activity_actor,
);
};
Ok(()) Ok(())
} }