Rework and fix (un)block user, announce, update post

pull/1652/head
Felix Ableitner 3 years ago
parent caba7e4cf0
commit e88ab170ef

@ -19,6 +19,7 @@ use crate::{
http::is_activity_already_known,
};
use activitystreams::activity::kind::AnnounceType;
use lemmy_apub::insert_activity;
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
@ -49,7 +50,7 @@ pub enum AnnouncableActivities {
pub struct AnnounceActivity {
to: PublicUrl,
object: AnnouncableActivities,
cc: [Url; 1],
cc: Vec<Url>,
#[serde(rename = "type")]
kind: AnnounceType,
#[serde(flatten)]
@ -65,6 +66,7 @@ impl ActivityHandlerNew for AnnounceActivity {
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_community(&self.common.actor, context, request_counter).await?;
self.object.verify(context, request_counter).await?;
Ok(())
}
@ -76,6 +78,14 @@ impl ActivityHandlerNew for AnnounceActivity {
if is_activity_already_known(context.pool(), self.object.common().id_unchecked()).await? {
return Ok(());
}
insert_activity(
self.object.common().id_unchecked(),
self.object.clone(),
false,
true,
context.pool(),
)
.await?;
self.object.receive(context, request_counter).await
}

@ -1,11 +1,11 @@
use crate::activities::verify_mod_action;
use crate::activities::{verify_activity, verify_mod_action, verify_person_in_community};
use activitystreams::activity::kind::BlockType;
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::fetcher::{
community::get_or_fetch_and_upsert_community,
person::get_or_fetch_and_upsert_person,
};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::{Bannable, Followable};
use lemmy_db_schema::source::community::{
CommunityFollower,
@ -31,10 +31,15 @@ pub struct BlockUserFromCommunity {
#[async_trait::async_trait(?Send)]
impl ActivityHandlerNew for BlockUserFromCommunity {
async fn verify(&self, context: &LemmyContext, _: &mut i32) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await
async fn verify(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_activity(self.common())?;
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
Ok(())
}
async fn receive(

@ -1,11 +1,16 @@
use crate::activities::{community::block_user::BlockUserFromCommunity, verify_mod_action};
use activitystreams::activity::kind::BlockType;
use crate::activities::{
community::block_user::BlockUserFromCommunity,
verify_activity,
verify_mod_action,
verify_person_in_community,
};
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::fetcher::{
community::get_or_fetch_and_upsert_community,
person::get_or_fetch_and_upsert_person,
};
use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_apub_lib::{ActivityCommonFields, ActivityHandlerNew, PublicUrl};
use lemmy_db_queries::Bannable;
use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm};
use lemmy_utils::LemmyError;
@ -19,7 +24,7 @@ pub struct UndoBlockUserFromCommunity {
object: BlockUserFromCommunity,
cc: [Url; 1],
#[serde(rename = "type")]
kind: BlockType,
kind: UndoType,
#[serde(flatten)]
common: ActivityCommonFields,
}
@ -31,10 +36,11 @@ impl ActivityHandlerNew for UndoBlockUserFromCommunity {
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.common.actor, self.common.id_unchecked())?;
check_is_apub_id_valid(&self.common.actor, false)?;
verify_activity(self.common())?;
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
verify_mod_action(&self.common.actor, self.cc[0].clone(), context).await?;
self.object.verify(context, request_counter).await
self.object.verify(context, request_counter).await?;
Ok(())
}
async fn receive(

@ -49,14 +49,13 @@ impl ActivityHandlerNew for UpdatePost {
verify_activity(self.common())?;
let community =
verify_person_in_community(&self.common.actor, &self.cc, context, request_counter).await?;
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
let temp_post = PostForm::from_apub(
&self.object,
context,
self.common.actor.clone(),
request_counter,
false,
true,
)
.await?;
let post_id: DbUrl = temp_post.ap_id.context(location_info!())?;
@ -66,9 +65,14 @@ impl ActivityHandlerNew for UpdatePost {
.await??;
let stickied = temp_post.stickied.context(location_info!())?;
let locked = temp_post.locked.context(location_info!())?;
// community mod changed locked/sticky status
if (stickied != old_post.stickied) || (locked != old_post.locked) {
verify_mod_action(&self.common.actor, community.actor_id(), context).await?;
}
// user edited their own post
else {
verify_domains_match_opt(&self.common.actor, self.object.id_unchecked())?;
}
Ok(())
}

@ -50,6 +50,8 @@ async fn payload_to_string(mut payload: Payload) -> Result<String, LemmyError> {
Bytes::from(bytes).as_ref().read_to_string(&mut unparsed)?;
Ok(unparsed)
}
// TODO: move most of this code to library
async fn receive_activity<'a, T>(
request: HttpRequest,
activity: &'a str,
@ -60,19 +62,23 @@ where
{
let activity = serde_json::from_str::<T>(activity)?;
let activity_data = activity.common();
// TODO: which order to check things?
// Do nothing if we received the same activity before
if is_activity_already_known(context.pool(), activity_data.id_unchecked()).await? {
return Ok(HttpResponse::Ok().finish());
}
let request_counter = &mut 0;
let actor =
get_or_fetch_and_upsert_actor(&activity_data.actor, &context, request_counter).await?;
verify_signature(&request, &actor.public_key().context(location_info!())?)?;
// Do nothing if we received the same activity before
if is_activity_already_known(context.pool(), activity_data.id_unchecked()).await? {
return Ok(HttpResponse::Ok().finish());
}
check_is_apub_id_valid(&activity_data.actor, false)?;
println!(
"Verifying activity {}",
activity_data.id_unchecked().to_string()
);
activity.verify(&context, request_counter).await?;
assert_activity_not_local(&activity)?;
check_is_apub_id_valid(&activity_data.actor, false)?;
// Log the activity, so we avoid receiving and parsing it twice. Note that this could still happen
// if we receive the same activity twice in very quick succession.
@ -85,6 +91,10 @@ where
)
.await?;
println!(
"Receiving activity {}",
activity_data.id_unchecked().to_string()
);
activity.receive(&context, request_counter).await?;
Ok(HttpResponse::Ok().finish())
}

Loading…
Cancel
Save