For FromApub trait, use `is_mod_action: bool` instead

This commit is contained in:
Felix Ableitner 2021-03-16 18:26:19 +01:00
parent be00f63fb2
commit 71067a8cb5
13 changed files with 114 additions and 49 deletions

View File

@ -23,7 +23,7 @@ pub(crate) async fn receive_create_comment(
let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)? let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let comment = Comment::from_apub(&note, context, Some(user.actor_id()), request_counter).await?; let comment = Comment::from_apub(&note, context, user.actor_id(), request_counter, false).await?;
let post_id = comment.post_id; let post_id = comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@ -66,7 +66,7 @@ pub(crate) async fn receive_update_comment(
.context(location_info!())?; .context(location_info!())?;
let user = get_actor_as_user(&update, context, request_counter).await?; let user = get_actor_as_user(&update, context, request_counter).await?;
let comment = Comment::from_apub(&note, context, Some(user.actor_id()), request_counter).await?; let comment = Comment::from_apub(&note, context, user.actor_id(), request_counter, false).await?;
let comment_id = comment.id; let comment_id = comment.id;
let post_id = comment.post_id; let post_id = comment.post_id;

View File

@ -32,7 +32,7 @@ pub(crate) async fn receive_create_post(
let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)? let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let post = Post::from_apub(&page, context, Some(user.actor_id()), request_counter).await?; let post = Post::from_apub(&page, context, user.actor_id(), request_counter, false).await?;
// Refetch the view // Refetch the view
let post_id = post.id; let post_id = post.id;
@ -72,20 +72,27 @@ pub(crate) async fn receive_update_post(
}) })
.await??; .await??;
let mut expected_domain = Some(user.actor_id());
// 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;
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??;
verify_mod_activity(&update, announce, &community, context).await?; verify_mod_activity(&update, announce, &community, context).await?;
expected_domain = None; is_mod_action = true;
} }
let post = Post::from_apub(&page, context, expected_domain, request_counter).await?; let post = Post::from_apub(
&page,
context,
user.actor_id(),
request_counter,
is_mod_action,
)
.await?;
let post_id = post.id; let post_id = post.id;
// Refetch the view // Refetch the view

View File

