Reorganize handlers and remove unneeded modules

This commit is contained in:
silverpill 2022-12-09 20:15:24 +00:00
parent e6be1cde2d
commit e247941695
9 changed files with 172 additions and 199 deletions

View file

@ -8,7 +8,7 @@ use crate::activitypub::{
actors::types::{Actor, ActorAddress},
handlers::{
create::handle_note,
update_person::update_remote_profile,
update::update_remote_profile,
},
identifiers::parse_local_object_id,
receiver::HandlerError,

View file

@ -14,7 +14,4 @@ pub mod r#move;
pub mod reject;
pub mod remove;
pub mod undo;
mod undo_follow;
pub mod update;
mod update_note;
pub mod update_person;

View file

@ -2,23 +2,54 @@ use tokio_postgres::GenericClient;
use crate::activitypub::{
activity::Activity,
identifiers::parse_local_actor_id,
receiver::find_object_id,
vocabulary::{ANNOUNCE, FOLLOW, LIKE},
};
use crate::config::Config;
use crate::database::DatabaseError;
use crate::errors::ValidationError;
use crate::models::posts::queries::{
delete_post,
get_post_by_remote_object_id,
};
use crate::models::profiles::queries::get_profile_by_remote_actor_id;
use crate::models::reactions::queries::{
delete_reaction,
get_reaction_by_remote_activity_id,
use crate::models::{
posts::queries::{
delete_post,
get_post_by_remote_object_id,
},
profiles::queries::{
get_profile_by_acct,
get_profile_by_remote_actor_id,
},
reactions::queries::{
delete_reaction,
get_reaction_by_remote_activity_id,
},
relationships::queries::unfollow,
};
use super::HandlerResult;
use super::undo_follow::handle_undo_follow;
async fn handle_undo_follow(
config: &Config,
db_client: &mut impl GenericClient,
activity: Activity,
) -> HandlerResult {
let source_profile = get_profile_by_remote_actor_id(
db_client,
&activity.actor,
).await?;
let target_actor_id = find_object_id(&activity.object["object"])?;
let target_username = parse_local_actor_id(
&config.instance_url(),
&target_actor_id,
)?;
// acct equals username if profile is local
let target_profile = get_profile_by_acct(db_client, &target_username).await?;
match unfollow(db_client, &source_profile.id, &target_profile.id).await {
Ok(_) => (),
// Ignore Undo if relationship doesn't exist
Err(DatabaseError::NotFound(_)) => return Ok(None),
Err(other_error) => return Err(other_error.into()),
};
Ok(Some(FOLLOW))
}
pub async fn handle_undo(
config: &Config,

View file

@ -1,41 +0,0 @@
use tokio_postgres::GenericClient;
use crate::activitypub::{
activity::Activity,
identifiers::parse_local_actor_id,
receiver::find_object_id,
vocabulary::FOLLOW,
};
use crate::config::Config;
use crate::database::DatabaseError;
use crate::models::profiles::queries::{
get_profile_by_acct,
get_profile_by_remote_actor_id,
};
use crate::models::relationships::queries::unfollow;
use super::HandlerResult;
pub async fn handle_undo_follow(
config: &Config,
db_client: &mut impl GenericClient,
activity: Activity,
) -> HandlerResult {
let source_profile = get_profile_by_remote_actor_id(
db_client,
&activity.actor,
).await?;
let target_actor_id = find_object_id(&activity.object["object"])?;
let target_username = parse_local_actor_id(
&config.instance_url(),
&target_actor_id,
)?;
// acct equals username if profile is local
let target_profile = get_profile_by_acct(db_client, &target_username).await?;
match unfollow(db_client, &source_profile.id, &target_profile.id).await {
Ok(_) => (),
// Ignore Undo if relationship doesn't exist
Err(DatabaseError::NotFound(_)) => return Ok(None),
Err(other_error) => return Err(other_error.into()),
};
Ok(Some(FOLLOW))
}

View file

@ -1,14 +1,123 @@
use std::path::Path;
use chrono::Utc;
use tokio_postgres::GenericClient;
use crate::activitypub::{
activity::{Activity, Object},
actors::types::Actor,
fetcher::fetchers::fetch_actor_images,
handlers::create::get_note_content,
vocabulary::{NOTE, PERSON},
};
use crate::config::Config;
use crate::config::{Config, Instance};
use crate::database::DatabaseError;
use crate::errors::ValidationError;
use super::HandlerResult;
use super::update_note::handle_update_note;
use super::update_person::handle_update_person;
use crate::models::{
posts::queries::{
get_post_by_remote_object_id,
update_post,
},
posts::types::PostUpdateData,
profiles::queries::{
get_profile_by_remote_actor_id,
update_profile,
},
profiles::types::{DbActorProfile, ProfileUpdateData},
};
use super::{HandlerError, HandlerResult};
async fn handle_update_note(
db_client: &mut impl GenericClient,
object: Object,
) -> HandlerResult {
let post_id = match get_post_by_remote_object_id(
db_client,
&object.id,
).await {
Ok(post) => post.id,
// Ignore Update if post is not found locally
Err(DatabaseError::NotFound(_)) => return Ok(None),
Err(other_error) => return Err(other_error.into()),
};
let content = get_note_content(&object)?;
let updated_at = object.updated.unwrap_or(Utc::now());
let post_data = PostUpdateData { content, updated_at };
update_post(db_client, &post_id, post_data).await?;
Ok(Some(NOTE))
}
/// Updates remote actor's profile
pub async fn update_remote_profile(
db_client: &impl GenericClient,
instance: &Instance,
media_dir: &Path,
profile: DbActorProfile,
actor: Actor,
) -> 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 {}",
actor_old.id,
actor.id,
);
};
if actor_old.public_key.public_key_pem != actor.public_key.public_key_pem {
log::warn!(
"actor public key changed from {} to {}",
actor_old.public_key.public_key_pem,
actor.public_key.public_key_pem,
);
};
let (maybe_avatar, maybe_banner) = fetch_actor_images(
instance,
&actor,
media_dir,
profile.avatar_file_name,
profile.banner_file_name,
).await;
let (identity_proofs, payment_options, extra_fields) =
actor.parse_attachments();
let mut profile_data = ProfileUpdateData {
display_name: actor.name.clone(),
bio: actor.summary.clone(),
bio_source: actor.summary.clone(),
avatar: maybe_avatar,
banner: maybe_banner,
identity_proofs,
payment_options,
extra_fields,
actor_json: Some(actor),
};
profile_data.clean()?;
let profile = update_profile(db_client, &profile.id, profile_data).await?;
Ok(profile)
}
async fn handle_update_person(
config: &Config,
db_client: &impl GenericClient,
activity: Activity,
) -> HandlerResult {
let actor: Actor = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid actor data"))?;
if actor.id != activity.actor {
return Err(ValidationError("actor ID mismatch").into());
};
let profile = get_profile_by_remote_actor_id(
db_client,
&actor.id,
).await?;
update_remote_profile(
db_client,
&config.instance(),
&config.media_dir(),
profile,
actor,
).await?;
Ok(Some(PERSON))
}
pub async fn handle_update(
config: &Config,

View file

@ -1,33 +0,0 @@
use chrono::Utc;
use tokio_postgres::GenericClient;
use crate::activitypub::activity::Object;
use crate::activitypub::vocabulary::NOTE;
use crate::database::DatabaseError;
use crate::models::posts::queries::{
get_post_by_remote_object_id,
update_post,
};
use crate::models::posts::types::PostUpdateData;
use super::HandlerResult;
use super::create::get_note_content;
pub async fn handle_update_note(
db_client: &mut impl GenericClient,
object: Object,
) -> HandlerResult {
let post_id = match get_post_by_remote_object_id(
db_client,
&object.id,
).await {
Ok(post) => post.id,
// Ignore Update if post is not found locally
Err(DatabaseError::NotFound(_)) => return Ok(None),
Err(other_error) => return Err(other_error.into()),
};
let content = get_note_content(&object)?;
let updated_at = object.updated.unwrap_or(Utc::now());
let post_data = PostUpdateData { content, updated_at };
update_post(db_client, &post_id, post_data).await?;
Ok(Some(NOTE))
}

View file

@ -1,90 +0,0 @@
use std::path::Path;
use tokio_postgres::GenericClient;
use crate::activitypub::{
activity::Activity,
actors::types::Actor,
fetcher::fetchers::fetch_actor_images,
vocabulary::PERSON,
};
use crate::config::{Config, Instance};
use crate::errors::ValidationError;
use crate::models::profiles::queries::{
get_profile_by_remote_actor_id,
update_profile,
};
use crate::models::profiles::types::{DbActorProfile, ProfileUpdateData};
use super::{HandlerError, HandlerResult};
pub async fn handle_update_person(
config: &Config,
db_client: &impl GenericClient,
activity: Activity,
) -> HandlerResult {
let actor: Actor = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid actor data"))?;
if actor.id != activity.actor {
return Err(ValidationError("actor ID mismatch").into());
};
let profile = get_profile_by_remote_actor_id(
db_client,
&actor.id,
).await?;
update_remote_profile(
db_client,
&config.instance(),
&config.media_dir(),
profile,
actor,
).await?;
Ok(Some(PERSON))
}
/// Updates remote actor's profile
pub async fn update_remote_profile(
db_client: &impl GenericClient,
instance: &Instance,
media_dir: &Path,
profile: DbActorProfile,
actor: Actor,
) -> 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 {}",
actor_old.id,
actor.id,
);
};
if actor_old.public_key.public_key_pem != actor.public_key.public_key_pem {
log::warn!(
"actor public key changed from {} to {}",
actor_old.public_key.public_key_pem,
actor.public_key.public_key_pem,
);
};
let (maybe_avatar, maybe_banner) = fetch_actor_images(
instance,
&actor,
media_dir,
profile.avatar_file_name,
profile.banner_file_name,
).await;
let (identity_proofs, payment_options, extra_fields) =
actor.parse_attachments();
let mut profile_data = ProfileUpdateData {
display_name: actor.name.clone(),
bio: actor.summary.clone(),
bio_source: actor.summary.clone(),
avatar: maybe_avatar,
banner: maybe_banner,
identity_proofs,
payment_options,
extra_fields,
actor_json: Some(actor),
};
profile_data.clean()?;
let profile = update_profile(db_client, &profile.id, profile_data).await?;
Ok(profile)
}

