Skip to content

Commit

Permalink
Ensure that posts, comments etc are addressed to public (ref #1220)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nutomic committed Nov 3, 2020
1 parent 3a6affa commit 238fd2f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 37 deletions.
10 changes: 9 additions & 1 deletion lemmy_apub/src/activities/receive/community.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::activities::receive::verify_activity_domains_valid;
use crate::{activities::receive::verify_activity_domains_valid, inbox::check_activity_is_public};
use activitystreams::{
activity::{ActorAndObjectRefExt, Delete, Remove, Undo},
base::{AnyBase, ExtendsExt},
Expand Down Expand Up @@ -45,6 +45,8 @@ pub(crate) async fn receive_remove_community(
) -> Result<(), LemmyError> {
let remove = Delete::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&remove, expected_domain, true)?;
check_activity_is_public(&remove)?;

let community_uri = remove
.object()
.to_owned()
Expand Down Expand Up @@ -85,9 +87,11 @@ pub(crate) async fn receive_undo_delete_community(
community: Community,
expected_domain: &Url,
) -> Result<(), LemmyError> {
check_activity_is_public(&undo)?;
let inner = undo.object().to_owned().one().context(location_info!())?;
let delete = Delete::from_any_base(inner)?.context(location_info!())?;
verify_activity_domains_valid(&delete, expected_domain, true)?;
check_activity_is_public(&delete)?;

let deleted_community = blocking(context.pool(), move |conn| {
Community::update_deleted(conn, community.id, false)
Expand Down Expand Up @@ -120,9 +124,13 @@ pub(crate) async fn receive_undo_remove_community(
) -> Result<(), LemmyError> {
let undo = Undo::from_any_base(undo)?.context(location_info!())?;
verify_activity_domains_valid(&undo, &expected_domain, true)?;
check_activity_is_public(&undo)?;

let inner = undo.object().to_owned().one().context(location_info!())?;
let remove = Remove::from_any_base(inner)?.context(location_info!())?;
verify_activity_domains_valid(&remove, &expected_domain, true)?;
check_activity_is_public(&remove)?;

let community_uri = remove
.object()
.to_owned()
Expand Down
3 changes: 0 additions & 3 deletions lemmy_apub/src/inbox/community_inbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ pub(crate) async fn community_receive_message(
) -> Result<HttpResponse, LemmyError> {
// TODO: check if the sending user is banned by the community

// TODO: check that post/comment actions are addressed to public() (meaning activities from user
// to community need to be public()

let any_base = activity.clone().into_any_base()?;
let actor_url = actor.actor_id()?;
let activity_kind = activity.kind().context(location_info!())?;
Expand Down
15 changes: 14 additions & 1 deletion lemmy_apub/src/inbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use activitystreams::{
activity::ActorAndObjectRefExt,
base::{AsBase, BaseExt, Extends},
object::{AsObject, ObjectExt},
public,
};
use actix_web::HttpRequest;
use anyhow::Context;
use anyhow::{anyhow, Context};
use lemmy_db::{activity::Activity, DbPool};
use lemmy_structs::blocking;
use lemmy_utils::{location_info, LemmyError};
Expand Down Expand Up @@ -77,6 +78,18 @@ where
Ok(to_and_cc)
}

pub(crate) fn check_activity_is_public<T, Kind>(activity: &T) -> Result<(), LemmyError>
where
T: AsBase<Kind> + AsObject<Kind> + ActorAndObjectRefExt,
{
let to_and_cc = get_activity_to_and_cc(activity)?;
if to_and_cc.contains(&public()) {
Ok(())
} else {
Err(anyhow!("Activity is not addressed to public").into())
}
}

pub(crate) async fn inbox_verify_http_signature<T, Kind>(
activity: &T,
context: &LemmyContext,
Expand Down
74 changes: 44 additions & 30 deletions lemmy_apub/src/inbox/receive_for_community.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
use crate::activities::receive::{
comment::{
receive_create_comment,
receive_delete_comment,
receive_dislike_comment,
receive_like_comment,
receive_remove_comment,
receive_update_comment,
use crate::{
activities::receive::{
comment::{
receive_create_comment,
receive_delete_comment,
receive_dislike_comment,
receive_like_comment,
receive_remove_comment,
receive_update_comment,
},
comment_undo::{
receive_undo_delete_comment,
receive_undo_dislike_comment,
receive_undo_like_comment,
receive_undo_remove_comment,
},
post::{
receive_create_post,
receive_delete_post,
receive_dislike_post,
receive_like_post,
receive_remove_post,
receive_update_post,
},
post_undo::{
receive_undo_delete_post,
receive_undo_dislike_post,
receive_undo_like_post,
receive_undo_remove_post,
},
receive_unhandled_activity,
verify_activity_domains_valid,
},
comment_undo::{
receive_undo_delete_comment,
receive_undo_dislike_comment,
receive_undo_like_comment,
receive_undo_remove_comment,
},
post::{
receive_create_post,
receive_delete_post,
receive_dislike_post,
receive_like_post,
receive_remove_post,
receive_update_post,
},
post_undo::{
receive_undo_delete_post,
receive_undo_dislike_post,
receive_undo_like_post,
receive_undo_remove_post,
},
receive_unhandled_activity,
verify_activity_domains_valid,
inbox::check_activity_is_public,
};
use activitystreams::{
activity::{Create, Delete, Dislike, Like, Remove, Undo, Update},
Expand All @@ -55,6 +58,7 @@ pub(in crate::inbox) async fn receive_create_for_community(
) -> Result<(), LemmyError> {
let create = Create::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&create, &expected_domain, true)?;
check_activity_is_public(&create)?;

match create.object().as_single_kind_str() {
Some("Page") => receive_create_post(create, context, request_counter).await,
Expand All @@ -72,6 +76,7 @@ pub(in crate::inbox) async fn receive_update_for_community(
) -> Result<(), LemmyError> {
let update = Update::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&update, &expected_domain, true)?;
check_activity_is_public(&update)?;

match update.object().as_single_kind_str() {
Some("Page") => receive_update_post(update, context, request_counter).await,
Expand All @@ -89,6 +94,7 @@ pub(in crate::inbox) async fn receive_like_for_community(
) -> Result<(), LemmyError> {
let like = Like::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&like, &expected_domain, false)?;
check_activity_is_public(&like)?;

match like.object().as_single_kind_str() {
Some("Page") => receive_like_post(like, context, request_counter).await,
Expand All @@ -114,6 +120,7 @@ pub(in crate::inbox) async fn receive_dislike_for_community(

let dislike = Dislike::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&dislike, &expected_domain, false)?;
check_activity_is_public(&dislike)?;

match dislike.object().as_single_kind_str() {
Some("Page") => receive_dislike_post(dislike, context, request_counter).await,
Expand All @@ -130,6 +137,7 @@ pub(in crate::inbox) async fn receive_delete_for_community(
) -> Result<(), LemmyError> {
let delete = Delete::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&delete, &expected_domain, true)?;
check_activity_is_public(&delete)?;

let object = delete
.object()
Expand All @@ -153,6 +161,7 @@ pub(in crate::inbox) async fn receive_remove_for_community(
) -> Result<(), LemmyError> {
let remove = Remove::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&remove, &expected_domain, false)?;
check_activity_is_public(&remove)?;

let cc = remove
.cc()
Expand Down Expand Up @@ -191,6 +200,7 @@ pub(in crate::inbox) async fn receive_undo_for_community(
) -> Result<(), LemmyError> {
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&undo, &expected_domain.to_owned(), true)?;
check_activity_is_public(&undo)?;

match undo.object().as_single_kind_str() {
Some("Delete") => receive_undo_delete_for_community(context, undo, expected_domain).await,
Expand All @@ -214,6 +224,7 @@ pub(in crate::inbox) async fn receive_undo_delete_for_community(
let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&delete, &expected_domain, true)?;
check_activity_is_public(&delete)?;

let object = delete
.object()
Expand All @@ -237,6 +248,7 @@ pub(in crate::inbox) async fn receive_undo_remove_for_community(
let remove = Remove::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&remove, &expected_domain, false)?;
check_activity_is_public(&remove)?;

let object = remove
.object()
Expand All @@ -261,6 +273,7 @@ pub(in crate::inbox) async fn receive_undo_like_for_community(
let like = Like::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&like, &expected_domain, false)?;
check_activity_is_public(&like)?;

let type_ = like
.object()
Expand All @@ -283,6 +296,7 @@ pub(in crate::inbox) async fn receive_undo_dislike_for_community(
let dislike = Dislike::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?;
verify_activity_domains_valid(&dislike, &expected_domain, false)?;
check_activity_is_public(&dislike)?;

let type_ = dislike
.object()
Expand Down
4 changes: 2 additions & 2 deletions lemmy_apub/src/inbox/user_inbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
check_is_apub_id_valid,
fetcher::get_or_fetch_and_upsert_community,
inbox::{
check_activity_is_public,
get_activity_id,
get_activity_to_and_cc,
inbox_verify_http_signature,
Expand Down Expand Up @@ -135,8 +136,6 @@ pub(crate) async fn user_receive_message(
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<HttpResponse, LemmyError> {
// TODO: check that messages from community are addressed to public()

// TODO: must be addressed to one or more local users, or to followers of a remote community

// TODO: if it is addressed to community followers, check that at least one local user is following it
Expand Down Expand Up @@ -219,6 +218,7 @@ async fn receive_announce(
) -> Result<(), LemmyError> {
let announce = Announce::from_any_base(activity)?.context(location_info!())?;
verify_activity_domains_valid(&announce, &actor.actor_id()?, false)?;
check_activity_is_public(&announce)?;

let kind = announce.object().as_single_kind_str();
let inner_activity = announce
Expand Down

0 comments on commit 238fd2f

Please sign in to comment.