@ -39,7 +39,7 @@ pub(crate) async fn receive_create_private_message(
.context(location_info!())?; .context(location_info!())?;
let private_message = let private_message =
PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?; PrivateMessage::from_apub(&note, context, expected_domain, request_counter, false).await?;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {
PrivateMessageView::read(conn, private_message.id) PrivateMessageView::read(conn, private_message.id)
@ -78,7 +78,7 @@ pub(crate) async fn receive_update_private_message(
let note = NoteExt::from_any_base(object)?.context(location_info!())?; let note = NoteExt::from_any_base(object)?.context(location_info!())?;
let private_message = let private_message =
PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?; PrivateMessage::from_apub(&note, context, expected_domain, request_counter, false).await?;
let private_message_id = private_message.id; let private_message_id = private_message.id;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {

View File

@ -71,8 +71,14 @@ async fn fetch_remote_community(
} }
let group = group?; let group = group?;
let community = let community = Community::from_apub(
Community::from_apub(&group, context, Some(apub_id.to_owned()), recursion_counter).await?; &group,
context,
apub_id.to_owned(),
recursion_counter,
false,
)
.await?;
// only fetch outbox for new communities, otherwise this can create an infinite loop // only fetch outbox for new communities, otherwise this can create an infinite loop
if old_community.is_none() { if old_community.is_none() {

View File

@ -33,8 +33,9 @@ pub(crate) async fn get_or_fetch_and_insert_post(
let post = Post::from_apub( let post = Post::from_apub(
&page, &page,
context, context,
Some(post_ap_id.to_owned()), post_ap_id.to_owned(),
recursion_counter, recursion_counter,
false,
) )
.await?; .await?;
@ -71,8 +72,9 @@ pub(crate) async fn get_or_fetch_and_insert_comment(
let comment = Comment::from_apub( let comment = Comment::from_apub(
&comment, &comment,
context, context,
Some(comment_ap_id.to_owned()), comment_ap_id.to_owned(),
recursion_counter, recursion_counter,
false,
) )
.await?; .await?;

View File

@ -147,13 +147,13 @@ async fn build_response(
]; ];
} }
SearchAcceptedObjects::Page(p) => { SearchAcceptedObjects::Page(p) => {
let p = Post::from_apub(&p, context, Some(query_url), recursion_counter).await?; let p = Post::from_apub(&p, context, query_url, recursion_counter, false).await?;
response.posts = response.posts =
vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??]; vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??];
} }
SearchAcceptedObjects::Comment(c) => { SearchAcceptedObjects::Comment(c) => {
let c = Comment::from_apub(&c, context, Some(query_url), recursion_counter).await?; let c = Comment::from_apub(&c, context, query_url, recursion_counter, false).await?;
response.comments = vec![ response.comments = vec![
blocking(context.pool(), move |conn| { blocking(context.pool(), move |conn| {

View File

@ -49,8 +49,9 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
let user = User_::from_apub( let user = User_::from_apub(
&person?, &person?,
context, context,
Some(apub_id.to_owned()), apub_id.to_owned(),
recursion_counter, recursion_counter,
false,
) )
.await?; .await?;
@ -71,8 +72,9 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
let user = User_::from_apub( let user = User_::from_apub(
&person, &person,
context, context,
Some(apub_id.to_owned()), apub_id.to_owned(),
recursion_counter, recursion_counter,
false,
) )
.await?; .await?;

View File

@ -97,11 +97,18 @@ impl FromApub for Comment {
async fn from_apub( async fn from_apub(
note: &NoteExt, note: &NoteExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<Comment, LemmyError> { ) -> Result<Comment, LemmyError> {
let comment: Comment = let comment: Comment = get_object_from_apub(
get_object_from_apub(note, context, expected_domain, request_counter).await?; note,
context,
expected_domain,
request_counter,
is_mod_action,
)
.await?;
let post_id = comment.post_id; let post_id = comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@ -126,10 +133,10 @@ impl FromApubToForm<NoteExt> for CommentForm {
async fn from_apub( async fn from_apub(
note: &NoteExt, note: &NoteExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
_is_mod_action: bool,
) -> Result<CommentForm, LemmyError> { ) -> Result<CommentForm, LemmyError> {
let expected_domain = expected_domain.expect("expected_domain must be set for comment");
let creator_actor_id = &note let creator_actor_id = &note
.attributed_to() .attributed_to()
.context(location_info!())? .context(location_info!())?

View File

@ -105,11 +105,18 @@ impl FromApub for Community {
async fn from_apub( async fn from_apub(
group: &GroupExt, group: &GroupExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<Community, LemmyError> { ) -> Result<Community, LemmyError> {
let community: Community = let community: Community = get_object_from_apub(
get_object_from_apub(group, context, expected_domain, request_counter).await?; group,
context,
expected_domain,
request_counter,
is_mod_action,
)
.await?;
let new_moderators = fetch_community_mods(context, group, request_counter).await?; let new_moderators = fetch_community_mods(context, group, request_counter).await?;
let community_id = community.id; let community_id = community.id;
@ -160,10 +167,10 @@ impl FromApubToForm<GroupExt> for CommunityForm {
async fn from_apub( async fn from_apub(
group: &GroupExt, group: &GroupExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
_is_mod_action: bool,
) -> Result<Self, LemmyError> { ) -> Result<Self, LemmyError> {
let expected_domain = expected_domain.expect("expected_domain must be set for community");
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!())?;

View File

@ -46,11 +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
async fn from_apub( async fn from_apub(
apub: &Self::ApubType, apub: &Self::ApubType,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<Self, LemmyError> ) -> Result<Self, LemmyError>
where where
Self: Sized; Self: Sized;
@ -61,8 +63,9 @@ pub(in crate::objects) trait FromApubToForm<ApubType> {
async fn from_apub( async fn from_apub(
apub: &ApubType, apub: &ApubType,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<Self, LemmyError> ) -> Result<Self, LemmyError>
where where
Self: Sized; Self: Sized;
@ -173,8 +176,9 @@ pub(in crate::objects) fn check_is_markdown(mime: Option<&Mime>) -> Result<(), L
pub(in crate::objects) async fn get_object_from_apub<From, Kind, To, ToForm>( pub(in crate::objects) async fn get_object_from_apub<From, Kind, To, ToForm>(
from: &From, from: &From,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<To, LemmyError> ) -> Result<To, LemmyError>
where where
From: BaseExt<Kind>, From: BaseExt<Kind>,
@ -194,7 +198,14 @@ where
} }
// otherwise parse and insert, assuring that it comes from the right domain // otherwise parse and insert, assuring that it comes from the right domain
else { else {
let to_form = ToForm::from_apub(&from, context, expected_domain, request_counter).await?; let to_form = ToForm::from_apub(
&from,
context,
expected_domain,
request_counter,
is_mod_action,
)
.await?;
let to = blocking(context.pool(), move |conn| To::upsert(conn, &to_form)).await??; let to = blocking(context.pool(), move |conn| To::upsert(conn, &to_form)).await??;
Ok(to) Ok(to)

View File

@ -116,10 +116,18 @@ impl FromApub for Post {
async fn from_apub( async fn from_apub(
page: &PageExt, page: &PageExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<Post, LemmyError> { ) -> Result<Post, LemmyError> {
let post: Post = get_object_from_apub(page, context, expected_domain, request_counter).await?; let post: Post = get_object_from_apub(
page,
context,
expected_domain,
request_counter,
is_mod_action,
)
.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)
.await?; .await?;
Ok(post) Ok(post)
@ -131,16 +139,16 @@ impl FromApubToForm<PageExt> for PostForm {
async fn from_apub( async fn from_apub(
page: &PageExt, page: &PageExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<PostForm, LemmyError> { ) -> Result<PostForm, LemmyError> {
let ap_id = match expected_domain { let ap_id = if is_mod_action {
Some(e) => check_object_domain(page, e)?,
None => {
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()
} } else {
check_object_domain(page, expected_domain)?
}; };
let ext = &page.ext_one; let ext = &page.ext_one;
let creator_actor_id = page let creator_actor_id = page

View File

@ -75,10 +75,18 @@ impl FromApub for PrivateMessage {
async fn from_apub( async fn from_apub(
note: &NoteExt, note: &NoteExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: bool,
) -> Result<PrivateMessage, LemmyError> { ) -> Result<PrivateMessage, LemmyError> {
get_object_from_apub(note, context, expected_domain, request_counter).await get_object_from_apub(
note,
context,
expected_domain,
request_counter,
is_mod_action,
)
.await
} }
} }
@ -87,10 +95,10 @@ impl FromApubToForm<NoteExt> for PrivateMessageForm {
async fn from_apub( async fn from_apub(
note: &NoteExt, note: &NoteExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
_is_mod_action: bool,
) -> Result<PrivateMessageForm, LemmyError> { ) -> Result<PrivateMessageForm, LemmyError> {
let expected_domain = expected_domain.expect("expected_domain must be set for private message");
let creator_actor_id = note let creator_actor_id = note
.attributed_to() .attributed_to()
.context(location_info!())? .context(location_info!())?

View File

@ -91,8 +91,9 @@ impl FromApub for User_ {
async fn from_apub( async fn from_apub(
person: &PersonExt, person: &PersonExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
request_counter: &mut i32, request_counter: &mut i32,
is_mod_action: 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!())?;
@ -103,8 +104,14 @@ impl FromApub for User_ {
.await??; .await??;
Ok(user) Ok(user)
} else { } else {
let user_form = let user_form = UserForm::from_apub(
UserForm::from_apub(person, context, expected_domain, request_counter).await?; person,
context,
expected_domain,
request_counter,
is_mod_action,
)
.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??;
Ok(user) Ok(user)
} }
@ -116,10 +123,10 @@ impl FromApubToForm<PersonExt> for UserForm {
async fn from_apub( async fn from_apub(
person: &PersonExt, person: &PersonExt,
_context: &LemmyContext, _context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Url,
_request_counter: &mut i32, _request_counter: &mut i32,
_is_mod_action: bool,
) -> Result<Self, LemmyError> { ) -> Result<Self, LemmyError> {
let expected_domain = expected_domain.expect("expected_domain must be set for user");
let avatar = match person.icon() { let avatar = match person.icon() {
Some(any_image) => Some( Some(any_image) => Some(
Image::from_any_base(any_image.as_one().context(location_info!())?.clone())? Image::from_any_base(any_image.as_one().context(location_info!())?.clone())?