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 tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::activity::Object;
|
use crate::activitypub::{
|
||||||
use crate::activitypub::actors::types::{Actor, ActorAddress};
|
activity::Object,
|
||||||
use crate::activitypub::handlers::{
|
actors::types::{Actor, ActorAddress},
|
||||||
|
handlers::{
|
||||||
create_note::handle_note,
|
create_note::handle_note,
|
||||||
update_person::update_remote_profile,
|
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::config::{Config, Instance};
|
||||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
use crate::errors::{DatabaseError, ValidationError};
|
||||||
use crate::http_signatures::verify::VerificationError;
|
|
||||||
use crate::models::posts::queries::{
|
use crate::models::posts::queries::{
|
||||||
get_post_by_id,
|
get_post_by_id,
|
||||||
get_post_by_remote_object_id,
|
get_post_by_remote_object_id,
|
||||||
|
@ -29,52 +31,17 @@ use super::fetchers::{
|
||||||
fetch_actor_images,
|
fetch_actor_images,
|
||||||
fetch_object,
|
fetch_object,
|
||||||
perform_webfinger_query,
|
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(
|
async fn create_remote_profile(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
actor: Actor,
|
actor: Actor,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, HandlerError> {
|
||||||
let actor_address = actor.address()?;
|
let actor_address = actor.address()?;
|
||||||
if actor_address.is_local(&instance.host()) {
|
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()
|
let maybe_also_known_as = actor.also_known_as.as_ref()
|
||||||
.and_then(|aliases| aliases.first());
|
.and_then(|aliases| aliases.first());
|
||||||
|
@ -112,9 +79,9 @@ pub async fn get_or_import_profile_by_actor_id(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
actor_id: &str,
|
actor_id: &str,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, HandlerError> {
|
||||||
if actor_id.starts_with(&instance.url()) {
|
if actor_id.starts_with(&instance.url()) {
|
||||||
return Err(ImportError::LocalObject);
|
return Err(HandlerError::LocalObject);
|
||||||
};
|
};
|
||||||
let profile = match get_profile_by_remote_actor_id(
|
let profile = match get_profile_by_remote_actor_id(
|
||||||
db_client,
|
db_client,
|
||||||
|
@ -188,9 +155,9 @@ pub async fn import_profile_by_actor_address(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
actor_address: &ActorAddress,
|
actor_address: &ActorAddress,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, HandlerError> {
|
||||||
if actor_address.hostname == instance.host() {
|
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_id = perform_webfinger_query(instance, actor_address).await?;
|
||||||
let actor = fetch_actor(instance, &actor_id).await?;
|
let actor = fetch_actor(instance, &actor_id).await?;
|
||||||
|
@ -218,11 +185,11 @@ pub async fn import_post(
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
object_id: String,
|
object_id: String,
|
||||||
object_received: Option<Object>,
|
object_received: Option<Object>,
|
||||||
) -> Result<Post, ImportError> {
|
) -> Result<Post, HandlerError> {
|
||||||
let instance = config.instance();
|
let instance = config.instance();
|
||||||
let media_dir = config.media_dir();
|
let media_dir = config.media_dir();
|
||||||
if parse_local_object_id(&instance.url(), &object_id).is_ok() {
|
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
|
let mut queue = vec![object_id]; // LIFO queue
|
||||||
|
|
|
@ -2,7 +2,6 @@ use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::{
|
use crate::activitypub::{
|
||||||
activity::Activity,
|
activity::Activity,
|
||||||
fetcher::helpers::ImportError,
|
|
||||||
identifiers::parse_local_actor_id,
|
identifiers::parse_local_actor_id,
|
||||||
receiver::find_object_id,
|
receiver::find_object_id,
|
||||||
vocabulary::PERSON,
|
vocabulary::PERSON,
|
||||||
|
@ -12,7 +11,7 @@ use crate::errors::ValidationError;
|
||||||
use crate::models::profiles::queries::get_profile_by_remote_actor_id;
|
use crate::models::profiles::queries::get_profile_by_remote_actor_id;
|
||||||
use crate::models::relationships::queries::subscribe_opt;
|
use crate::models::relationships::queries::subscribe_opt;
|
||||||
use crate::models::users::queries::get_user_by_name;
|
use crate::models::users::queries::get_user_by_name;
|
||||||
use super::HandlerResult;
|
use super::{HandlerError, HandlerResult};
|
||||||
|
|
||||||
pub async fn handle_add(
|
pub async fn handle_add(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
@ -23,7 +22,7 @@ pub async fn handle_add(
|
||||||
db_client,
|
db_client,
|
||||||
&activity.actor,
|
&activity.actor,
|
||||||
).await?;
|
).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_value = activity.target.ok_or(ValidationError("target is missing"))?;
|
||||||
let target_id = find_object_id(&target_value)?;
|
let target_id = find_object_id(&target_value)?;
|
||||||
if Some(target_id) == actor.subscribers {
|
if Some(target_id) == actor.subscribers {
|
||||||
|
|
|
@ -13,10 +13,9 @@ use crate::activitypub::{
|
||||||
fetcher::helpers::{
|
fetcher::helpers::{
|
||||||
get_or_import_profile_by_actor_id,
|
get_or_import_profile_by_actor_id,
|
||||||
import_profile_by_actor_address,
|
import_profile_by_actor_address,
|
||||||
ImportError,
|
|
||||||
},
|
},
|
||||||
identifiers::parse_local_actor_id,
|
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},
|
vocabulary::{DOCUMENT, HASHTAG, IMAGE, LINK, MENTION, NOTE},
|
||||||
};
|
};
|
||||||
use crate::config::Instance;
|
use crate::config::Instance;
|
||||||
|
@ -125,7 +124,7 @@ pub async fn handle_note(
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
object: Object,
|
object: Object,
|
||||||
redirects: &HashMap<String, String>,
|
redirects: &HashMap<String, String>,
|
||||||
) -> Result<Post, ImportError> {
|
) -> Result<Post, HandlerError> {
|
||||||
if object.object_type != NOTE {
|
if object.object_type != NOTE {
|
||||||
// Could be Page (in Lemmy) or some other type
|
// Could be Page (in Lemmy) or some other type
|
||||||
log::warn!("processing object of type {}", object.object_type);
|
log::warn!("processing object of type {}", object.object_type);
|
||||||
|
@ -267,7 +266,7 @@ pub async fn handle_note(
|
||||||
&actor_address,
|
&actor_address,
|
||||||
).await {
|
).await {
|
||||||
Ok(profile) => profile,
|
Ok(profile) => profile,
|
||||||
Err(ImportError::FetchError(error)) => {
|
Err(HandlerError::FetchError(error)) => {
|
||||||
// Ignore mention if fetcher fails
|
// Ignore mention if fetcher fails
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"failed to find mentioned profile {}: {}",
|
"failed to find mentioned profile {}: {}",
|
||||||
|
|
|
@ -3,7 +3,7 @@ use tokio_postgres::GenericClient;
|
||||||
use crate::activitypub::{
|
use crate::activitypub::{
|
||||||
activity::Activity,
|
activity::Activity,
|
||||||
builders::accept_follow::prepare_accept_follow,
|
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,
|
identifiers::parse_local_actor_id,
|
||||||
receiver::find_object_id,
|
receiver::find_object_id,
|
||||||
vocabulary::PERSON,
|
vocabulary::PERSON,
|
||||||
|
@ -12,7 +12,7 @@ use crate::config::Config;
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
use crate::models::relationships::queries::follow;
|
use crate::models::relationships::queries::follow;
|
||||||
use crate::models::users::queries::get_user_by_name;
|
use crate::models::users::queries::get_user_by_name;
|
||||||
use super::HandlerResult;
|
use super::{HandlerError, HandlerResult};
|
||||||
|
|
||||||
pub async fn handle_follow(
|
pub async fn handle_follow(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
@ -26,7 +26,7 @@ pub async fn handle_follow(
|
||||||
&activity.actor,
|
&activity.actor,
|
||||||
).await?;
|
).await?;
|
||||||
let source_actor = source_profile.actor_json
|
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_actor_id = find_object_id(&activity.object)?;
|
||||||
let target_username = parse_local_actor_id(
|
let target_username = parse_local_actor_id(
|
||||||
&config.instance_url(),
|
&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
|
// Handlers should return object type if activity has been accepted
|
||||||
// or None if it has been ignored
|
// 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 accept_follow;
|
||||||
pub mod add;
|
pub mod add;
|
||||||
|
|
|
@ -2,7 +2,6 @@ use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::{
|
use crate::activitypub::{
|
||||||
activity::Activity,
|
activity::Activity,
|
||||||
fetcher::helpers::ImportError,
|
|
||||||
identifiers::parse_local_actor_id,
|
identifiers::parse_local_actor_id,
|
||||||
receiver::find_object_id,
|
receiver::find_object_id,
|
||||||
vocabulary::PERSON,
|
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::profiles::queries::get_profile_by_remote_actor_id;
|
||||||
use crate::models::relationships::queries::unsubscribe;
|
use crate::models::relationships::queries::unsubscribe;
|
||||||
use crate::models::users::queries::get_user_by_name;
|
use crate::models::users::queries::get_user_by_name;
|
||||||
use super::HandlerResult;
|
use super::{HandlerError, HandlerResult};
|
||||||
|
|
||||||
pub async fn handle_remove(
|
pub async fn handle_remove(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
@ -26,7 +25,7 @@ pub async fn handle_remove(
|
||||||
db_client,
|
db_client,
|
||||||
&activity.actor,
|
&activity.actor,
|
||||||
).await?;
|
).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_value = activity.target.ok_or(ValidationError("target is missing"))?;
|
||||||
let target_id = find_object_id(&target_value)?;
|
let target_id = find_object_id(&target_value)?;
|
||||||
if Some(target_id) == actor.subscribers {
|
if Some(target_id) == actor.subscribers {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::activitypub::{
|
||||||
activity::Activity,
|
activity::Activity,
|
||||||
actors::types::Actor,
|
actors::types::Actor,
|
||||||
fetcher::fetchers::fetch_actor_images,
|
fetcher::fetchers::fetch_actor_images,
|
||||||
fetcher::helpers::ImportError,
|
|
||||||
vocabulary::PERSON,
|
vocabulary::PERSON,
|
||||||
};
|
};
|
||||||
use crate::config::{Config, Instance};
|
use crate::config::{Config, Instance};
|
||||||
|
@ -16,7 +15,7 @@ use crate::models::profiles::queries::{
|
||||||
update_profile,
|
update_profile,
|
||||||
};
|
};
|
||||||
use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData};
|
use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData};
|
||||||
use super::HandlerResult;
|
use super::{HandlerError, HandlerResult};
|
||||||
|
|
||||||
pub async fn handle_update_person(
|
pub async fn handle_update_person(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
@ -49,8 +48,8 @@ pub async fn update_remote_profile(
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
profile: DbActorProfile,
|
profile: DbActorProfile,
|
||||||
actor: Actor,
|
actor: Actor,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, HandlerError> {
|
||||||
let actor_old = profile.actor_json.ok_or(ImportError::LocalObject)?;
|
let actor_old = profile.actor_json.ok_or(HandlerError::LocalObject)?;
|
||||||
if actor_old.id != actor.id {
|
if actor_old.id != actor.id {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"actor ID changed from {} to {}",
|
"actor ID changed from {} to {}",
|
||||||
|
|
|
@ -4,13 +4,21 @@ use serde_json::Value;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::errors::{ConversionError, ValidationError};
|
use crate::errors::{
|
||||||
|
ConversionError,
|
||||||
|
DatabaseError,
|
||||||
|
HttpError,
|
||||||
|
ValidationError,
|
||||||
|
};
|
||||||
use crate::http_signatures::verify::{
|
use crate::http_signatures::verify::{
|
||||||
verify_signed_request,
|
verify_signed_request,
|
||||||
VerificationError,
|
VerificationError,
|
||||||
};
|
};
|
||||||
use super::activity::{Activity, Object};
|
use super::activity::{Activity, Object};
|
||||||
use super::fetcher::helpers::{import_post, ImportError};
|
use super::fetcher::{
|
||||||
|
fetchers::FetchError,
|
||||||
|
helpers::import_post,
|
||||||
|
};
|
||||||
use super::handlers::{
|
use super::handlers::{
|
||||||
accept_follow::handle_accept_follow,
|
accept_follow::handle_accept_follow,
|
||||||
add::handle_add,
|
add::handle_add,
|
||||||
|
@ -28,6 +36,40 @@ use super::handlers::{
|
||||||
};
|
};
|
||||||
use super::vocabulary::*;
|
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
|
/// Transforms arbitrary property value into array of strings
|
||||||
pub fn parse_array(value: &Value) -> Result<Vec<String>, ConversionError> {
|
pub fn parse_array(value: &Value) -> Result<Vec<String>, ConversionError> {
|
||||||
let result = match value {
|
let result = match value {
|
||||||
|
@ -108,7 +150,7 @@ pub async fn receive_activity(
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
request: &HttpRequest,
|
request: &HttpRequest,
|
||||||
activity_raw: &Value,
|
activity_raw: &Value,
|
||||||
) -> Result<(), ImportError> {
|
) -> Result<(), HandlerError> {
|
||||||
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();
|
||||||
|
|
|
@ -9,9 +9,9 @@ use regex::Regex;
|
||||||
use rsa::RsaPublicKey;
|
use rsa::RsaPublicKey;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::fetcher::helpers::{
|
use crate::activitypub::{
|
||||||
get_or_import_profile_by_actor_id,
|
fetcher::helpers::get_or_import_profile_by_actor_id,
|
||||||
ImportError,
|
handlers::HandlerError,
|
||||||
};
|
};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
|
@ -183,7 +183,7 @@ pub async fn verify_signed_request(
|
||||||
&actor_id,
|
&actor_id,
|
||||||
).await {
|
).await {
|
||||||
Ok(profile) => profile,
|
Ok(profile) => profile,
|
||||||
Err(ImportError::DatabaseError(error)) => return Err(error.into()),
|
Err(HandlerError::DatabaseError(error)) => return Err(error.into()),
|
||||||
Err(other_error) => {
|
Err(other_error) => {
|
||||||
return Err(VerificationError::ActorError(other_error.to_string()));
|
return Err(VerificationError::ActorError(other_error.to_string()));
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue