mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-14 08:23:59 +00:00
Fix three federation test cases
This commit is contained in:
parent
b3a5b4eb82
commit
4f7dca7c2b
10 changed files with 62 additions and 42 deletions
|
@ -23,6 +23,7 @@ import {
|
||||||
banUserFromSite,
|
banUserFromSite,
|
||||||
searchPostLocal,
|
searchPostLocal,
|
||||||
banUserFromCommunity,
|
banUserFromCommunity,
|
||||||
|
followCommunity,
|
||||||
} from './shared';
|
} from './shared';
|
||||||
import { PostView, CommunityView } from 'lemmy-js-client';
|
import { PostView, CommunityView } from 'lemmy-js-client';
|
||||||
|
|
||||||
|
@ -169,35 +170,38 @@ test('Sticky a post', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Lock a post', async () => {
|
test('Lock a post', async () => {
|
||||||
|
await followCommunity(alpha, true, betaCommunity.community.id);
|
||||||
let postRes = await createPost(alpha, betaCommunity.community.id);
|
let postRes = await createPost(alpha, betaCommunity.community.id);
|
||||||
|
|
||||||
// Lock the post
|
// Lock the post
|
||||||
let lockedPostRes = await lockPost(alpha, true, postRes.post_view.post);
|
let searchBeta = await searchPost(beta, postRes.post_view.post);
|
||||||
|
let betaPost1 = searchBeta.posts[0];
|
||||||
|
let lockedPostRes = await lockPost(beta, true, betaPost1.post);
|
||||||
expect(lockedPostRes.post_view.post.locked).toBe(true);
|
expect(lockedPostRes.post_view.post.locked).toBe(true);
|
||||||
|
|
||||||
// Make sure that post is locked on beta
|
// Make sure that post is locked on alpha
|
||||||
let searchBeta = await searchPostLocal(beta, postRes.post_view.post);
|
let searchAlpha = await searchPostLocal(alpha, postRes.post_view.post);
|
||||||
let betaPost1 = searchBeta.posts[0];
|
let alphaPost1 = searchAlpha.posts[0];
|
||||||
expect(betaPost1.post.locked).toBe(true);
|
expect(alphaPost1.post.locked).toBe(true);
|
||||||
|
|
||||||
// Try to make a new comment there, on alpha
|
// Try to make a new comment there, on alpha
|
||||||
let comment: any = await createComment(alpha, postRes.post_view.post.id);
|
let comment: any = await createComment(alpha, alphaPost1.post.id);
|
||||||
expect(comment['error']).toBe('locked');
|
expect(comment['error']).toBe('locked');
|
||||||
|
|
||||||
// Unlock a post
|
// Unlock a post
|
||||||
let unlockedPost = await lockPost(alpha, false, postRes.post_view.post);
|
let unlockedPost = await lockPost(beta, false, betaPost1.post);
|
||||||
expect(unlockedPost.post_view.post.locked).toBe(false);
|
expect(unlockedPost.post_view.post.locked).toBe(false);
|
||||||
|
|
||||||
// Make sure that post is unlocked on beta
|
// Make sure that post is unlocked on alpha
|
||||||
let searchBeta2 = await searchPost(beta, postRes.post_view.post);
|
let searchAlpha2 = await searchPostLocal(alpha, postRes.post_view.post);
|
||||||
let betaPost2 = searchBeta2.posts[0];
|
let alphaPost2 = searchAlpha2.posts[0];
|
||||||
expect(betaPost2.community.local).toBe(true);
|
expect(alphaPost2.community.local).toBe(false);
|
||||||
expect(betaPost2.creator.local).toBe(false);
|
expect(alphaPost2.creator.local).toBe(true);
|
||||||
expect(betaPost2.post.locked).toBe(false);
|
expect(alphaPost2.post.locked).toBe(false);
|
||||||
|
|
||||||
// Try to create a new comment, on beta
|
// Try to create a new comment, on alpha
|
||||||
let commentBeta = await createComment(beta, betaPost2.post.id);
|
let commentAlpha = await createComment(alpha, alphaPost1.post.id);
|
||||||
expect(commentBeta).toBeDefined();
|
expect(commentAlpha).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Delete a post', async () => {
|
test('Delete a post', async () => {
|
||||||
|
|
|
@ -75,14 +75,17 @@ pub(crate) async fn receive_update_post(
|
||||||
// If sticked or locked state was changed, make sure the actor is a mod
|
// If sticked or locked state was changed, make sure the actor is a mod
|
||||||
let stickied = page.ext_one.stickied.context(location_info!())?;
|
let stickied = page.ext_one.stickied.context(location_info!())?;
|
||||||
let locked = !page.ext_one.comments_enabled.context(location_info!())?;
|
let locked = !page.ext_one.comments_enabled.context(location_info!())?;
|
||||||
let mut is_mod_action = false;
|
let mut mod_action_allowed = false;
|
||||||
if stickied != old_post.stickied || locked != old_post.locked {
|
if stickied != old_post.stickied || locked != old_post.locked {
|
||||||
let community = blocking(context.pool(), move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read(conn, old_post.community_id)
|
Community::read(conn, old_post.community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
// Only check mod status if the community is local, otherwise we trust that it was sent correctly.
|
||||||
|
if community.local {
|
||||||
verify_mod_activity(&update, announce, &community, context).await?;
|
verify_mod_activity(&update, announce, &community, context).await?;
|
||||||
is_mod_action = true;
|
}
|
||||||
|
mod_action_allowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let post = Post::from_apub(
|
let post = Post::from_apub(
|
||||||
|
@ -90,7 +93,7 @@ pub(crate) async fn receive_update_post(
|
||||||
context,
|
context,
|
||||||
user.actor_id(),
|
user.actor_id(),
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ impl CommunityType for Community {
|
||||||
.set_many_contexts(lemmy_context()?)
|
.set_many_contexts(lemmy_context()?)
|
||||||
.set_id(generate_activity_id(AnnounceType::Announce)?)
|
.set_id(generate_activity_id(AnnounceType::Announce)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.actor_id()]);
|
.set_many_ccs(vec![self.followers_url.clone().into_inner()]);
|
||||||
|
|
||||||
send_to_community_followers(announce, self, context).await?;
|
send_to_community_followers(announce, self, context).await?;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::receive::{
|
activities::receive::{
|
||||||
|
comment::{receive_create_comment, receive_update_comment},
|
||||||
community::{
|
community::{
|
||||||
receive_delete_community,
|
receive_delete_community,
|
||||||
receive_remove_community,
|
receive_remove_community,
|
||||||
|
@ -326,6 +327,8 @@ pub async fn receive_announce(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Receive either a new private message, or a new comment mention. We distinguish them by checking
|
||||||
|
/// whether the activity is public.
|
||||||
async fn receive_create(
|
async fn receive_create(
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
|
@ -334,9 +337,15 @@ async fn receive_create(
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
||||||
verify_activity_domains_valid(&create, &expected_domain, true)?;
|
verify_activity_domains_valid(&create, &expected_domain, true)?;
|
||||||
|
if verify_is_addressed_to_public(&create).is_ok() {
|
||||||
|
receive_create_comment(create, context, request_counter).await
|
||||||
|
} else {
|
||||||
receive_create_private_message(&context, create, expected_domain, request_counter).await
|
receive_create_private_message(&context, create, expected_domain, request_counter).await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receive either an updated private message, or an updated comment mention. We distinguish
|
||||||
|
/// them by checking whether the activity is public.
|
||||||
async fn receive_update(
|
async fn receive_update(
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
|
@ -345,8 +354,12 @@ async fn receive_update(
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
||||||
verify_activity_domains_valid(&update, &expected_domain, true)?;
|
verify_activity_domains_valid(&update, &expected_domain, true)?;
|
||||||
|
if verify_is_addressed_to_public(&update).is_ok() {
|
||||||
|
receive_update_comment(update, context, request_counter).await
|
||||||
|
} else {
|
||||||
receive_update_private_message(&context, update, expected_domain, request_counter).await
|
receive_update_private_message(&context, update, expected_domain, request_counter).await
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive_delete(
|
async fn receive_delete(
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
|
|
|
@ -99,14 +99,14 @@ impl FromApub for Comment {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<Comment, LemmyError> {
|
) -> Result<Comment, LemmyError> {
|
||||||
let comment: Comment = get_object_from_apub(
|
let comment: Comment = get_object_from_apub(
|
||||||
note,
|
note,
|
||||||
context,
|
context,
|
||||||
expected_domain,
|
expected_domain,
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ impl FromApubToForm<NoteExt> for CommentForm {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
_is_mod_action: bool,
|
_mod_action_allowed: bool,
|
||||||
) -> Result<CommentForm, LemmyError> {
|
) -> Result<CommentForm, LemmyError> {
|
||||||
let creator_actor_id = ¬e
|
let creator_actor_id = ¬e
|
||||||
.attributed_to()
|
.attributed_to()
|
||||||
|
|
|
@ -107,14 +107,14 @@ impl FromApub for Community {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<Community, LemmyError> {
|
) -> Result<Community, LemmyError> {
|
||||||
let community: Community = get_object_from_apub(
|
let community: Community = get_object_from_apub(
|
||||||
group,
|
group,
|
||||||
context,
|
context,
|
||||||
expected_domain,
|
expected_domain,
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ impl FromApubToForm<GroupExt> for CommunityForm {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
_is_mod_action: bool,
|
_mod_action_allowed: bool,
|
||||||
) -> Result<Self, LemmyError> {
|
) -> Result<Self, LemmyError> {
|
||||||
let moderator_uris = fetch_community_mods(context, group, request_counter).await?;
|
let moderator_uris = fetch_community_mods(context, group, request_counter).await?;
|
||||||
let creator_uri = moderator_uris.first().context(location_info!())?;
|
let creator_uri = moderator_uris.first().context(location_info!())?;
|
||||||
|
|
|
@ -46,13 +46,13 @@ pub(crate) trait FromApub {
|
||||||
/// * `apub` The object to read from
|
/// * `apub` The object to read from
|
||||||
/// * `context` LemmyContext which holds DB pool, HTTP client etc
|
/// * `context` LemmyContext which holds DB pool, HTTP client etc
|
||||||
/// * `expected_domain` Domain where the object was received from. None in case of mod action.
|
/// * `expected_domain` Domain where the object was received from. None in case of mod action.
|
||||||
/// * `is_mod_action` True if the object was sent in a mod activity, ignore `expected_domain` in this case
|
/// * `mod_action_allowed` True if the object can be a mod activity, ignore `expected_domain` in this case
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: &Self::ApubType,
|
apub: &Self::ApubType,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<Self, LemmyError>
|
) -> Result<Self, LemmyError>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
@ -65,7 +65,7 @@ pub(in crate::objects) trait FromApubToForm<ApubType> {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<Self, LemmyError>
|
) -> Result<Self, LemmyError>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
|
@ -118,14 +118,14 @@ impl FromApub for Post {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<Post, LemmyError> {
|
) -> Result<Post, LemmyError> {
|
||||||
let post: Post = get_object_from_apub(
|
let post: Post = get_object_from_apub(
|
||||||
page,
|
page,
|
||||||
context,
|
context,
|
||||||
expected_domain,
|
expected_domain,
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
check_object_for_community_or_site_ban(page, post.community_id, context, request_counter)
|
check_object_for_community_or_site_ban(page, post.community_id, context, request_counter)
|
||||||
|
@ -141,9 +141,9 @@ impl FromApubToForm<PageExt> for PostForm {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<PostForm, LemmyError> {
|
) -> Result<PostForm, LemmyError> {
|
||||||
let ap_id = if is_mod_action {
|
let ap_id = if mod_action_allowed {
|
||||||
let id = page.id_unchecked().context(location_info!())?;
|
let id = page.id_unchecked().context(location_info!())?;
|
||||||
check_is_apub_id_valid(id)?;
|
check_is_apub_id_valid(id)?;
|
||||||
id.to_owned().into()
|
id.to_owned().into()
|
||||||
|
|
|
@ -77,14 +77,14 @@ impl FromApub for PrivateMessage {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<PrivateMessage, LemmyError> {
|
) -> Result<PrivateMessage, LemmyError> {
|
||||||
get_object_from_apub(
|
get_object_from_apub(
|
||||||
note,
|
note,
|
||||||
context,
|
context,
|
||||||
expected_domain,
|
expected_domain,
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ impl FromApubToForm<NoteExt> for PrivateMessageForm {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
_is_mod_action: bool,
|
_mod_action_allowed: bool,
|
||||||
) -> Result<PrivateMessageForm, LemmyError> {
|
) -> Result<PrivateMessageForm, LemmyError> {
|
||||||
let creator_actor_id = note
|
let creator_actor_id = note
|
||||||
.attributed_to()
|
.attributed_to()
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl FromApub for User_ {
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
request_counter: &mut i32,
|
request_counter: &mut i32,
|
||||||
is_mod_action: bool,
|
mod_action_allowed: bool,
|
||||||
) -> Result<User_, LemmyError> {
|
) -> Result<User_, LemmyError> {
|
||||||
let user_id = person.id_unchecked().context(location_info!())?.to_owned();
|
let user_id = person.id_unchecked().context(location_info!())?.to_owned();
|
||||||
let domain = user_id.domain().context(location_info!())?;
|
let domain = user_id.domain().context(location_info!())?;
|
||||||
|
@ -109,7 +109,7 @@ impl FromApub for User_ {
|
||||||
context,
|
context,
|
||||||
expected_domain,
|
expected_domain,
|
||||||
request_counter,
|
request_counter,
|
||||||
is_mod_action,
|
mod_action_allowed,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let user = blocking(context.pool(), move |conn| User_::upsert(conn, &user_form)).await??;
|
let user = blocking(context.pool(), move |conn| User_::upsert(conn, &user_form)).await??;
|
||||||
|
@ -125,7 +125,7 @@ impl FromApubToForm<PersonExt> for UserForm {
|
||||||
_context: &LemmyContext,
|
_context: &LemmyContext,
|
||||||
expected_domain: Url,
|
expected_domain: Url,
|
||||||
_request_counter: &mut i32,
|
_request_counter: &mut i32,
|
||||||
_is_mod_action: bool,
|
_mod_action_allowed: bool,
|
||||||
) -> Result<Self, LemmyError> {
|
) -> Result<Self, LemmyError> {
|
||||||
let avatar = match person.icon() {
|
let avatar = match person.icon() {
|
||||||
Some(any_image) => Some(
|
Some(any_image) => Some(
|
||||||
|
|
Loading…
Reference in a new issue