mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-05 20:15:01 +00:00
implemented some more
This commit is contained in:
parent
d24f274cb7
commit
b605057e85
9 changed files with 167 additions and 167 deletions
|
@ -1,6 +1,6 @@
|
|||
use crate::activities::receive::get_actor_as_person;
|
||||
use activitystreams::{
|
||||
activity::{ActorAndObjectRefExt, Create, Dislike, Like, Update},
|
||||
activity::{ActorAndObjectRefExt, Dislike, Like, Update},
|
||||
base::ExtendsExt,
|
||||
};
|
||||
use anyhow::Context;
|
||||
|
@ -15,71 +15,6 @@ use lemmy_db_views::comment_view::CommentView;
|
|||
use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
|
||||
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation, UserOperationCrud};
|
||||
|
||||
// TODO:
|
||||
// - define traits for all activity types
|
||||
// - implement inbox routing with these traits
|
||||
// - replace context with actix style Data struct (actix_web::web::Data)
|
||||
pub(crate) trait ReceiveCreate {
|
||||
fn receive_create(self, create: Create, context: LemmyContext, request_counter: &mut i32);
|
||||
}
|
||||
|
||||
impl ReceiveCreate for Comment {
|
||||
fn receive_create(self, _create: Create, _context: LemmyContext, _request_counter: &mut i32) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_create_comment(
|
||||
create: Create,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let person = get_actor_as_person(&create, context, request_counter).await?;
|
||||
let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
|
||||
.context(location_info!())?;
|
||||
|
||||
let comment =
|
||||
Comment::from_apub(¬e, context, person.actor_id(), request_counter, false).await?;
|
||||
|
||||
let post_id = comment.post_id;
|
||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
|
||||
// Note:
|
||||
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
||||
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||
// anyway.
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
let recipient_ids = send_local_notifs(
|
||||
mentions,
|
||||
comment.clone(),
|
||||
person,
|
||||
post,
|
||||
context.pool(),
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Refetch the view
|
||||
let comment_view = blocking(context.pool(), move |conn| {
|
||||
CommentView::read(conn, comment.id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = CommentResponse {
|
||||
comment_view,
|
||||
recipient_ids,
|
||||
form_id: None,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendComment {
|
||||
op: UserOperationCrud::CreateComment,
|
||||
comment: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_update_comment(
|
||||
update: Update,
|
||||
context: &LemmyContext,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::activities::receive::verify_activity_domains_valid;
|
||||
use activitystreams::{
|
||||
activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update},
|
||||
activity::{ActorAndObjectRefExt, Delete, Undo, Update},
|
||||
base::{AsBase, ExtendsExt},
|
||||
object::AsObject,
|
||||
public,
|
||||
|
@ -21,54 +21,6 @@ use lemmy_utils::{location_info, LemmyError};
|
|||
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
pub(crate) async fn receive_create_private_message(
|
||||
context: &LemmyContext,
|
||||
create: Create,
|
||||
expected_domain: Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
check_private_message_activity_valid(&create, context, request_counter).await?;
|
||||
|
||||
let note = NoteExt::from_any_base(
|
||||
create
|
||||
.object()
|
||||
.as_one()
|
||||
.context(location_info!())?
|
||||
.to_owned(),
|
||||
)?
|
||||
.context(location_info!())?;
|
||||
|
||||
let private_message =
|
||||
PrivateMessage::from_apub(¬e, context, expected_domain, request_counter, false).await?;
|
||||
|
||||
let message = blocking(&context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, private_message.id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
};
|
||||
|
||||
// Send notifications to the local recipient, if one exists
|
||||
let recipient_id = res.private_message_view.recipient.id;
|
||||
let local_recipient_id = blocking(context.pool(), move |conn| {
|
||||
LocalUserView::read_person(conn, recipient_id)
|
||||
})
|
||||
.await??
|
||||
.local_user
|
||||
.id;
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperationCrud::CreatePrivateMessage,
|
||||
response: res,
|
||||
local_recipient_id,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_update_private_message(
|
||||
context: &LemmyContext,
|
||||
update: Update,
|
||||
|
|
74
crates/apub_receive/src/activities_new/comment.rs
Normal file
74
crates/apub_receive/src/activities_new/comment.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use crate::inbox::new_inbox_routing::{ReceiveActivity, Activity, PublicUrl};
|
||||
use url::Url;
|
||||
use lemmy_apub::NoteExt;
|
||||
use activitystreams::
|
||||
activity::kind::{CreateType};
|
||||
use lemmy_websocket::{LemmyContext, UserOperationCrud};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_db_views::comment_view::CommentView;
|
||||
use lemmy_api_common::comment::CommentResponse;
|
||||
use lemmy_websocket::messages::SendComment;
|
||||
use lemmy_api_common::{send_local_notifs, blocking};
|
||||
use lemmy_db_schema::source::comment::Comment;
|
||||
use lemmy_apub::objects::FromApub;
|
||||
use lemmy_utils::utils::scrape_text_for_mentions;
|
||||
use lemmy_db_schema::source::post::Post;
|
||||
use lemmy_db_queries::Crud;
|
||||
use lemmy_apub::fetcher::person::get_or_fetch_and_upsert_person;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateComment {
|
||||
actor: Url,
|
||||
to: PublicUrl,
|
||||
object: NoteExt,
|
||||
#[serde(rename = "type")]
|
||||
kind: CreateType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<CreateComment> {
|
||||
async fn receive(&self, context: &LemmyContext, request_counter: &mut i32) -> Result<(), LemmyError> {
|
||||
let comment =
|
||||
Comment::from_apub(&self.inner.object, context, self.inner.actor.clone(), request_counter, false).await?;
|
||||
|
||||
let post_id = comment.post_id;
|
||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||
let actor = get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
|
||||
// Note:
|
||||
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
||||
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||
// anyway.
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
let recipient_ids = send_local_notifs(
|
||||
mentions,
|
||||
comment.clone(),
|
||||
actor,
|
||||
post,
|
||||
context.pool(),
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Refetch the view
|
||||
let comment_view = blocking(context.pool(), move |conn| {
|
||||
CommentView::read(conn, comment.id, None)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = CommentResponse {
|
||||
comment_view,
|
||||
recipient_ids,
|
||||
form_id: None,
|
||||
};
|
||||
|
||||
context.chat_server().do_send(SendComment {
|
||||
op: UserOperationCrud::CreateComment,
|
||||
comment: res,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
use crate::{
|
||||
activities::receive::verify_activity_domains_valid,
|
||||
inbox::new_inbox_routing::{verify_domains_match, Activity, ReceiveActivity},
|
||||
};
|
||||
use activitystreams::{
|
||||
activity::kind::{AcceptType, FollowType},
|
||||
base::ExtendsExt,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::{
|
||||
community::get_or_fetch_and_upsert_community,
|
||||
|
@ -14,14 +11,13 @@ use lemmy_apub::fetcher::{
|
|||
};
|
||||
use lemmy_db_queries::Followable;
|
||||
use lemmy_db_schema::source::community::CommunityFollower;
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_utils::{LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Follow {
|
||||
// todo: implement newtypes PersonUrl, GroupUrl etc (with deref function)
|
||||
actor: Url,
|
||||
to: Url,
|
||||
object: Url,
|
||||
|
@ -33,8 +29,8 @@ pub struct Follow {
|
|||
impl ReceiveActivity for Activity<Follow> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
_context: &LemmyContext,
|
||||
_request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
println!("receive follow");
|
||||
todo!()
|
||||
|
@ -44,7 +40,6 @@ impl ReceiveActivity for Activity<Follow> {
|
|||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Accept {
|
||||
// todo: implement newtypes PersonUrl, GroupUrl etc (with deref function)
|
||||
actor: Url,
|
||||
to: Url,
|
||||
object: Activity<Follow>,
|
||||
|
@ -60,6 +55,7 @@ impl ReceiveActivity for Activity<Accept> {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
// TODO: move check for id.domain == actor.domain to library and do it automatically
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
let follow = &self.inner.object;
|
||||
verify_domains_match(&follow.inner.actor, &follow.id_unchecked())?;
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
pub mod comment;
|
||||
pub mod follow;
|
||||
pub mod private_message;
|
||||
|
|
64
crates/apub_receive/src/activities_new/private_message.rs
Normal file
64
crates/apub_receive/src/activities_new/private_message.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
use crate::inbox::new_inbox_routing::{Activity, ReceiveActivity};
|
||||
use activitystreams::activity::kind::CreateType;
|
||||
use lemmy_api_common::{blocking, person::PrivateMessageResponse};
|
||||
use lemmy_apub::{objects::FromApub, NoteExt};
|
||||
use lemmy_db_schema::source::private_message::PrivateMessage;
|
||||
use lemmy_db_views::{local_user_view::LocalUserView, private_message_view::PrivateMessageView};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperationCrud};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreatePrivateMessage {
|
||||
actor: Url,
|
||||
to: Url,
|
||||
object: NoteExt,
|
||||
#[serde(rename = "type")]
|
||||
kind: CreateType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<CreatePrivateMessage> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let private_message = PrivateMessage::from_apub(
|
||||
&self.inner.object,
|
||||
context,
|
||||
self.inner.actor.clone(),
|
||||
request_counter,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let message = blocking(&context.pool(), move |conn| {
|
||||
PrivateMessageView::read(conn, private_message.id)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let res = PrivateMessageResponse {
|
||||
private_message_view: message,
|
||||
};
|
||||
|
||||
// Send notifications to the local recipient, if one exists
|
||||
let recipient_id = res.private_message_view.recipient.id;
|
||||
let local_recipient_id = blocking(context.pool(), move |conn| {
|
||||
LocalUserView::read_person(conn, recipient_id)
|
||||
})
|
||||
.await??
|
||||
.local_user
|
||||
.id;
|
||||
|
||||
context.chat_server().do_send(SendUserRoomMessage {
|
||||
op: UserOperationCrud::CreatePrivateMessage,
|
||||
response: res,
|
||||
local_recipient_id,
|
||||
websocket_id: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ use lemmy_utils::LemmyError;
|
|||
use lemmy_websocket::LemmyContext;
|
||||
use std::marker::PhantomData;
|
||||
use url::Url;
|
||||
use crate::activities_new::private_message::CreatePrivateMessage;
|
||||
use crate::activities_new::comment::CreateComment;
|
||||
|
||||
// for now, limit it to activity routing only, no http sigs, parsing or any of that
|
||||
// need to route in this order:
|
||||
|
@ -24,16 +26,22 @@ use url::Url;
|
|||
// .checkHttpSig::<RequestType>()
|
||||
// .fetchObject() - for custom http client
|
||||
// .checkActivity() - for common validity checks
|
||||
struct InboxConfig {
|
||||
pub struct InboxConfig {
|
||||
//actors: Vec<ActorConfig>,
|
||||
}
|
||||
|
||||
impl InboxConfig {
|
||||
fn shared_inbox_handler() {
|
||||
pub fn shared_inbox_handler() {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub enum PublicUrl {
|
||||
#[serde(rename = "https://www.w3.org/ns/activitystreams#Public")]
|
||||
Public,
|
||||
}
|
||||
|
||||
pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> {
|
||||
if a.domain() != b.domain() {
|
||||
return Err(DomainError.into());
|
||||
|
@ -94,6 +102,8 @@ impl<Kind> Activity<Kind> {
|
|||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub enum PersonAcceptedActivitiesNew {
|
||||
Accept(Accept),
|
||||
CreatePrivateMessage(CreatePrivateMessage),
|
||||
CreateComment(CreateComment)
|
||||
}
|
||||
|
||||
// todo: there should be a better way to do this (maybe needs a derive macro)
|
||||
|
@ -104,7 +114,6 @@ impl ReceiveActivity for PersonAcceptedActivitiesNew {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
use PersonAcceptedActivitiesNew::*;
|
||||
self.receive(context, request_counter).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
activities::receive::{
|
||||
comment::{receive_create_comment, receive_update_comment},
|
||||
comment::receive_update_comment,
|
||||
community::{
|
||||
receive_delete_community,
|
||||
receive_remove_community,
|
||||
|
@ -8,7 +8,6 @@ use crate::{
|
|||
receive_undo_remove_community,
|
||||
},
|
||||
private_message::{
|
||||
receive_create_private_message,
|
||||
receive_delete_private_message,
|
||||
receive_undo_delete_private_message,
|
||||
receive_update_private_message,
|
||||
|
@ -17,9 +16,6 @@ use crate::{
|
|||
verify_activity_domains_valid,
|
||||
},
|
||||
inbox::{
|
||||
assert_activity_not_local,
|
||||
get_activity_id,
|
||||
inbox_verify_http_signature,
|
||||
is_activity_already_known,
|
||||
is_addressed_to_community_followers,
|
||||
is_addressed_to_local_person,
|
||||
|
@ -39,7 +35,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use activitystreams::{
|
||||
activity::{Accept, ActorAndObject, Announce, Create, Delete, Follow, Remove, Undo, Update},
|
||||
activity::{ActorAndObject, Announce, Delete, Remove, Undo, Update},
|
||||
base::AnyBase,
|
||||
prelude::*,
|
||||
};
|
||||
|
@ -49,12 +45,10 @@ use diesel::NotFound;
|
|||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::{
|
||||
check_is_apub_id_valid,
|
||||
fetcher::community::get_or_fetch_and_upsert_community,
|
||||
get_activity_to_and_cc,
|
||||
insert_activity,
|
||||
ActorType,
|
||||
};
|
||||
use lemmy_db_queries::{source::person::Person_, ApubObject, Followable};
|
||||
use lemmy_db_queries::{ApubObject, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower},
|
||||
person::Person,
|
||||
|
@ -85,14 +79,14 @@ pub type PersonAcceptedActivities = ActorAndObject<PersonValidTypes>;
|
|||
|
||||
/// Handler for all incoming activities to person inboxes.
|
||||
pub async fn person_inbox(
|
||||
request: HttpRequest,
|
||||
_request: HttpRequest,
|
||||
input: web::Json<Activity<PersonAcceptedActivitiesNew>>,
|
||||
path: web::Path<String>,
|
||||
_path: web::Path<String>,
|
||||
context: web::Data<LemmyContext>,
|
||||
) -> Result<HttpResponse, LemmyError> {
|
||||
let activity = input.into_inner();
|
||||
let request_counter = &mut 0;
|
||||
activity.inner.receive(&context, request_counter);
|
||||
activity.inner.receive(&context, request_counter).await?;
|
||||
todo!()
|
||||
/*
|
||||
// First of all check the http signature
|
||||
|
@ -134,7 +128,7 @@ pub async fn person_inbox(
|
|||
/// Receives Accept/Follow, Announce, private messages and community (undo) remove, (undo) delete
|
||||
pub(crate) async fn person_receive_message(
|
||||
activity: PersonAcceptedActivities,
|
||||
to_person: Option<Person>,
|
||||
_to_person: Option<Person>,
|
||||
actor: &dyn ActorType,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
|
@ -158,15 +152,7 @@ pub(crate) async fn person_receive_message(
|
|||
PersonValidTypes::Announce => {
|
||||
Box::pin(receive_announce(&context, any_base, actor, request_counter)).await?
|
||||
}
|
||||
PersonValidTypes::Create => {
|
||||
Box::pin(receive_create(
|
||||
&context,
|
||||
any_base,
|
||||
actor_url,
|
||||
request_counter,
|
||||
))
|
||||
.await?
|
||||
}
|
||||
PersonValidTypes::Create => {}
|
||||
PersonValidTypes::Update => {
|
||||
Box::pin(receive_update(
|
||||
&context,
|
||||
|
@ -326,23 +312,6 @@ pub async fn receive_announce(
|
|||
}
|
||||
}
|
||||
|
||||
/// Receive either a new private message, or a new comment mention. We distinguish them by checking
|
||||
/// whether the activity is public.
|
||||
async fn receive_create(
|
||||
context: &LemmyContext,
|
||||
activity: AnyBase,
|
||||
expected_domain: Url,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&create, &expected_domain, true)?;
|
||||
if verify_is_addressed_to_public(&create).is_ok() {
|
||||
receive_create_comment(create, context, request_counter).await
|
||||
} else {
|
||||
receive_create_private_message(&context, create, expected_domain, request_counter).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive either an updated private message, or an updated comment mention. We distinguish
|
||||
/// them by checking whether the activity is public.
|
||||
async fn receive_update(
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
activities::receive::{
|
||||
comment::{
|
||||
receive_create_comment,
|
||||
receive_delete_comment,
|
||||
receive_dislike_comment,
|
||||
receive_like_comment,
|
||||
|
@ -137,7 +136,7 @@ pub(in crate::inbox) async fn receive_create_for_community(
|
|||
.and_then(|s| s.parse().ok());
|
||||
match kind {
|
||||
Some(ObjectTypes::Page) => receive_create_post(create, context, request_counter).await,
|
||||
Some(ObjectTypes::Note) => receive_create_comment(create, context, request_counter).await,
|
||||
Some(ObjectTypes::Note) => todo!(),
|
||||
_ => receive_unhandled_activity(create),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue