lemmy/crates/apub/src/activities/community/announce.rs

91 lines
2.6 KiB
Rust
Raw Normal View History

use crate::{
2021-11-02 13:02:39 +00:00
activities::{generate_activity_id, send_lemmy_activity, verify_activity, verify_is_public},
activity_lists::AnnouncableActivities,
http::{is_activity_already_known, ActivityCommonFields},
insert_activity,
objects::community::ApubCommunity,
protocol::activities::community::announce::AnnounceActivity,
};
use activitystreams::{activity::kind::AnnounceType, public};
use lemmy_apub_lib::{
data::Data,
2021-11-05 00:24:10 +00:00
object_id::ObjectId,
traits::{ActivityHandler, ActorType},
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
#[async_trait::async_trait(?Send)]
pub(crate) trait GetCommunity {
async fn get_community(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<ApubCommunity, LemmyError>;
}
impl AnnounceActivity {
pub async fn send(
object: AnnouncableActivities,
community: &ApubCommunity,
additional_inboxes: Vec<Url>,
context: &LemmyContext,
) -> Result<(), LemmyError> {
let announce = AnnounceActivity {
actor: ObjectId::new(community.actor_id()),
to: vec![public()],
object,
2021-11-05 00:24:10 +00:00
cc: vec![community.followers_url.clone().into()],
kind: AnnounceType::Announce,
id: generate_activity_id(
&AnnounceType::Announce,
&context.settings().get_protocol_and_hostname(),
)?,
unparsed: Default::default(),
};
2021-11-02 13:02:39 +00:00
let inboxes = community
.get_follower_inboxes(additional_inboxes, context)
.await?;
send_lemmy_activity(context, &announce, &announce.id, community, inboxes, false).await
}
}
#[async_trait::async_trait(?Send)]
impl ActivityHandler for AnnounceActivity {
type DataType = LemmyContext;
async fn verify(
&self,
context: &Data<LemmyContext>,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_is_public(&self.to, &self.cc)?;
verify_activity(&self.id, self.actor.inner(), &context.settings())?;
self.object.verify(context, request_counter).await?;
Ok(())
}
async fn receive(
self,
context: &Data<LemmyContext>,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
// TODO: this is pretty ugly, but i cant think of a much better way
let object = serde_json::to_string(&self.object)?;
let object_data: ActivityCommonFields = serde_json::from_str(&object)?;
if is_activity_already_known(context.pool(), &object_data.id).await? {
return Ok(());
}
insert_activity(
&object_data.id,
self.object.clone(),
false,
true,
context.pool(),
)
.await?;
self.object.receive(context, request_counter).await
}
}