.await??;
let community_id = post.community_id;
- let object = PostOrComment::Post(Box::new(post));
+ let object = PostOrComment::Post(post);
// Only add the like if the score isnt 0
let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
context,
)
.await?;
- let object = PostOrComment::Post(Box::new(apub_post));
+ let object = PostOrComment::Post(apub_post);
Vote::send(
&object,
&local_user_view.person.clone().into(),
},
activity_lists::AnnouncableActivities,
objects::{community::ApubCommunity, person::ApubPerson},
- protocol::{activities::community::update::UpdateCommunity, objects::group::Group},
+ protocol::activities::community::update::UpdateCommunity,
};
use activitystreams::{activity::kind::UpdateType, public};
use lemmy_api_common::blocking;
let update = UpdateCommunity {
actor: ObjectId::new(actor.actor_id()),
to: vec![public()],
- object: community.clone().into_apub(context).await?,
+ object: Box::new(community.clone().into_apub(context).await?),
cc: vec![community.actor_id()],
kind: UpdateType::Update,
id: id.clone(),
unparsed: Default::default(),
};
- let activity = AnnouncableActivities::UpdateCommunity(Box::new(update));
+ let activity = AnnouncableActivities::UpdateCommunity(update);
send_to_community(activity, &id, actor, &community, vec![], context).await
}
}
) -> Result<(), LemmyError> {
let community = self.get_community(context, request_counter).await?;
- let updated_community = Group::into_form(
- self.object,
- &community.actor_id.clone().into(),
- &context.settings(),
- )
- .await?;
+ let updated_community = self
+ .object
+ .into_form(&community.actor_id.clone().into(), &context.settings())
+ .await?;
let cf = CommunityForm {
name: updated_community.name,
title: updated_community.title,
}
pub enum DeletableObjects {
- Community(Box<ApubCommunity>),
- Comment(Box<ApubComment>),
- Post(Box<ApubPost>),
+ Community(ApubCommunity),
+ Comment(ApubComment),
+ Post(ApubPost),
}
impl DeletableObjects {
context: &LemmyContext,
) -> Result<DeletableObjects, LemmyError> {
if let Some(c) = ApubCommunity::read_from_apub_id(ap_id.clone(), context).await? {
- return Ok(DeletableObjects::Community(Box::new(c)));
+ return Ok(DeletableObjects::Community(c));
}
if let Some(p) = ApubPost::read_from_apub_id(ap_id.clone(), context).await? {
- return Ok(DeletableObjects::Post(Box::new(p)));
+ return Ok(DeletableObjects::Post(p));
}
if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? {
- return Ok(DeletableObjects::Comment(Box::new(c)));
+ return Ok(DeletableObjects::Comment(c));
}
Err(diesel::NotFound.into())
}
.into();
let create_or_update = CreateOrUpdatePost::new(post, actor, &community, kind, context).await?;
let id = create_or_update.id.clone();
- let activity = AnnouncableActivities::CreateOrUpdatePost(Box::new(create_or_update));
+ let activity = AnnouncableActivities::CreateOrUpdatePost(create_or_update);
send_to_community(activity, &id, actor, &community, vec![], context).await
}
}
use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
-use std::ops::Deref;
impl UndoVote {
pub async fn send(
.dereference(context, request_counter)
.await?;
match object {
- PostOrComment::Post(p) => undo_vote_post(actor, p.deref(), context).await,
+ PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
}
}
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
-use std::ops::Deref;
impl Vote {
pub(in crate::activities::voting) fn new(
let actor = self.actor.dereference(context, request_counter).await?;
let object = self.object.dereference(context, request_counter).await?;
match object {
- PostOrComment::Post(p) => vote_post(&self.kind, actor, p.deref(), context).await,
+ PostOrComment::Post(p) => vote_post(&self.kind, actor, &p, context).await,
PostOrComment::Comment(c) => vote_comment(&self.kind, actor, &c, context).await,
}
}
GroupInboxActivities(GroupInboxActivities),
// Note, pm activities need to be at the end, otherwise comments will end up here. We can probably
// avoid this problem by replacing createpm.object with our own struct, instead of NoteExt.
- PersonInboxActivities(PersonInboxActivities),
+ PersonInboxActivities(Box<PersonInboxActivities>),
}
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
pub enum GroupInboxActivities {
FollowCommunity(FollowCommunity),
UndoFollowCommunity(UndoFollowCommunity),
- AnnouncableActivities(AnnouncableActivities),
+ AnnouncableActivities(Box<AnnouncableActivities>),
Report(Report),
}
CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage),
DeletePrivateMessage(DeletePrivateMessage),
UndoDeletePrivateMessage(UndoDeletePrivateMessage),
- AnnounceActivity(Box<AnnounceActivity>),
+ AnnounceActivity(AnnounceActivity),
}
#[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
#[activity_handler(LemmyContext)]
pub enum AnnouncableActivities {
CreateOrUpdateComment(CreateOrUpdateComment),
- CreateOrUpdatePost(Box<CreateOrUpdatePost>),
+ CreateOrUpdatePost(CreateOrUpdatePost),
Vote(Vote),
UndoVote(UndoVote),
Delete(Delete),
UndoDelete(UndoDelete),
- UpdateCommunity(Box<UpdateCommunity>),
+ UpdateCommunity(UpdateCommunity),
BlockUserFromCommunity(BlockUserFromCommunity),
UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
AddMod(AddMod),
#[derive(Clone, Debug)]
pub enum PostOrComment {
- Post(Box<ApubPost>),
+ Post(ApubPost),
Comment(ApubComment),
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum PageOrNote {
- Page(Box<Page>),
- Note(Box<Note>),
+ Page(Page),
+ Note(Note),
}
#[async_trait::async_trait(?Send)]
) -> Result<Option<Self>, LemmyError> {
let post = ApubPost::read_from_apub_id(object_id.clone(), data).await?;
Ok(match post {
- Some(o) => Some(PostOrComment::Post(Box::new(o))),
+ Some(o) => Some(PostOrComment::Post(o)),
None => ApubComment::read_from_apub_id(object_id, data)
.await?
.map(PostOrComment::Comment),
request_counter: &mut i32,
) -> Result<Self, LemmyError> {
Ok(match apub {
- PageOrNote::Page(p) => PostOrComment::Post(Box::new(
- ApubPost::from_apub(*p, context, expected_domain, request_counter).await?,
- )),
+ PageOrNote::Page(p) => PostOrComment::Post(
+ ApubPost::from_apub(p, context, expected_domain, request_counter).await?,
+ ),
PageOrNote::Note(n) => PostOrComment::Comment(
- ApubComment::from_apub(*n, context, expected_domain, request_counter).await?,
+ ApubComment::from_apub(n, context, expected_domain, request_counter).await?,
),
})
}
let community = announcable.get_community(context, &mut 0).await?;
verify_person_in_community(&actor_id, &community, context, &mut 0).await?;
if community.local {
- AnnounceActivity::send(announcable, &community, vec![], context).await?;
+ AnnounceActivity::send(*announcable, &community, vec![], context).await?;
}
}
receive_group_inbox(g, activity_data, request, &context).await
}
SharedInboxActivities::PersonInboxActivities(p) => {
- receive_person_inbox(p, activity_data, request, &context).await
+ receive_person_inbox(*p, activity_data, request, &context).await
}
}
}
generate_moderators_url,
generate_outbox_url,
protocol::{
- objects::{group::Group, tombstone::Tombstone},
+ objects::{group::Group, tombstone::Tombstone, Endpoints},
ImageObject,
Source,
},
};
-use activitystreams::{
- actor::{kind::GroupType, Endpoints},
- object::kind::ImageType,
-};
+use activitystreams::{actor::kind::GroupType, object::kind::ImageType};
use chrono::NaiveDateTime;
use itertools::Itertools;
use lemmy_api_common::blocking;
followers: self.followers_url.clone().into(),
endpoints: Endpoints {
shared_inbox: self.shared_inbox_url.clone().map(|s| s.into()),
- ..Default::default()
},
public_key: self.get_public_key()?,
published: Some(convert_datetime(self.published)),
generate_outbox_url,
objects::get_summary_from_string_or_source,
protocol::{
- objects::person::{Person, UserTypes},
+ objects::{
+ person::{Person, UserTypes},
+ Endpoints,
+ },
ImageObject,
Source,
},
};
-use activitystreams::{actor::Endpoints, object::kind::ImageType};
+use activitystreams::object::kind::ImageType;
use chrono::NaiveDateTime;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
outbox: generate_outbox_url(&self.actor_id)?.into(),
endpoints: Endpoints {
shared_inbox: self.shared_inbox_url.clone().map(|s| s.into()),
- ..Default::default()
},
public_key: self.get_public_key()?,
updated: self.updated.map(convert_datetime),
pub(crate) actor: ObjectId<ApubPerson>,
pub(crate) to: Vec<Url>,
// TODO: would be nice to use a separate struct here, which only contains the fields updated here
- pub(crate) object: Group,
+ pub(crate) object: Box<Group>,
pub(crate) cc: Vec<Url>,
#[serde(rename = "type")]
pub(crate) kind: UpdateType,
community_outbox::ApubCommunityOutbox,
},
objects::{community::ApubCommunity, get_summary_from_string_or_source},
- protocol::{ImageObject, Source},
-};
-use activitystreams::{
- actor::{kind::GroupType, Endpoints},
- unparsed::Unparsed,
+ protocol::{objects::Endpoints, ImageObject, Source},
};
+use activitystreams::{actor::kind::GroupType, unparsed::Unparsed};
use chrono::{DateTime, FixedOffset};
use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey, verify::verify_domains_match};
use lemmy_db_schema::{naive_now, source::community::CommunityForm};
pub(crate) inbox: Url,
pub(crate) outbox: ObjectId<ApubCommunityOutbox>,
pub(crate) followers: Url,
- pub(crate) endpoints: Endpoints<Url>,
+ pub(crate) endpoints: Endpoints,
pub(crate) public_key: PublicKey,
pub(crate) published: Option<DateTime<FixedOffset>>,
pub(crate) updated: Option<DateTime<FixedOffset>>,
check_slurs(&title, slur_regex)?;
check_slurs_opt(&description, slur_regex)?;
- // TODO: test_parse_lemmy_community_moderators() keeps failing here with stack overflow
Ok(CommunityForm {
name,
title,
+use serde::{Deserialize, Serialize};
+use url::Url;
+
pub(crate) mod chat_message;
pub(crate) mod group;
pub(crate) mod note;
pub(crate) mod person;
pub(crate) mod tombstone;
+#[derive(Clone, Debug, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct Endpoints {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub shared_inbox: Option<Url>,
+}
+
#[cfg(test)]
mod tests {
use crate::protocol::{
use crate::{
objects::person::ApubPerson,
- protocol::{ImageObject, Source},
+ protocol::{objects::Endpoints, ImageObject, Source},
};
-use activitystreams::{actor::Endpoints, unparsed::Unparsed, url::Url};
+use activitystreams::{unparsed::Unparsed, url::Url};
use chrono::{DateTime, FixedOffset};
use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey};
use serde::{Deserialize, Serialize};
pub(crate) inbox: Url,
/// mandatory field in activitypub, currently empty in lemmy
pub(crate) outbox: Url,
- pub(crate) endpoints: Endpoints<Url>,
+ pub(crate) endpoints: Endpoints,
pub(crate) public_key: PublicKey,
pub(crate) published: Option<DateTime<FixedOffset>>,
pub(crate) updated: Option<DateTime<FixedOffset>>,
.unwrap();
}
+/// We store Url on the heap because it is quite large (88 bytes).
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
#[serde(transparent)]
-pub struct ObjectId<Kind>(Url, #[serde(skip)] PhantomData<Kind>)
+pub struct ObjectId<Kind>(Box<Url>, #[serde(skip)] PhantomData<Kind>)
where
Kind: ApubObject + Send + 'static,
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>;
where
T: Into<Url>,
{
- ObjectId(url.into(), PhantomData::<Kind>)
+ ObjectId(Box::new(url.into()), PhantomData::<Kind>)
}
pub fn inner(&self) -> &Url {
data: &<Kind as ApubObject>::DataType,
) -> Result<Option<Kind>, LemmyError> {
let id = self.0.clone();
- ApubObject::read_from_apub_id(id, data).await
+ ApubObject::read_from_apub_id(*id, data).await
}
async fn dereference_from_http(
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
{
fn from(id: ObjectId<Kind>) -> Self {
- id.0
+ *id.0
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PublicKey {
- pub id: String,
- pub owner: Url,
+ pub(crate) id: String,
+ pub(crate) owner: Box<Url>,
pub public_key_pem: String,
}
fn get_public_key(&self) -> Result<PublicKey, LemmyError> {
Ok(PublicKey {
id: format!("{}#main-key", self.actor_id()),
- owner: self.actor_id(),
+ owner: Box::new(self.actor_id()),
public_key_pem: self.public_key().context(location_info!())?,
})
}