mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-30 00:01:25 +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,
|
// 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
|
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||||
// anyway.
|
// 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);
|
let mentions = scrape_text_for_mentions(&comment.content);
|
||||||
send_local_notifs(mentions, comment.clone(), actor, post, context.pool(), true).await
|
send_local_notifs(mentions, comment.clone(), actor, post, context.pool(), true).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub struct DeleteCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<DeleteCommunity> {
|
impl VerifyActivity for Activity<DeleteCommunity> {
|
||||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
|
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
|
||||||
let object = self.inner.object.clone();
|
let object = self.inner.object.clone();
|
||||||
let community = blocking(context.pool(), move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_apub_id(conn, &object.into())
|
Community::read_from_apub_id(conn, &object.into())
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub struct RemoveCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<RemoveCommunity> {
|
impl VerifyActivity for Activity<RemoveCommunity> {
|
||||||
async fn verify(&self, _context: &LemmyContext) -> Result<(), LemmyError> {
|
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)?;
|
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.object)?;
|
||||||
verify_domains_match(&self.inner.actor, &self.inner.cc[0])
|
verify_domains_match(&self.inner.actor, &self.inner.cc[0])
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub struct UndoDeleteCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<UndoDeleteCommunity> {
|
impl VerifyActivity for Activity<UndoDeleteCommunity> {
|
||||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
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 object = self.inner.object.inner.object.clone();
|
||||||
let community = blocking(context.pool(), move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_apub_id(conn, &object.into())
|
Community::read_from_apub_id(conn, &object.into())
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub struct UndoRemoveCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<UndoRemoveCommunity> {
|
impl VerifyActivity for Activity<UndoRemoveCommunity> {
|
||||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
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)?;
|
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.object.inner.object)?;
|
||||||
verify_domains_match(&self.inner.actor, &self.inner.cc[0])?;
|
verify_domains_match(&self.inner.actor, &self.inner.cc[0])?;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub::{check_is_apub_id_valid, objects::FromApubToForm, GroupExt};
|
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_queries::{ApubObject, Crud};
|
||||||
use lemmy_db_schema::source::community::{Community, CommunityForm};
|
use lemmy_db_schema::source::community::{Community, CommunityForm};
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
|
@ -28,6 +28,7 @@ pub struct UpdateCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<UpdateCommunity> {
|
impl VerifyActivity for Activity<UpdateCommunity> {
|
||||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
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())?;
|
self.inner.object.id(self.inner.cc[0].as_str())?;
|
||||||
check_is_apub_id_valid(&self.inner.actor, false)?;
|
check_is_apub_id_valid(&self.inner.actor, false)?;
|
||||||
verify_is_community_mod(self.inner.actor.clone(), self.inner.cc[0].clone(), context).await
|
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 crate::{activities_new::follow::follow::FollowCommunity, inbox::new_inbox_routing::Activity};
|
||||||
use activitystreams::activity::kind::{AcceptType, FollowType};
|
use activitystreams::activity::kind::AcceptType;
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_apub::fetcher::{
|
use lemmy_apub::{
|
||||||
community::get_or_fetch_and_upsert_community,
|
check_is_apub_id_valid,
|
||||||
person::get_or_fetch_and_upsert_person,
|
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_apub_lib::{verify_domains_match, ReceiveActivity, VerifyActivity};
|
||||||
use lemmy_db_queries::Followable;
|
use lemmy_db_queries::Followable;
|
||||||
|
@ -12,35 +12,6 @@ use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use url::Url;
|
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)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AcceptFollowCommunity {
|
pub struct AcceptFollowCommunity {
|
||||||
|
@ -54,7 +25,8 @@ pub struct AcceptFollowCommunity {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl VerifyActivity for Activity<AcceptFollowCommunity> {
|
impl VerifyActivity for Activity<AcceptFollowCommunity> {
|
||||||
async fn verify(&self, context: &LemmyContext) -> Result<(), LemmyError> {
|
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
|
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,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> 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 post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||||
|
|
||||||
let deleted_post = blocking(context.pool(), move |conn| {
|
let deleted_post = blocking(context.pool(), move |conn| {
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl ReceiveActivity for Activity<RemovePost> {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<(), LemmyError> {
|
) -> 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 post = get_or_fetch_and_insert_post(&self.inner.object, context, request_counter).await?;
|
||||||
|
|
||||||
let removed_post = blocking(context.pool(), move |conn| {
|
let removed_post = blocking(context.pool(), move |conn| {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use crate::{
|
use crate::inbox::{
|
||||||
activities::receive::verify_activity_domains_valid,
|
|
||||||
inbox::{
|
|
||||||
assert_activity_not_local,
|
assert_activity_not_local,
|
||||||
get_activity_id,
|
get_activity_id,
|
||||||
inbox_verify_http_signature,
|
inbox_verify_http_signature,
|
||||||
|
@ -12,11 +10,9 @@ use crate::{
|
||||||
receive_undo_for_community,
|
receive_undo_for_community,
|
||||||
},
|
},
|
||||||
verify_is_addressed_to_public,
|
verify_is_addressed_to_public,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
activity::{kind::FollowType, ActorAndObject, Follow, Undo},
|
activity::{kind::FollowType, ActorAndObject},
|
||||||
base::AnyBase,
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
|
@ -29,11 +25,8 @@ use lemmy_apub::{
|
||||||
ActorType,
|
ActorType,
|
||||||
CommunityType,
|
CommunityType,
|
||||||
};
|
};
|
||||||
use lemmy_db_queries::{source::community::Community_, ApubObject, Followable};
|
use lemmy_db_queries::{source::community::Community_, ApubObject};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{community::Community, person::Person};
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
|
||||||
person::Person,
|
|
||||||
};
|
|
||||||
use lemmy_utils::{location_info, LemmyError};
|
use lemmy_utils::{location_info, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
@ -132,16 +125,7 @@ pub(crate) async fn community_receive_message(
|
||||||
let actor_url = actor.actor_id();
|
let actor_url = actor.actor_id();
|
||||||
let activity_kind = activity.kind().context(location_info!())?;
|
let activity_kind = activity.kind().context(location_info!())?;
|
||||||
let do_announce = match activity_kind {
|
let do_announce = match activity_kind {
|
||||||
CommunityValidTypes::Follow => {
|
CommunityValidTypes::Follow => todo!(),
|
||||||
Box::pin(handle_follow(
|
|
||||||
any_base.clone(),
|
|
||||||
person,
|
|
||||||
&to_community,
|
|
||||||
&context,
|
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
CommunityValidTypes::Undo => {
|
CommunityValidTypes::Undo => {
|
||||||
Box::pin(handle_undo(
|
Box::pin(handle_undo(
|
||||||
context,
|
context,
|
||||||
|
@ -212,39 +196,11 @@ pub(crate) async fn community_receive_message(
|
||||||
Ok(HttpResponse::Ok().finish())
|
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(
|
async fn handle_undo(
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
activity: CommunityAcceptedActivities,
|
activity: CommunityAcceptedActivities,
|
||||||
actor_url: Url,
|
actor_url: Url,
|
||||||
to_community: &Community,
|
_to_community: &Community,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
) -> Result<bool, LemmyError> {
|
) -> Result<bool, LemmyError> {
|
||||||
let inner_kind = activity
|
let inner_kind = activity
|
||||||
|
@ -252,43 +208,9 @@ async fn handle_undo(
|
||||||
.is_single_kind(&FollowType::Follow.to_string());
|
.is_single_kind(&FollowType::Follow.to_string());
|
||||||
let any_base = activity.into_any_base()?;
|
let any_base = activity.into_any_base()?;
|
||||||
if inner_kind {
|
if inner_kind {
|
||||||
handle_undo_follow(any_base, actor_url, to_community, &context).await?;
|
todo!()
|
||||||
Ok(false)
|
|
||||||
} else {
|
} else {
|
||||||
receive_undo_for_community(context, any_base, None, &actor_url, request_counter).await?;
|
receive_undo_for_community(context, any_base, None, &actor_url, request_counter).await?;
|
||||||
Ok(true)
|
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,
|
undo_remove::UndoRemoveCommunity,
|
||||||
update::UpdateCommunity,
|
update::UpdateCommunity,
|
||||||
},
|
},
|
||||||
follow::AcceptFollowCommunity,
|
follow::{accept::AcceptFollowCommunity, follow::FollowCommunity, undo::UndoFollowCommunity},
|
||||||
post::{
|
post::{
|
||||||
create::CreatePost,
|
create::CreatePost,
|
||||||
delete::DeletePost,
|
delete::DeletePost,
|
||||||
|
@ -63,7 +63,9 @@ impl<Kind> Activity<Kind> {
|
||||||
// TODO: this is probably wrong, it contains all activities
|
// TODO: this is probably wrong, it contains all activities
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
pub enum PersonAcceptedActivitiesNew {
|
pub enum PersonAcceptedActivitiesNew {
|
||||||
|
FollowCommunity(FollowCommunity),
|
||||||
AcceptFollowCommunity(AcceptFollowCommunity),
|
AcceptFollowCommunity(AcceptFollowCommunity),
|
||||||
|
UndoFollowCommunity(UndoFollowCommunity),
|
||||||
CreatePrivateMessage(CreatePrivateMessage),
|
CreatePrivateMessage(CreatePrivateMessage),
|
||||||
UpdatePrivateMessage(UpdatePrivateMessage),
|
UpdatePrivateMessage(UpdatePrivateMessage),
|
||||||
DeletePrivateMessage(DeletePrivateMessage),
|
DeletePrivateMessage(DeletePrivateMessage),
|
||||||
|
|
Loading…
Reference in a new issue