Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/apub/activities/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ serde_with.workspace = true
enum_delegate = "0.2.0"
either = { workspace = true }
lemmy_diesel_utils = { workspace = true }
md5 = "0.8.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use sha2 which we are already using as dependency.


[dev-dependencies]

Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/block/block_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl BlockUser {
kind: BlockType::Block,
remove_data,
summary: Some(reason),
id: generate_activity_id(BlockType::Block, context)?,
id: generate_activity_id(BlockType::Block, None, context)?,
end_time: expires,
audience: target.as_ref().right().map(|c| c.ap_id.clone().into()),
})
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/block/undo_block_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl UndoBlockUser {
let block = BlockUser::new(target, user, mod_, None, reason, None, context).await?;
let to = to(target)?;

let id = generate_activity_id(UndoType::Undo, context)?;
let id = generate_activity_id(UndoType::Undo, None, context)?;
let undo = UndoBlockUser {
actor: mod_.id().clone().into(),
to,
Expand Down
14 changes: 9 additions & 5 deletions crates/apub/activities/src/community/announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,19 @@ impl AnnounceActivity {
pub fn new(
object: RawAnnouncableActivities,
community: &ApubCommunity,
object_id: Option<&str>,
context: &Data<LemmyContext>,
) -> LemmyResult<AnnounceActivity> {
let inner_kind = object
.other
.get("type")
.and_then(serde_json::Value::as_str)
.unwrap_or("other");
let id =
generate_announce_activity_id(inner_kind, &context.settings().get_protocol_and_hostname())?;
let id = generate_announce_activity_id(
inner_kind,
&context.settings().get_protocol_and_hostname(),
object_id,
)?;
Ok(AnnounceActivity {
actor: community.id().clone().into(),
to: generate_to(community)?,
Expand All @@ -111,7 +115,7 @@ impl AnnounceActivity {
community: &ApubCommunity,
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let announce = AnnounceActivity::new(object.clone(), community, context)?;
let announce = AnnounceActivity::new(object.clone(), community, None, context)?;
let inboxes = ActivitySendTargets::to_local_community_followers(community.id);
send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?;

Expand All @@ -122,14 +126,14 @@ impl AnnounceActivity {
// Hack: need to convert Page into a format which can be sent as activity, which requires
// adding actor field.
let announcable_page = RawAnnouncableActivities {
id: generate_activity_id(AnnounceType::Announce, context)?,
id: generate_activity_id(AnnounceType::Announce, None, context)?,
actor: c.actor.clone().into_inner(),
other: serde_json::to_value(c.object)?
.as_object()
.ok_or(UntranslatedError::Unreachable)?
.clone(),
};
let announce_compat = AnnounceActivity::new(announcable_page, community, context)?;
let announce_compat = AnnounceActivity::new(announcable_page, community, None, context)?;
send_lemmy_activity(context, announce_compat, community, inboxes, false).await?;
}
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/collection_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl CollectionAdd {
actor: &ApubPerson,
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let id = generate_activity_id(AddType::Add, context)?;
let id = generate_activity_id(AddType::Add, None, context)?;
let add = CollectionAdd {
actor: actor.id().clone().into(),
to: generate_to(community)?,
Expand All @@ -68,7 +68,7 @@ impl CollectionAdd {
actor: &ApubPerson,
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let id = generate_activity_id(AddType::Add, context)?;
let id = generate_activity_id(AddType::Add, None, context)?;
let add = CollectionAdd {
actor: actor.id().clone().into(),
to: generate_to(community)?,
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/collection_remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl CollectionRemove {
actor: &ApubPerson,
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let id = generate_activity_id(RemoveType::Remove, context)?;
let id = generate_activity_id(RemoveType::Remove, None, context)?;
let remove = CollectionRemove {
actor: actor.id().clone().into(),
to: generate_to(community)?,
Expand All @@ -65,7 +65,7 @@ impl CollectionRemove {
actor: &ApubPerson,
context: &Data<LemmyContext>,
) -> LemmyResult<()> {
let id = generate_activity_id(RemoveType::Remove, context)?;
let id = generate_activity_id(RemoveType::Remove, None, context)?;
let remove = CollectionRemove {
actor: actor.id().clone().into(),
to: generate_to(community)?,
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub(crate) async fn send_lock(
context: Data<LemmyContext>,
) -> LemmyResult<()> {
let community: ApubCommunity = post_or_comment_community(&object, &context).await?.into();
let id = generate_activity_id(LockType::Lock, &context)?;
let id = generate_activity_id(LockType::Lock, None, &context)?;
let community_id = community.ap_id.inner().clone();
let ap_id = match object {
PostOrComment::Left(p) => p.ap_id.clone(),
Expand All @@ -177,7 +177,7 @@ pub(crate) async fn send_lock(
let activity = if locked {
AnnouncableActivities::Lock(lock)
} else {
let id = generate_activity_id(UndoType::Undo, &context)?;
let id = generate_activity_id(UndoType::Undo, None, &context)?;
let undo = UndoLockPageOrNote {
actor: lock.actor.clone(),
to: generate_to(&community)?,
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Report {
context: &Data<LemmyContext>,
) -> LemmyResult<Self> {
let kind = FlagType::Flag;
let id = generate_activity_id(kind.clone(), context)?;
let id = generate_activity_id(kind.clone(), None, context)?;
Ok(Report {
actor: actor.id().clone().into(),
to: [receiver.id().clone().into()],
Expand Down Expand Up @@ -151,7 +151,7 @@ impl Activity for Report {
// forward to remote mods
let object_id = self.object.object_id(context).await?;
let announce = AnnouncableActivities::Report(self);
let announce = AnnounceActivity::new(announce.try_into()?, community, context)?;
let announce = AnnounceActivity::new(announce.try_into()?, community, None, context)?;
let inboxes = report_inboxes(object_id, &receiver, &actor, context).await?;
send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?;
}
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/resolve_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl ResolveReport {
context: Data<LemmyContext>,
) -> LemmyResult<()> {
let kind = ResolveType::Resolve;
let id = generate_activity_id(kind.clone(), &context)?;
let id = generate_activity_id(kind.clone(), None, &context)?;
let object = Report::new(&object_id, report_creator, receiver, None, &context)?;
let resolve = ResolveReport {
actor: actor.id().clone().into(),
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Activity for ResolveReport {
// forward to remote mods
let object_id = self.object.object.object_id(context).await?;
let announce = AnnouncableActivities::ResolveReport(self);
let announce = AnnounceActivity::new(announce.try_into()?, community, context)?;
let announce = AnnounceActivity::new(announce.try_into()?, community, None, context)?;
let inboxes = report_inboxes(object_id, &receiver, &reporter, context).await?;
send_lemmy_activity(context, announce, community, inboxes.clone(), false).await?;
}
Expand Down
4 changes: 2 additions & 2 deletions crates/apub/activities/src/community/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub(crate) async fn send_update_community(
) -> LemmyResult<()> {
let community: ApubCommunity = community.into();
let actor: ApubPerson = actor.into();
let id = generate_activity_id(UpdateType::Update, &context)?;
let id = generate_activity_id(UpdateType::Update, None, &context)?;
let update = Update {
actor: actor.id().clone().into(),
to: generate_to(&community)?,
Expand Down Expand Up @@ -65,7 +65,7 @@ pub(crate) async fn send_update_multi_community(
) -> LemmyResult<()> {
let multi: ApubMultiCommunity = multi.into();
let actor: ApubPerson = actor.into();
let id = generate_activity_id(UpdateType::Update, &context)?;
let id = generate_activity_id(UpdateType::Update, None, &context)?;
let update = Update {
actor: actor.id().clone().into(),
to: vec![multi.ap_id.clone().into(), public()],
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/create_or_update/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl CreateOrUpdateNote {
.await?
.into();

let id = generate_activity_id(kind.clone(), &context)?;
let id = generate_activity_id(kind.clone(), None, &context)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let id = generate_activity_id(kind.clone(), None, &context)?;
let id = generate_activity_id(kind.clone(), Some(comment.ap_id), &context)?;

let note = ApubComment(comment).into_json(&context).await?;

let create_or_update = CreateOrUpdateNote {
Expand Down
5 changes: 3 additions & 2 deletions crates/apub/activities/src/create_or_update/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ impl CreateOrUpdatePage {
actor: &ApubPerson,
community: &ApubCommunity,
kind: CreateOrUpdateType,
object_id: Option<&str>,
context: &Data<LemmyContext>,
) -> LemmyResult<CreateOrUpdatePage> {
let id = generate_activity_id(kind.clone(), context)?;
let id = generate_activity_id(kind.clone(), object_id, context)?;
Ok(CreateOrUpdatePage {
actor: actor.id().clone().into(),
to: generate_to(community)?,
Expand All @@ -71,7 +72,7 @@ impl CreateOrUpdatePage {
.into();

let create_or_update =
CreateOrUpdatePage::new(post.into(), &person, &community, kind, &context).await?;
CreateOrUpdatePage::new(post.into(), &person, &community, kind, None, &context).await?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CreateOrUpdatePage::new(post.into(), &person, &community, kind, None, &context).await?;
CreateOrUpdatePage::new(post.into(), &person, &community, kind, Some(post.ap_id), &context).await?;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this can be a problem when editing the post, then each Update activity will have the same id. So you also need to hash the timestamp (published_at or updated_at).

let inboxes = tagged_user_inboxes(&create_or_update.object.tag, &context).await?;
let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update);
send_activity_in_community(activity, &person, &community, inboxes, false, &context).await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(crate) async fn send_create_or_update_pm(
let actor: ApubPerson = pm_view.creator.into();
let recipient: ApubPerson = pm_view.recipient.into();

let id = generate_activity_id(kind.clone(), &context)?;
let id = generate_activity_id(kind.clone(), None, &context)?;
let create_or_update = CreateOrUpdatePrivateMessage {
id: id.clone(),
actor: actor.id().clone().into(),
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/deletion/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl Delete {
with_replies: Option<bool>,
context: &Data<LemmyContext>,
) -> LemmyResult<Delete> {
let id = generate_activity_id(DeleteType::Delete, context)?;
let id = generate_activity_id(DeleteType::Delete, None, context)?;
let cc: Option<Url> = community.map(|c| c.ap_id.clone().into());
Ok(Delete {
actor: actor.ap_id.clone().into(),
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/deletion/undo_delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl UndoDelete {
context,
)?;

let id = generate_activity_id(UndoType::Undo, context)?;
let id = generate_activity_id(UndoType::Undo, None, context)?;
let cc: Option<Url> = community.map(|c| c.ap_id.clone().into());
Ok(UndoDelete {
actor: actor.ap_id.clone().into(),
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/following/accept.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl AcceptFollow {
to: Some([person.id().clone().into()]),
object: follow,
kind: AcceptType::Accept,
id: generate_activity_id(AcceptType::Accept, context)?,
id: generate_activity_id(AcceptType::Accept, None, context)?,
};
let inbox = ActivitySendTargets::to_inbox(person.shared_inbox_or_inbox());
send_lemmy_activity(context, accept, &target, inbox, true).await
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/following/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Follow {
object: target.id().clone().into(),
to: Some([target.id().clone().into()]),
kind: FollowType::Follow,
id: generate_activity_id(FollowType::Follow, context)?,
id: generate_activity_id(FollowType::Follow, None, context)?,
})
}

Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/following/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub async fn send_accept_or_reject_follow(
to: Some([community.ap_id.clone().into()]),
object: community.ap_id.into(),
kind: FollowType::Follow,
id: generate_activity_id(FollowType::Follow, context)?,
id: generate_activity_id(FollowType::Follow, None, context)?,
};
if accepted {
AcceptFollow::send(follow, context).await
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/following/reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl RejectFollow {
to: Some([person.id().clone().into()]),
object: follow,
kind: RejectType::Reject,
id: generate_activity_id(RejectType::Reject, context)?,
id: generate_activity_id(RejectType::Reject, None, context)?,
};
let inbox = ActivitySendTargets::to_inbox(person.shared_inbox_or_inbox());
send_activity_from_user_or_community_or_multi(context, reject, user_or_community, inbox).await
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/following/undo_follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl UndoFollow {
to: Some([target.id().clone().into()]),
object,
kind: UndoType::Undo,
id: generate_activity_id(UndoType::Undo, context)?,
id: generate_activity_id(UndoType::Undo, None, context)?,
};
let inbox = ActivitySendTargets::to_inbox(target.shared_inbox_or_inbox());
send_lemmy_activity(context, undo, actor, inbox, true).await
Expand Down
38 changes: 29 additions & 9 deletions crates/apub/activities/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,50 @@ pub(crate) fn check_community_deleted_or_removed(community: &Community) -> Lemmy

/// Generate a unique ID for an activity, in the format:
/// `http(s)://example.com/receive/create/202daf0a-1489-45df-8d2e-c8a3173fed36`
fn generate_activity_id<T>(kind: T, context: &LemmyContext) -> Result<Url, ParseError>
fn generate_activity_id<T>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid passing None in so many places, you could do:

fn generate_activity_id_with_object_id(kind, context) {
  generate_activity_id(kind, None, context)
}

fn generate_activity_id(kind, object_id, context) {
  generate_activity_id(kind, context)
}

kind: T,
object_id: Option<&str>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
object_id: Option<&str>,
object_id: Option<&Url>,

context: &LemmyContext,
) -> Result<Url, ParseError>
where
T: ToString,
{
let id = format!(
"{}/activities/{}/{}",
&context.settings().get_protocol_and_hostname(),
kind.to_string().to_lowercase(),
Uuid::new_v4()
);
let hostname = context.settings().get_protocol_and_hostname();
let kind_str = kind.to_string().to_lowercase();

let uuid_str = if let Some(o) = object_id {
let input = format!("{}:{}", kind_str, o);
Uuid::from_bytes(md5::compute(input).0).to_string()
} else {
Uuid::new_v4().to_string()
};

let id = format!("{}/activities/{}/{}", hostname, kind_str, uuid_str);
Url::parse(&id)
}

/// like generate_activity_id but also add the inner kind for easier debugging
fn generate_announce_activity_id(
inner_kind: &str,
protocol_and_hostname: &str,
object_id: Option<&str>,
) -> Result<Url, ParseError> {
let inner_kind_str = inner_kind.to_lowercase();

let uuid_str = if let Some(o) = object_id {
// add "announce:" in front to avoid collision with generate_activity_id
let input = format!("announce:{}:{}", inner_kind_str, o);
Uuid::from_bytes(md5::compute(input).0).to_string()
} else {
Uuid::new_v4().to_string()
};

let id = format!(
"{}/activities/{}/{}/{}",
protocol_and_hostname,
AnnounceType::Announce.to_string().to_lowercase(),
inner_kind.to_lowercase(),
Uuid::new_v4()
inner_kind_str,
uuid_str
);
Url::parse(&id)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/voting/undo_vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl UndoVote {
actor: actor.id().clone().into(),
object: vote,
kind: UndoType::Undo,
id: generate_activity_id(UndoType::Undo, context)?,
id: generate_activity_id(UndoType::Undo, None, context)?,
audience: Some(community.ap_id.clone().into()),
})
}
Expand Down
2 changes: 1 addition & 1 deletion crates/apub/activities/src/voting/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Vote {
actor: actor.id().clone().into(),
object: object_id,
kind: kind.clone(),
id: generate_activity_id(kind, context)?,
id: generate_activity_id(kind, None, context)?,
audience: Some(community.ap_id.clone().into()),
})
}
Expand Down
Loading