mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 14:21:19 +00:00
attempted fix
This commit is contained in:
parent
ae78eaa3b1
commit
21eedb8dc0
4 changed files with 89 additions and 17 deletions
|
@ -298,6 +298,20 @@ test.only("Fetch remote content in private community", async () => {
|
||||||
const comment_id = comment.comment_view.comment.id;
|
const comment_id = comment.comment_view.comment.id;
|
||||||
expect(comment_id).toBeDefined();
|
expect(comment_id).toBeDefined();
|
||||||
|
|
||||||
|
// Wait for post and comment to federate
|
||||||
|
/*
|
||||||
|
console.log('a');
|
||||||
|
await waitUntil(
|
||||||
|
() => resolvePost(alpha, post.post_view.post),
|
||||||
|
p => p?.post?.post.id != undefined,
|
||||||
|
);
|
||||||
|
await waitUntil(
|
||||||
|
() => resolveComment(gamma, comment.comment_view.comment),
|
||||||
|
p => p?.post?.post.id != undefined,
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
console.log("b");
|
||||||
|
|
||||||
// create gamma user and follow community
|
// create gamma user and follow community
|
||||||
const gammaCommunityId = (
|
const gammaCommunityId = (
|
||||||
await resolveCommunity(gamma, community.community_view.community.actor_id)
|
await resolveCommunity(gamma, community.community_view.community.actor_id)
|
||||||
|
@ -310,23 +324,22 @@ test.only("Fetch remote content in private community", async () => {
|
||||||
await approveFollower(alpha, alphaCommunityId);
|
await approveFollower(alpha, alphaCommunityId);
|
||||||
|
|
||||||
// now user can fetch posts and comments in community (using signed fetch), and create posts
|
// now user can fetch posts and comments in community (using signed fetch), and create posts
|
||||||
|
// TODO: this fails because beta doesnt know if the gamma user was approved by alpha community
|
||||||
|
console.log(0);
|
||||||
let resolvedPost = await waitUntil(
|
let resolvedPost = await waitUntil(
|
||||||
() => resolvePost(gamma, post.post_view.post),
|
() => resolvePost(gamma, post.post_view.post),
|
||||||
p => p?.post?.post.id != undefined,
|
p => p?.post?.post.id != undefined,
|
||||||
);
|
);
|
||||||
console.log(post.post_view.post);
|
|
||||||
console.log(resolvedPost.post?.post);
|
|
||||||
expect(resolvedPost.post?.post.ap_id).toBe(post.post_view.post.ap_id);
|
expect(resolvedPost.post?.post.ap_id).toBe(post.post_view.post.ap_id);
|
||||||
const resolvedComment = (
|
console.log(1);
|
||||||
await resolveComment(gamma, comment.comment_view.comment)
|
const resolvedComment = await waitUntil(
|
||||||
).comment;
|
() => resolveComment(gamma, comment.comment_view.comment),
|
||||||
expect(resolvedComment?.comment.ap_id).toBe(
|
p => p?.post?.post.id != undefined,
|
||||||
|
);
|
||||||
|
expect(resolvedComment?.comment?.comment.ap_id).toBe(
|
||||||
comment.comment_view.comment.ap_id,
|
comment.comment_view.comment.ap_id,
|
||||||
);
|
);
|
||||||
|
console.log(2);
|
||||||
// TODO: this test should fail as check_has_followers_from_instance() on beta returns errors
|
|
||||||
// because it doesnt know the community follower. yet for some reason the test passes???
|
|
||||||
fail();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function approveFollower(user: LemmyHttp, community_id: number) {
|
async function approveFollower(user: LemmyHttp, community_id: number) {
|
||||||
|
|
|
@ -6,16 +6,19 @@ use crate::{
|
||||||
community_moderators::ApubCommunityModerators,
|
community_moderators::ApubCommunityModerators,
|
||||||
community_outbox::ApubCommunityOutbox,
|
community_outbox::ApubCommunityOutbox,
|
||||||
},
|
},
|
||||||
|
fetcher::site_or_community_or_user::SiteOrCommunityOrUser,
|
||||||
http::{check_community_fetchable, create_apub_response, create_apub_tombstone_response},
|
http::{check_community_fetchable, create_apub_response, create_apub_tombstone_response},
|
||||||
objects::community::ApubCommunity,
|
objects::community::ApubCommunity,
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
||||||
|
fetch::object_id::ObjectId,
|
||||||
traits::{Collection, Object},
|
traits::{Collection, Object},
|
||||||
};
|
};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_db_schema::{source::community::Community, traits::ApubActor};
|
use lemmy_db_schema::{source::community::Community, traits::ApubActor};
|
||||||
|
use lemmy_db_views_actor::structs::CommunityFollowerView;
|
||||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
@ -24,6 +27,11 @@ pub(crate) struct CommunityQuery {
|
||||||
community_name: String,
|
community_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CommunityIsFollowerQuery {
|
||||||
|
is_follower: Option<ObjectId<SiteOrCommunityOrUser>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the ActivityPub json representation of a local community over HTTP.
|
/// Return the ActivityPub json representation of a local community over HTTP.
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub(crate) async fn get_apub_community_http(
|
pub(crate) async fn get_apub_community_http(
|
||||||
|
@ -48,11 +56,26 @@ pub(crate) async fn get_apub_community_http(
|
||||||
/// Returns an empty followers collection, only populating the size (for privacy).
|
/// Returns an empty followers collection, only populating the size (for privacy).
|
||||||
pub(crate) async fn get_apub_community_followers(
|
pub(crate) async fn get_apub_community_followers(
|
||||||
info: web::Path<CommunityQuery>,
|
info: web::Path<CommunityQuery>,
|
||||||
|
query: web::Query<CommunityIsFollowerQuery>,
|
||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::NotFound)?;
|
.ok_or(LemmyErrorType::NotFound)?;
|
||||||
|
if let Some(is_follower) = &query.is_follower {
|
||||||
|
let instance_id = is_follower.dereference(&context).await?.instance_id();
|
||||||
|
let has_followers = CommunityFollowerView::check_has_followers_from_instance(
|
||||||
|
community.id,
|
||||||
|
instance_id,
|
||||||
|
&mut context.pool(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return if has_followers.is_ok() {
|
||||||
|
Ok(HttpResponse::Ok().finish())
|
||||||
|
} else {
|
||||||
|
Ok(HttpResponse::NotFound().finish())
|
||||||
|
};
|
||||||
|
}
|
||||||
check_community_fetchable(&community)?;
|
check_community_fetchable(&community)?;
|
||||||
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
||||||
create_apub_response(&followers)
|
create_apub_response(&followers)
|
||||||
|
|
|
@ -8,6 +8,7 @@ use activitypub_federation::{
|
||||||
actix_web::{inbox::receive_activity, signing_actor},
|
actix_web::{inbox::receive_activity, signing_actor},
|
||||||
config::Data,
|
config::Data,
|
||||||
protocol::context::WithContext,
|
protocol::context::WithContext,
|
||||||
|
traits::Actor,
|
||||||
FEDERATION_CONTENT_TYPE,
|
FEDERATION_CONTENT_TYPE,
|
||||||
};
|
};
|
||||||
use actix_web::{web, web::Bytes, HttpRequest, HttpResponse};
|
use actix_web::{web, web::Bytes, HttpRequest, HttpResponse};
|
||||||
|
@ -145,6 +146,7 @@ async fn check_community_content_fetchable(
|
||||||
// from the fetching instance then fetching is allowed
|
// from the fetching instance then fetching is allowed
|
||||||
Private => {
|
Private => {
|
||||||
let signing_actor = signing_actor::<SiteOrCommunityOrUser>(request, None, context).await?;
|
let signing_actor = signing_actor::<SiteOrCommunityOrUser>(request, None, context).await?;
|
||||||
|
if community.local {
|
||||||
Ok(
|
Ok(
|
||||||
CommunityFollowerView::check_has_followers_from_instance(
|
CommunityFollowerView::check_has_followers_from_instance(
|
||||||
community.id,
|
community.id,
|
||||||
|
@ -153,6 +155,21 @@ async fn check_community_content_fetchable(
|
||||||
)
|
)
|
||||||
.await?,
|
.await?,
|
||||||
)
|
)
|
||||||
|
} else if let Some(followers_url) = community.followers_url.clone() {
|
||||||
|
let mut followers_url = followers_url.inner().clone();
|
||||||
|
followers_url
|
||||||
|
.query_pairs_mut()
|
||||||
|
.append_pair("is_follower", signing_actor.id().as_str());
|
||||||
|
context
|
||||||
|
.client()
|
||||||
|
.get(followers_url.as_str())
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(LemmyErrorType::NotFound.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,6 +232,25 @@ impl CommunityFollowerView {
|
||||||
.then_some(())
|
.then_some(())
|
||||||
.ok_or(diesel::NotFound)
|
.ok_or(diesel::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn is_follower(
|
||||||
|
community_id: CommunityId,
|
||||||
|
instance_id: InstanceId,
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let conn = &mut get_conn(pool).await?;
|
||||||
|
select(exists(
|
||||||
|
action_query(community_actions::followed)
|
||||||
|
.inner_join(person::table.on(community_actions::person_id.eq(person::id)))
|
||||||
|
.filter(community_actions::community_id.eq(community_id))
|
||||||
|
.filter(person::instance_id.eq(instance_id))
|
||||||
|
.filter(community_actions::follow_state.eq(CommunityFollowerState::Accepted)),
|
||||||
|
))
|
||||||
|
.get_result::<bool>(conn)
|
||||||
|
.await?
|
||||||
|
.then_some(())
|
||||||
|
.ok_or(diesel::NotFound)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue