From: Felix Ableitner Date: Sat, 31 Jul 2021 20:58:11 +0000 (+0200) Subject: Rewrite private message apub and merge create/update X-Git-Url: http://these/git/%7B%60%24%7BwebArchiveUrl%7D/%22%7B%7D/%7Bthis.state.thumbnail%7D?a=commitdiff_plain;h=6b57d716e1756290178f8f924288a64b27a740c6;p=lemmy.git Rewrite private message apub and merge create/update --- diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 3e3074ad..1da6466d 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -6,7 +6,14 @@ use lemmy_api_common::{ person::{CreatePrivateMessage, PrivateMessageResponse}, send_email_to_user, }; -use lemmy_apub::{generate_apub_endpoint, ApubObjectType, EndpointType}; +use lemmy_apub::{ + activities::{ + private_message::create_or_update::CreateOrUpdatePrivateMessage, + CreateOrUpdateType, + }, + generate_apub_endpoint, + EndpointType, +}; use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; use lemmy_db_schema::source::private_message::{PrivateMessage, PrivateMessageForm}; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; @@ -63,9 +70,13 @@ impl PerformCrud for CreatePrivateMessage { .await? .map_err(|_| ApiError::err("couldnt_create_private_message"))?; - updated_private_message - .send_create(&local_user_view.person, context) - .await?; + CreateOrUpdatePrivateMessage::send( + &updated_private_message, + &local_user_view.person, + CreateOrUpdateType::Create, + context, + ) + .await?; let private_message_view = blocking(context.pool(), move |conn| { PrivateMessageView::read(conn, inserted_private_message.id) diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 33c29d00..5f5f7b84 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -5,7 +5,10 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, person::{EditPrivateMessage, PrivateMessageResponse}, }; -use lemmy_apub::ApubObjectType; +use lemmy_apub::activities::{ + private_message::create_or_update::CreateOrUpdatePrivateMessage, + CreateOrUpdateType, +}; use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud, DeleteableOrRemoveable}; use lemmy_db_schema::source::private_message::PrivateMessage; use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView}; @@ -44,9 +47,13 @@ impl PerformCrud for EditPrivateMessage { .map_err(|_| ApiError::err("couldnt_update_private_message"))?; // Send the apub update - updated_private_message - .send_update(&local_user_view.person, context) - .await?; + CreateOrUpdatePrivateMessage::send( + &updated_private_message, + &local_user_view.person, + CreateOrUpdateType::Update, + context, + ) + .await?; let private_message_id = data.private_message_id; let mut private_message_view = blocking(context.pool(), move |conn| { diff --git a/crates/apub/src/activities/private_message/create.rs b/crates/apub/src/activities/private_message/create.rs deleted file mode 100644 index 5e6db4ea..00000000 --- a/crates/apub/src/activities/private_message/create.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::{ - activities::{private_message::send_websocket_message, verify_activity, verify_person}, - objects::FromApub, - NoteExt, -}; -use activitystreams::{activity::kind::CreateType, base::BaseExt}; -use lemmy_apub_lib::{verify_domains_match_opt, ActivityCommonFields, ActivityHandler}; -use lemmy_db_schema::source::private_message::PrivateMessage; -use lemmy_utils::LemmyError; -use lemmy_websocket::{LemmyContext, UserOperationCrud}; -use url::Url; - -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct CreatePrivateMessage { - to: Url, - object: NoteExt, - #[serde(rename = "type")] - kind: CreateType, - #[serde(flatten)] - common: ActivityCommonFields, -} - -#[async_trait::async_trait(?Send)] -impl ActivityHandler for CreatePrivateMessage { - async fn verify( - &self, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - verify_activity(self.common())?; - verify_person(&self.common.actor, context, request_counter).await?; - verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?; - Ok(()) - } - - async fn receive( - &self, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - let private_message = PrivateMessage::from_apub( - &self.object, - context, - self.common.actor.clone(), - request_counter, - false, - ) - .await?; - - send_websocket_message( - private_message.id, - UserOperationCrud::CreatePrivateMessage, - context, - ) - .await?; - - Ok(()) - } - - fn common(&self) -> &ActivityCommonFields { - &self.common - } -} diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs new file mode 100644 index 00000000..05f3c98f --- /dev/null +++ b/crates/apub/src/activities/private_message/create_or_update.rs @@ -0,0 +1,107 @@ +use crate::{ + activities::{ + generate_activity_id, + private_message::send_websocket_message, + verify_activity, + verify_person, + CreateOrUpdateType, + }, + activity_queue::send_activity_new, + extensions::context::lemmy_context, + objects::{private_message::Note, FromApub, ToApub}, + ActorType, +}; +use lemmy_api_common::blocking; +use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandler}; +use lemmy_db_queries::Crud; +use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_utils::LemmyError; +use lemmy_websocket::{LemmyContext, UserOperationCrud}; +use url::Url; + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CreateOrUpdatePrivateMessage { + to: Url, + object: Note, + #[serde(rename = "type")] + kind: CreateOrUpdateType, + #[serde(flatten)] + common: ActivityCommonFields, +} + +impl CreateOrUpdatePrivateMessage { + pub async fn send( + private_message: &PrivateMessage, + actor: &Person, + kind: CreateOrUpdateType, + context: &LemmyContext, + ) -> Result<(), LemmyError> { + let recipient_id = private_message.recipient_id; + let recipient = + blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; + + let id = generate_activity_id(kind.clone())?; + let create_or_update = CreateOrUpdatePrivateMessage { + to: recipient.actor_id(), + object: private_message.to_apub(context.pool()).await?, + kind, + common: ActivityCommonFields { + context: lemmy_context(), + id: id.clone(), + actor: actor.actor_id(), + unparsed: Default::default(), + }, + }; + send_activity_new( + context, + &create_or_update, + &id, + actor, + vec![recipient.get_shared_inbox_or_inbox_url()], + true, + ) + .await + } +} +#[async_trait::async_trait(?Send)] +impl ActivityHandler for CreateOrUpdatePrivateMessage { + async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_activity(self.common())?; + verify_person(&self.common.actor, context, request_counter).await?; + verify_domains_match(&self.common.actor, &self.object.id)?; + self.object.verify(context, request_counter).await?; + Ok(()) + } + + async fn receive( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + let private_message = PrivateMessage::from_apub( + &self.object, + context, + self.common.actor.clone(), + request_counter, + false, + ) + .await?; + + let notif_type = match self.kind { + CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage, + CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage, + }; + send_websocket_message(private_message.id, notif_type, context).await?; + + Ok(()) + } + + fn common(&self) -> &ActivityCommonFields { + &self.common + } +} diff --git a/crates/apub/src/activities/private_message/mod.rs b/crates/apub/src/activities/private_message/mod.rs index beb28b29..0c055728 100644 --- a/crates/apub/src/activities/private_message/mod.rs +++ b/crates/apub/src/activities/private_message/mod.rs @@ -4,10 +4,9 @@ use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::Priva use lemmy_utils::LemmyError; use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud}; -pub mod create; +pub mod create_or_update; pub mod delete; pub mod undo_delete; -pub mod update; async fn send_websocket_message( private_message_id: PrivateMessageId, diff --git a/crates/apub/src/activities/private_message/update.rs b/crates/apub/src/activities/private_message/update.rs deleted file mode 100644 index 72ac0749..00000000 --- a/crates/apub/src/activities/private_message/update.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::{ - activities::{private_message::send_websocket_message, verify_activity, verify_person}, - objects::FromApub, - NoteExt, -}; -use activitystreams::{activity::kind::UpdateType, base::BaseExt}; -use lemmy_apub_lib::{verify_domains_match_opt, ActivityCommonFields, ActivityHandler}; -use lemmy_db_schema::source::private_message::PrivateMessage; -use lemmy_utils::LemmyError; -use lemmy_websocket::{LemmyContext, UserOperationCrud}; -use url::Url; - -#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "camelCase")] -pub struct UpdatePrivateMessage { - to: Url, - object: NoteExt, - #[serde(rename = "type")] - kind: UpdateType, - #[serde(flatten)] - common: ActivityCommonFields, -} - -#[async_trait::async_trait(?Send)] -impl ActivityHandler for UpdatePrivateMessage { - async fn verify( - &self, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - verify_activity(self.common())?; - verify_person(&self.common.actor, context, request_counter).await?; - verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?; - Ok(()) - } - - async fn receive( - &self, - context: &LemmyContext, - request_counter: &mut i32, - ) -> Result<(), LemmyError> { - let private_message = PrivateMessage::from_apub( - &self.object, - context, - self.common.actor.clone(), - request_counter, - false, - ) - .await?; - - send_websocket_message( - private_message.id, - UserOperationCrud::EditPrivateMessage, - context, - ) - .await?; - - Ok(()) - } - - fn common(&self) -> &ActivityCommonFields { - &self.common - } -} diff --git a/crates/apub/src/activities/send/community.rs b/crates/apub/src/activities/send/community.rs index fbc61fc0..85241062 100644 --- a/crates/apub/src/activities/send/community.rs +++ b/crates/apub/src/activities/send/community.rs @@ -54,7 +54,7 @@ impl ActorType for Community { self.local } fn actor_id(&self) -> Url { - self.actor_id.to_owned().into_inner() + self.actor_id.to_owned().into() } fn name(&self) -> String { self.name.clone() @@ -78,7 +78,7 @@ impl ActorType for Community { #[async_trait::async_trait(?Send)] impl CommunityType for Community { fn followers_url(&self) -> Url { - self.followers_url.clone().into_inner() + self.followers_url.clone().into() } /// As a local community, accept the follow request from a remote person. diff --git a/crates/apub/src/activities/send/private_message.rs b/crates/apub/src/activities/send/private_message.rs index 67d0afcd..7461926c 100644 --- a/crates/apub/src/activities/send/private_message.rs +++ b/crates/apub/src/activities/send/private_message.rs @@ -2,19 +2,17 @@ use crate::{ activities::generate_activity_id, activity_queue::send_activity_single_dest, extensions::context::lemmy_context, - objects::ToApub, ActorType, ApubObjectType, }; use activitystreams::{ activity::{ - kind::{CreateType, DeleteType, UndoType, UpdateType}, - Create, + kind::{DeleteType, UndoType}, Delete, Undo, - Update, }, - prelude::*, + base::{BaseExt, ExtendsExt}, + object::ObjectExt, }; use lemmy_api_common::blocking; use lemmy_db_queries::Crud; @@ -24,47 +22,20 @@ use lemmy_websocket::LemmyContext; #[async_trait::async_trait(?Send)] impl ApubObjectType for PrivateMessage { - /// Send out information about a newly created private message - async fn send_create(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> { - let note = self.to_apub(context.pool()).await?; - - let recipient_id = self.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; - - let mut create = Create::new( - creator.actor_id.to_owned().into_inner(), - note.into_any_base()?, - ); - - create - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(CreateType::Create)?) - .set_to(recipient.actor_id()); - - send_activity_single_dest(create, creator, recipient.inbox_url.into(), context).await?; - Ok(()) + async fn send_create( + &self, + _creator: &Person, + _context: &LemmyContext, + ) -> Result<(), LemmyError> { + unimplemented!() } - /// Send out information about an edited private message, to the followers of the community. - async fn send_update(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> { - let note = self.to_apub(context.pool()).await?; - - let recipient_id = self.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; - - let mut update = Update::new( - creator.actor_id.to_owned().into_inner(), - note.into_any_base()?, - ); - update - .set_many_contexts(lemmy_context()) - .set_id(generate_activity_id(UpdateType::Update)?) - .set_to(recipient.actor_id()); - - send_activity_single_dest(update, creator, recipient.inbox_url.into(), context).await?; - Ok(()) + async fn send_update( + &self, + _creator: &Person, + _context: &LemmyContext, + ) -> Result<(), LemmyError> { + unimplemented!() } async fn send_delete(&self, creator: &Person, context: &LemmyContext) -> Result<(), LemmyError> { diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 6b264fad..587c6cfb 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -155,7 +155,7 @@ pub(crate) async fn get_apub_community_moderators( let moderators: Vec = moderators .into_iter() - .map(|m| m.moderator.actor_id.into_inner()) + .map(|m| m.moderator.actor_id.into()) .collect(); let mut collection = OrderedCollection::new(); collection diff --git a/crates/apub/src/http/inbox_enums.rs b/crates/apub/src/http/inbox_enums.rs index 2950799a..f8ee0cb2 100644 --- a/crates/apub/src/http/inbox_enums.rs +++ b/crates/apub/src/http/inbox_enums.rs @@ -11,10 +11,9 @@ use crate::activities::{ following::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity}, post::create_or_update::CreateOrUpdatePost, private_message::{ - create::CreatePrivateMessage, + create_or_update::CreateOrUpdatePrivateMessage, delete::DeletePrivateMessage, undo_delete::UndoDeletePrivateMessage, - update::UpdatePrivateMessage, }, removal::{ remove::RemovePostCommentCommunityOrMod, @@ -36,8 +35,7 @@ use serde::{Deserialize, Serialize}; #[serde(untagged)] pub enum PersonInboxActivities { AcceptFollowCommunity(AcceptFollowCommunity), - CreatePrivateMessage(CreatePrivateMessage), - UpdatePrivateMessage(UpdatePrivateMessage), + CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage), DeletePrivateMessage(DeletePrivateMessage), UndoDeletePrivateMessage(UndoDeletePrivateMessage), AnnounceActivity(Box), @@ -71,7 +69,7 @@ pub enum SharedInboxActivities { FollowCommunity(FollowCommunity), UndoFollowCommunity(UndoFollowCommunity), CreateOrUpdateComment(CreateOrUpdateComment), - CreateOrUpdatePost(CreateOrUpdatePost), + CreateOrUpdatePost(Box), LikePostOrComment(LikePostOrComment), DislikePostOrComment(DislikePostOrComment), UndoDislikePostOrComment(UndoDislikePostOrComment), @@ -88,8 +86,7 @@ pub enum SharedInboxActivities { AcceptFollowCommunity(AcceptFollowCommunity), // 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. - CreatePrivateMessage(CreatePrivateMessage), - UpdatePrivateMessage(UpdatePrivateMessage), + CreateOrUpdatePrivateMessage(CreateOrUpdatePrivateMessage), DeletePrivateMessage(DeletePrivateMessage), UndoDeletePrivateMessage(UndoDeletePrivateMessage), AnnounceActivity(Box), diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 94da33cc..16773aae 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -20,7 +20,7 @@ use activitystreams::{ activity::Follow, actor, base::AnyBase, - object::{ApObject, AsObject, Note, ObjectExt}, + object::{ApObject, AsObject, ObjectExt}, }; use activitystreams_ext::Ext2; use anyhow::{anyhow, Context}; @@ -53,7 +53,6 @@ pub type GroupExt = type PersonExt = Ext2>>, PersonExtension, PublicKeyExtension>; pub type SiteExt = actor::ApActor>; -pub type NoteExt = ApObject; #[derive(Clone, Copy, Debug, serde::Deserialize, serde::Serialize, PartialEq)] pub enum UserTypes { @@ -314,7 +313,7 @@ pub fn generate_inbox_url(actor_id: &DbUrl) -> Result { } pub fn generate_shared_inbox_url(actor_id: &DbUrl) -> Result { - let actor_id = actor_id.clone().into_inner(); + let actor_id: Url = actor_id.clone().into(); let url = format!( "{}://{}{}/inbox", &actor_id.scheme(), diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 624123ec..2b284a2d 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -1,60 +1,93 @@ use crate::{ extensions::context::lemmy_context, fetcher::person::get_or_fetch_and_upsert_person, - objects::{ - check_object_domain, - create_tombstone, - get_object_from_apub, - get_source_markdown_value, - set_content_and_source, - FromApub, - FromApubToForm, - ToApub, - }, - NoteExt, + objects::{create_tombstone, FromApub, Source, ToApub}, }; use activitystreams::{ - object::{kind::NoteType, ApObject, Note, Tombstone}, - prelude::*, + base::AnyBase, + object::{kind::NoteType, Tombstone}, + primitives::OneOrMany, + unparsed::Unparsed, }; -use anyhow::Context; +use anyhow::anyhow; +use chrono::{DateTime, FixedOffset}; use lemmy_api_common::blocking; -use lemmy_db_queries::{Crud, DbPool}; +use lemmy_apub_lib::{ + values::{MediaTypeHtml, MediaTypeMarkdown}, + verify_domains_match, +}; +use lemmy_db_queries::{ApubObject, Crud, DbPool}; use lemmy_db_schema::source::{ person::Person, private_message::{PrivateMessage, PrivateMessageForm}, }; -use lemmy_utils::{location_info, utils::convert_datetime, LemmyError}; +use lemmy_utils::{utils::convert_datetime, LemmyError}; use lemmy_websocket::LemmyContext; +use serde::{Deserialize, Serialize}; use url::Url; +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Note { + #[serde(rename = "@context")] + context: OneOrMany, + r#type: NoteType, + pub(crate) id: Url, + pub(crate) attributed_to: Url, + to: Url, + content: String, + media_type: MediaTypeHtml, + source: Source, + published: DateTime, + updated: Option>, + #[serde(flatten)] + unparsed: Unparsed, +} + +impl Note { + pub(crate) async fn verify( + &self, + context: &LemmyContext, + request_counter: &mut i32, + ) -> Result<(), LemmyError> { + verify_domains_match(&self.attributed_to, &self.id)?; + let person = + get_or_fetch_and_upsert_person(&self.attributed_to, context, request_counter).await?; + if person.banned { + return Err(anyhow!("Person is banned from site").into()); + } + Ok(()) + } +} + #[async_trait::async_trait(?Send)] impl ToApub for PrivateMessage { - type ApubType = NoteExt; - - async fn to_apub(&self, pool: &DbPool) -> Result { - let mut private_message = ApObject::new(Note::new()); + type ApubType = Note; + async fn to_apub(&self, pool: &DbPool) -> Result { let creator_id = self.creator_id; let creator = blocking(pool, move |conn| Person::read(conn, creator_id)).await??; let recipient_id = self.recipient_id; let recipient = blocking(pool, move |conn| Person::read(conn, recipient_id)).await??; - private_message - .set_many_contexts(lemmy_context()) - .set_id(self.ap_id.to_owned().into_inner()) - .set_published(convert_datetime(self.published)) - .set_to(recipient.actor_id.into_inner()) - .set_attributed_to(creator.actor_id.into_inner()); - - set_content_and_source(&mut private_message, &self.content)?; - - if let Some(u) = self.updated { - private_message.set_updated(convert_datetime(u)); - } - - Ok(private_message) + let note = Note { + context: lemmy_context(), + r#type: NoteType::Note, + id: self.ap_id.clone().into(), + attributed_to: creator.actor_id.into_inner(), + to: recipient.actor_id.into(), + content: self.content.clone(), + media_type: MediaTypeHtml::Html, + source: Source { + content: self.content.clone(), + media_type: MediaTypeMarkdown::Markdown, + }, + published: convert_datetime(self.published), + updated: self.updated.map(convert_datetime), + unparsed: Default::default(), + }; + Ok(note) } fn to_tombstone(&self) -> Result { @@ -69,66 +102,35 @@ impl ToApub for PrivateMessage { #[async_trait::async_trait(?Send)] impl FromApub for PrivateMessage { - type ApubType = NoteExt; + type ApubType = Note; async fn from_apub( - note: &NoteExt, + note: &Note, context: &LemmyContext, - expected_domain: Url, - request_counter: &mut i32, - mod_action_allowed: bool, - ) -> Result { - get_object_from_apub( - note, - context, - expected_domain, - request_counter, - mod_action_allowed, - ) - .await - } -} - -#[async_trait::async_trait(?Send)] -impl FromApubToForm for PrivateMessageForm { - async fn from_apub( - note: &NoteExt, - context: &LemmyContext, - expected_domain: Url, + _expected_domain: Url, request_counter: &mut i32, _mod_action_allowed: bool, - ) -> Result { - let creator_actor_id = note - .attributed_to() - .context(location_info!())? - .clone() - .single_xsd_any_uri() - .context(location_info!())?; - + ) -> Result { let creator = - get_or_fetch_and_upsert_person(&creator_actor_id, context, request_counter).await?; - let recipient_actor_id = note - .to() - .context(location_info!())? - .clone() - .single_xsd_any_uri() - .context(location_info!())?; - let recipient = - get_or_fetch_and_upsert_person(&recipient_actor_id, context, request_counter).await?; - let ap_id = Some(check_object_domain(note, expected_domain, false)?); - - let content = get_source_markdown_value(note)?.context(location_info!())?; + get_or_fetch_and_upsert_person(¬e.attributed_to, context, request_counter).await?; + let recipient = get_or_fetch_and_upsert_person(¬e.to, context, request_counter).await?; - Ok(PrivateMessageForm { + let form = PrivateMessageForm { creator_id: creator.id, recipient_id: recipient.id, - content, - published: note.published().map(|u| u.to_owned().naive_local()), - updated: note.updated().map(|u| u.to_owned().naive_local()), + content: note.source.content.clone(), + published: Some(note.published.naive_local()), + updated: note.updated.map(|u| u.to_owned().naive_local()), deleted: None, read: None, - ap_id, + ap_id: Some(note.id.clone().into()), local: Some(false), - }) + }; + Ok( + blocking(context.pool(), move |conn| { + PrivateMessage::upsert(conn, &form) + }) + .await??, + ) } } diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index 4efa983f..3c8abaf7 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -92,6 +92,7 @@ where } impl DbUrl { + // TODO: remove this method and just use into() pub fn into_inner(self) -> Url { self.0 } @@ -99,7 +100,7 @@ impl DbUrl { impl Display for DbUrl { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - self.to_owned().into_inner().fmt(f) + self.to_owned().0.fmt(f) } }