From 256e22574270f1e64520332543233ebd71a037e3 Mon Sep 17 00:00:00 2001 From: silverpill Date: Sun, 23 Oct 2022 22:18:01 +0000 Subject: [PATCH] Rename ImportError to HandlerError --- src/activitypub/fetcher/helpers.rs | 69 ++++++----------------- src/activitypub/handlers/add.rs | 5 +- src/activitypub/handlers/create_note.rs | 7 +-- src/activitypub/handlers/follow.rs | 6 +- src/activitypub/handlers/mod.rs | 4 +- src/activitypub/handlers/remove.rs | 5 +- src/activitypub/handlers/update_person.rs | 7 +-- src/activitypub/receiver.rs | 48 +++++++++++++++- src/http_signatures/verify.rs | 8 +-- 9 files changed, 82 insertions(+), 77 deletions(-) diff --git a/src/activitypub/fetcher/helpers.rs b/src/activitypub/fetcher/helpers.rs index 0396f68..96fa5f6 100644 --- a/src/activitypub/fetcher/helpers.rs +++ b/src/activitypub/fetcher/helpers.rs @@ -3,16 +3,18 @@ use std::path::Path; use tokio_postgres::GenericClient; -use crate::activitypub::activity::Object; -use crate::activitypub::actors::types::{Actor, ActorAddress}; -use crate::activitypub::handlers::{ - create_note::handle_note, - update_person::update_remote_profile, +use crate::activitypub::{ + activity::Object, + actors::types::{Actor, ActorAddress}, + handlers::{ + create_note::handle_note, + update_person::update_remote_profile, + }, + identifiers::parse_local_object_id, + receiver::HandlerError, }; -use crate::activitypub::identifiers::parse_local_object_id; use crate::config::{Config, Instance}; -use crate::errors::{DatabaseError, HttpError, ValidationError}; -use crate::http_signatures::verify::VerificationError; +use crate::errors::{DatabaseError, ValidationError}; use crate::models::posts::queries::{ get_post_by_id, get_post_by_remote_object_id, @@ -29,52 +31,17 @@ use super::fetchers::{ fetch_actor_images, fetch_object, perform_webfinger_query, - FetchError, }; -#[derive(thiserror::Error, Debug)] -pub enum ImportError { - #[error("local object")] - LocalObject, - - #[error(transparent)] - FetchError(#[from] FetchError), - - #[error(transparent)] - ValidationError(#[from] ValidationError), - - #[error(transparent)] - DatabaseError(#[from] DatabaseError), - - #[error(transparent)] - AuthError(#[from] VerificationError), -} - -impl From for HttpError { - fn from(error: ImportError) -> Self { - match error { - ImportError::LocalObject => HttpError::InternalError, - ImportError::FetchError(error) => { - HttpError::ValidationError(error.to_string()) - }, - ImportError::ValidationError(error) => error.into(), - ImportError::DatabaseError(error) => error.into(), - ImportError::AuthError(_) => { - HttpError::AuthError("invalid signature") - }, - } - } -} - async fn create_remote_profile( db_client: &impl GenericClient, instance: &Instance, media_dir: &Path, actor: Actor, -) -> Result { +) -> Result { let actor_address = actor.address()?; if actor_address.is_local(&instance.host()) { - return Err(ImportError::LocalObject); + return Err(HandlerError::LocalObject); }; let maybe_also_known_as = actor.also_known_as.as_ref() .and_then(|aliases| aliases.first()); @@ -112,9 +79,9 @@ pub async fn get_or_import_profile_by_actor_id( instance: &Instance, media_dir: &Path, actor_id: &str, -) -> Result { +) -> Result { if actor_id.starts_with(&instance.url()) { - return Err(ImportError::LocalObject); + return Err(HandlerError::LocalObject); }; let profile = match get_profile_by_remote_actor_id( db_client, @@ -188,9 +155,9 @@ pub async fn import_profile_by_actor_address( instance: &Instance, media_dir: &Path, actor_address: &ActorAddress, -) -> Result { +) -> Result { if actor_address.hostname == instance.host() { - return Err(ImportError::LocalObject); + return Err(HandlerError::LocalObject); }; let actor_id = perform_webfinger_query(instance, actor_address).await?; let actor = fetch_actor(instance, &actor_id).await?; @@ -218,11 +185,11 @@ pub async fn import_post( db_client: &mut impl GenericClient, object_id: String, object_received: Option, -) -> Result { +) -> Result { let instance = config.instance(); let media_dir = config.media_dir(); if parse_local_object_id(&instance.url(), &object_id).is_ok() { - return Err(ImportError::LocalObject); + return Err(HandlerError::LocalObject); }; let mut queue = vec![object_id]; // LIFO queue diff --git a/src/activitypub/handlers/add.rs b/src/activitypub/handlers/add.rs index c096d97..de80b42 100644 --- a/src/activitypub/handlers/add.rs +++ b/src/activitypub/handlers/add.rs @@ -2,7 +2,6 @@ use tokio_postgres::GenericClient; use crate::activitypub::{ activity::Activity, - fetcher::helpers::ImportError, identifiers::parse_local_actor_id, receiver::find_object_id, vocabulary::PERSON, @@ -12,7 +11,7 @@ use crate::errors::ValidationError; use crate::models::profiles::queries::get_profile_by_remote_actor_id; use crate::models::relationships::queries::subscribe_opt; use crate::models::users::queries::get_user_by_name; -use super::HandlerResult; +use super::{HandlerError, HandlerResult}; pub async fn handle_add( config: &Config, @@ -23,7 +22,7 @@ pub async fn handle_add( db_client, &activity.actor, ).await?; - let actor = actor_profile.actor_json.ok_or(ImportError::LocalObject)?; + let actor = actor_profile.actor_json.ok_or(HandlerError::LocalObject)?; let target_value = activity.target.ok_or(ValidationError("target is missing"))?; let target_id = find_object_id(&target_value)?; if Some(target_id) == actor.subscribers { diff --git a/src/activitypub/handlers/create_note.rs b/src/activitypub/handlers/create_note.rs index f66b22f..12713b4 100644 --- a/src/activitypub/handlers/create_note.rs +++ b/src/activitypub/handlers/create_note.rs @@ -13,10 +13,9 @@ use crate::activitypub::{ fetcher::helpers::{ get_or_import_profile_by_actor_id, import_profile_by_actor_address, - ImportError, }, identifiers::parse_local_actor_id, - receiver::{parse_array, parse_property_value}, + receiver::{parse_array, parse_property_value, HandlerError}, vocabulary::{DOCUMENT, HASHTAG, IMAGE, LINK, MENTION, NOTE}, }; use crate::config::Instance; @@ -125,7 +124,7 @@ pub async fn handle_note( media_dir: &Path, object: Object, redirects: &HashMap, -) -> Result { +) -> Result { if object.object_type != NOTE { // Could be Page (in Lemmy) or some other type log::warn!("processing object of type {}", object.object_type); @@ -267,7 +266,7 @@ pub async fn handle_note( &actor_address, ).await { Ok(profile) => profile, - Err(ImportError::FetchError(error)) => { + Err(HandlerError::FetchError(error)) => { // Ignore mention if fetcher fails log::warn!( "failed to find mentioned profile {}: {}", diff --git a/src/activitypub/handlers/follow.rs b/src/activitypub/handlers/follow.rs index a1c4c91..fb827bc 100644 --- a/src/activitypub/handlers/follow.rs +++ b/src/activitypub/handlers/follow.rs @@ -3,7 +3,7 @@ use tokio_postgres::GenericClient; use crate::activitypub::{ activity::Activity, builders::accept_follow::prepare_accept_follow, - fetcher::helpers::{get_or_import_profile_by_actor_id, ImportError}, + fetcher::helpers::get_or_import_profile_by_actor_id, identifiers::parse_local_actor_id, receiver::find_object_id, vocabulary::PERSON, @@ -12,7 +12,7 @@ use crate::config::Config; use crate::errors::DatabaseError; use crate::models::relationships::queries::follow; use crate::models::users::queries::get_user_by_name; -use super::HandlerResult; +use super::{HandlerError, HandlerResult}; pub async fn handle_follow( config: &Config, @@ -26,7 +26,7 @@ pub async fn handle_follow( &activity.actor, ).await?; let source_actor = source_profile.actor_json - .ok_or(ImportError::LocalObject)?; + .ok_or(HandlerError::LocalObject)?; let target_actor_id = find_object_id(&activity.object)?; let target_username = parse_local_actor_id( &config.instance_url(), diff --git a/src/activitypub/handlers/mod.rs b/src/activitypub/handlers/mod.rs index 1e66315..56b624f 100644 --- a/src/activitypub/handlers/mod.rs +++ b/src/activitypub/handlers/mod.rs @@ -1,7 +1,7 @@ -use super::fetcher::helpers::ImportError; +pub use super::receiver::HandlerError; // Handlers should return object type if activity has been accepted // or None if it has been ignored -pub type HandlerResult = Result, ImportError>; +pub type HandlerResult = Result, HandlerError>; pub mod accept_follow; pub mod add; diff --git a/src/activitypub/handlers/remove.rs b/src/activitypub/handlers/remove.rs index 7059f37..50cae08 100644 --- a/src/activitypub/handlers/remove.rs +++ b/src/activitypub/handlers/remove.rs @@ -2,7 +2,6 @@ use tokio_postgres::GenericClient; use crate::activitypub::{ activity::Activity, - fetcher::helpers::ImportError, identifiers::parse_local_actor_id, receiver::find_object_id, vocabulary::PERSON, @@ -15,7 +14,7 @@ use crate::models::notifications::queries::{ use crate::models::profiles::queries::get_profile_by_remote_actor_id; use crate::models::relationships::queries::unsubscribe; use crate::models::users::queries::get_user_by_name; -use super::HandlerResult; +use super::{HandlerError, HandlerResult}; pub async fn handle_remove( config: &Config, @@ -26,7 +25,7 @@ pub async fn handle_remove( db_client, &activity.actor, ).await?; - let actor = actor_profile.actor_json.ok_or(ImportError::LocalObject)?; + let actor = actor_profile.actor_json.ok_or(HandlerError::LocalObject)?; let target_value = activity.target.ok_or(ValidationError("target is missing"))?; let target_id = find_object_id(&target_value)?; if Some(target_id) == actor.subscribers { diff --git a/src/activitypub/handlers/update_person.rs b/src/activitypub/handlers/update_person.rs index 7d03593..0f7ff13 100644 --- a/src/activitypub/handlers/update_person.rs +++ b/src/activitypub/handlers/update_person.rs @@ -6,7 +6,6 @@ use crate::activitypub::{ activity::Activity, actors::types::Actor, fetcher::fetchers::fetch_actor_images, - fetcher::helpers::ImportError, vocabulary::PERSON, }; use crate::config::{Config, Instance}; @@ -16,7 +15,7 @@ use crate::models::profiles::queries::{ update_profile, }; use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData}; -use super::HandlerResult; +use super::{HandlerError, HandlerResult}; pub async fn handle_update_person( config: &Config, @@ -49,8 +48,8 @@ pub async fn update_remote_profile( media_dir: &Path, profile: DbActorProfile, actor: Actor, -) -> Result { - let actor_old = profile.actor_json.ok_or(ImportError::LocalObject)?; +) -> Result { + let actor_old = profile.actor_json.ok_or(HandlerError::LocalObject)?; if actor_old.id != actor.id { log::warn!( "actor ID changed from {} to {}", diff --git a/src/activitypub/receiver.rs b/src/activitypub/receiver.rs index ef7ee38..1b8a281 100644 --- a/src/activitypub/receiver.rs +++ b/src/activitypub/receiver.rs @@ -4,13 +4,21 @@ use serde_json::Value; use tokio_postgres::GenericClient; use crate::config::Config; -use crate::errors::{ConversionError, ValidationError}; +use crate::errors::{ + ConversionError, + DatabaseError, + HttpError, + ValidationError, +}; use crate::http_signatures::verify::{ verify_signed_request, VerificationError, }; use super::activity::{Activity, Object}; -use super::fetcher::helpers::{import_post, ImportError}; +use super::fetcher::{ + fetchers::FetchError, + helpers::import_post, +}; use super::handlers::{ accept_follow::handle_accept_follow, add::handle_add, @@ -28,6 +36,40 @@ use super::handlers::{ }; use super::vocabulary::*; +#[derive(thiserror::Error, Debug)] +pub enum HandlerError { + #[error("local object")] + LocalObject, + + #[error(transparent)] + FetchError(#[from] FetchError), + + #[error(transparent)] + ValidationError(#[from] ValidationError), + + #[error(transparent)] + DatabaseError(#[from] DatabaseError), + + #[error(transparent)] + AuthError(#[from] VerificationError), +} + +impl From for HttpError { + fn from(error: HandlerError) -> Self { + match error { + HandlerError::LocalObject => HttpError::InternalError, + HandlerError::FetchError(error) => { + HttpError::ValidationError(error.to_string()) + }, + HandlerError::ValidationError(error) => error.into(), + HandlerError::DatabaseError(error) => error.into(), + HandlerError::AuthError(_) => { + HttpError::AuthError("invalid signature") + }, + } + } +} + /// Transforms arbitrary property value into array of strings pub fn parse_array(value: &Value) -> Result, ConversionError> { let result = match value { @@ -108,7 +150,7 @@ pub async fn receive_activity( db_client: &mut impl GenericClient, request: &HttpRequest, activity_raw: &Value, -) -> Result<(), ImportError> { +) -> Result<(), HandlerError> { let activity: Activity = serde_json::from_value(activity_raw.clone()) .map_err(|_| ValidationError("invalid activity"))?; let activity_type = activity.activity_type.clone(); diff --git a/src/http_signatures/verify.rs b/src/http_signatures/verify.rs index 4bad8a6..e8737e1 100644 --- a/src/http_signatures/verify.rs +++ b/src/http_signatures/verify.rs @@ -9,9 +9,9 @@ use regex::Regex; use rsa::RsaPublicKey; use tokio_postgres::GenericClient; -use crate::activitypub::fetcher::helpers::{ - get_or_import_profile_by_actor_id, - ImportError, +use crate::activitypub::{ + fetcher::helpers::get_or_import_profile_by_actor_id, + handlers::HandlerError, }; use crate::config::Config; use crate::errors::DatabaseError; @@ -183,7 +183,7 @@ pub async fn verify_signed_request( &actor_id, ).await { Ok(profile) => profile, - Err(ImportError::DatabaseError(error)) => return Err(error.into()), + Err(HandlerError::DatabaseError(error)) => return Err(error.into()), Err(other_error) => { return Err(VerificationError::ActorError(other_error.to_string())); },