@ -6,7 +6,7 @@ use crate::{
community_moderators ::ApubCommunityModerators ,
community_outbox ::ApubCommunityOutbox ,
} ,
http ::{ c reate_apub_response, create_apub_tombstone_response } ,
http ::{ c heck_community_public, c reate_apub_response, create_apub_tombstone_response } ,
objects ::{ community ::ApubCommunity , person ::ApubPerson } ,
} ;
use activitypub_federation ::{
@ -18,10 +18,10 @@ use activitypub_federation::{
use actix_web ::{ web , web ::Bytes , HttpRequest , HttpResponse } ;
use lemmy_api_common ::context ::LemmyContext ;
use lemmy_db_schema ::{ source ::community ::Community , traits ::ApubActor } ;
use lemmy_utils ::error ::{ LemmyError , LemmyErrorType } ;
use lemmy_utils ::error ::LemmyError ;
use serde ::Deserialize ;
#[ derive(Deserialize )]
#[ derive(Deserialize , Clone )]
pub ( crate ) struct CommunityQuery {
community_name : String ,
}
@ -37,13 +37,13 @@ pub(crate) async fn get_apub_community_http(
. await ?
. into ( ) ;
if ! community . deleted & & ! community . removed {
let apub = community . into_json ( & context ) . await ? ;
create_apub_response ( & apub )
} else {
create_apub_tombstone_response ( community . actor_id . clone ( ) )
if community . deleted | | community . removed {
return create_apub_tombstone_response ( community . actor_id . clone ( ) ) ;
}
check_community_public ( & community ) ? ;
let apub = community . into_json ( & context ) . await ? ;
create_apub_response ( & apub )
}
/// Handler for all incoming receive to community inboxes.
@ -66,6 +66,7 @@ pub(crate) async fn get_apub_community_followers(
) -> Result < HttpResponse , LemmyError > {
let community =
Community ::read_from_name ( & mut context . pool ( ) , & info . community_name , false ) . await ? ;
check_community_public ( & community ) ? ;
let followers = ApubCommunityFollower ::read_local ( & community . into ( ) , & context ) . await ? ;
create_apub_response ( & followers )
}
@ -80,9 +81,7 @@ pub(crate) async fn get_apub_community_outbox(
Community ::read_from_name ( & mut context . pool ( ) , & info . community_name , false )
. await ?
. into ( ) ;
if community . deleted | | community . removed {
Err ( LemmyErrorType ::Deleted ) ?
}
check_community_public ( & community ) ? ;
let outbox = ApubCommunityOutbox ::read_local ( & community , & context ) . await ? ;
create_apub_response ( & outbox )
}
@ -96,9 +95,7 @@ pub(crate) async fn get_apub_community_moderators(
Community ::read_from_name ( & mut context . pool ( ) , & info . community_name , false )
. await ?
. into ( ) ;
if community . deleted | | community . removed {
Err ( LemmyErrorType ::Deleted ) ?
}
check_community_public ( & community ) ? ;
let moderators = ApubCommunityModerators ::read_local ( & community , & context ) . await ? ;
create_apub_response ( & moderators )
}
@ -112,9 +109,153 @@ pub(crate) async fn get_apub_community_featured(
Community ::read_from_name ( & mut context . pool ( ) , & info . community_name , false )
. await ?
. into ( ) ;
if community . deleted | | community . removed {
Err ( LemmyErrorType ::Deleted ) ?
}
check_community_public ( & community ) ? ;
let featured = ApubCommunityFeatured ::read_local ( & community , & context ) . await ? ;
create_apub_response ( & featured )
}
#[ cfg(test) ]
pub ( crate ) mod tests {
#![ allow(clippy::unwrap_used) ]
#![ allow(clippy::indexing_slicing) ]
use super ::* ;
use crate ::protocol ::objects ::{ group ::Group , tombstone ::Tombstone } ;
use actix_web ::body ::to_bytes ;
use lemmy_db_schema ::{
source ::{
community ::{ Community , CommunityInsertForm } ,
instance ::Instance ,
} ,
traits ::Crud ,
CommunityVisibility ,
} ;
use lemmy_utils ::error ::LemmyResult ;
use serde ::de ::DeserializeOwned ;
use serial_test ::serial ;
async fn init (
deleted : bool ,
visibility : CommunityVisibility ,
context : & Data < LemmyContext > ,
) -> Result < ( Instance , Community ) , LemmyError > {
let instance =
Instance ::read_or_create ( & mut context . pool ( ) , "my_domain.tld" . to_string ( ) ) . await ? ;
let community_form = CommunityInsertForm ::builder ( )
. name ( "testcom6" . to_string ( ) )
. title ( "nada" . to_owned ( ) )
. public_key ( "pubkey" . to_string ( ) )
. instance_id ( instance . id )
. deleted ( Some ( deleted ) )
. visibility ( Some ( visibility ) )
. build ( ) ;
let community = Community ::create ( & mut context . pool ( ) , & community_form ) . await ? ;
Ok ( ( instance , community ) )
}
async fn decode_response < T : DeserializeOwned > ( res : HttpResponse ) -> Result < T , LemmyError > {
let body = to_bytes ( res . into_body ( ) ) . await . unwrap ( ) ;
let body = std ::str ::from_utf8 ( & body ) ? ;
Ok ( serde_json ::from_str ( body ) ? )
}
#[ tokio::test ]
#[ serial ]
async fn test_get_community ( ) -> LemmyResult < ( ) > {
let context = LemmyContext ::init_test_context ( ) . await ;
// fetch invalid community
let query = CommunityQuery {
community_name : "asd" . to_string ( ) ,
} ;
let res = get_apub_community_http ( query . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let ( instance , community ) = init ( false , CommunityVisibility ::Public , & context ) . await ? ;
// fetch valid community
let query = CommunityQuery {
community_name : community . name . clone ( ) ,
} ;
let res = get_apub_community_http ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 200 , res . status ( ) ) ;
let res_group : Group = decode_response ( res ) . await ? ;
let community : ApubCommunity = community . into ( ) ;
let group = community . clone ( ) . into_json ( & context ) . await ? ;
assert_eq! ( group , res_group ) ;
let res =
get_apub_community_featured ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 200 , res . status ( ) ) ;
let res =
get_apub_community_followers ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 200 , res . status ( ) ) ;
let res =
get_apub_community_moderators ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 200 , res . status ( ) ) ;
let res = get_apub_community_outbox ( query . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 200 , res . status ( ) ) ;
Instance ::delete ( & mut context . pool ( ) , instance . id ) . await ? ;
Ok ( ( ) )
}
#[ tokio::test ]
#[ serial ]
async fn test_get_deleted_community ( ) -> LemmyResult < ( ) > {
let context = LemmyContext ::init_test_context ( ) . await ;
let ( instance , community ) = init ( true , CommunityVisibility ::LocalOnly , & context ) . await ? ;
// should return tombstone
let query = CommunityQuery {
community_name : community . name . clone ( ) ,
} ;
let res = get_apub_community_http ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ? ;
assert_eq! ( 410 , res . status ( ) ) ;
let res_tombstone = decode_response ::< Tombstone > ( res ) . await ;
assert! ( res_tombstone . is_ok ( ) ) ;
let res =
get_apub_community_featured ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res =
get_apub_community_followers ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res =
get_apub_community_moderators ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res = get_apub_community_outbox ( query . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
//Community::delete(&mut context.pool(), community.id).await?;
Instance ::delete ( & mut context . pool ( ) , instance . id ) . await ? ;
Ok ( ( ) )
}
#[ tokio::test ]
#[ serial ]
async fn test_get_local_only_community ( ) -> LemmyResult < ( ) > {
let context = LemmyContext ::init_test_context ( ) . await ;
let ( instance , community ) = init ( false , CommunityVisibility ::LocalOnly , & context ) . await ? ;
let query = CommunityQuery {
community_name : community . name . clone ( ) ,
} ;
let res = get_apub_community_http ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res =
get_apub_community_featured ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res =
get_apub_community_followers ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res =
get_apub_community_moderators ( query . clone ( ) . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
let res = get_apub_community_outbox ( query . into ( ) , context . reset_request_count ( ) ) . await ;
assert! ( res . is_err ( ) ) ;
Instance ::delete ( & mut context . pool ( ) , instance . id ) . await ? ;
Ok ( ( ) )
}
}