mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 14:21:19 +00:00
convert inbox functions, add missing checks
This commit is contained in:
parent
074febb960
commit
5460c658a7
14 changed files with 165 additions and 134 deletions
|
@ -38,6 +38,7 @@ async fn get_notif_recipients(
|
|||
// 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.
|
||||
// TODO: for compatibility with other projects, it would be much better to read this from cc or tags
|
||||
let mentions = scrape_text_for_mentions(&comment.content);
|
||||
send_local_notifs(mentions, comment.clone(), actor, post, context.pool(), true).await
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ pub struct DeleteCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<DeleteCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
let object = self.inner.object.clone();
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read_from_apub_id(conn, &object.into())
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct RemoveCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<RemoveCommunity> {
|
||||
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||
verify_domains_match(&self.inner.actor, &self.inner.object)?;
|
||||
verify_domains_match(&self.inner.actor, &self.inner.cc[0])
|
||||
|
|
|
@ -38,6 +38,7 @@ pub struct UndoDeleteCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<UndoDeleteCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
let object = self.inner.object.inner.object.clone();
|
||||
let community = blocking(context.pool(), move |conn| {
|
||||
Community::read_from_apub_id(conn, &object.into())
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct UndoRemoveCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<UndoRemoveCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||
verify_domains_match(&self.inner.actor, &self.inner.object.inner.object)?;
|
||||
verify_domains_match(&self.inner.actor, &self.inner.cc[0])?;
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::{check_is_apub_id_valid, objects::FromApubToForm, GroupExt};
|
||||
use lemmy_apub_lib::{PublicUrl, ReceiveActivity, VerifyActivity};
|
||||
use lemmy_apub_lib::{verify_domains_match, PublicUrl, ReceiveActivity, VerifyActivity};
|
||||
use lemmy_db_queries::{ApubObject, Crud};
|
||||
use lemmy_db_schema::source::community::{Community, CommunityForm};
|
||||
use lemmy_utils::LemmyError;
|
||||
|
@ -28,6 +28,7 @@ pub struct UpdateCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<UpdateCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
self.inner.object.id(self.inner.cc[0].as_str())?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||
verify_is_community_mod(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::inbox::new_inbox_routing::Activity;
|
||||
use activitystreams::activity::kind::{AcceptType, FollowType};
|
||||
use crate::{activities_new::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::AcceptType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::fetcher::{
|
||||
community::get_or_fetch_and_upsert_community,
|
||||
person::get_or_fetch_and_upsert_person,
|
||||
use lemmy_apub::{
|
||||
check_is_apub_id_valid,
|
||||
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
|
||||
};
|
||||
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
|
||||
use lemmy_db_queries::Followable;
|
||||
|
@ -12,35 +12,6 @@ use lemmy_utils::LemmyError;
|
|||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FollowCommunity {
|
||||
actor: Url,
|
||||
to: Url,
|
||||
object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: FollowType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<FollowCommunity> {
|
||||
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<FollowCommunity> {
|
||||
async fn receive(
|
||||
&self,
|
||||
_context: &LemmyContext,
|
||||
_request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
println!("receive follow");
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AcceptFollowCommunity {
|
||||
|
@ -54,7 +25,8 @@ pub struct AcceptFollowCommunity {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<AcceptFollowCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(self.id_unchecked(), &self.inner.actor)?;
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||
self.inner.object.verify(context).await
|
||||
}
|
||||
}
|
67
crates/apub_receive/src/activities_new/follow/follow.rs
Normal file
67
crates/apub_receive/src/activities_new/follow/follow.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use crate::inbox::new_inbox_routing::Activity;
|
||||
use activitystreams::{
|
||||
activity::{kind::FollowType, Follow},
|
||||
base::{AnyBase, ExtendsExt},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::{
|
||||
check_is_apub_id_valid,
|
||||
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
|
||||
CommunityType,
|
||||
};
|
||||
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
|
||||
use lemmy_db_queries::Followable;
|
||||
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FollowCommunity {
|
||||
actor: Url,
|
||||
to: Url,
|
||||
pub(in crate::activities_new::follow) object: Url,
|
||||
#[serde(rename = "type")]
|
||||
kind: FollowType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<FollowCommunity> {
|
||||
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
verify_domains_match(&self.inner.to, &self.inner.object)?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<FollowCommunity> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let community =
|
||||
get_or_fetch_and_upsert_community(&self.inner.object, context, request_counter).await?;
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
let community_follower_form = CommunityFollowerForm {
|
||||
community_id: community.id,
|
||||
person_id: person.id,
|
||||
pending: false,
|
||||
};
|
||||
|
||||
// This will fail if they're already a follower, but ignore the error.
|
||||
blocking(&context.pool(), move |conn| {
|
||||
CommunityFollower::follow(&conn, &community_follower_form).ok()
|
||||
})
|
||||
.await?;
|
||||
|
||||
// TODO: avoid the conversion and pass our own follow struct directly
|
||||
let anybase = AnyBase::from_arbitrary_json(serde_json::to_string(self)?)?;
|
||||
let anybase = Follow::from_any_base(anybase)?.context(location_info!())?;
|
||||
community.send_accept_follow(anybase, context).await
|
||||
}
|
||||
}
|
3
crates/apub_receive/src/activities_new/follow/mod.rs
Normal file
3
crates/apub_receive/src/activities_new/follow/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod accept;
|
||||
pub mod follow;
|
||||
pub mod undo;
|
60
crates/apub_receive/src/activities_new/follow/undo.rs
Normal file
60
crates/apub_receive/src/activities_new/follow/undo.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use crate::{activities_new::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity};
|
||||
use activitystreams::activity::kind::UndoType;
|
||||
use lemmy_api_common::blocking;
|
||||
use lemmy_apub::{
|
||||
check_is_apub_id_valid,
|
||||
fetcher::{community::get_or_fetch_and_upsert_community, person::get_or_fetch_and_upsert_person},
|
||||
};
|
||||
use lemmy_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
|
||||
use lemmy_db_queries::Followable;
|
||||
use lemmy_db_schema::source::community::{CommunityFollower, CommunityFollowerForm};
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UndoFollowCommunity {
|
||||
actor: Url,
|
||||
to: Url,
|
||||
object: Activity<FollowCommunity>,
|
||||
#[serde(rename = "type")]
|
||||
kind: UndoType,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl VerifyActivity for Activity<UndoFollowCommunity> {
|
||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||
verify_domains_match(&self.inner.to, &self.inner.object.inner.object)?;
|
||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||
self.inner.object.verify(context).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ReceiveActivity for Activity<UndoFollowCommunity> {
|
||||
async fn receive(
|
||||
&self,
|
||||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
let community =
|
||||
get_or_fetch_and_upsert_community(&self.inner.to, context, request_counter).await?;
|
||||
let person =
|
||||
get_or_fetch_and_upsert_person(&self.inner.actor, context, request_counter).await?;
|
||||
|
||||
let community_follower_form = CommunityFollowerForm {
|
||||
community_id: community.id,
|
||||
person_id: person.id,
|
||||
pending: false,
|
||||
};
|
||||
|
||||
// This will fail if they aren't a follower, but ignore the error.
|
||||
blocking(&context.pool(), move |conn| {
|
||||
CommunityFollower::unfollow(&conn, &community_follower_form).ok()
|
||||
})
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -36,7 +36,6 @@ impl ReceiveActivity for Activity<DeletePost> {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
// TODO: check that actor is from same instance as post (same for DeleteComment)
|
||||
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let deleted_post = blocking(context.pool(), move |conn| {
|
||||
|
|
|
@ -39,7 +39,7 @@ impl ReceiveActivity for Activity<RemovePost> {
|
|||
context: &LemmyContext,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<(), LemmyError> {
|
||||
// TODO: check that actor is instance mod if community is local (same for DeleteComment)
|
||||
// TODO: check that actor is instance mod if community is local (same for RemoveComment)
|
||||
let post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||
|
||||
let removed_post = blocking(context.pool(), move |conn| {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use crate::{
|
||||
activities::receive::verify_activity_domains_valid,
|
||||
inbox::{
|
||||
use crate::inbox::{
|
||||
assert_activity_not_local,
|
||||
get_activity_id,
|
||||
inbox_verify_http_signature,
|
||||
|
@ -12,11 +10,9 @@ use crate::{
|
|||
receive_undo_for_community,
|
||||
},
|
||||
verify_is_addressed_to_public,
|
||||
},
|
||||
};
|
||||
use activitystreams::{
|
||||
activity::{kind::FollowType, ActorAndObject, Follow, Undo},
|
||||
base::AnyBase,
|
||||
activity::{kind::FollowType, ActorAndObject},
|
||||
prelude::*,
|
||||
};
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
|
@ -29,11 +25,8 @@ use lemmy_apub::{
|
|||
ActorType,
|
||||
CommunityType,
|
||||
};
|
||||
use lemmy_db_queries::{source::community::Community_, ApubObject, Followable};
|
||||
use lemmy_db_schema::source::{
|
||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||
person::Person,
|
||||
};
|
||||
use lemmy_db_queries::{source::community::Community_, ApubObject};
|
||||
use lemmy_db_schema::source::{community::Community, person::Person};
|
||||
use lemmy_utils::{location_info, LemmyError};
|
||||
use lemmy_websocket::LemmyContext;
|
||||
use log::info;
|
||||
|
@ -132,16 +125,7 @@ pub(crate) async fn community_receive_message(
|
|||
let actor_url = actor.actor_id();
|
||||
let activity_kind = activity.kind().context(location_info!())?;
|
||||
let do_announce = match activity_kind {
|
||||
CommunityValidTypes::Follow => {
|
||||
Box::pin(handle_follow(
|
||||
any_base.clone(),
|
||||
person,
|
||||
&to_community,
|
||||
&context,
|
||||
))
|
||||
.await?;
|
||||
false
|
||||
}
|
||||
CommunityValidTypes::Follow => todo!(),
|
||||
CommunityValidTypes::Undo => {
|
||||
Box::pin(handle_undo(
|
||||
context,
|
||||
|
@ -212,39 +196,11 @@ pub(crate) async fn community_receive_message(
|
|||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
/// Handle a follow request from a remote person, adding the person as follower and returning an
|
||||
/// Accept activity.
|
||||
async fn handle_follow(
|
||||
activity: AnyBase,
|
||||
person: Person,
|
||||
community: &Community,
|
||||
context: &LemmyContext,
|
||||
) -> Result<HttpResponse, LemmyError> {
|
||||
let follow = Follow::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&follow, &person.actor_id(), false)?;
|
||||
|
||||
let community_follower_form = CommunityFollowerForm {
|
||||
community_id: community.id,
|
||||
person_id: person.id,
|
||||
pending: false,
|
||||
};
|
||||
|
||||
// This will fail if they're already a follower, but ignore the error.
|
||||
blocking(&context.pool(), move |conn| {
|
||||
CommunityFollower::follow(&conn, &community_follower_form).ok()
|
||||
})
|
||||
.await?;
|
||||
|
||||
community.send_accept_follow(follow, context).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
async fn handle_undo(
|
||||
context: &LemmyContext,
|
||||
activity: CommunityAcceptedActivities,
|
||||
actor_url: Url,
|
||||
to_community: &Community,
|
||||
_to_community: &Community,
|
||||
request_counter: &mut i32,
|
||||
) -> Result<bool, LemmyError> {
|
||||
let inner_kind = activity
|
||||
|
@ -252,43 +208,9 @@ async fn handle_undo(
|
|||
.is_single_kind(&FollowType::Follow.to_string());
|
||||
let any_base = activity.into_any_base()?;
|
||||
if inner_kind {
|
||||
handle_undo_follow(any_base, actor_url, to_community, &context).await?;
|
||||
Ok(false)
|
||||
todo!()
|
||||
} else {
|
||||
receive_undo_for_community(context, any_base, None, &actor_url, request_counter).await?;
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle `Undo/Follow` from a person, removing the person from followers list.
|
||||
async fn handle_undo_follow(
|
||||
activity: AnyBase,
|
||||
person_url: Url,
|
||||
community: &Community,
|
||||
context: &LemmyContext,
|
||||
) -> Result<(), LemmyError> {
|
||||
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&undo, &person_url, true)?;
|
||||
|
||||
let object = undo.object().to_owned().one().context(location_info!())?;
|
||||
let follow = Follow::from_any_base(object)?.context(location_info!())?;
|
||||
verify_activity_domains_valid(&follow, &person_url, false)?;
|
||||
|
||||
let person = blocking(&context.pool(), move |conn| {
|
||||
Person::read_from_apub_id(&conn, &person_url.into())
|
||||
})
|
||||
.await??;
|
||||
let community_follower_form = CommunityFollowerForm {
|
||||
community_id: community.id,
|
||||
person_id: person.id,
|
||||
pending: false,
|
||||
};
|
||||
|
||||
// This will fail if they aren't a follower, but ignore the error.
|
||||
blocking(&context.pool(), move |conn| {
|
||||
CommunityFollower::unfollow(&conn, &community_follower_form).ok()
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::activities_new::{
|
|||
undo_remove::UndoRemoveCommunity,
|
||||
update::UpdateCommunity,
|
||||
},
|
||||
follow::AcceptFollowCommunity,
|
||||
follow::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity},
|
||||
post::{
|
||||
create::CreatePost,
|
||||
delete::DeletePost,
|
||||
|
@ -63,7 +63,9 @@ impl<Kind> Activity<Kind> {
|
|||
// TODO: this is probably wrong, it contains all activities
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub enum PersonAcceptedActivitiesNew {
|
||||
FollowCommunity(FollowCommunity),
|
||||
AcceptFollowCommunity(AcceptFollowCommunity),
|
||||
UndoFollowCommunity(UndoFollowCommunity),
|
||||
CreatePrivateMessage(CreatePrivateMessage),
|
||||
UpdatePrivateMessage(UpdatePrivateMessage),
|
||||
DeletePrivateMessage(DeletePrivateMessage),
|
||||
|
|
Loading…
Reference in a new issue