Move code for building Update(Person) activity to builders::update_person

This commit is contained in:
silverpill 2022-06-01 21:39:23 +00:00
parent 275e5ae5ca
commit 50986cd358
6 changed files with 106 additions and 77 deletions

View file

@ -6,10 +6,8 @@ use uuid::Uuid;
use crate::frontend::get_tag_page_url;
use crate::models::posts::types::{Post, Visibility};
use crate::models::profiles::types::DbActorProfile;
use crate::models::users::types::User;
use crate::utils::files::get_file_url;
use crate::utils::id::new_uuid;
use super::actor::{get_local_actor, ActorKeyError};
use super::constants::{AP_CONTEXT, AP_PUBLIC};
use super::views::{
get_actor_url,
@ -142,7 +140,7 @@ pub struct Activity {
pub cc: Option<Value>,
}
fn create_activity(
pub fn create_activity(
instance_url: &str,
actor_name: &str,
activity_type: &str,
@ -366,31 +364,6 @@ pub fn create_activity_undo_announce(
)
}
pub fn create_activity_delete_note(
instance_url: &str,
post: &Post,
) -> Activity {
let object_id = post.get_object_id(instance_url);
let object = Object {
context: Some(json!(AP_CONTEXT)),
id: object_id,
object_type: TOMBSTONE.to_string(),
former_type: Some(NOTE.to_string()),
..Default::default()
};
let activity_id = format!("{}/delete", object.id);
let activity = create_activity(
instance_url,
&post.author.username,
DELETE,
activity_id,
object,
vec![AP_PUBLIC.to_string()],
vec![],
);
activity
}
pub fn create_activity_follow(
instance_url: &str,
actor_profile: &DbActorProfile,
@ -477,28 +450,6 @@ pub fn create_activity_undo_follow(
activity
}
pub fn create_activity_update_person(
user: &User,
instance_url: &str,
) -> Result<Activity, ActorKeyError> {
let actor = get_local_actor(user, instance_url)?;
// Update(Person) is idempotent so its ID can be random
let activity_id = get_object_url(instance_url, &new_uuid());
let activity = create_activity(
instance_url,
&user.profile.username,
UPDATE,
activity_id,
actor,
vec![
AP_PUBLIC.to_string(),
get_followers_url(instance_url, &user.profile.username),
],
vec![],
);
Ok(activity)
}
#[cfg(test)]
mod tests {
use crate::activitypub::actor::Actor;

View file

@ -1,13 +1,41 @@
use serde_json::json;
use tokio_postgres::GenericClient;
use crate::activitypub::activity::create_activity_delete_note as build_delete_note;
use crate::activitypub::activity::{create_activity, Activity, Object};
use crate::activitypub::constants::{AP_CONTEXT, AP_PUBLIC};
use crate::activitypub::deliverer::OutgoingActivity;
use crate::activitypub::vocabulary::{DELETE, NOTE, TOMBSTONE};
use crate::config::Instance;
use crate::errors::DatabaseError;
use crate::mastodon_api::statuses::helpers::get_note_recipients;
use crate::models::posts::types::Post;
use crate::models::users::types::User;
fn build_delete_note(
instance_url: &str,
post: &Post,
) -> Activity {
let object_id = post.get_object_id(instance_url);
let object = Object {
context: Some(json!(AP_CONTEXT)),
id: object_id,
object_type: TOMBSTONE.to_string(),
former_type: Some(NOTE.to_string()),
..Default::default()
};
let activity_id = format!("{}/delete", object.id);
let activity = create_activity(
instance_url,
&post.author.username,
DELETE,
activity_id,
object,
vec![AP_PUBLIC.to_string()],
vec![],
);
activity
}
pub async fn prepare_delete_note(
db_client: &impl GenericClient,
instance: Instance,

View file

@ -1 +1,2 @@
pub mod delete_note;
pub mod update_person;

View file

@ -0,0 +1,68 @@
use tokio_postgres::GenericClient;
use uuid::Uuid;
use crate::activitypub::{
activity::{create_activity, Activity},
actor::{get_local_actor, Actor, ActorKeyError},
constants::AP_PUBLIC,
deliverer::OutgoingActivity,
views::{get_followers_url, get_object_url},
vocabulary::UPDATE,
};
use crate::config::Instance;
use crate::errors::{ConversionError, DatabaseError};
use crate::models::relationships::queries::get_followers;
use crate::models::users::types::User;
use crate::utils::id::new_uuid;
fn build_update_person(
instance_url: &str,
user: &User,
) -> Result<Activity, ActorKeyError> {
let actor = get_local_actor(user, instance_url)?;
// Update(Person) is idempotent so its ID can be random
let activity_id = get_object_url(instance_url, &new_uuid());
let activity = create_activity(
instance_url,
&user.profile.username,
UPDATE,
activity_id,
actor,
vec![
AP_PUBLIC.to_string(),
get_followers_url(instance_url, &user.profile.username),
],
vec![],
);
Ok(activity)
}
async fn get_update_person_recipients(
db_client: &impl GenericClient,
user_id: &Uuid,
) -> Result<Vec<Actor>, DatabaseError> {
let followers = get_followers(db_client, user_id, None, None).await?;
let mut recipients: Vec<Actor> = Vec::new();
for profile in followers {
if let Some(remote_actor) = profile.actor_json {
recipients.push(remote_actor);
};
};
Ok(recipients)
}
pub async fn prepare_update_person(
db_client: &impl GenericClient,
instance: Instance,
user: &User,
) -> Result<OutgoingActivity, DatabaseError> {
let activity = build_update_person(&instance.url(), user)
.map_err(|_| ConversionError)?;
let recipients = get_update_person_recipients(db_client, &user.id).await?;
Ok(OutgoingActivity {
instance,
sender: user.clone(),
activity,
recipients,
})
}

View file

@ -1,26 +1,11 @@
use tokio_postgres::GenericClient;
use uuid::Uuid;
use crate::activitypub::actor::Actor;
use crate::errors::DatabaseError;
use crate::models::relationships::queries::{get_followers, get_relationships};
use crate::models::relationships::queries::get_relationships;
use crate::models::relationships::types::RelationshipType;
use super::types::RelationshipMap;
pub async fn get_profile_update_recipients(
db_client: &impl GenericClient,
current_user_id: &Uuid,
) -> Result<Vec<Actor>, DatabaseError> {
let followers = get_followers(db_client, current_user_id, None, None).await?;
let mut recipients: Vec<Actor> = Vec::new();
for profile in followers {
if let Some(remote_actor) = profile.actor_json {
recipients.push(remote_actor);
};
};
Ok(recipients)
}
pub async fn get_relationship(
db_client: &impl GenericClient,
source_id: &Uuid,

View file

@ -5,8 +5,8 @@ use uuid::Uuid;
use crate::activitypub::activity::{
create_activity_follow,
create_activity_undo_follow,
create_activity_update_person,
};
use crate::activitypub::builders::update_person::prepare_update_person;
use crate::activitypub::deliverer::deliver_activity;
use crate::config::Config;
use crate::database::{Pool, get_database_client};
@ -52,7 +52,7 @@ use crate::utils::crypto::{
serialize_private_key,
};
use crate::utils::files::FileError;
use super::helpers::{get_profile_update_recipients, get_relationship};
use super::helpers::get_relationship;
use super::types::{
Account,
AccountCreateData,
@ -201,10 +201,8 @@ async fn update_credentials(
).await?;
// Federate
let activity = create_activity_update_person(&current_user, &config.instance_url())
.map_err(|_| HttpError::InternalError)?;
let recipients = get_profile_update_recipients(db_client, &current_user.id).await?;
deliver_activity(&config, &current_user, activity, recipients);
prepare_update_person(db_client, config.instance(), &current_user).await?
.spawn_deliver();
let account = Account::from_user(current_user, &config.instance_url());
Ok(HttpResponse::Ok().json(account))
@ -271,10 +269,8 @@ async fn create_identity_proof(
).await?;
// Federate
let activity = create_activity_update_person(&current_user, &config.instance_url())
.map_err(|_| HttpError::InternalError)?;
let recipients = get_profile_update_recipients(db_client, &current_user.id).await?;
deliver_activity(&config, &current_user, activity, recipients);
prepare_update_person(db_client, config.instance(), &current_user).await?
.spawn_deliver();
let account = Account::from_user(current_user, &config.instance_url());
Ok(HttpResponse::Ok().json(account))