Rename ImportError to HandlerError
This commit is contained in:
parent
1e575b2f6f
commit
256e225742
9 changed files with 82 additions and 77 deletions
|
@ -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<ImportError> 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<DbActorProfile, ImportError> {
|
||||
) -> Result<DbActorProfile, HandlerError> {
|
||||
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<DbActorProfile, ImportError> {
|
||||
) -> Result<DbActorProfile, HandlerError> {
|
||||
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<DbActorProfile, ImportError> {
|
||||
) -> Result<DbActorProfile, HandlerError> {
|
||||
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<Object>,
|
||||
) -> Result<Post, ImportError> {
|
||||
) -> Result<Post, HandlerError> {
|
||||
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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<String, String>,
|
||||
) -> Result<Post, ImportError> {
|
||||
) -> Result<Post, HandlerError> {
|
||||
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 {}: {}",
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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<Option<&'static str>, ImportError>;
|
||||
pub type HandlerResult = Result<Option<&'static str>, HandlerError>;
|
||||
|
||||
pub mod accept_follow;
|
||||
pub mod add;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<DbActorProfile, ImportError> {
|
||||
let actor_old = profile.actor_json.ok_or(ImportError::LocalObject)?;
|
||||
) -> Result<DbActorProfile, HandlerError> {
|
||||
let actor_old = profile.actor_json.ok_or(HandlerError::LocalObject)?;
|
||||
if actor_old.id != actor.id {
|
||||
log::warn!(
|
||||
"actor ID changed from {} to {}",
|
||||
|
|
|
@ -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<HandlerError> 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<Vec<String>, 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();
|
||||
|
|
|
@ -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()));
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue