Skip to content

Commit

Permalink
Merge pull request #187 from LemmyNet/main
Browse files Browse the repository at this point in the history
[pull] master from LemmyNet:main
  • Loading branch information
pull[bot] authored Oct 27, 2024
2 parents 5326572 + f05afea commit 305f4b8
Show file tree
Hide file tree
Showing 40 changed files with 306 additions and 239 deletions.
17 changes: 8 additions & 9 deletions api_tests/src/comment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,16 @@ test("Delete a comment", async () => {
expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
expect(deleteCommentRes.comment_view.comment.content).toBe("");

// Make sure that comment is undefined on beta
// Make sure that comment is deleted on beta
await waitUntil(
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
e => e.message == "not_found",
() => resolveComment(beta, commentRes.comment_view.comment),
c => c.comment?.comment.deleted === true,
);

// Make sure that comment is undefined on gamma after delete
// Make sure that comment is deleted on gamma after delete
await waitUntil(
() => resolveComment(gamma, commentRes.comment_view.comment).catch(e => e),
e => e.message === "not_found",
() => resolveComment(gamma, commentRes.comment_view.comment),
c => c.comment?.comment.deleted === true,
);

// Test undeleting the comment
Expand All @@ -181,11 +181,10 @@ test("Delete a comment", async () => {
// Make sure that comment is undeleted on beta
let betaComment2 = (
await waitUntil(
() => resolveComment(beta, commentRes.comment_view.comment).catch(e => e),
e => e.message !== "not_found",
() => resolveComment(beta, commentRes.comment_view.comment),
c => c.comment?.comment.deleted === false,
)
).comment;
expect(betaComment2?.comment.deleted).toBe(false);
assertCommentFederation(betaComment2, undeleteCommentRes.comment_view);
});

Expand Down
1 change: 0 additions & 1 deletion crates/api/src/comment/like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ pub async fn like_comment(

let like_form = CommentLikeForm {
comment_id: data.comment_id,
post_id: orig_comment.post.id,
person_id: local_user_view.person.id,
score: data.score,
};
Expand Down
13 changes: 6 additions & 7 deletions crates/api_common/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ use lemmy_utils::{
email::{send_email, translations::Lang},
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
rate_limit::{ActionType, BucketConfig},
settings::structs::{PictrsImageMode, Settings},
settings::{
structs::{PictrsImageMode, Settings},
SETTINGS,
},
utils::{
markdown::{image_links::markdown_rewrite_image_links, markdown_check_for_blocked_urls},
slurs::{build_slur_regex, remove_slurs},
Expand Down Expand Up @@ -973,12 +976,8 @@ pub fn generate_followers_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
Ok(Url::parse(&format!("{actor_id}/followers"))?.into())
}

pub fn generate_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
Ok(Url::parse(&format!("{actor_id}/inbox"))?.into())
}

pub fn generate_shared_inbox_url(settings: &Settings) -> LemmyResult<DbUrl> {
let url = format!("{}/inbox", settings.get_protocol_and_hostname());
pub fn generate_inbox_url() -> LemmyResult<DbUrl> {
let url = format!("{}/inbox", SETTINGS.get_protocol_and_hostname());
Ok(Url::parse(&url)?.into())
}

Expand Down
1 change: 0 additions & 1 deletion crates/api_crud/src/comment/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ pub async fn create_comment(
// You like your own comment by default
let like_form = CommentLikeForm {
comment_id: inserted_comment.id,
post_id: post.id,
person_id: local_user_view.person.id,
score: 1,
};
Expand Down
4 changes: 1 addition & 3 deletions crates/api_crud/src/community/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use lemmy_api_common::{
generate_followers_url,
generate_inbox_url,
generate_local_apub_endpoint,
generate_shared_inbox_url,
get_url_blocklist,
is_admin,
local_site_to_slur_regex,
Expand Down Expand Up @@ -96,8 +95,7 @@ pub async fn create_community(
actor_id: Some(community_actor_id.clone()),
private_key: Some(keypair.private_key),
followers_url: Some(generate_followers_url(&community_actor_id)?),
inbox_url: Some(generate_inbox_url(&community_actor_id)?),
shared_inbox_url: Some(generate_shared_inbox_url(context.settings())?),
inbox_url: Some(generate_inbox_url()?),
posting_restricted_to_mods: data.posting_restricted_to_mods,
visibility: data.visibility,
..CommunityInsertForm::new(
Expand Down
4 changes: 2 additions & 2 deletions crates/api_crud/src/site/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use lemmy_api_common::{
context::LemmyContext,
site::{CreateSite, SiteResponse},
utils::{
generate_shared_inbox_url,
generate_inbox_url,
get_url_blocklist,
is_admin,
local_site_rate_limit_to_rate_limit_config,
Expand Down Expand Up @@ -55,7 +55,7 @@ pub async fn create_site(
validate_create_payload(&local_site, &data)?;

let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
let inbox_url = Some(generate_shared_inbox_url(context.settings())?);
let inbox_url = Some(generate_inbox_url()?);
let keypair = generate_actor_keypair()?;

let slur_regex = local_site_to_slur_regex(&local_site);
Expand Down
4 changes: 1 addition & 3 deletions crates/api_crud/src/user/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use lemmy_api_common::{
check_user_valid,
generate_inbox_url,
generate_local_apub_endpoint,
generate_shared_inbox_url,
honeypot_check,
local_site_to_slur_regex,
password_length_check,
Expand Down Expand Up @@ -418,8 +417,7 @@ async fn create_person(
// Register the new person
let person_form = PersonInsertForm {
actor_id: Some(actor_id.clone()),
inbox_url: Some(generate_inbox_url(&actor_id)?),
shared_inbox_url: Some(generate_shared_inbox_url(context.settings())?),
inbox_url: Some(generate_inbox_url()?),
private_key: Some(actor_keypair.private_key),
..PersonInsertForm::new(username.clone(), actor_keypair.public_key, instance_id)
};
Expand Down
10 changes: 8 additions & 2 deletions crates/apub/src/activities/community/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,14 @@ impl ActivityHandler for UpdateCommunity {
icon: Some(self.object.icon.map(|i| i.url.into())),
banner: Some(self.object.image.map(|i| i.url.into())),
followers_url: self.object.followers.map(Into::into),
inbox_url: Some(self.object.inbox.into()),
shared_inbox_url: Some(self.object.endpoints.map(|e| e.shared_inbox.into())),
inbox_url: Some(
self
.object
.endpoints
.map(|e| e.shared_inbox)
.unwrap_or(self.object.inbox)
.into(),
),
moderators_url: self.object.attributed_to.map(Into::into),
posting_restricted_to_mods: self.object.posting_restricted_to_mods,
featured_url: self.object.featured.map(Into::into),
Expand Down
1 change: 0 additions & 1 deletion crates/apub/src/activities/create_or_update/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ impl ActivityHandler for CreateOrUpdateNote {
// author likes their own comment by default
let like_form = CommentLikeForm {
comment_id: comment.id,
post_id: comment.post_id,
person_id: comment.creator_id,
score: 1,
};
Expand Down
1 change: 0 additions & 1 deletion crates/apub/src/activities/voting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ async fn vote_comment(
let comment_id = comment.id;
let like_form = CommentLikeForm {
comment_id,
post_id: comment.post_id,
person_id: actor.id,
score: vote_type.into(),
};
Expand Down
140 changes: 124 additions & 16 deletions crates/apub/src/api/resolve_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::fetcher::{
};
use activitypub_federation::config::Data;
use actix_web::web::{Json, Query};
use diesel::NotFound;
use lemmy_api_common::{
context::LemmyContext,
site::{ResolveObject, ResolveObjectResponse},
Expand Down Expand Up @@ -47,36 +46,145 @@ async fn convert_response(
local_user_view: Option<LocalUserView>,
pool: &mut DbPool<'_>,
) -> LemmyResult<Json<ResolveObjectResponse>> {
let removed_or_deleted;
let mut res = ResolveObjectResponse::default();
let local_user = local_user_view.map(|l| l.local_user);
let is_admin = local_user.clone().map(|l| l.admin).unwrap_or_default();

match object {
SearchableObjects::PostOrComment(pc) => match *pc {
PostOrComment::Post(p) => {
removed_or_deleted = p.deleted || p.removed;
res.post = Some(PostView::read(pool, p.id, local_user.as_ref(), false).await?)
res.post = Some(PostView::read(pool, p.id, local_user.as_ref(), is_admin).await?)
}
PostOrComment::Comment(c) => {
removed_or_deleted = c.deleted || c.removed;
res.comment = Some(CommentView::read(pool, c.id, local_user.as_ref()).await?)
}
},
SearchableObjects::PersonOrCommunity(pc) => match *pc {
UserOrCommunity::User(u) => {
removed_or_deleted = u.deleted;
res.person = Some(PersonView::read(pool, u.id).await?)
}
UserOrCommunity::User(u) => res.person = Some(PersonView::read(pool, u.id).await?),
UserOrCommunity::Community(c) => {
removed_or_deleted = c.deleted || c.removed;
res.community = Some(CommunityView::read(pool, c.id, local_user.as_ref(), false).await?)
res.community = Some(CommunityView::read(pool, c.id, local_user.as_ref(), is_admin).await?)
}
},
};
// if the object was deleted from database, dont return it
if removed_or_deleted {
Err(NotFound {}.into())
} else {
Ok(Json(res))

Ok(Json(res))
}

#[cfg(test)]
mod tests {
use crate::api::resolve_object::resolve_object;
use actix_web::web::Query;
use lemmy_api_common::{context::LemmyContext, site::ResolveObject};
use lemmy_db_schema::{
source::{
community::{Community, CommunityInsertForm},
instance::Instance,
local_site::{LocalSite, LocalSiteInsertForm},
post::{Post, PostInsertForm, PostUpdateForm},
site::{Site, SiteInsertForm},
},
traits::Crud,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
use serial_test::serial;

#[tokio::test]
#[serial]
#[expect(clippy::unwrap_used)]
async fn test_object_visibility() -> LemmyResult<()> {
let context = LemmyContext::init_test_context().await;
let pool = &mut context.pool();

let name = "test_local_user_name";
let bio = "test_local_user_bio";

let creator = LocalUserView::create_test_user(pool, name, bio, false).await?;
let regular_user = LocalUserView::create_test_user(pool, name, bio, false).await?;
let admin_user = LocalUserView::create_test_user(pool, name, bio, true).await?;

let instance_id = creator.person.instance_id;
let site_form = SiteInsertForm::new("test site".to_string(), instance_id);
let site = Site::create(pool, &site_form).await?;

let local_site_form = LocalSiteInsertForm {
site_setup: Some(true),
private_instance: Some(false),
..LocalSiteInsertForm::new(site.id)
};
LocalSite::create(pool, &local_site_form).await?;

let community = Community::create(
pool,
&CommunityInsertForm::new(
instance_id,
"test".to_string(),
"test".to_string(),
"pubkey".to_string(),
),
)
.await?;

let post_insert_form = PostInsertForm::new("Test".to_string(), creator.person.id, community.id);
let post = Post::create(pool, &post_insert_form).await?;

let query = format!("q={}", post.ap_id).to_string();
let query: Query<ResolveObject> = Query::from_query(&query)?;

// Objects should be resolvable without authentication
let res = resolve_object(query.clone(), context.reset_request_count(), None).await?;
assert_eq!(res.post.as_ref().unwrap().post.ap_id, post.ap_id);
// Objects should be resolvable by regular users
let res = resolve_object(
query.clone(),
context.reset_request_count(),
Some(regular_user.clone()),
)
.await?;
assert_eq!(res.post.as_ref().unwrap().post.ap_id, post.ap_id);
// Objects should be resolvable by admins
let res = resolve_object(
query.clone(),
context.reset_request_count(),
Some(admin_user.clone()),
)
.await?;
assert_eq!(res.post.as_ref().unwrap().post.ap_id, post.ap_id);

Post::update(
pool,
post.id,
&PostUpdateForm {
deleted: Some(true),
..Default::default()
},
)
.await?;

// Deleted objects should not be resolvable without authentication
let res = resolve_object(query.clone(), context.reset_request_count(), None).await;
assert!(res.is_err_and(|e| e.error_type == LemmyErrorType::NotFound));
// Deleted objects should not be resolvable by regular users
let res = resolve_object(
query.clone(),
context.reset_request_count(),
Some(regular_user.clone()),
)
.await;
assert!(res.is_err_and(|e| e.error_type == LemmyErrorType::NotFound));
// Deleted objects should be resolvable by admins
let res = resolve_object(
query.clone(),
context.reset_request_count(),
Some(admin_user.clone()),
)
.await?;
assert_eq!(res.post.as_ref().unwrap().post.ap_id, post.ap_id);

LocalSite::delete(pool).await?;
Site::delete(pool, site.id).await?;
Instance::delete(pool, instance_id).await?;

Ok(())
}
}
Loading

0 comments on commit 305f4b8

Please sign in to comment.