Handle Move(Person) activity
https://codeberg.org/silverpill/mitra/issues/10
This commit is contained in:
parent
ec349afc80
commit
9b31395853
|
@ -16,6 +16,7 @@ The following activities are supported:
|
||||||
- Update(Note)
|
- Update(Note)
|
||||||
- Follow(Person)
|
- Follow(Person)
|
||||||
- Update(Person)
|
- Update(Person)
|
||||||
|
- Move(Person)
|
||||||
- Delete(Person)
|
- Delete(Person)
|
||||||
- Add(Person)
|
- Add(Person)
|
||||||
- Remove(Person)
|
- Remove(Person)
|
||||||
|
|
|
@ -187,11 +187,15 @@ impl<A: Serialize + Send + 'static> OutgoingActivity<A> {
|
||||||
).await
|
).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn deliver_or_log(self) -> () {
|
||||||
|
self.deliver().await.unwrap_or_else(|err| {
|
||||||
|
log::error!("{}", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn_deliver(self) -> () {
|
pub fn spawn_deliver(self) -> () {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
self.deliver().await.unwrap_or_else(|err| {
|
self.deliver_or_log().await;
|
||||||
log::error!("{}", err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ pub mod create_note;
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
pub mod follow;
|
pub mod follow;
|
||||||
pub mod like;
|
pub mod like;
|
||||||
|
pub mod move_person;
|
||||||
pub mod reject_follow;
|
pub mod reject_follow;
|
||||||
pub mod remove;
|
pub mod remove;
|
||||||
pub mod undo;
|
pub mod undo;
|
||||||
|
|
103
src/activitypub/handlers/move_person.rs
Normal file
103
src/activitypub/handlers/move_person.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
|
use crate::activitypub::{
|
||||||
|
activity::Activity,
|
||||||
|
builders::{
|
||||||
|
follow::prepare_follow,
|
||||||
|
undo_follow::prepare_undo_follow,
|
||||||
|
},
|
||||||
|
fetcher::helpers::get_or_import_profile_by_actor_id,
|
||||||
|
receiver::find_object_id,
|
||||||
|
vocabulary::PERSON,
|
||||||
|
};
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::errors::{DatabaseError, ValidationError};
|
||||||
|
use crate::models::{
|
||||||
|
relationships::queries::{
|
||||||
|
create_follow_request,
|
||||||
|
get_followers,
|
||||||
|
unfollow,
|
||||||
|
},
|
||||||
|
users::queries::get_user_by_id,
|
||||||
|
};
|
||||||
|
use super::HandlerResult;
|
||||||
|
|
||||||
|
pub async fn handle_move_person(
|
||||||
|
config: &Config,
|
||||||
|
db_client: &mut impl GenericClient,
|
||||||
|
activity: Activity,
|
||||||
|
) -> HandlerResult {
|
||||||
|
let object_id = find_object_id(&activity.object)?;
|
||||||
|
if object_id != activity.actor {
|
||||||
|
return Err(ValidationError("actor ID mismatch").into());
|
||||||
|
};
|
||||||
|
let target_value = activity.target
|
||||||
|
.ok_or(ValidationError("target is missing"))?;
|
||||||
|
let target_id = find_object_id(&target_value)?;
|
||||||
|
|
||||||
|
let instance = config.instance();
|
||||||
|
let media_dir = config.media_dir();
|
||||||
|
let old_profile = get_or_import_profile_by_actor_id(
|
||||||
|
db_client,
|
||||||
|
&instance,
|
||||||
|
&media_dir,
|
||||||
|
&activity.actor,
|
||||||
|
).await?;
|
||||||
|
let old_actor = old_profile.actor_json.unwrap();
|
||||||
|
let new_profile = get_or_import_profile_by_actor_id(
|
||||||
|
db_client,
|
||||||
|
&instance,
|
||||||
|
&media_dir,
|
||||||
|
&target_id,
|
||||||
|
).await?;
|
||||||
|
let new_actor = new_profile.actor_json.unwrap();
|
||||||
|
let maybe_also_known_as = new_actor.also_known_as.as_ref()
|
||||||
|
.and_then(|aliases| aliases.first());
|
||||||
|
if maybe_also_known_as != Some(&old_actor.id) {
|
||||||
|
return Err(ValidationError("target ID is not an alias").into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let followers = get_followers(db_client, &old_profile.id).await?;
|
||||||
|
let mut activities = vec![];
|
||||||
|
for follower in followers {
|
||||||
|
let follower = get_user_by_id(db_client, &follower.id).await?;
|
||||||
|
// Unfollow old profile
|
||||||
|
let maybe_follow_request_id = unfollow(
|
||||||
|
db_client,
|
||||||
|
&follower.id,
|
||||||
|
&old_profile.id,
|
||||||
|
).await?;
|
||||||
|
// The target is remote profile, so follow request must exist
|
||||||
|
let follow_request_id = maybe_follow_request_id.unwrap();
|
||||||
|
activities.push(prepare_undo_follow(
|
||||||
|
&instance,
|
||||||
|
&follower,
|
||||||
|
&old_actor,
|
||||||
|
&follow_request_id,
|
||||||
|
));
|
||||||
|
// Follow new profile
|
||||||
|
match create_follow_request(
|
||||||
|
db_client,
|
||||||
|
&follower.id,
|
||||||
|
&new_profile.id,
|
||||||
|
).await {
|
||||||
|
Ok(follow_request) => {
|
||||||
|
activities.push(prepare_follow(
|
||||||
|
&instance,
|
||||||
|
&follower,
|
||||||
|
&new_actor,
|
||||||
|
&follow_request.id,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
Err(DatabaseError::AlreadyExists(_)) => (), // already following
|
||||||
|
Err(other_error) => return Err(other_error.into()),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tokio::spawn(async move {
|
||||||
|
for activity in activities {
|
||||||
|
activity.deliver_or_log().await;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(Some(PERSON))
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ use super::handlers::{
|
||||||
delete::handle_delete,
|
delete::handle_delete,
|
||||||
follow::handle_follow,
|
follow::handle_follow,
|
||||||
like::handle_like,
|
like::handle_like,
|
||||||
|
move_person::handle_move_person,
|
||||||
reject_follow::handle_reject_follow,
|
reject_follow::handle_reject_follow,
|
||||||
remove::handle_remove,
|
remove::handle_remove,
|
||||||
undo::handle_undo,
|
undo::handle_undo,
|
||||||
|
@ -197,6 +198,10 @@ pub async fn receive_activity(
|
||||||
require_actor_signature(&activity.actor, &signer_id)?;
|
require_actor_signature(&activity.actor, &signer_id)?;
|
||||||
handle_update_person(config, db_client, activity).await?
|
handle_update_person(config, db_client, activity).await?
|
||||||
},
|
},
|
||||||
|
(MOVE, _) => {
|
||||||
|
require_actor_signature(&activity.actor, &signer_id)?;
|
||||||
|
handle_move_person(config, db_client, activity).await?
|
||||||
|
},
|
||||||
(ADD, _) => {
|
(ADD, _) => {
|
||||||
require_actor_signature(&activity.actor, &signer_id)?;
|
require_actor_signature(&activity.actor, &signer_id)?;
|
||||||
handle_add(config, db_client, activity).await?
|
handle_add(config, db_client, activity).await?
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub const DELETE: &str = "Delete";
|
||||||
pub const EMOJI_REACT: &str = "EmojiReact";
|
pub const EMOJI_REACT: &str = "EmojiReact";
|
||||||
pub const FOLLOW: &str = "Follow";
|
pub const FOLLOW: &str = "Follow";
|
||||||
pub const LIKE: &str = "Like";
|
pub const LIKE: &str = "Like";
|
||||||
|
pub const MOVE: &str = "Move";
|
||||||
pub const QUESTION: &str = "Question";
|
pub const QUESTION: &str = "Question";
|
||||||
pub const REJECT: &str = "Reject";
|
pub const REJECT: &str = "Reject";
|
||||||
pub const REMOVE: &str = "Remove";
|
pub const REMOVE: &str = "Remove";
|
||||||
|
|
Loading…
Reference in a new issue