Make activity IDs deterministic
This commit is contained in:
parent
0bc3c32fcd
commit
aa997e3a82
2 changed files with 45 additions and 22 deletions
|
@ -140,7 +140,7 @@ fn create_activity(
|
||||||
instance_url: &str,
|
instance_url: &str,
|
||||||
actor_name: &str,
|
actor_name: &str,
|
||||||
activity_type: &str,
|
activity_type: &str,
|
||||||
internal_activity_id: Option<&Uuid>,
|
activity_id: String,
|
||||||
object: impl Serialize,
|
object: impl Serialize,
|
||||||
primary_audience: Vec<String>,
|
primary_audience: Vec<String>,
|
||||||
secondary_audience: Vec<String>,
|
secondary_audience: Vec<String>,
|
||||||
|
@ -149,13 +149,6 @@ fn create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
actor_name,
|
actor_name,
|
||||||
);
|
);
|
||||||
let mut activity_id = get_object_url(
|
|
||||||
instance_url,
|
|
||||||
internal_activity_id.unwrap_or(&new_uuid()),
|
|
||||||
);
|
|
||||||
if activity_type == CREATE {
|
|
||||||
activity_id.push_str("/create");
|
|
||||||
};
|
|
||||||
Activity {
|
Activity {
|
||||||
context: json!(AP_CONTEXT),
|
context: json!(AP_CONTEXT),
|
||||||
id: activity_id,
|
id: activity_id,
|
||||||
|
@ -265,11 +258,12 @@ pub fn create_activity_note(
|
||||||
let object = create_note(instance_host, instance_url, post);
|
let object = create_note(instance_host, instance_url, post);
|
||||||
let primary_audience = object.to.clone();
|
let primary_audience = object.to.clone();
|
||||||
let secondary_audience = object.cc.clone();
|
let secondary_audience = object.cc.clone();
|
||||||
|
let activity_id = get_object_url(instance_url, &post.id) + "/create";
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&post.author.username,
|
&post.author.username,
|
||||||
CREATE,
|
CREATE,
|
||||||
Some(&post.id),
|
activity_id,
|
||||||
object,
|
object,
|
||||||
primary_audience,
|
primary_audience,
|
||||||
secondary_audience,
|
secondary_audience,
|
||||||
|
@ -284,11 +278,12 @@ pub fn create_activity_like(
|
||||||
reaction_id: &Uuid,
|
reaction_id: &Uuid,
|
||||||
recipient_id: &str,
|
recipient_id: &str,
|
||||||
) -> Activity {
|
) -> Activity {
|
||||||
|
let activity_id = get_object_url(instance_url, reaction_id);
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
LIKE,
|
LIKE,
|
||||||
Some(reaction_id),
|
activity_id,
|
||||||
note_id,
|
note_id,
|
||||||
vec![AP_PUBLIC.to_string(), recipient_id.to_string()],
|
vec![AP_PUBLIC.to_string(), recipient_id.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -306,11 +301,12 @@ pub fn create_activity_undo_like(
|
||||||
instance_url,
|
instance_url,
|
||||||
reaction_id,
|
reaction_id,
|
||||||
);
|
);
|
||||||
|
let activity_id = get_object_url(instance_url, reaction_id) + "/undo";
|
||||||
create_activity(
|
create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
UNDO,
|
UNDO,
|
||||||
None,
|
activity_id,
|
||||||
object_id,
|
object_id,
|
||||||
vec![AP_PUBLIC.to_string(), recipient_id.to_string()],
|
vec![AP_PUBLIC.to_string(), recipient_id.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -324,12 +320,13 @@ pub fn create_activity_announce(
|
||||||
repost_id: &Uuid,
|
repost_id: &Uuid,
|
||||||
) -> Activity {
|
) -> Activity {
|
||||||
let object_id = post.get_object_id(instance_url);
|
let object_id = post.get_object_id(instance_url);
|
||||||
|
let activity_id = get_object_url(instance_url, repost_id);
|
||||||
let recipient_id = post.author.actor_id(instance_url);
|
let recipient_id = post.author.actor_id(instance_url);
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
ANNOUNCE,
|
ANNOUNCE,
|
||||||
Some(repost_id),
|
activity_id,
|
||||||
object_id,
|
object_id,
|
||||||
vec![AP_PUBLIC.to_string(), recipient_id],
|
vec![AP_PUBLIC.to_string(), recipient_id],
|
||||||
vec![get_followers_url(instance_url, &actor_profile.username)],
|
vec![get_followers_url(instance_url, &actor_profile.username)],
|
||||||
|
@ -347,6 +344,7 @@ pub fn create_activity_undo_announce(
|
||||||
instance_url,
|
instance_url,
|
||||||
repost_id,
|
repost_id,
|
||||||
);
|
);
|
||||||
|
let activity_id = get_object_url(instance_url, repost_id) + "/undo";
|
||||||
let primary_audience = vec![
|
let primary_audience = vec![
|
||||||
AP_PUBLIC.to_string(),
|
AP_PUBLIC.to_string(),
|
||||||
recipient_id.to_string(),
|
recipient_id.to_string(),
|
||||||
|
@ -355,7 +353,7 @@ pub fn create_activity_undo_announce(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
UNDO,
|
UNDO,
|
||||||
None,
|
activity_id,
|
||||||
object_id,
|
object_id,
|
||||||
primary_audience,
|
primary_audience,
|
||||||
vec![get_followers_url(instance_url, &actor_profile.username)],
|
vec![get_followers_url(instance_url, &actor_profile.username)],
|
||||||
|
@ -374,11 +372,12 @@ pub fn create_activity_delete_note(
|
||||||
former_type: Some(NOTE.to_string()),
|
former_type: Some(NOTE.to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let activity_id = get_object_url(instance_url, &post.id) + "/delete";
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&post.author.username,
|
&post.author.username,
|
||||||
DELETE,
|
DELETE,
|
||||||
None,
|
activity_id,
|
||||||
object,
|
object,
|
||||||
vec![AP_PUBLIC.to_string()],
|
vec![AP_PUBLIC.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -398,11 +397,12 @@ pub fn create_activity_follow(
|
||||||
object_type: PERSON.to_string(),
|
object_type: PERSON.to_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let activity_id = get_object_url(instance_url, follow_request_id);
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
FOLLOW,
|
FOLLOW,
|
||||||
Some(follow_request_id),
|
activity_id,
|
||||||
object,
|
object,
|
||||||
vec![target_actor_id.to_string()],
|
vec![target_actor_id.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -416,18 +416,18 @@ pub fn create_activity_accept_follow(
|
||||||
follow_activity_id: &str,
|
follow_activity_id: &str,
|
||||||
source_actor_id: &str,
|
source_actor_id: &str,
|
||||||
) -> Activity {
|
) -> Activity {
|
||||||
// TODO: use received activity as object
|
|
||||||
let object = Object {
|
let object = Object {
|
||||||
context: Some(json!(AP_CONTEXT)),
|
context: Some(json!(AP_CONTEXT)),
|
||||||
id: follow_activity_id.to_string(),
|
id: follow_activity_id.to_string(),
|
||||||
object_type: FOLLOW.to_string(),
|
object_type: FOLLOW.to_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let activity_id = follow_activity_id.to_string() + "/accept";
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
ACCEPT,
|
ACCEPT,
|
||||||
None,
|
activity_id,
|
||||||
object,
|
object,
|
||||||
vec![source_actor_id.to_string()],
|
vec![source_actor_id.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -441,7 +441,6 @@ pub fn create_activity_undo_follow(
|
||||||
follow_request_id: &Uuid,
|
follow_request_id: &Uuid,
|
||||||
target_actor_id: &str,
|
target_actor_id: &str,
|
||||||
) -> Activity {
|
) -> Activity {
|
||||||
// TODO: retrieve 'Follow' activity from database
|
|
||||||
let follow_activity_id = get_object_url(
|
let follow_activity_id = get_object_url(
|
||||||
instance_url,
|
instance_url,
|
||||||
follow_request_id,
|
follow_request_id,
|
||||||
|
@ -452,17 +451,18 @@ pub fn create_activity_undo_follow(
|
||||||
);
|
);
|
||||||
let object = Object {
|
let object = Object {
|
||||||
context: Some(json!(AP_CONTEXT)),
|
context: Some(json!(AP_CONTEXT)),
|
||||||
id: follow_activity_id,
|
id: follow_activity_id.clone(),
|
||||||
object_type: FOLLOW.to_string(),
|
object_type: FOLLOW.to_string(),
|
||||||
actor: Some(follow_actor_id),
|
actor: Some(follow_actor_id),
|
||||||
object: Some(target_actor_id.to_owned()),
|
object: Some(target_actor_id.to_owned()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let activity_id = follow_activity_id + "/undo";
|
||||||
let activity = create_activity(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&actor_profile.username,
|
&actor_profile.username,
|
||||||
UNDO,
|
UNDO,
|
||||||
None,
|
activity_id,
|
||||||
object,
|
object,
|
||||||
vec![target_actor_id.to_string()],
|
vec![target_actor_id.to_string()],
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -475,11 +475,13 @@ pub fn create_activity_update_person(
|
||||||
instance_url: &str,
|
instance_url: &str,
|
||||||
) -> Result<Activity, ActorKeyError> {
|
) -> Result<Activity, ActorKeyError> {
|
||||||
let actor = get_local_actor(user, instance_url)?;
|
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(
|
let activity = create_activity(
|
||||||
instance_url,
|
instance_url,
|
||||||
&user.profile.username,
|
&user.profile.username,
|
||||||
UPDATE,
|
UPDATE,
|
||||||
None,
|
activity_id,
|
||||||
actor,
|
actor,
|
||||||
vec![
|
vec![
|
||||||
AP_PUBLIC.to_string(),
|
AP_PUBLIC.to_string(),
|
||||||
|
@ -596,6 +598,28 @@ mod tests {
|
||||||
assert_eq!(note.to, vec![AP_PUBLIC, parent_author_actor_id]);
|
assert_eq!(note.to, vec![AP_PUBLIC, parent_author_actor_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_activity_create_note() {
|
||||||
|
let author_username = "author";
|
||||||
|
let author = DbActorProfile {
|
||||||
|
username: author_username.to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let post = Post { author, ..Default::default() };
|
||||||
|
let activity = create_activity_note(INSTANCE_HOST, INSTANCE_URL, &post);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
activity.id,
|
||||||
|
format!("{}/objects/{}/create", INSTANCE_URL, post.id),
|
||||||
|
);
|
||||||
|
assert_eq!(activity.activity_type, CREATE);
|
||||||
|
assert_eq!(
|
||||||
|
activity.actor,
|
||||||
|
format!("{}/users/{}", INSTANCE_URL, author_username),
|
||||||
|
);
|
||||||
|
assert_eq!(activity.to.unwrap(), json!([AP_PUBLIC]));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_activity_follow() {
|
fn test_create_activity_follow() {
|
||||||
let follower = DbActorProfile {
|
let follower = DbActorProfile {
|
||||||
|
|
|
@ -149,7 +149,6 @@ async fn outbox(
|
||||||
let db_client = &**get_database_client(&db_pool).await?;
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
let user = get_user_by_name(db_client, &username).await?;
|
let user = get_user_by_name(db_client, &username).await?;
|
||||||
// Posts are ordered by creation date
|
// Posts are ordered by creation date
|
||||||
// TODO: include reposts
|
|
||||||
let posts = get_posts_by_author(
|
let posts = get_posts_by_author(
|
||||||
db_client,
|
db_client,
|
||||||
&user.id,
|
&user.id,
|
||||||
|
|
Loading…
Reference in a new issue