View file

@ -231,39 +231,39 @@ pub async fn receive_activity(
ACCEPT => {
handle_accept(config, db_client, activity).await?
},
REJECT => {
handle_reject(config, db_client, activity).await?
},
CREATE => {
handle_create(config, db_client, activity, is_authenticated).await?
ADD => {
handle_add(config, db_client, activity).await?
},
ANNOUNCE => {
handle_announce(config, db_client, activity).await?
},
CREATE => {
handle_create(config, db_client, activity, is_authenticated).await?
},
DELETE => {
handle_delete(config, db_client, activity).await?
},
EMOJI_REACT | LIKE => {
handle_like(config, db_client, activity).await?
},
FOLLOW => {
handle_follow(config, db_client, activity).await?
},
LIKE | EMOJI_REACT => {
handle_like(config, db_client, activity).await?
},
MOVE => {
handle_move(config, db_client, activity).await?
},
REJECT => {
handle_reject(config, db_client, activity).await?
},
REMOVE => {
handle_remove(config, db_client, activity).await?
},
UNDO => {
handle_undo(config, db_client, activity).await?
},
UPDATE => {
handle_update(config, db_client, activity).await?
},
MOVE => {
handle_move(config, db_client, activity).await?
},
ADD => {
handle_add(config, db_client, activity).await?
},
REMOVE => {
handle_remove(config, db_client, activity).await?
},
_ => {
log::warn!("activity type is not supported: {}", activity_raw);
return Ok(());

View file

@ -7,7 +7,7 @@ use uuid::Uuid;
use crate::activitypub::builders::delete_note::prepare_delete_note;
use crate::activitypub::builders::delete_person::prepare_delete_person;
use crate::activitypub::fetcher::fetchers::fetch_actor;
use crate::activitypub::handlers::update_person::update_remote_profile;
use crate::activitypub::handlers::update::update_remote_profile;
use crate::config::Config;
use crate::ethereum::signatures::generate_ecdsa_key;
use crate::ethereum::sync::save_current_block_number;