mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-23 19:31:33 +00:00
Implement context (#86)
Implement context Co-authored-by: Felix Ableitner <me@nutomic.com> Reviewed-on: https://yerbamate.dev/LemmyNet/lemmy/pulls/86
This commit is contained in:
parent
53d449d5d7
commit
14f2d190e5
34 changed files with 1535 additions and 1607 deletions
|
@ -15,9 +15,10 @@ use crate::{
|
||||||
WebsocketInfo,
|
WebsocketInfo,
|
||||||
},
|
},
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
use actix_web::web::Data;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::*,
|
comment::*,
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
|
@ -126,12 +127,11 @@ impl Perform for CreateComment {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &CreateComment = &self;
|
let data: &CreateComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
||||||
|
|
||||||
|
@ -151,9 +151,9 @@ impl Perform for CreateComment {
|
||||||
|
|
||||||
// Check for a community ban
|
// Check for a community ban
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, post.community_id, pool).await?;
|
check_community_ban(user.id, post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Check if post is locked, no new comments
|
// Check if post is locked, no new comments
|
||||||
if post.locked {
|
if post.locked {
|
||||||
|
@ -162,15 +162,18 @@ impl Perform for CreateComment {
|
||||||
|
|
||||||
// Create the comment
|
// Create the comment
|
||||||
let comment_form2 = comment_form.clone();
|
let comment_form2 = comment_form.clone();
|
||||||
let inserted_comment =
|
let inserted_comment = match blocking(context.pool(), move |conn| {
|
||||||
match blocking(pool, move |conn| Comment::create(&conn, &comment_form2)).await? {
|
Comment::create(&conn, &comment_form2)
|
||||||
Ok(comment) => comment,
|
})
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
|
.await?
|
||||||
};
|
{
|
||||||
|
Ok(comment) => comment,
|
||||||
|
Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
|
||||||
|
};
|
||||||
|
|
||||||
// Necessary to update the ap_id
|
// Necessary to update the ap_id
|
||||||
let inserted_comment_id = inserted_comment.id;
|
let inserted_comment_id = inserted_comment.id;
|
||||||
let updated_comment: Comment = match blocking(pool, move |conn| {
|
let updated_comment: Comment = match blocking(context.pool(), move |conn| {
|
||||||
let apub_id =
|
let apub_id =
|
||||||
make_apub_endpoint(EndpointType::Comment, &inserted_comment_id.to_string()).to_string();
|
make_apub_endpoint(EndpointType::Comment, &inserted_comment_id.to_string()).to_string();
|
||||||
Comment::update_ap_id(&conn, inserted_comment_id, apub_id)
|
Comment::update_ap_id(&conn, inserted_comment_id, apub_id)
|
||||||
|
@ -181,12 +184,19 @@ impl Perform for CreateComment {
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
|
Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
updated_comment.send_create(&user, &client, pool).await?;
|
updated_comment.send_create(&user, context).await?;
|
||||||
|
|
||||||
// Scan the comment for user mentions, add those rows
|
// Scan the comment for user mentions, add those rows
|
||||||
let mentions = scrape_text_for_mentions(&comment_form.content);
|
let mentions = scrape_text_for_mentions(&comment_form.content);
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, updated_comment.clone(), &user, post, pool, true).await?;
|
mentions,
|
||||||
|
updated_comment.clone(),
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// You like your own comment by default
|
// You like your own comment by default
|
||||||
let like_form = CommentLikeForm {
|
let like_form = CommentLikeForm {
|
||||||
|
@ -197,14 +207,14 @@ impl Perform for CreateComment {
|
||||||
};
|
};
|
||||||
|
|
||||||
let like = move |conn: &'_ _| CommentLike::like(&conn, &like_form);
|
let like = move |conn: &'_ _| CommentLike::like(&conn, &like_form);
|
||||||
if blocking(pool, like).await?.is_err() {
|
if blocking(context.pool(), like).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_like_comment").into());
|
return Err(APIError::err("couldnt_like_comment").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
updated_comment.send_like(&user, &client, pool).await?;
|
updated_comment.send_like(&user, context).await?;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(&conn, inserted_comment.id, Some(user_id))
|
CommentView::read(&conn, inserted_comment.id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -237,18 +247,19 @@ impl Perform for EditComment {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &EditComment = &self;
|
let data: &EditComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_comment =
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, edit_id, None)).await??;
|
CommentView::read(&conn, edit_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_comment.community_id, pool).await?;
|
check_community_ban(user.id, orig_comment.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the creator can edit
|
// Verify that only the creator can edit
|
||||||
if user.id != orig_comment.creator_id {
|
if user.id != orig_comment.creator_id {
|
||||||
|
@ -258,7 +269,7 @@ impl Perform for EditComment {
|
||||||
// Do the update
|
// Do the update
|
||||||
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let updated_comment = match blocking(pool, move |conn| {
|
let updated_comment = match blocking(context.pool(), move |conn| {
|
||||||
Comment::update_content(conn, edit_id, &content_slurs_removed)
|
Comment::update_content(conn, edit_id, &content_slurs_removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -268,20 +279,27 @@ impl Perform for EditComment {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
updated_comment.send_update(&user, &client, pool).await?;
|
updated_comment.send_update(&user, context).await?;
|
||||||
|
|
||||||
// Do the mentions / recipients
|
// Do the mentions / recipients
|
||||||
let post_id = orig_comment.post_id;
|
let post_id = orig_comment.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let updated_comment_content = updated_comment.content.to_owned();
|
let updated_comment_content = updated_comment.content.to_owned();
|
||||||
let mentions = scrape_text_for_mentions(&updated_comment_content);
|
let mentions = scrape_text_for_mentions(&updated_comment_content);
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, updated_comment, &user, post, pool, false).await?;
|
mentions,
|
||||||
|
updated_comment,
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, edit_id, Some(user_id))
|
CommentView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -314,18 +332,19 @@ impl Perform for DeleteComment {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &DeleteComment = &self;
|
let data: &DeleteComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_comment =
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, edit_id, None)).await??;
|
CommentView::read(&conn, edit_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_comment.community_id, pool).await?;
|
check_community_ban(user.id, orig_comment.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the creator can delete
|
// Verify that only the creator can delete
|
||||||
if user.id != orig_comment.creator_id {
|
if user.id != orig_comment.creator_id {
|
||||||
|
@ -334,7 +353,7 @@ impl Perform for DeleteComment {
|
||||||
|
|
||||||
// Do the delete
|
// Do the delete
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_comment = match blocking(pool, move |conn| {
|
let updated_comment = match blocking(context.pool(), move |conn| {
|
||||||
Comment::update_deleted(conn, edit_id, deleted)
|
Comment::update_deleted(conn, edit_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -345,27 +364,32 @@ impl Perform for DeleteComment {
|
||||||
|
|
||||||
// Send the apub message
|
// Send the apub message
|
||||||
if deleted {
|
if deleted {
|
||||||
updated_comment.send_delete(&user, &client, pool).await?;
|
updated_comment.send_delete(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_comment
|
updated_comment.send_undo_delete(&user, context).await?;
|
||||||
.send_undo_delete(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, edit_id, Some(user_id))
|
CommentView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Build the recipients
|
// Build the recipients
|
||||||
let post_id = comment_view.post_id;
|
let post_id = comment_view.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
let mentions = vec![];
|
let mentions = vec![];
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, updated_comment, &user, post, pool, false).await?;
|
mentions,
|
||||||
|
updated_comment,
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut res = CommentResponse {
|
let mut res = CommentResponse {
|
||||||
comment: comment_view,
|
comment: comment_view,
|
||||||
|
@ -395,25 +419,26 @@ impl Perform for RemoveComment {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &RemoveComment = &self;
|
let data: &RemoveComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_comment =
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, edit_id, None)).await??;
|
CommentView::read(&conn, edit_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_comment.community_id, pool).await?;
|
check_community_ban(user.id, orig_comment.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only a mod or admin can remove
|
// Verify that only a mod or admin can remove
|
||||||
is_mod_or_admin(pool, user.id, orig_comment.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_comment.community_id).await?;
|
||||||
|
|
||||||
// Do the remove
|
// Do the remove
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_comment = match blocking(pool, move |conn| {
|
let updated_comment = match blocking(context.pool(), move |conn| {
|
||||||
Comment::update_removed(conn, edit_id, removed)
|
Comment::update_removed(conn, edit_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -429,31 +454,39 @@ impl Perform for RemoveComment {
|
||||||
removed: Some(removed),
|
removed: Some(removed),
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModRemoveComment::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModRemoveComment::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Send the apub message
|
// Send the apub message
|
||||||
if removed {
|
if removed {
|
||||||
updated_comment.send_remove(&user, &client, pool).await?;
|
updated_comment.send_remove(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_comment
|
updated_comment.send_undo_remove(&user, context).await?;
|
||||||
.send_undo_remove(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, edit_id, Some(user_id))
|
CommentView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Build the recipients
|
// Build the recipients
|
||||||
let post_id = comment_view.post_id;
|
let post_id = comment_view.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
let mentions = vec![];
|
let mentions = vec![];
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, updated_comment, &user, post, pool, false).await?;
|
mentions,
|
||||||
|
updated_comment,
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut res = CommentResponse {
|
let mut res = CommentResponse {
|
||||||
comment: comment_view,
|
comment: comment_view,
|
||||||
|
@ -483,33 +516,37 @@ impl Perform for MarkCommentAsRead {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &MarkCommentAsRead = &self;
|
let data: &MarkCommentAsRead = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_comment =
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, edit_id, None)).await??;
|
CommentView::read(&conn, edit_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_comment.community_id, pool).await?;
|
check_community_ban(user.id, orig_comment.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the recipient can mark as read
|
// Verify that only the recipient can mark as read
|
||||||
// Needs to fetch the parent comment / post to get the recipient
|
// Needs to fetch the parent comment / post to get the recipient
|
||||||
let parent_id = orig_comment.parent_id;
|
let parent_id = orig_comment.parent_id;
|
||||||
match parent_id {
|
match parent_id {
|
||||||
Some(pid) => {
|
Some(pid) => {
|
||||||
let parent_comment =
|
let parent_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, pid, None)).await??;
|
CommentView::read(&conn, pid, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
if user.id != parent_comment.creator_id {
|
if user.id != parent_comment.creator_id {
|
||||||
return Err(APIError::err("no_comment_edit_allowed").into());
|
return Err(APIError::err("no_comment_edit_allowed").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let parent_post_id = orig_comment.post_id;
|
let parent_post_id = orig_comment.post_id;
|
||||||
let parent_post = blocking(pool, move |conn| Post::read(conn, parent_post_id)).await??;
|
let parent_post =
|
||||||
|
blocking(context.pool(), move |conn| Post::read(conn, parent_post_id)).await??;
|
||||||
if user.id != parent_post.creator_id {
|
if user.id != parent_post.creator_id {
|
||||||
return Err(APIError::err("no_comment_edit_allowed").into());
|
return Err(APIError::err("no_comment_edit_allowed").into());
|
||||||
}
|
}
|
||||||
|
@ -518,7 +555,11 @@ impl Perform for MarkCommentAsRead {
|
||||||
|
|
||||||
// Do the mark as read
|
// Do the mark as read
|
||||||
let read = data.read;
|
let read = data.read;
|
||||||
match blocking(pool, move |conn| Comment::update_read(conn, edit_id, read)).await? {
|
match blocking(context.pool(), move |conn| {
|
||||||
|
Comment::update_read(conn, edit_id, read)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(comment) => comment,
|
Ok(comment) => comment,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
|
Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
|
||||||
};
|
};
|
||||||
|
@ -526,7 +567,7 @@ impl Perform for MarkCommentAsRead {
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, edit_id, Some(user_id))
|
CommentView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -547,12 +588,11 @@ impl Perform for SaveComment {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &SaveComment = &self;
|
let data: &SaveComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let comment_saved_form = CommentSavedForm {
|
let comment_saved_form = CommentSavedForm {
|
||||||
comment_id: data.comment_id,
|
comment_id: data.comment_id,
|
||||||
|
@ -561,19 +601,19 @@ impl Perform for SaveComment {
|
||||||
|
|
||||||
if data.save {
|
if data.save {
|
||||||
let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form);
|
let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form);
|
||||||
if blocking(pool, save_comment).await?.is_err() {
|
if blocking(context.pool(), save_comment).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_save_comment").into());
|
return Err(APIError::err("couldnt_save_comment").into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let unsave_comment = move |conn: &'_ _| CommentSaved::unsave(conn, &comment_saved_form);
|
let unsave_comment = move |conn: &'_ _| CommentSaved::unsave(conn, &comment_saved_form);
|
||||||
if blocking(pool, unsave_comment).await?.is_err() {
|
if blocking(context.pool(), unsave_comment).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_save_comment").into());
|
return Err(APIError::err("couldnt_save_comment").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, comment_id, Some(user_id))
|
CommentView::read(conn, comment_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -592,40 +632,42 @@ impl Perform for CreateCommentLike {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommentResponse, LemmyError> {
|
) -> Result<CommentResponse, LemmyError> {
|
||||||
let data: &CreateCommentLike = &self;
|
let data: &CreateCommentLike = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let mut recipient_ids = Vec::new();
|
let mut recipient_ids = Vec::new();
|
||||||
|
|
||||||
// Don't do a downvote if site has downvotes disabled
|
// Don't do a downvote if site has downvotes disabled
|
||||||
if data.score == -1 {
|
if data.score == -1 {
|
||||||
let site = blocking(pool, move |conn| SiteView::read(conn)).await??;
|
let site = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
|
||||||
if !site.enable_downvotes {
|
if !site.enable_downvotes {
|
||||||
return Err(APIError::err("downvotes_disabled").into());
|
return Err(APIError::err("downvotes_disabled").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
let orig_comment =
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(&conn, comment_id, None)).await??;
|
CommentView::read(&conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let post_id = orig_comment.post_id;
|
let post_id = orig_comment.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
check_community_ban(user.id, post.community_id, pool).await?;
|
check_community_ban(user.id, post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
let comment = blocking(pool, move |conn| Comment::read(conn, comment_id)).await??;
|
let comment = blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??;
|
||||||
|
|
||||||
// Add to recipient ids
|
// Add to recipient ids
|
||||||
match comment.parent_id {
|
match comment.parent_id {
|
||||||
Some(parent_id) => {
|
Some(parent_id) => {
|
||||||
let parent_comment = blocking(pool, move |conn| Comment::read(conn, parent_id)).await??;
|
let parent_comment =
|
||||||
|
blocking(context.pool(), move |conn| Comment::read(conn, parent_id)).await??;
|
||||||
if parent_comment.creator_id != user.id {
|
if parent_comment.creator_id != user.id {
|
||||||
let parent_user = blocking(pool, move |conn| {
|
let parent_user = blocking(context.pool(), move |conn| {
|
||||||
User_::read(conn, parent_comment.creator_id)
|
User_::read(conn, parent_comment.creator_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -646,7 +688,7 @@ impl Perform for CreateCommentLike {
|
||||||
|
|
||||||
// Remove any likes first
|
// Remove any likes first
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommentLike::remove(conn, user_id, comment_id)
|
CommentLike::remove(conn, user_id, comment_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -656,23 +698,23 @@ impl Perform for CreateCommentLike {
|
||||||
if do_add {
|
if do_add {
|
||||||
let like_form2 = like_form.clone();
|
let like_form2 = like_form.clone();
|
||||||
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2);
|
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2);
|
||||||
if blocking(pool, like).await?.is_err() {
|
if blocking(context.pool(), like).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_like_comment").into());
|
return Err(APIError::err("couldnt_like_comment").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if like_form.score == 1 {
|
if like_form.score == 1 {
|
||||||
comment.send_like(&user, &client, pool).await?;
|
comment.send_like(&user, context).await?;
|
||||||
} else if like_form.score == -1 {
|
} else if like_form.score == -1 {
|
||||||
comment.send_dislike(&user, &client, pool).await?;
|
comment.send_dislike(&user, context).await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
comment.send_undo_like(&user, &client, pool).await?;
|
comment.send_undo_like(&user, context).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have to refetch the comment to get the current state
|
// Have to refetch the comment to get the current state
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let liked_comment = blocking(pool, move |conn| {
|
let liked_comment = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, comment_id, Some(user_id))
|
CommentView::read(conn, comment_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -705,12 +747,11 @@ impl Perform for GetComments {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetCommentsResponse, LemmyError> {
|
) -> Result<GetCommentsResponse, LemmyError> {
|
||||||
let data: &GetComments = &self;
|
let data: &GetComments = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
|
|
||||||
let type_ = ListingType::from_str(&data.type_)?;
|
let type_ = ListingType::from_str(&data.type_)?;
|
||||||
|
@ -719,7 +760,7 @@ impl Perform for GetComments {
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let comments = blocking(pool, move |conn| {
|
let comments = blocking(context.pool(), move |conn| {
|
||||||
CommentQueryBuilder::create(conn)
|
CommentQueryBuilder::create(conn)
|
||||||
.listing_type(type_)
|
.listing_type(type_)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
|
|
|
@ -8,9 +8,7 @@ use crate::{
|
||||||
UserOperation,
|
UserOperation,
|
||||||
WebsocketInfo,
|
WebsocketInfo,
|
||||||
},
|
},
|
||||||
DbPool,
|
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
|
@ -167,25 +165,28 @@ impl Perform for GetCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetCommunityResponse, LemmyError> {
|
) -> Result<GetCommunityResponse, LemmyError> {
|
||||||
let data: &GetCommunity = &self;
|
let data: &GetCommunity = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
|
|
||||||
let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
|
let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
|
||||||
let community = match data.id {
|
let community = match data.id {
|
||||||
Some(id) => blocking(pool, move |conn| Community::read(conn, id)).await??,
|
Some(id) => blocking(context.pool(), move |conn| Community::read(conn, id)).await??,
|
||||||
None => match blocking(pool, move |conn| Community::read_from_name(conn, &name)).await? {
|
None => match blocking(context.pool(), move |conn| {
|
||||||
|
Community::read_from_name(conn, &name)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(community) => community,
|
Ok(community) => community,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
|
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let community_view = match blocking(pool, move |conn| {
|
let community_view = match blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, user_id)
|
CommunityView::read(conn, community_id, user_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -195,7 +196,7 @@ impl Perform for GetCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let moderators: Vec<CommunityModeratorView> = match blocking(pool, move |conn| {
|
let moderators: Vec<CommunityModeratorView> = match blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -236,12 +237,11 @@ impl Perform for CreateCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let data: &CreateCommunity = &self;
|
let data: &CreateCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.name)?;
|
check_slurs(&data.name)?;
|
||||||
check_slurs(&data.title)?;
|
check_slurs(&data.title)?;
|
||||||
|
@ -254,7 +254,7 @@ impl Perform for CreateCommunity {
|
||||||
// Double check for duplicate community actor_ids
|
// Double check for duplicate community actor_ids
|
||||||
let actor_id = make_apub_endpoint(EndpointType::Community, &data.name).to_string();
|
let actor_id = make_apub_endpoint(EndpointType::Community, &data.name).to_string();
|
||||||
let actor_id_cloned = actor_id.to_owned();
|
let actor_id_cloned = actor_id.to_owned();
|
||||||
let community_dupe = blocking(pool, move |conn| {
|
let community_dupe = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, &actor_id_cloned)
|
Community::read_from_actor_id(conn, &actor_id_cloned)
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -285,11 +285,14 @@ impl Perform for CreateCommunity {
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_community =
|
let inserted_community = match blocking(context.pool(), move |conn| {
|
||||||
match blocking(pool, move |conn| Community::create(conn, &community_form)).await? {
|
Community::create(conn, &community_form)
|
||||||
Ok(community) => community,
|
})
|
||||||
Err(_e) => return Err(APIError::err("community_already_exists").into()),
|
.await?
|
||||||
};
|
{
|
||||||
|
Ok(community) => community,
|
||||||
|
Err(_e) => return Err(APIError::err("community_already_exists").into()),
|
||||||
|
};
|
||||||
|
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
|
@ -297,7 +300,7 @@ impl Perform for CreateCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
if blocking(pool, join).await?.is_err() {
|
if blocking(context.pool(), join).await?.is_err() {
|
||||||
return Err(APIError::err("community_moderator_already_exists").into());
|
return Err(APIError::err("community_moderator_already_exists").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,12 +310,12 @@ impl Perform for CreateCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
if blocking(pool, follow).await?.is_err() {
|
if blocking(context.pool(), follow).await?.is_err() {
|
||||||
return Err(APIError::err("community_follower_already_exists").into());
|
return Err(APIError::err("community_follower_already_exists").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(pool, move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, inserted_community.id, Some(user_id))
|
CommunityView::read(conn, inserted_community.id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -329,19 +332,18 @@ impl Perform for EditCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let data: &EditCommunity = &self;
|
let data: &EditCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.title)?;
|
check_slurs(&data.title)?;
|
||||||
check_slurs_opt(&data.description)?;
|
check_slurs_opt(&data.description)?;
|
||||||
|
|
||||||
// Verify its a mod (only mods can edit it)
|
// Verify its a mod (only mods can edit it)
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let mods: Vec<i32> = blocking(pool, move |conn| {
|
let mods: Vec<i32> = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, edit_id)
|
CommunityModeratorView::for_community(conn, edit_id)
|
||||||
.map(|v| v.into_iter().map(|m| m.user_id).collect())
|
.map(|v| v.into_iter().map(|m| m.user_id).collect())
|
||||||
})
|
})
|
||||||
|
@ -351,7 +353,8 @@ impl Perform for EditCommunity {
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let read_community = blocking(pool, move |conn| Community::read(conn, edit_id)).await??;
|
let read_community =
|
||||||
|
blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite(&data.icon);
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite(&data.banner);
|
||||||
|
@ -377,7 +380,7 @@ impl Perform for EditCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
match blocking(pool, move |conn| {
|
match blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, edit_id, &community_form)
|
Community::update(conn, edit_id, &community_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -391,7 +394,7 @@ impl Perform for EditCommunity {
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(pool, move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, edit_id, Some(user_id))
|
CommunityView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -412,16 +415,16 @@ impl Perform for DeleteCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let data: &DeleteCommunity = &self;
|
let data: &DeleteCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Verify its the creator (only a creator can delete the community)
|
// Verify its the creator (only a creator can delete the community)
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let read_community = blocking(pool, move |conn| Community::read(conn, edit_id)).await??;
|
let read_community =
|
||||||
|
blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
|
||||||
if read_community.creator_id != user.id {
|
if read_community.creator_id != user.id {
|
||||||
return Err(APIError::err("no_community_edit_allowed").into());
|
return Err(APIError::err("no_community_edit_allowed").into());
|
||||||
}
|
}
|
||||||
|
@ -429,7 +432,7 @@ impl Perform for DeleteCommunity {
|
||||||
// Do the delete
|
// Do the delete
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_community = match blocking(pool, move |conn| {
|
let updated_community = match blocking(context.pool(), move |conn| {
|
||||||
Community::update_deleted(conn, edit_id, deleted)
|
Community::update_deleted(conn, edit_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -440,16 +443,14 @@ impl Perform for DeleteCommunity {
|
||||||
|
|
||||||
// Send apub messages
|
// Send apub messages
|
||||||
if deleted {
|
if deleted {
|
||||||
updated_community.send_delete(&user, &client, pool).await?;
|
updated_community.send_delete(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_community
|
updated_community.send_undo_delete(&user, context).await?;
|
||||||
.send_undo_delete(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(pool, move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, edit_id, Some(user_id))
|
CommunityView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -470,20 +471,19 @@ impl Perform for RemoveCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let data: &RemoveCommunity = &self;
|
let data: &RemoveCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Verify its an admin (only an admin can remove a community)
|
// Verify its an admin (only an admin can remove a community)
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
// Do the remove
|
// Do the remove
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_community = match blocking(pool, move |conn| {
|
let updated_community = match blocking(context.pool(), move |conn| {
|
||||||
Community::update_removed(conn, edit_id, removed)
|
Community::update_removed(conn, edit_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -504,20 +504,21 @@ impl Perform for RemoveCommunity {
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
expires,
|
expires,
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModRemoveCommunity::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModRemoveCommunity::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Apub messages
|
// Apub messages
|
||||||
if removed {
|
if removed {
|
||||||
updated_community.send_remove(&user, &client, pool).await?;
|
updated_community.send_remove(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_community
|
updated_community.send_undo_remove(&user, context).await?;
|
||||||
.send_undo_remove(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(pool, move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, edit_id, Some(user_id))
|
CommunityView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -538,12 +539,11 @@ impl Perform for ListCommunities {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<ListCommunitiesResponse, LemmyError> {
|
) -> Result<ListCommunitiesResponse, LemmyError> {
|
||||||
let data: &ListCommunities = &self;
|
let data: &ListCommunities = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_id = match &user {
|
let user_id = match &user {
|
||||||
Some(user) => Some(user.id),
|
Some(user) => Some(user.id),
|
||||||
|
@ -559,7 +559,7 @@ impl Perform for ListCommunities {
|
||||||
|
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let communities = blocking(pool, move |conn| {
|
let communities = blocking(context.pool(), move |conn| {
|
||||||
CommunityQueryBuilder::create(conn)
|
CommunityQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.for_user(user_id)
|
.for_user(user_id)
|
||||||
|
@ -581,15 +581,17 @@ impl Perform for FollowCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<CommunityResponse, LemmyError> {
|
) -> Result<CommunityResponse, LemmyError> {
|
||||||
let data: &FollowCommunity = &self;
|
let data: &FollowCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
@ -598,28 +600,24 @@ impl Perform for FollowCommunity {
|
||||||
if community.local {
|
if community.local {
|
||||||
if data.follow {
|
if data.follow {
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
if blocking(pool, follow).await?.is_err() {
|
if blocking(context.pool(), follow).await?.is_err() {
|
||||||
return Err(APIError::err("community_follower_already_exists").into());
|
return Err(APIError::err("community_follower_already_exists").into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let unfollow =
|
let unfollow =
|
||||||
move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
||||||
if blocking(pool, unfollow).await?.is_err() {
|
if blocking(context.pool(), unfollow).await?.is_err() {
|
||||||
return Err(APIError::err("community_follower_already_exists").into());
|
return Err(APIError::err("community_follower_already_exists").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if data.follow {
|
} else if data.follow {
|
||||||
// Dont actually add to the community followers here, because you need
|
// Dont actually add to the community followers here, because you need
|
||||||
// to wait for the accept
|
// to wait for the accept
|
||||||
user
|
user.send_follow(&community.actor_id()?, context).await?;
|
||||||
.send_follow(&community.actor_id()?, &client, pool)
|
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
user
|
user.send_unfollow(&community.actor_id()?, context).await?;
|
||||||
.send_unfollow(&community.actor_id()?, &client, pool)
|
|
||||||
.await?;
|
|
||||||
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
||||||
if blocking(pool, unfollow).await?.is_err() {
|
if blocking(context.pool(), unfollow).await?.is_err() {
|
||||||
return Err(APIError::err("community_follower_already_exists").into());
|
return Err(APIError::err("community_follower_already_exists").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,7 +625,7 @@ impl Perform for FollowCommunity {
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(pool, move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, Some(user_id))
|
CommunityView::read(conn, community_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -644,15 +642,14 @@ impl Perform for GetFollowedCommunities {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetFollowedCommunitiesResponse, LemmyError> {
|
) -> Result<GetFollowedCommunitiesResponse, LemmyError> {
|
||||||
let data: &GetFollowedCommunities = &self;
|
let data: &GetFollowedCommunities = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let communities = match blocking(pool, move |conn| {
|
let communities = match blocking(context.pool(), move |conn| {
|
||||||
CommunityFollowerView::for_user(conn, user_id)
|
CommunityFollowerView::for_user(conn, user_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -672,18 +669,17 @@ impl Perform for BanFromCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<BanFromCommunityResponse, LemmyError> {
|
) -> Result<BanFromCommunityResponse, LemmyError> {
|
||||||
let data: &BanFromCommunity = &self;
|
let data: &BanFromCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let banned_user_id = data.user_id;
|
let banned_user_id = data.user_id;
|
||||||
|
|
||||||
// Verify that only mods or admins can ban
|
// Verify that only mods or admins can ban
|
||||||
is_mod_or_admin(pool, user.id, community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, community_id).await?;
|
||||||
|
|
||||||
let community_user_ban_form = CommunityUserBanForm {
|
let community_user_ban_form = CommunityUserBanForm {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
|
@ -692,12 +688,12 @@ impl Perform for BanFromCommunity {
|
||||||
|
|
||||||
if data.ban {
|
if data.ban {
|
||||||
let ban = move |conn: &'_ _| CommunityUserBan::ban(conn, &community_user_ban_form);
|
let ban = move |conn: &'_ _| CommunityUserBan::ban(conn, &community_user_ban_form);
|
||||||
if blocking(pool, ban).await?.is_err() {
|
if blocking(context.pool(), ban).await?.is_err() {
|
||||||
return Err(APIError::err("community_user_already_banned").into());
|
return Err(APIError::err("community_user_already_banned").into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let unban = move |conn: &'_ _| CommunityUserBan::unban(conn, &community_user_ban_form);
|
let unban = move |conn: &'_ _| CommunityUserBan::unban(conn, &community_user_ban_form);
|
||||||
if blocking(pool, unban).await?.is_err() {
|
if blocking(context.pool(), unban).await?.is_err() {
|
||||||
return Err(APIError::err("community_user_already_banned").into());
|
return Err(APIError::err("community_user_already_banned").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,14 +701,14 @@ impl Perform for BanFromCommunity {
|
||||||
// Remove/Restore their data if that's desired
|
// Remove/Restore their data if that's desired
|
||||||
if let Some(remove_data) = data.remove_data {
|
if let Some(remove_data) = data.remove_data {
|
||||||
// Posts
|
// Posts
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(context.pool(), move |conn: &'_ _| {
|
||||||
Post::update_removed_for_creator(conn, banned_user_id, Some(community_id), remove_data)
|
Post::update_removed_for_creator(conn, banned_user_id, Some(community_id), remove_data)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
// Diesel doesn't allow updates with joins, so this has to be a loop
|
// Diesel doesn't allow updates with joins, so this has to be a loop
|
||||||
let comments = blocking(pool, move |conn| {
|
let comments = blocking(context.pool(), move |conn| {
|
||||||
CommentQueryBuilder::create(conn)
|
CommentQueryBuilder::create(conn)
|
||||||
.for_creator_id(banned_user_id)
|
.for_creator_id(banned_user_id)
|
||||||
.for_community_id(community_id)
|
.for_community_id(community_id)
|
||||||
|
@ -723,7 +719,7 @@ impl Perform for BanFromCommunity {
|
||||||
|
|
||||||
for comment in &comments {
|
for comment in &comments {
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(context.pool(), move |conn: &'_ _| {
|
||||||
Comment::update_removed(conn, comment_id, remove_data)
|
Comment::update_removed(conn, comment_id, remove_data)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -745,10 +741,16 @@ impl Perform for BanFromCommunity {
|
||||||
banned: Some(data.ban),
|
banned: Some(data.ban),
|
||||||
expires,
|
expires,
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModBanFromCommunity::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModBanFromCommunity::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let user_id = data.user_id;
|
let user_id = data.user_id;
|
||||||
let user_view = blocking(pool, move |conn| UserView::get_user_secure(conn, user_id)).await??;
|
let user_view = blocking(context.pool(), move |conn| {
|
||||||
|
UserView::get_user_secure(conn, user_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = BanFromCommunityResponse {
|
let res = BanFromCommunityResponse {
|
||||||
user: user_view,
|
user: user_view,
|
||||||
|
@ -774,12 +776,11 @@ impl Perform for AddModToCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<AddModToCommunityResponse, LemmyError> {
|
) -> Result<AddModToCommunityResponse, LemmyError> {
|
||||||
let data: &AddModToCommunity = &self;
|
let data: &AddModToCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
|
@ -789,16 +790,16 @@ impl Perform for AddModToCommunity {
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
|
|
||||||
// Verify that only mods or admins can add mod
|
// Verify that only mods or admins can add mod
|
||||||
is_mod_or_admin(pool, user.id, community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, community_id).await?;
|
||||||
|
|
||||||
if data.added {
|
if data.added {
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
if blocking(pool, join).await?.is_err() {
|
if blocking(context.pool(), join).await?.is_err() {
|
||||||
return Err(APIError::err("community_moderator_already_exists").into());
|
return Err(APIError::err("community_moderator_already_exists").into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let leave = move |conn: &'_ _| CommunityModerator::leave(conn, &community_moderator_form);
|
let leave = move |conn: &'_ _| CommunityModerator::leave(conn, &community_moderator_form);
|
||||||
if blocking(pool, leave).await?.is_err() {
|
if blocking(context.pool(), leave).await?.is_err() {
|
||||||
return Err(APIError::err("community_moderator_already_exists").into());
|
return Err(APIError::err("community_moderator_already_exists").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,10 +811,13 @@ impl Perform for AddModToCommunity {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
removed: Some(!data.added),
|
removed: Some(!data.added),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModAddCommunity::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModAddCommunity::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let moderators = blocking(pool, move |conn| {
|
let moderators = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -839,20 +843,24 @@ impl Perform for TransferCommunity {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetCommunityResponse, LemmyError> {
|
) -> Result<GetCommunityResponse, LemmyError> {
|
||||||
let data: &TransferCommunity = &self;
|
let data: &TransferCommunity = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let read_community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let read_community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let site_creator_id =
|
let site_creator_id = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| Site::read(conn, 1).map(|s| s.creator_id)).await??;
|
Site::read(conn, 1).map(|s| s.creator_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
|
let mut admins = blocking(context.pool(), move |conn| UserView::admins(conn)).await??;
|
||||||
|
|
||||||
let creator_index = admins
|
let creator_index = admins
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -869,13 +877,13 @@ impl Perform for TransferCommunity {
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let new_creator = data.user_id;
|
let new_creator = data.user_id;
|
||||||
let update = move |conn: &'_ _| Community::update_creator(conn, community_id, new_creator);
|
let update = move |conn: &'_ _| Community::update_creator(conn, community_id, new_creator);
|
||||||
if blocking(pool, update).await?.is_err() {
|
if blocking(context.pool(), update).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_community").into());
|
return Err(APIError::err("couldnt_update_community").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
// You also have to re-do the community_moderator table, reordering it.
|
// You also have to re-do the community_moderator table, reordering it.
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let mut community_mods = blocking(pool, move |conn| {
|
let mut community_mods = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -887,7 +895,7 @@ impl Perform for TransferCommunity {
|
||||||
community_mods.insert(0, creator_user);
|
community_mods.insert(0, creator_user);
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommunityModerator::delete_for_community(conn, community_id)
|
CommunityModerator::delete_for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -900,7 +908,7 @@ impl Perform for TransferCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
if blocking(pool, join).await?.is_err() {
|
if blocking(context.pool(), join).await?.is_err() {
|
||||||
return Err(APIError::err("community_moderator_already_exists").into());
|
return Err(APIError::err("community_moderator_already_exists").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,11 +920,14 @@ impl Perform for TransferCommunity {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
removed: Some(false),
|
removed: Some(false),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModAddCommunity::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModAddCommunity::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = match blocking(pool, move |conn| {
|
let community_view = match blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, Some(user_id))
|
CommunityView::read(conn, community_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -926,7 +937,7 @@ impl Perform for TransferCommunity {
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let moderators = match blocking(pool, move |conn| {
|
let moderators = match blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
use crate::{api::claims::Claims, blocking, websocket::WebsocketInfo, DbPool, LemmyError};
|
use crate::{
|
||||||
use actix_web::client::Client;
|
api::claims::Claims,
|
||||||
|
blocking,
|
||||||
|
websocket::WebsocketInfo,
|
||||||
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
|
LemmyError,
|
||||||
|
};
|
||||||
|
use actix_web::web::Data;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::*,
|
community::*,
|
||||||
community_view::*,
|
community_view::*,
|
||||||
|
@ -39,9 +46,8 @@ pub trait Perform {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<Self::Response, LemmyError>;
|
) -> Result<Self::Response, LemmyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ use crate::{
|
||||||
UserOperation,
|
UserOperation,
|
||||||
WebsocketInfo,
|
WebsocketInfo,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
use actix_web::web::Data;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
community_view::*,
|
community_view::*,
|
||||||
|
@ -145,12 +145,11 @@ impl Perform for CreatePost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &CreatePost = &self;
|
let data: &CreatePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.name)?;
|
check_slurs(&data.name)?;
|
||||||
check_slurs_opt(&data.body)?;
|
check_slurs_opt(&data.body)?;
|
||||||
|
@ -159,7 +158,7 @@ impl Perform for CreatePost {
|
||||||
return Err(APIError::err("invalid_post_title").into());
|
return Err(APIError::err("invalid_post_title").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
check_community_ban(user.id, data.community_id, pool).await?;
|
check_community_ban(user.id, data.community_id, context.pool()).await?;
|
||||||
|
|
||||||
if let Some(url) = data.url.as_ref() {
|
if let Some(url) = data.url.as_ref() {
|
||||||
match Url::parse(url) {
|
match Url::parse(url) {
|
||||||
|
@ -170,7 +169,7 @@ impl Perform for CreatePost {
|
||||||
|
|
||||||
// Fetch Iframely and pictrs cached image
|
// Fetch Iframely and pictrs cached image
|
||||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||||
fetch_iframely_and_pictrs_data(&client, data.url.to_owned()).await;
|
fetch_iframely_and_pictrs_data(context.client(), data.url.to_owned()).await;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: data.name.trim().to_owned(),
|
name: data.name.trim().to_owned(),
|
||||||
|
@ -193,21 +192,22 @@ impl Perform for CreatePost {
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_post = match blocking(pool, move |conn| Post::create(conn, &post_form)).await? {
|
let inserted_post =
|
||||||
Ok(post) => post,
|
match blocking(context.pool(), move |conn| Post::create(conn, &post_form)).await? {
|
||||||
Err(e) => {
|
Ok(post) => post,
|
||||||
let err_type = if e.to_string() == "value too long for type character varying(200)" {
|
Err(e) => {
|
||||||
"post_title_too_long"
|
let err_type = if e.to_string() == "value too long for type character varying(200)" {
|
||||||
} else {
|
"post_title_too_long"
|
||||||
"couldnt_create_post"
|
} else {
|
||||||
};
|
"couldnt_create_post"
|
||||||
|
};
|
||||||
|
|
||||||
return Err(APIError::err(err_type).into());
|
return Err(APIError::err(err_type).into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_post_id = inserted_post.id;
|
let inserted_post_id = inserted_post.id;
|
||||||
let updated_post = match blocking(pool, move |conn| {
|
let updated_post = match blocking(context.pool(), move |conn| {
|
||||||
let apub_id =
|
let apub_id =
|
||||||
make_apub_endpoint(EndpointType::Post, &inserted_post_id.to_string()).to_string();
|
make_apub_endpoint(EndpointType::Post, &inserted_post_id.to_string()).to_string();
|
||||||
Post::update_ap_id(conn, inserted_post_id, apub_id)
|
Post::update_ap_id(conn, inserted_post_id, apub_id)
|
||||||
|
@ -218,7 +218,7 @@ impl Perform for CreatePost {
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_post").into()),
|
Err(_e) => return Err(APIError::err("couldnt_create_post").into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
updated_post.send_create(&user, &client, pool).await?;
|
updated_post.send_create(&user, context).await?;
|
||||||
|
|
||||||
// They like their own post by default
|
// They like their own post by default
|
||||||
let like_form = PostLikeForm {
|
let like_form = PostLikeForm {
|
||||||
|
@ -228,15 +228,15 @@ impl Perform for CreatePost {
|
||||||
};
|
};
|
||||||
|
|
||||||
let like = move |conn: &'_ _| PostLike::like(conn, &like_form);
|
let like = move |conn: &'_ _| PostLike::like(conn, &like_form);
|
||||||
if blocking(pool, like).await?.is_err() {
|
if blocking(context.pool(), like).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_like_post").into());
|
return Err(APIError::err("couldnt_like_post").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
updated_post.send_like(&user, &client, pool).await?;
|
updated_post.send_like(&user, context).await?;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let inserted_post_id = inserted_post.id;
|
let inserted_post_id = inserted_post.id;
|
||||||
let post_view = match blocking(pool, move |conn| {
|
let post_view = match blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, inserted_post_id, Some(user.id))
|
PostView::read(conn, inserted_post_id, Some(user.id))
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -265,22 +265,25 @@ impl Perform for GetPost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetPostResponse, LemmyError> {
|
) -> Result<GetPostResponse, LemmyError> {
|
||||||
let data: &GetPost = &self;
|
let data: &GetPost = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
|
|
||||||
let id = data.id;
|
let id = data.id;
|
||||||
let post_view = match blocking(pool, move |conn| PostView::read(conn, id, user_id)).await? {
|
let post_view = match blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, id, user_id)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(post) => post,
|
Ok(post) => post,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
|
Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = data.id;
|
let id = data.id;
|
||||||
let comments = blocking(pool, move |conn| {
|
let comments = blocking(context.pool(), move |conn| {
|
||||||
CommentQueryBuilder::create(conn)
|
CommentQueryBuilder::create(conn)
|
||||||
.for_post_id(id)
|
.for_post_id(id)
|
||||||
.my_user_id(user_id)
|
.my_user_id(user_id)
|
||||||
|
@ -290,13 +293,13 @@ impl Perform for GetPost {
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = post_view.community_id;
|
let community_id = post_view.community_id;
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, user_id)
|
CommunityView::read(conn, community_id, user_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = post_view.community_id;
|
let community_id = post_view.community_id;
|
||||||
let moderators = blocking(pool, move |conn| {
|
let moderators = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -333,12 +336,11 @@ impl Perform for GetPosts {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetPostsResponse, LemmyError> {
|
) -> Result<GetPostsResponse, LemmyError> {
|
||||||
let data: &GetPosts = &self;
|
let data: &GetPosts = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_id = match &user {
|
let user_id = match &user {
|
||||||
Some(user) => Some(user.id),
|
Some(user) => Some(user.id),
|
||||||
|
@ -357,7 +359,7 @@ impl Perform for GetPosts {
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community_name = data.community_name.to_owned();
|
let community_name = data.community_name.to_owned();
|
||||||
let posts = match blocking(pool, move |conn| {
|
let posts = match blocking(context.pool(), move |conn| {
|
||||||
PostQueryBuilder::create(conn)
|
PostQueryBuilder::create(conn)
|
||||||
.listing_type(type_)
|
.listing_type(type_)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
|
@ -399,16 +401,15 @@ impl Perform for CreatePostLike {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &CreatePostLike = &self;
|
let data: &CreatePostLike = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Don't do a downvote if site has downvotes disabled
|
// Don't do a downvote if site has downvotes disabled
|
||||||
if data.score == -1 {
|
if data.score == -1 {
|
||||||
let site = blocking(pool, move |conn| SiteView::read(conn)).await??;
|
let site = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
|
||||||
if !site.enable_downvotes {
|
if !site.enable_downvotes {
|
||||||
return Err(APIError::err("downvotes_disabled").into());
|
return Err(APIError::err("downvotes_disabled").into());
|
||||||
}
|
}
|
||||||
|
@ -416,9 +417,9 @@ impl Perform for CreatePostLike {
|
||||||
|
|
||||||
// Check for a community ban
|
// Check for a community ban
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, post.community_id, pool).await?;
|
check_community_ban(user.id, post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
let like_form = PostLikeForm {
|
let like_form = PostLikeForm {
|
||||||
post_id: data.post_id,
|
post_id: data.post_id,
|
||||||
|
@ -428,29 +429,32 @@ impl Perform for CreatePostLike {
|
||||||
|
|
||||||
// Remove any likes first
|
// Remove any likes first
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| PostLike::remove(conn, user_id, post_id)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
PostLike::remove(conn, user_id, post_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Only add the like if the score isnt 0
|
// Only add the like if the score isnt 0
|
||||||
let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
|
let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
|
||||||
if do_add {
|
if do_add {
|
||||||
let like_form2 = like_form.clone();
|
let like_form2 = like_form.clone();
|
||||||
let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
|
let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
|
||||||
if blocking(pool, like).await?.is_err() {
|
if blocking(context.pool(), like).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_like_post").into());
|
return Err(APIError::err("couldnt_like_post").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if like_form.score == 1 {
|
if like_form.score == 1 {
|
||||||
post.send_like(&user, &client, pool).await?;
|
post.send_like(&user, context).await?;
|
||||||
} else if like_form.score == -1 {
|
} else if like_form.score == -1 {
|
||||||
post.send_dislike(&user, &client, pool).await?;
|
post.send_dislike(&user, context).await?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
post.send_undo_like(&user, &client, pool).await?;
|
post.send_undo_like(&user, context).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let post_view = match blocking(pool, move |conn| {
|
let post_view = match blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, post_id, Some(user_id))
|
PostView::read(conn, post_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -479,12 +483,11 @@ impl Perform for EditPost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &EditPost = &self;
|
let data: &EditPost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.name)?;
|
check_slurs(&data.name)?;
|
||||||
check_slurs_opt(&data.body)?;
|
check_slurs_opt(&data.body)?;
|
||||||
|
@ -494,9 +497,9 @@ impl Perform for EditPost {
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_post = blocking(pool, move |conn| Post::read(conn, edit_id)).await??;
|
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_post.community_id, pool).await?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the creator can edit
|
// Verify that only the creator can edit
|
||||||
if !Post::is_post_creator(user.id, orig_post.creator_id) {
|
if !Post::is_post_creator(user.id, orig_post.creator_id) {
|
||||||
|
@ -505,7 +508,7 @@ impl Perform for EditPost {
|
||||||
|
|
||||||
// Fetch Iframely and Pictrs cached image
|
// Fetch Iframely and Pictrs cached image
|
||||||
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
let (iframely_title, iframely_description, iframely_html, pictrs_thumbnail) =
|
||||||
fetch_iframely_and_pictrs_data(&client, data.url.to_owned()).await;
|
fetch_iframely_and_pictrs_data(context.client(), data.url.to_owned()).await;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: data.name.trim().to_owned(),
|
name: data.name.trim().to_owned(),
|
||||||
|
@ -529,7 +532,10 @@ impl Perform for EditPost {
|
||||||
};
|
};
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let res = blocking(pool, move |conn| Post::update(conn, edit_id, &post_form)).await?;
|
let res = blocking(context.pool(), move |conn| {
|
||||||
|
Post::update(conn, edit_id, &post_form)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
let updated_post: Post = match res {
|
let updated_post: Post = match res {
|
||||||
Ok(post) => post,
|
Ok(post) => post,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -544,10 +550,10 @@ impl Perform for EditPost {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send apub update
|
// Send apub update
|
||||||
updated_post.send_update(&user, &client, pool).await?;
|
updated_post.send_update(&user, context).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, edit_id, Some(user.id))
|
PostView::read(conn, edit_id, Some(user.id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -572,17 +578,16 @@ impl Perform for DeletePost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &DeletePost = &self;
|
let data: &DeletePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_post = blocking(pool, move |conn| Post::read(conn, edit_id)).await??;
|
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_post.community_id, pool).await?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the creator can delete
|
// Verify that only the creator can delete
|
||||||
if !Post::is_post_creator(user.id, orig_post.creator_id) {
|
if !Post::is_post_creator(user.id, orig_post.creator_id) {
|
||||||
|
@ -592,21 +597,21 @@ impl Perform for DeletePost {
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_post = blocking(pool, move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_deleted(conn, edit_id, deleted)
|
Post::update_deleted(conn, edit_id, deleted)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// apub updates
|
// apub updates
|
||||||
if deleted {
|
if deleted {
|
||||||
updated_post.send_delete(&user, &client, pool).await?;
|
updated_post.send_delete(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_post.send_undo_delete(&user, &client, pool).await?;
|
updated_post.send_undo_delete(&user, context).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, edit_id, Some(user.id))
|
PostView::read(conn, edit_id, Some(user.id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -631,25 +636,24 @@ impl Perform for RemovePost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &RemovePost = &self;
|
let data: &RemovePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_post = blocking(pool, move |conn| Post::read(conn, edit_id)).await??;
|
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_post.community_id, pool).await?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the mods can remove
|
// Verify that only the mods can remove
|
||||||
is_mod_or_admin(pool, user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_post = blocking(pool, move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_removed(conn, edit_id, removed)
|
Post::update_removed(conn, edit_id, removed)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -661,19 +665,22 @@ impl Perform for RemovePost {
|
||||||
removed: Some(removed),
|
removed: Some(removed),
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModRemovePost::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModRemovePost::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// apub updates
|
// apub updates
|
||||||
if removed {
|
if removed {
|
||||||
updated_post.send_remove(&user, &client, pool).await?;
|
updated_post.send_remove(&user, context).await?;
|
||||||
} else {
|
} else {
|
||||||
updated_post.send_undo_remove(&user, &client, pool).await?;
|
updated_post.send_undo_remove(&user, context).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, edit_id, Some(user_id))
|
PostView::read(conn, edit_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -698,26 +705,27 @@ impl Perform for LockPost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &LockPost = &self;
|
let data: &LockPost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_post = blocking(pool, move |conn| Post::read(conn, edit_id)).await??;
|
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_post.community_id, pool).await?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the mods can lock
|
// Verify that only the mods can lock
|
||||||
is_mod_or_admin(pool, user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let locked = data.locked;
|
let locked = data.locked;
|
||||||
let updated_post =
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| Post::update_locked(conn, edit_id, locked)).await??;
|
Post::update_locked(conn, edit_id, locked)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModLockPostForm {
|
let form = ModLockPostForm {
|
||||||
|
@ -725,14 +733,14 @@ impl Perform for LockPost {
|
||||||
post_id: data.edit_id,
|
post_id: data.edit_id,
|
||||||
locked: Some(locked),
|
locked: Some(locked),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModLockPost::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
|
||||||
|
|
||||||
// apub updates
|
// apub updates
|
||||||
updated_post.send_update(&user, &client, pool).await?;
|
updated_post.send_update(&user, context).await?;
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, edit_id, Some(user.id))
|
PostView::read(conn, edit_id, Some(user.id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -757,25 +765,24 @@ impl Perform for StickyPost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &StickyPost = &self;
|
let data: &StickyPost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_post = blocking(pool, move |conn| Post::read(conn, edit_id)).await??;
|
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
||||||
|
|
||||||
check_community_ban(user.id, orig_post.community_id, pool).await?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
// Verify that only the mods can sticky
|
// Verify that only the mods can sticky
|
||||||
is_mod_or_admin(pool, user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let stickied = data.stickied;
|
let stickied = data.stickied;
|
||||||
let updated_post = blocking(pool, move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_stickied(conn, edit_id, stickied)
|
Post::update_stickied(conn, edit_id, stickied)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -786,15 +793,18 @@ impl Perform for StickyPost {
|
||||||
post_id: data.edit_id,
|
post_id: data.edit_id,
|
||||||
stickied: Some(stickied),
|
stickied: Some(stickied),
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| ModStickyPost::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
ModStickyPost::create(conn, &form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Apub updates
|
// Apub updates
|
||||||
// TODO stickied should pry work like locked for ease of use
|
// TODO stickied should pry work like locked for ease of use
|
||||||
updated_post.send_update(&user, &client, pool).await?;
|
updated_post.send_update(&user, context).await?;
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, edit_id, Some(user.id))
|
PostView::read(conn, edit_id, Some(user.id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -819,12 +829,11 @@ impl Perform for SavePost {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<PostResponse, LemmyError> {
|
) -> Result<PostResponse, LemmyError> {
|
||||||
let data: &SavePost = &self;
|
let data: &SavePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let post_saved_form = PostSavedForm {
|
let post_saved_form = PostSavedForm {
|
||||||
post_id: data.post_id,
|
post_id: data.post_id,
|
||||||
|
@ -833,19 +842,19 @@ impl Perform for SavePost {
|
||||||
|
|
||||||
if data.save {
|
if data.save {
|
||||||
let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form);
|
let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form);
|
||||||
if blocking(pool, save).await?.is_err() {
|
if blocking(context.pool(), save).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_save_post").into());
|
return Err(APIError::err("couldnt_save_post").into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let unsave = move |conn: &'_ _| PostSaved::unsave(conn, &post_saved_form);
|
let unsave = move |conn: &'_ _| PostSaved::unsave(conn, &post_saved_form);
|
||||||
if blocking(pool, unsave).await?.is_err() {
|
if blocking(context.pool(), unsave).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_save_post").into());
|
return Err(APIError::err("couldnt_save_post").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, post_id, Some(user_id))
|
PostView::read(conn, post_id, Some(user_id))
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
|
@ -17,10 +17,10 @@ use crate::{
|
||||||
UserOperation,
|
UserOperation,
|
||||||
WebsocketInfo,
|
WebsocketInfo,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
category::*,
|
category::*,
|
||||||
|
@ -166,13 +166,12 @@ impl Perform for ListCategories {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<ListCategoriesResponse, LemmyError> {
|
) -> Result<ListCategoriesResponse, LemmyError> {
|
||||||
let _data: &ListCategories = &self;
|
let _data: &ListCategories = &self;
|
||||||
|
|
||||||
let categories = blocking(pool, move |conn| Category::list_all(conn)).await??;
|
let categories = blocking(context.pool(), move |conn| Category::list_all(conn)).await??;
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(ListCategoriesResponse { categories })
|
Ok(ListCategoriesResponse { categories })
|
||||||
|
@ -185,9 +184,8 @@ impl Perform for GetModlog {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetModlogResponse, LemmyError> {
|
) -> Result<GetModlogResponse, LemmyError> {
|
||||||
let data: &GetModlog = &self;
|
let data: &GetModlog = &self;
|
||||||
|
|
||||||
|
@ -195,39 +193,39 @@ impl Perform for GetModlog {
|
||||||
let mod_user_id = data.mod_user_id;
|
let mod_user_id = data.mod_user_id;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let removed_posts = blocking(pool, move |conn| {
|
let removed_posts = blocking(context.pool(), move |conn| {
|
||||||
ModRemovePostView::list(conn, community_id, mod_user_id, page, limit)
|
ModRemovePostView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let locked_posts = blocking(pool, move |conn| {
|
let locked_posts = blocking(context.pool(), move |conn| {
|
||||||
ModLockPostView::list(conn, community_id, mod_user_id, page, limit)
|
ModLockPostView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let stickied_posts = blocking(pool, move |conn| {
|
let stickied_posts = blocking(context.pool(), move |conn| {
|
||||||
ModStickyPostView::list(conn, community_id, mod_user_id, page, limit)
|
ModStickyPostView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let removed_comments = blocking(pool, move |conn| {
|
let removed_comments = blocking(context.pool(), move |conn| {
|
||||||
ModRemoveCommentView::list(conn, community_id, mod_user_id, page, limit)
|
ModRemoveCommentView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let banned_from_community = blocking(pool, move |conn| {
|
let banned_from_community = blocking(context.pool(), move |conn| {
|
||||||
ModBanFromCommunityView::list(conn, community_id, mod_user_id, page, limit)
|
ModBanFromCommunityView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let added_to_community = blocking(pool, move |conn| {
|
let added_to_community = blocking(context.pool(), move |conn| {
|
||||||
ModAddCommunityView::list(conn, community_id, mod_user_id, page, limit)
|
ModAddCommunityView::list(conn, community_id, mod_user_id, page, limit)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// These arrays are only for the full modlog, when a community isn't given
|
// These arrays are only for the full modlog, when a community isn't given
|
||||||
let (removed_communities, banned, added) = if data.community_id.is_none() {
|
let (removed_communities, banned, added) = if data.community_id.is_none() {
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Ok((
|
Ok((
|
||||||
ModRemoveCommunityView::list(conn, mod_user_id, page, limit)?,
|
ModRemoveCommunityView::list(conn, mod_user_id, page, limit)?,
|
||||||
ModBanView::list(conn, mod_user_id, page, limit)?,
|
ModBanView::list(conn, mod_user_id, page, limit)?,
|
||||||
|
@ -260,19 +258,18 @@ impl Perform for CreateSite {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<SiteResponse, LemmyError> {
|
) -> Result<SiteResponse, LemmyError> {
|
||||||
let data: &CreateSite = &self;
|
let data: &CreateSite = &self;
|
||||||
|
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.name)?;
|
check_slurs(&data.name)?;
|
||||||
check_slurs_opt(&data.description)?;
|
check_slurs_opt(&data.description)?;
|
||||||
|
|
||||||
// Make sure user is an admin
|
// Make sure user is an admin
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
let site_form = SiteForm {
|
let site_form = SiteForm {
|
||||||
name: data.name.to_owned(),
|
name: data.name.to_owned(),
|
||||||
|
@ -287,11 +284,11 @@ impl Perform for CreateSite {
|
||||||
};
|
};
|
||||||
|
|
||||||
let create_site = move |conn: &'_ _| Site::create(conn, &site_form);
|
let create_site = move |conn: &'_ _| Site::create(conn, &site_form);
|
||||||
if blocking(pool, create_site).await?.is_err() {
|
if blocking(context.pool(), create_site).await?.is_err() {
|
||||||
return Err(APIError::err("site_already_exists").into());
|
return Err(APIError::err("site_already_exists").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let site_view = blocking(pool, move |conn| SiteView::read(conn)).await??;
|
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
|
||||||
|
|
||||||
Ok(SiteResponse { site: site_view })
|
Ok(SiteResponse { site: site_view })
|
||||||
}
|
}
|
||||||
|
@ -302,20 +299,19 @@ impl Perform for EditSite {
|
||||||
type Response = SiteResponse;
|
type Response = SiteResponse;
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<SiteResponse, LemmyError> {
|
) -> Result<SiteResponse, LemmyError> {
|
||||||
let data: &EditSite = &self;
|
let data: &EditSite = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
check_slurs(&data.name)?;
|
check_slurs(&data.name)?;
|
||||||
check_slurs_opt(&data.description)?;
|
check_slurs_opt(&data.description)?;
|
||||||
|
|
||||||
// Make sure user is an admin
|
// Make sure user is an admin
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
let found_site = blocking(pool, move |conn| Site::read(conn, 1)).await??;
|
let found_site = blocking(context.pool(), move |conn| Site::read(conn, 1)).await??;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite(&data.icon);
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite(&data.banner);
|
||||||
|
@ -333,11 +329,11 @@ impl Perform for EditSite {
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form);
|
let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form);
|
||||||
if blocking(pool, update_site).await?.is_err() {
|
if blocking(context.pool(), update_site).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_site").into());
|
return Err(APIError::err("couldnt_update_site").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let site_view = blocking(pool, move |conn| SiteView::read(conn)).await??;
|
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
|
||||||
|
|
||||||
let res = SiteResponse { site: site_view };
|
let res = SiteResponse { site: site_view };
|
||||||
|
|
||||||
|
@ -359,16 +355,15 @@ impl Perform for GetSite {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<GetSiteResponse, LemmyError> {
|
) -> Result<GetSiteResponse, LemmyError> {
|
||||||
let data: &GetSite = &self;
|
let data: &GetSite = &self;
|
||||||
|
|
||||||
// TODO refactor this a little
|
// TODO refactor this a little
|
||||||
let res = blocking(pool, move |conn| Site::read(conn, 1)).await?;
|
let res = blocking(context.pool(), move |conn| Site::read(conn, 1)).await?;
|
||||||
let site_view = if res.is_ok() {
|
let site_view = if res.is_ok() {
|
||||||
Some(blocking(pool, move |conn| SiteView::read(conn)).await??)
|
Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
|
||||||
} else if let Some(setup) = Settings::get().setup.as_ref() {
|
} else if let Some(setup) = Settings::get().setup.as_ref() {
|
||||||
let register = Register {
|
let register = Register {
|
||||||
username: setup.admin_username.to_owned(),
|
username: setup.admin_username.to_owned(),
|
||||||
|
@ -380,9 +375,7 @@ impl Perform for GetSite {
|
||||||
captcha_uuid: None,
|
captcha_uuid: None,
|
||||||
captcha_answer: None,
|
captcha_answer: None,
|
||||||
};
|
};
|
||||||
let login_response = register
|
let login_response = register.perform(context, websocket_info.clone()).await?;
|
||||||
.perform(pool, websocket_info.clone(), client.clone())
|
|
||||||
.await?;
|
|
||||||
info!("Admin {} created", setup.admin_username);
|
info!("Admin {} created", setup.admin_username);
|
||||||
|
|
||||||
let create_site = CreateSite {
|
let create_site = CreateSite {
|
||||||
|
@ -395,16 +388,14 @@ impl Perform for GetSite {
|
||||||
enable_nsfw: true,
|
enable_nsfw: true,
|
||||||
auth: login_response.jwt,
|
auth: login_response.jwt,
|
||||||
};
|
};
|
||||||
create_site
|
create_site.perform(context, websocket_info.clone()).await?;
|
||||||
.perform(pool, websocket_info.clone(), client.clone())
|
|
||||||
.await?;
|
|
||||||
info!("Site {} created", setup.site_name);
|
info!("Site {} created", setup.site_name);
|
||||||
Some(blocking(pool, move |conn| SiteView::read(conn)).await??)
|
Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
|
let mut admins = blocking(context.pool(), move |conn| UserView::admins(conn)).await??;
|
||||||
|
|
||||||
// Make sure the site creator is the top admin
|
// Make sure the site creator is the top admin
|
||||||
if let Some(site_view) = site_view.to_owned() {
|
if let Some(site_view) = site_view.to_owned() {
|
||||||
|
@ -417,7 +408,7 @@ impl Perform for GetSite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let banned = blocking(pool, move |conn| UserView::banned(conn)).await??;
|
let banned = blocking(context.pool(), move |conn| UserView::banned(conn)).await??;
|
||||||
|
|
||||||
let online = if let Some(ws) = websocket_info {
|
let online = if let Some(ws) = websocket_info {
|
||||||
ws.chatserver.send(GetUsersOnline).await.unwrap_or(1)
|
ws.chatserver.send(GetUsersOnline).await.unwrap_or(1)
|
||||||
|
@ -425,12 +416,14 @@ impl Perform for GetSite {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let my_user = get_user_from_jwt_opt(&data.auth, pool).await?.map(|mut u| {
|
let my_user = get_user_from_jwt_opt(&data.auth, context.pool())
|
||||||
u.password_encrypted = "".to_string();
|
.await?
|
||||||
u.private_key = None;
|
.map(|mut u| {
|
||||||
u.public_key = None;
|
u.password_encrypted = "".to_string();
|
||||||
u
|
u.private_key = None;
|
||||||
});
|
u.public_key = None;
|
||||||
|
u
|
||||||
|
});
|
||||||
|
|
||||||
Ok(GetSiteResponse {
|
Ok(GetSiteResponse {
|
||||||
site: site_view,
|
site: site_view,
|
||||||
|
@ -450,20 +443,19 @@ impl Perform for Search {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<SearchResponse, LemmyError> {
|
) -> Result<SearchResponse, LemmyError> {
|
||||||
let data: &Search = &self;
|
let data: &Search = &self;
|
||||||
|
|
||||||
dbg!(&data);
|
dbg!(&data);
|
||||||
|
|
||||||
match search_by_apub_id(&data.q, &client, pool).await {
|
match search_by_apub_id(&data.q, context).await {
|
||||||
Ok(r) => return Ok(r),
|
Ok(r) => return Ok(r),
|
||||||
Err(e) => debug!("Failed to resolve search query as activitypub ID: {}", e),
|
Err(e) => debug!("Failed to resolve search query as activitypub ID: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
|
|
||||||
let type_ = SearchType::from_str(&data.type_)?;
|
let type_ = SearchType::from_str(&data.type_)?;
|
||||||
|
@ -482,7 +474,7 @@ impl Perform for Search {
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
match type_ {
|
match type_ {
|
||||||
SearchType::Posts => {
|
SearchType::Posts => {
|
||||||
posts = blocking(pool, move |conn| {
|
posts = blocking(context.pool(), move |conn| {
|
||||||
PostQueryBuilder::create(conn)
|
PostQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.show_nsfw(true)
|
.show_nsfw(true)
|
||||||
|
@ -496,7 +488,7 @@ impl Perform for Search {
|
||||||
.await??;
|
.await??;
|
||||||
}
|
}
|
||||||
SearchType::Comments => {
|
SearchType::Comments => {
|
||||||
comments = blocking(pool, move |conn| {
|
comments = blocking(context.pool(), move |conn| {
|
||||||
CommentQueryBuilder::create(&conn)
|
CommentQueryBuilder::create(&conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -508,7 +500,7 @@ impl Perform for Search {
|
||||||
.await??;
|
.await??;
|
||||||
}
|
}
|
||||||
SearchType::Communities => {
|
SearchType::Communities => {
|
||||||
communities = blocking(pool, move |conn| {
|
communities = blocking(context.pool(), move |conn| {
|
||||||
CommunityQueryBuilder::create(conn)
|
CommunityQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -519,7 +511,7 @@ impl Perform for Search {
|
||||||
.await??;
|
.await??;
|
||||||
}
|
}
|
||||||
SearchType::Users => {
|
SearchType::Users => {
|
||||||
users = blocking(pool, move |conn| {
|
users = blocking(context.pool(), move |conn| {
|
||||||
UserQueryBuilder::create(conn)
|
UserQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -530,7 +522,7 @@ impl Perform for Search {
|
||||||
.await??;
|
.await??;
|
||||||
}
|
}
|
||||||
SearchType::All => {
|
SearchType::All => {
|
||||||
posts = blocking(pool, move |conn| {
|
posts = blocking(context.pool(), move |conn| {
|
||||||
PostQueryBuilder::create(conn)
|
PostQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.show_nsfw(true)
|
.show_nsfw(true)
|
||||||
|
@ -546,7 +538,7 @@ impl Perform for Search {
|
||||||
let q = data.q.to_owned();
|
let q = data.q.to_owned();
|
||||||
let sort = SortType::from_str(&data.sort)?;
|
let sort = SortType::from_str(&data.sort)?;
|
||||||
|
|
||||||
comments = blocking(pool, move |conn| {
|
comments = blocking(context.pool(), move |conn| {
|
||||||
CommentQueryBuilder::create(conn)
|
CommentQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -560,7 +552,7 @@ impl Perform for Search {
|
||||||
let q = data.q.to_owned();
|
let q = data.q.to_owned();
|
||||||
let sort = SortType::from_str(&data.sort)?;
|
let sort = SortType::from_str(&data.sort)?;
|
||||||
|
|
||||||
communities = blocking(pool, move |conn| {
|
communities = blocking(context.pool(), move |conn| {
|
||||||
CommunityQueryBuilder::create(conn)
|
CommunityQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -573,7 +565,7 @@ impl Perform for Search {
|
||||||
let q = data.q.to_owned();
|
let q = data.q.to_owned();
|
||||||
let sort = SortType::from_str(&data.sort)?;
|
let sort = SortType::from_str(&data.sort)?;
|
||||||
|
|
||||||
users = blocking(pool, move |conn| {
|
users = blocking(context.pool(), move |conn| {
|
||||||
UserQueryBuilder::create(conn)
|
UserQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.search_term(q)
|
.search_term(q)
|
||||||
|
@ -584,7 +576,7 @@ impl Perform for Search {
|
||||||
.await??;
|
.await??;
|
||||||
}
|
}
|
||||||
SearchType::Url => {
|
SearchType::Url => {
|
||||||
posts = blocking(pool, move |conn| {
|
posts = blocking(context.pool(), move |conn| {
|
||||||
PostQueryBuilder::create(conn)
|
PostQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.show_nsfw(true)
|
.show_nsfw(true)
|
||||||
|
@ -615,19 +607,18 @@ impl Perform for TransferSite {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetSiteResponse, LemmyError> {
|
) -> Result<GetSiteResponse, LemmyError> {
|
||||||
let data: &TransferSite = &self;
|
let data: &TransferSite = &self;
|
||||||
let mut user = get_user_from_jwt(&data.auth, pool).await?;
|
let mut user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// TODO add a User_::read_safe() for this.
|
// TODO add a User_::read_safe() for this.
|
||||||
user.password_encrypted = "".to_string();
|
user.password_encrypted = "".to_string();
|
||||||
user.private_key = None;
|
user.private_key = None;
|
||||||
user.public_key = None;
|
user.public_key = None;
|
||||||
|
|
||||||
let read_site = blocking(pool, move |conn| Site::read(conn, 1)).await??;
|
let read_site = blocking(context.pool(), move |conn| Site::read(conn, 1)).await??;
|
||||||
|
|
||||||
// Make sure user is the creator
|
// Make sure user is the creator
|
||||||
if read_site.creator_id != user.id {
|
if read_site.creator_id != user.id {
|
||||||
|
@ -636,7 +627,7 @@ impl Perform for TransferSite {
|
||||||
|
|
||||||
let new_creator_id = data.user_id;
|
let new_creator_id = data.user_id;
|
||||||
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
|
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
|
||||||
if blocking(pool, transfer_site).await?.is_err() {
|
if blocking(context.pool(), transfer_site).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_site").into());
|
return Err(APIError::err("couldnt_update_site").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -647,11 +638,11 @@ impl Perform for TransferSite {
|
||||||
removed: Some(false),
|
removed: Some(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
blocking(pool, move |conn| ModAdd::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| ModAdd::create(conn, &form)).await??;
|
||||||
|
|
||||||
let site_view = blocking(pool, move |conn| SiteView::read(conn)).await??;
|
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
|
||||||
|
|
||||||
let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
|
let mut admins = blocking(context.pool(), move |conn| UserView::admins(conn)).await??;
|
||||||
let creator_index = admins
|
let creator_index = admins
|
||||||
.iter()
|
.iter()
|
||||||
.position(|r| r.id == site_view.creator_id)
|
.position(|r| r.id == site_view.creator_id)
|
||||||
|
@ -659,7 +650,7 @@ impl Perform for TransferSite {
|
||||||
let creator_user = admins.remove(creator_index);
|
let creator_user = admins.remove(creator_index);
|
||||||
admins.insert(0, creator_user);
|
admins.insert(0, creator_user);
|
||||||
|
|
||||||
let banned = blocking(pool, move |conn| UserView::banned(conn)).await??;
|
let banned = blocking(context.pool(), move |conn| UserView::banned(conn)).await??;
|
||||||
|
|
||||||
Ok(GetSiteResponse {
|
Ok(GetSiteResponse {
|
||||||
site: Some(site_view),
|
site: Some(site_view),
|
||||||
|
@ -679,15 +670,14 @@ impl Perform for GetSiteConfig {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetSiteConfigResponse, LemmyError> {
|
) -> Result<GetSiteConfigResponse, LemmyError> {
|
||||||
let data: &GetSiteConfig = &self;
|
let data: &GetSiteConfig = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Only let admins read this
|
// Only let admins read this
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
let config_hjson = Settings::read_config_file()?;
|
let config_hjson = Settings::read_config_file()?;
|
||||||
|
|
||||||
|
@ -701,15 +691,14 @@ impl Perform for SaveSiteConfig {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetSiteConfigResponse, LemmyError> {
|
) -> Result<GetSiteConfigResponse, LemmyError> {
|
||||||
let data: &SaveSiteConfig = &self;
|
let data: &SaveSiteConfig = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Only let admins read this
|
// Only let admins read this
|
||||||
let admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
|
let admins = blocking(context.pool(), move |conn| UserView::admins(conn)).await??;
|
||||||
let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.id).collect();
|
let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.id).collect();
|
||||||
|
|
||||||
if !admin_ids.contains(&user.id) {
|
if !admin_ids.contains(&user.id) {
|
||||||
|
|
|
@ -16,10 +16,10 @@ use crate::{
|
||||||
UserOperation,
|
UserOperation,
|
||||||
WebsocketInfo,
|
WebsocketInfo,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use captcha::{gen, Difficulty};
|
use captcha::{gen, Difficulty};
|
||||||
|
@ -302,15 +302,14 @@ impl Perform for Login {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<LoginResponse, LemmyError> {
|
) -> Result<LoginResponse, LemmyError> {
|
||||||
let data: &Login = &self;
|
let data: &Login = &self;
|
||||||
|
|
||||||
// Fetch that username / email
|
// Fetch that username / email
|
||||||
let username_or_email = data.username_or_email.clone();
|
let username_or_email = data.username_or_email.clone();
|
||||||
let user = match blocking(pool, move |conn| {
|
let user = match blocking(context.pool(), move |conn| {
|
||||||
User_::find_by_email_or_username(conn, &username_or_email)
|
User_::find_by_email_or_username(conn, &username_or_email)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -338,14 +337,13 @@ impl Perform for Register {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<LoginResponse, LemmyError> {
|
) -> Result<LoginResponse, LemmyError> {
|
||||||
let data: &Register = &self;
|
let data: &Register = &self;
|
||||||
|
|
||||||
// Make sure site has open registration
|
// Make sure site has open registration
|
||||||
if let Ok(site) = blocking(pool, move |conn| SiteView::read(conn)).await? {
|
if let Ok(site) = blocking(context.pool(), move |conn| SiteView::read(conn)).await? {
|
||||||
let site: SiteView = site;
|
let site: SiteView = site;
|
||||||
if !site.open_registration {
|
if !site.open_registration {
|
||||||
return Err(APIError::err("registration_closed").into());
|
return Err(APIError::err("registration_closed").into());
|
||||||
|
@ -385,7 +383,7 @@ impl Perform for Register {
|
||||||
check_slurs(&data.username)?;
|
check_slurs(&data.username)?;
|
||||||
|
|
||||||
// Make sure there are no admins
|
// Make sure there are no admins
|
||||||
let any_admins = blocking(pool, move |conn| {
|
let any_admins = blocking(context.pool(), move |conn| {
|
||||||
UserView::admins(conn).map(|a| a.is_empty())
|
UserView::admins(conn).map(|a| a.is_empty())
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -426,7 +424,11 @@ impl Perform for Register {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the user
|
// Create the user
|
||||||
let inserted_user = match blocking(pool, move |conn| User_::register(conn, &user_form)).await? {
|
let inserted_user = match blocking(context.pool(), move |conn| {
|
||||||
|
User_::register(conn, &user_form)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(user) => user,
|
Ok(user) => user,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let err_type = if e.to_string()
|
let err_type = if e.to_string()
|
||||||
|
@ -444,7 +446,9 @@ impl Perform for Register {
|
||||||
let main_community_keypair = generate_actor_keypair()?;
|
let main_community_keypair = generate_actor_keypair()?;
|
||||||
|
|
||||||
// Create the main community if it doesn't exist
|
// Create the main community if it doesn't exist
|
||||||
let main_community = match blocking(pool, move |conn| Community::read(conn, 2)).await? {
|
let main_community = match blocking(context.pool(), move |conn| Community::read(conn, 2))
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
let default_community_name = "main";
|
let default_community_name = "main";
|
||||||
|
@ -467,7 +471,10 @@ impl Perform for Register {
|
||||||
icon: None,
|
icon: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
};
|
};
|
||||||
blocking(pool, move |conn| Community::create(conn, &community_form)).await??
|
blocking(context.pool(), move |conn| {
|
||||||
|
Community::create(conn, &community_form)
|
||||||
|
})
|
||||||
|
.await??
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,7 +485,7 @@ impl Perform for Register {
|
||||||
};
|
};
|
||||||
|
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
if blocking(pool, follow).await?.is_err() {
|
if blocking(context.pool(), follow).await?.is_err() {
|
||||||
return Err(APIError::err("community_follower_already_exists").into());
|
return Err(APIError::err("community_follower_already_exists").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -490,7 +497,7 @@ impl Perform for Register {
|
||||||
};
|
};
|
||||||
|
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
if blocking(pool, join).await?.is_err() {
|
if blocking(context.pool(), join).await?.is_err() {
|
||||||
return Err(APIError::err("community_moderator_already_exists").into());
|
return Err(APIError::err("community_moderator_already_exists").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,9 +515,8 @@ impl Perform for GetCaptcha {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
_pool: &DbPool,
|
_context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<Self::Response, LemmyError> {
|
) -> Result<Self::Response, LemmyError> {
|
||||||
let captcha_settings = Settings::get().captcha;
|
let captcha_settings = Settings::get().captcha;
|
||||||
|
|
||||||
|
@ -557,15 +563,14 @@ impl Perform for SaveUserSettings {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<LoginResponse, LemmyError> {
|
) -> Result<LoginResponse, LemmyError> {
|
||||||
let data: &SaveUserSettings = &self;
|
let data: &SaveUserSettings = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let read_user = blocking(pool, move |conn| User_::read(conn, user_id)).await??;
|
let read_user = blocking(context.pool(), move |conn| User_::read(conn, user_id)).await??;
|
||||||
|
|
||||||
let bio = match &data.bio {
|
let bio = match &data.bio {
|
||||||
Some(bio) => {
|
Some(bio) => {
|
||||||
|
@ -611,7 +616,7 @@ impl Perform for SaveUserSettings {
|
||||||
return Err(APIError::err("password_incorrect").into());
|
return Err(APIError::err("password_incorrect").into());
|
||||||
}
|
}
|
||||||
let new_password = new_password.to_owned();
|
let new_password = new_password.to_owned();
|
||||||
let user = blocking(pool, move |conn| {
|
let user = blocking(context.pool(), move |conn| {
|
||||||
User_::update_password(conn, user_id, &new_password)
|
User_::update_password(conn, user_id, &new_password)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -652,7 +657,10 @@ impl Perform for SaveUserSettings {
|
||||||
last_refreshed_at: None,
|
last_refreshed_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = blocking(pool, move |conn| User_::update(conn, user_id, &user_form)).await?;
|
let res = blocking(context.pool(), move |conn| {
|
||||||
|
User_::update(conn, user_id, &user_form)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
let updated_user: User_ = match res {
|
let updated_user: User_ = match res {
|
||||||
Ok(user) => user,
|
Ok(user) => user,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -681,12 +689,11 @@ impl Perform for GetUserDetails {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetUserDetailsResponse, LemmyError> {
|
) -> Result<GetUserDetailsResponse, LemmyError> {
|
||||||
let data: &GetUserDetails = &self;
|
let data: &GetUserDetails = &self;
|
||||||
let user = get_user_from_jwt_opt(&data.auth, pool).await?;
|
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let show_nsfw = match &user {
|
let show_nsfw = match &user {
|
||||||
Some(user) => user.show_nsfw,
|
Some(user) => user.show_nsfw,
|
||||||
|
@ -702,7 +709,10 @@ impl Perform for GetUserDetails {
|
||||||
let user_details_id = match data.user_id {
|
let user_details_id = match data.user_id {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => {
|
None => {
|
||||||
let user = blocking(pool, move |conn| User_::read_from_name(conn, &username)).await?;
|
let user = blocking(context.pool(), move |conn| {
|
||||||
|
User_::read_from_name(conn, &username)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
match user {
|
match user {
|
||||||
Ok(user) => user.id,
|
Ok(user) => user.id,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
|
Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
|
||||||
|
@ -710,7 +720,7 @@ impl Perform for GetUserDetails {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_view = blocking(pool, move |conn| {
|
let user_view = blocking(context.pool(), move |conn| {
|
||||||
UserView::get_user_secure(conn, user_details_id)
|
UserView::get_user_secure(conn, user_details_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -720,7 +730,7 @@ impl Perform for GetUserDetails {
|
||||||
let saved_only = data.saved_only;
|
let saved_only = data.saved_only;
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
let (posts, comments) = blocking(pool, move |conn| {
|
let (posts, comments) = blocking(context.pool(), move |conn| {
|
||||||
let mut posts_query = PostQueryBuilder::create(conn)
|
let mut posts_query = PostQueryBuilder::create(conn)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.show_nsfw(show_nsfw)
|
.show_nsfw(show_nsfw)
|
||||||
|
@ -751,11 +761,11 @@ impl Perform for GetUserDetails {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let follows = blocking(pool, move |conn| {
|
let follows = blocking(context.pool(), move |conn| {
|
||||||
CommunityFollowerView::for_user(conn, user_details_id)
|
CommunityFollowerView::for_user(conn, user_details_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let moderates = blocking(pool, move |conn| {
|
let moderates = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_user(conn, user_details_id)
|
CommunityModeratorView::for_user(conn, user_details_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -777,20 +787,19 @@ impl Perform for AddAdmin {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<AddAdminResponse, LemmyError> {
|
) -> Result<AddAdminResponse, LemmyError> {
|
||||||
let data: &AddAdmin = &self;
|
let data: &AddAdmin = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Make sure user is an admin
|
// Make sure user is an admin
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
let added = data.added;
|
let added = data.added;
|
||||||
let added_user_id = data.user_id;
|
let added_user_id = data.user_id;
|
||||||
let add_admin = move |conn: &'_ _| User_::add_admin(conn, added_user_id, added);
|
let add_admin = move |conn: &'_ _| User_::add_admin(conn, added_user_id, added);
|
||||||
if blocking(pool, add_admin).await?.is_err() {
|
if blocking(context.pool(), add_admin).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_user").into());
|
return Err(APIError::err("couldnt_update_user").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,12 +810,14 @@ impl Perform for AddAdmin {
|
||||||
removed: Some(!data.added),
|
removed: Some(!data.added),
|
||||||
};
|
};
|
||||||
|
|
||||||
blocking(pool, move |conn| ModAdd::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| ModAdd::create(conn, &form)).await??;
|
||||||
|
|
||||||
let site_creator_id =
|
let site_creator_id = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| Site::read(conn, 1).map(|s| s.creator_id)).await??;
|
Site::read(conn, 1).map(|s| s.creator_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??;
|
let mut admins = blocking(context.pool(), move |conn| UserView::admins(conn)).await??;
|
||||||
let creator_index = admins
|
let creator_index = admins
|
||||||
.iter()
|
.iter()
|
||||||
.position(|r| r.id == site_creator_id)
|
.position(|r| r.id == site_creator_id)
|
||||||
|
@ -834,39 +845,38 @@ impl Perform for BanUser {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<BanUserResponse, LemmyError> {
|
) -> Result<BanUserResponse, LemmyError> {
|
||||||
let data: &BanUser = &self;
|
let data: &BanUser = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Make sure user is an admin
|
// Make sure user is an admin
|
||||||
is_admin(pool, user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
let ban = data.ban;
|
let ban = data.ban;
|
||||||
let banned_user_id = data.user_id;
|
let banned_user_id = data.user_id;
|
||||||
let ban_user = move |conn: &'_ _| User_::ban_user(conn, banned_user_id, ban);
|
let ban_user = move |conn: &'_ _| User_::ban_user(conn, banned_user_id, ban);
|
||||||
if blocking(pool, ban_user).await?.is_err() {
|
if blocking(context.pool(), ban_user).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_user").into());
|
return Err(APIError::err("couldnt_update_user").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove their data if that's desired
|
// Remove their data if that's desired
|
||||||
if let Some(remove_data) = data.remove_data {
|
if let Some(remove_data) = data.remove_data {
|
||||||
// Posts
|
// Posts
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(context.pool(), move |conn: &'_ _| {
|
||||||
Post::update_removed_for_creator(conn, banned_user_id, None, remove_data)
|
Post::update_removed_for_creator(conn, banned_user_id, None, remove_data)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Communities
|
// Communities
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(context.pool(), move |conn: &'_ _| {
|
||||||
Community::update_removed_for_creator(conn, banned_user_id, remove_data)
|
Community::update_removed_for_creator(conn, banned_user_id, remove_data)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(context.pool(), move |conn: &'_ _| {
|
||||||
Comment::update_removed_for_creator(conn, banned_user_id, remove_data)
|
Comment::update_removed_for_creator(conn, banned_user_id, remove_data)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -886,10 +896,13 @@ impl Perform for BanUser {
|
||||||
expires,
|
expires,
|
||||||
};
|
};
|
||||||
|
|
||||||
blocking(pool, move |conn| ModBan::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??;
|
||||||
|
|
||||||
let user_id = data.user_id;
|
let user_id = data.user_id;
|
||||||
let user_view = blocking(pool, move |conn| UserView::get_user_secure(conn, user_id)).await??;
|
let user_view = blocking(context.pool(), move |conn| {
|
||||||
|
UserView::get_user_secure(conn, user_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = BanUserResponse {
|
let res = BanUserResponse {
|
||||||
user: user_view,
|
user: user_view,
|
||||||
|
@ -914,12 +927,11 @@ impl Perform for GetReplies {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetRepliesResponse, LemmyError> {
|
) -> Result<GetRepliesResponse, LemmyError> {
|
||||||
let data: &GetReplies = &self;
|
let data: &GetReplies = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let sort = SortType::from_str(&data.sort)?;
|
let sort = SortType::from_str(&data.sort)?;
|
||||||
|
|
||||||
|
@ -927,7 +939,7 @@ impl Perform for GetReplies {
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let unread_only = data.unread_only;
|
let unread_only = data.unread_only;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let replies = blocking(pool, move |conn| {
|
let replies = blocking(context.pool(), move |conn| {
|
||||||
ReplyQueryBuilder::create(conn, user_id)
|
ReplyQueryBuilder::create(conn, user_id)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.unread_only(unread_only)
|
.unread_only(unread_only)
|
||||||
|
@ -947,12 +959,11 @@ impl Perform for GetUserMentions {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetUserMentionsResponse, LemmyError> {
|
) -> Result<GetUserMentionsResponse, LemmyError> {
|
||||||
let data: &GetUserMentions = &self;
|
let data: &GetUserMentions = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let sort = SortType::from_str(&data.sort)?;
|
let sort = SortType::from_str(&data.sort)?;
|
||||||
|
|
||||||
|
@ -960,7 +971,7 @@ impl Perform for GetUserMentions {
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let unread_only = data.unread_only;
|
let unread_only = data.unread_only;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let mentions = blocking(pool, move |conn| {
|
let mentions = blocking(context.pool(), move |conn| {
|
||||||
UserMentionQueryBuilder::create(conn, user_id)
|
UserMentionQueryBuilder::create(conn, user_id)
|
||||||
.sort(&sort)
|
.sort(&sort)
|
||||||
.unread_only(unread_only)
|
.unread_only(unread_only)
|
||||||
|
@ -980,16 +991,17 @@ impl Perform for MarkUserMentionAsRead {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<UserMentionResponse, LemmyError> {
|
) -> Result<UserMentionResponse, LemmyError> {
|
||||||
let data: &MarkUserMentionAsRead = &self;
|
let data: &MarkUserMentionAsRead = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_mention_id = data.user_mention_id;
|
let user_mention_id = data.user_mention_id;
|
||||||
let read_user_mention =
|
let read_user_mention = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| UserMention::read(conn, user_mention_id)).await??;
|
UserMention::read(conn, user_mention_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
if user.id != read_user_mention.recipient_id {
|
if user.id != read_user_mention.recipient_id {
|
||||||
return Err(APIError::err("couldnt_update_comment").into());
|
return Err(APIError::err("couldnt_update_comment").into());
|
||||||
|
@ -998,13 +1010,13 @@ impl Perform for MarkUserMentionAsRead {
|
||||||
let user_mention_id = read_user_mention.id;
|
let user_mention_id = read_user_mention.id;
|
||||||
let read = data.read;
|
let read = data.read;
|
||||||
let update_mention = move |conn: &'_ _| UserMention::update_read(conn, user_mention_id, read);
|
let update_mention = move |conn: &'_ _| UserMention::update_read(conn, user_mention_id, read);
|
||||||
if blocking(pool, update_mention).await?.is_err() {
|
if blocking(context.pool(), update_mention).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_comment").into());
|
return Err(APIError::err("couldnt_update_comment").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_mention_id = read_user_mention.id;
|
let user_mention_id = read_user_mention.id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let user_mention_view = blocking(pool, move |conn| {
|
let user_mention_view = blocking(context.pool(), move |conn| {
|
||||||
UserMentionView::read(conn, user_mention_id, user_id)
|
UserMentionView::read(conn, user_mention_id, user_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -1021,15 +1033,14 @@ impl Perform for MarkAllAsRead {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<GetRepliesResponse, LemmyError> {
|
) -> Result<GetRepliesResponse, LemmyError> {
|
||||||
let data: &MarkAllAsRead = &self;
|
let data: &MarkAllAsRead = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let replies = blocking(pool, move |conn| {
|
let replies = blocking(context.pool(), move |conn| {
|
||||||
ReplyQueryBuilder::create(conn, user_id)
|
ReplyQueryBuilder::create(conn, user_id)
|
||||||
.unread_only(true)
|
.unread_only(true)
|
||||||
.page(1)
|
.page(1)
|
||||||
|
@ -1044,20 +1055,23 @@ impl Perform for MarkAllAsRead {
|
||||||
for reply in &replies {
|
for reply in &replies {
|
||||||
let reply_id = reply.id;
|
let reply_id = reply.id;
|
||||||
let mark_as_read = move |conn: &'_ _| Comment::update_read(conn, reply_id, true);
|
let mark_as_read = move |conn: &'_ _| Comment::update_read(conn, reply_id, true);
|
||||||
if blocking(pool, mark_as_read).await?.is_err() {
|
if blocking(context.pool(), mark_as_read).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_comment").into());
|
return Err(APIError::err("couldnt_update_comment").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark all user mentions as read
|
// Mark all user mentions as read
|
||||||
let update_user_mentions = move |conn: &'_ _| UserMention::mark_all_as_read(conn, user_id);
|
let update_user_mentions = move |conn: &'_ _| UserMention::mark_all_as_read(conn, user_id);
|
||||||
if blocking(pool, update_user_mentions).await?.is_err() {
|
if blocking(context.pool(), update_user_mentions)
|
||||||
|
.await?
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
return Err(APIError::err("couldnt_update_comment").into());
|
return Err(APIError::err("couldnt_update_comment").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark all private_messages as read
|
// Mark all private_messages as read
|
||||||
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, user_id);
|
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, user_id);
|
||||||
if blocking(pool, update_pm).await?.is_err() {
|
if blocking(context.pool(), update_pm).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_private_message").into());
|
return Err(APIError::err("couldnt_update_private_message").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,12 +1085,11 @@ impl Perform for DeleteAccount {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<LoginResponse, LemmyError> {
|
) -> Result<LoginResponse, LemmyError> {
|
||||||
let data: &DeleteAccount = &self;
|
let data: &DeleteAccount = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Verify the password
|
// Verify the password
|
||||||
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
|
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
|
||||||
|
@ -1087,13 +1100,13 @@ impl Perform for DeleteAccount {
|
||||||
// Comments
|
// Comments
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
|
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, user_id);
|
||||||
if blocking(pool, permadelete).await?.is_err() {
|
if blocking(context.pool(), permadelete).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_comment").into());
|
return Err(APIError::err("couldnt_update_comment").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Posts
|
// Posts
|
||||||
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, user_id);
|
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, user_id);
|
||||||
if blocking(pool, permadelete).await?.is_err() {
|
if blocking(context.pool(), permadelete).await?.is_err() {
|
||||||
return Err(APIError::err("couldnt_update_post").into());
|
return Err(APIError::err("couldnt_update_post").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,15 +1122,18 @@ impl Perform for PasswordReset {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<PasswordResetResponse, LemmyError> {
|
) -> Result<PasswordResetResponse, LemmyError> {
|
||||||
let data: &PasswordReset = &self;
|
let data: &PasswordReset = &self;
|
||||||
|
|
||||||
// Fetch that email
|
// Fetch that email
|
||||||
let email = data.email.clone();
|
let email = data.email.clone();
|
||||||
let user = match blocking(pool, move |conn| User_::find_by_email(conn, &email)).await? {
|
let user = match blocking(context.pool(), move |conn| {
|
||||||
|
User_::find_by_email(conn, &email)
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
{
|
||||||
Ok(user) => user,
|
Ok(user) => user,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
|
Err(_e) => return Err(APIError::err("couldnt_find_that_username_or_email").into()),
|
||||||
};
|
};
|
||||||
|
@ -1128,7 +1144,7 @@ impl Perform for PasswordReset {
|
||||||
// Insert the row
|
// Insert the row
|
||||||
let token2 = token.clone();
|
let token2 = token.clone();
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
PasswordResetRequest::create_token(conn, user_id, &token2)
|
PasswordResetRequest::create_token(conn, user_id, &token2)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -1154,15 +1170,14 @@ impl Perform for PasswordChange {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<LoginResponse, LemmyError> {
|
) -> Result<LoginResponse, LemmyError> {
|
||||||
let data: &PasswordChange = &self;
|
let data: &PasswordChange = &self;
|
||||||
|
|
||||||
// Fetch the user_id from the token
|
// Fetch the user_id from the token
|
||||||
let token = data.token.clone();
|
let token = data.token.clone();
|
||||||
let user_id = blocking(pool, move |conn| {
|
let user_id = blocking(context.pool(), move |conn| {
|
||||||
PasswordResetRequest::read_from_token(conn, &token).map(|p| p.user_id)
|
PasswordResetRequest::read_from_token(conn, &token).map(|p| p.user_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -1174,7 +1189,7 @@ impl Perform for PasswordChange {
|
||||||
|
|
||||||
// Update the user with the new password
|
// Update the user with the new password
|
||||||
let password = data.password.clone();
|
let password = data.password.clone();
|
||||||
let updated_user = match blocking(pool, move |conn| {
|
let updated_user = match blocking(context.pool(), move |conn| {
|
||||||
User_::update_password(conn, user_id, &password)
|
User_::update_password(conn, user_id, &password)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -1196,12 +1211,11 @@ impl Perform for CreatePrivateMessage {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||||
let data: &CreatePrivateMessage = &self;
|
let data: &CreatePrivateMessage = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let hostname = &format!("https://{}", Settings::get().hostname);
|
let hostname = &format!("https://{}", Settings::get().hostname);
|
||||||
|
|
||||||
|
@ -1219,7 +1233,7 @@ impl Perform for CreatePrivateMessage {
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_private_message = match blocking(pool, move |conn| {
|
let inserted_private_message = match blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::create(conn, &private_message_form)
|
PrivateMessage::create(conn, &private_message_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -1231,7 +1245,7 @@ impl Perform for CreatePrivateMessage {
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_private_message_id = inserted_private_message.id;
|
let inserted_private_message_id = inserted_private_message.id;
|
||||||
let updated_private_message = match blocking(pool, move |conn| {
|
let updated_private_message = match blocking(context.pool(), move |conn| {
|
||||||
let apub_id = make_apub_endpoint(
|
let apub_id = make_apub_endpoint(
|
||||||
EndpointType::PrivateMessage,
|
EndpointType::PrivateMessage,
|
||||||
&inserted_private_message_id.to_string(),
|
&inserted_private_message_id.to_string(),
|
||||||
|
@ -1245,13 +1259,12 @@ impl Perform for CreatePrivateMessage {
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_private_message").into()),
|
Err(_e) => return Err(APIError::err("couldnt_create_private_message").into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
updated_private_message
|
updated_private_message.send_create(&user, context).await?;
|
||||||
.send_create(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Send notifications to the recipient
|
// Send notifications to the recipient
|
||||||
let recipient_id = data.recipient_id;
|
let recipient_id = data.recipient_id;
|
||||||
let recipient_user = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient_user =
|
||||||
|
blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
if recipient_user.send_notifications_to_email {
|
if recipient_user.send_notifications_to_email {
|
||||||
if let Some(email) = recipient_user.email {
|
if let Some(email) = recipient_user.email {
|
||||||
let subject = &format!(
|
let subject = &format!(
|
||||||
|
@ -1270,7 +1283,7 @@ impl Perform for CreatePrivateMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = blocking(pool, move |conn| {
|
let message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, inserted_private_message.id)
|
PrivateMessageView::read(conn, inserted_private_message.id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -1296,17 +1309,18 @@ impl Perform for EditPrivateMessage {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||||
let data: &EditPrivateMessage = &self;
|
let data: &EditPrivateMessage = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_private_message =
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| PrivateMessage::read(conn, edit_id)).await??;
|
PrivateMessage::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
if user.id != orig_private_message.creator_id {
|
if user.id != orig_private_message.creator_id {
|
||||||
return Err(APIError::err("no_private_message_edit_allowed").into());
|
return Err(APIError::err("no_private_message_edit_allowed").into());
|
||||||
}
|
}
|
||||||
|
@ -1314,7 +1328,7 @@ impl Perform for EditPrivateMessage {
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let content_slurs_removed = remove_slurs(&data.content);
|
let content_slurs_removed = remove_slurs(&data.content);
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let updated_private_message = match blocking(pool, move |conn| {
|
let updated_private_message = match blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::update_content(conn, edit_id, &content_slurs_removed)
|
PrivateMessage::update_content(conn, edit_id, &content_slurs_removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -1324,12 +1338,13 @@ impl Perform for EditPrivateMessage {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
updated_private_message
|
updated_private_message.send_update(&user, context).await?;
|
||||||
.send_update(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let message = blocking(pool, move |conn| PrivateMessageView::read(conn, edit_id)).await??;
|
let message = blocking(context.pool(), move |conn| {
|
||||||
|
PrivateMessageView::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
let recipient_id = message.recipient_id;
|
let recipient_id = message.recipient_id;
|
||||||
|
|
||||||
let res = PrivateMessageResponse { message };
|
let res = PrivateMessageResponse { message };
|
||||||
|
@ -1353,17 +1368,18 @@ impl Perform for DeletePrivateMessage {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
client: Client,
|
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||||
let data: &DeletePrivateMessage = &self;
|
let data: &DeletePrivateMessage = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_private_message =
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| PrivateMessage::read(conn, edit_id)).await??;
|
PrivateMessage::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
if user.id != orig_private_message.creator_id {
|
if user.id != orig_private_message.creator_id {
|
||||||
return Err(APIError::err("no_private_message_edit_allowed").into());
|
return Err(APIError::err("no_private_message_edit_allowed").into());
|
||||||
}
|
}
|
||||||
|
@ -1371,7 +1387,7 @@ impl Perform for DeletePrivateMessage {
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_private_message = match blocking(pool, move |conn| {
|
let updated_private_message = match blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::update_deleted(conn, edit_id, deleted)
|
PrivateMessage::update_deleted(conn, edit_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -1382,17 +1398,18 @@ impl Perform for DeletePrivateMessage {
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
if data.deleted {
|
if data.deleted {
|
||||||
updated_private_message
|
updated_private_message.send_delete(&user, context).await?;
|
||||||
.send_delete(&user, &client, pool)
|
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
updated_private_message
|
updated_private_message
|
||||||
.send_undo_delete(&user, &client, pool)
|
.send_undo_delete(&user, context)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let message = blocking(pool, move |conn| PrivateMessageView::read(conn, edit_id)).await??;
|
let message = blocking(context.pool(), move |conn| {
|
||||||
|
PrivateMessageView::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
let recipient_id = message.recipient_id;
|
let recipient_id = message.recipient_id;
|
||||||
|
|
||||||
let res = PrivateMessageResponse { message };
|
let res = PrivateMessageResponse { message };
|
||||||
|
@ -1416,17 +1433,18 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
) -> Result<PrivateMessageResponse, LemmyError> {
|
||||||
let data: &MarkPrivateMessageAsRead = &self;
|
let data: &MarkPrivateMessageAsRead = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// Checking permissions
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let orig_private_message =
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| PrivateMessage::read(conn, edit_id)).await??;
|
PrivateMessage::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
if user.id != orig_private_message.recipient_id {
|
if user.id != orig_private_message.recipient_id {
|
||||||
return Err(APIError::err("couldnt_update_private_message").into());
|
return Err(APIError::err("couldnt_update_private_message").into());
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1452,7 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let read = data.read;
|
let read = data.read;
|
||||||
match blocking(pool, move |conn| {
|
match blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::update_read(conn, edit_id, read)
|
PrivateMessage::update_read(conn, edit_id, read)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -1446,7 +1464,10 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
// No need to send an apub update
|
// No need to send an apub update
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let edit_id = data.edit_id;
|
||||||
let message = blocking(pool, move |conn| PrivateMessageView::read(conn, edit_id)).await??;
|
let message = blocking(context.pool(), move |conn| {
|
||||||
|
PrivateMessageView::read(conn, edit_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
let recipient_id = message.recipient_id;
|
let recipient_id = message.recipient_id;
|
||||||
|
|
||||||
let res = PrivateMessageResponse { message };
|
let res = PrivateMessageResponse { message };
|
||||||
|
@ -1470,18 +1491,17 @@ impl Perform for GetPrivateMessages {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_info: Option<WebsocketInfo>,
|
_websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<PrivateMessagesResponse, LemmyError> {
|
) -> Result<PrivateMessagesResponse, LemmyError> {
|
||||||
let data: &GetPrivateMessages = &self;
|
let data: &GetPrivateMessages = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
|
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let unread_only = data.unread_only;
|
let unread_only = data.unread_only;
|
||||||
let messages = blocking(pool, move |conn| {
|
let messages = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessageQueryBuilder::create(&conn, user_id)
|
PrivateMessageQueryBuilder::create(&conn, user_id)
|
||||||
.page(page)
|
.page(page)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
@ -1500,12 +1520,11 @@ impl Perform for UserJoin {
|
||||||
|
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
pool: &DbPool,
|
context: &Data<LemmyContext>,
|
||||||
websocket_info: Option<WebsocketInfo>,
|
websocket_info: Option<WebsocketInfo>,
|
||||||
_client: Client,
|
|
||||||
) -> Result<UserJoinResponse, LemmyError> {
|
) -> Result<UserJoinResponse, LemmyError> {
|
||||||
let data: &UserJoin = &self;
|
let data: &UserJoin = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, pool).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
if let Some(ws) = websocket_info {
|
if let Some(ws) = websocket_info {
|
||||||
if let Some(id) = ws.id {
|
if let Some(id) = ws.id {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
ActorType,
|
ActorType,
|
||||||
},
|
},
|
||||||
request::retry_custom,
|
request::retry_custom,
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::base::AnyBase;
|
use activitystreams::base::AnyBase;
|
||||||
|
@ -23,16 +23,15 @@ pub async fn send_activity_to_community(
|
||||||
community: &Community,
|
community: &Community,
|
||||||
to: Vec<Url>,
|
to: Vec<Url>,
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
insert_activity(creator.id, activity.clone(), true, pool).await?;
|
insert_activity(creator.id, activity.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
// if this is a local community, we need to do an announce from the community instead
|
// if this is a local community, we need to do an announce from the community instead
|
||||||
if community.local {
|
if community.local {
|
||||||
do_announce(activity, &community, creator, client, pool).await?;
|
do_announce(activity, &community, creator, context).await?;
|
||||||
} else {
|
} else {
|
||||||
send_activity(client, &activity, creator, to).await?;
|
send_activity(context.client(), &activity, creator, to).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -18,8 +18,8 @@ use crate::{
|
||||||
ToApub,
|
ToApub,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::DbPoolParam,
|
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -34,13 +34,12 @@ use activitystreams::{
|
||||||
Update,
|
Update,
|
||||||
},
|
},
|
||||||
base::AnyBase,
|
base::AnyBase,
|
||||||
context,
|
|
||||||
link::Mention,
|
link::Mention,
|
||||||
object::{kind::NoteType, Note, Tombstone},
|
object::{kind::NoteType, Note, Tombstone},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
use actix_web::{body::Body, client::Client, web::Path, HttpResponse};
|
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
|
@ -70,13 +69,15 @@ pub struct CommentQuery {
|
||||||
/// Return the post json over HTTP.
|
/// Return the post json over HTTP.
|
||||||
pub async fn get_apub_comment(
|
pub async fn get_apub_comment(
|
||||||
info: Path<CommentQuery>,
|
info: Path<CommentQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let id = info.comment_id.parse::<i32>()?;
|
let id = info.comment_id.parse::<i32>()?;
|
||||||
let comment = blocking(&db, move |conn| Comment::read(conn, id)).await??;
|
let comment = blocking(context.pool(), move |conn| Comment::read(conn, id)).await??;
|
||||||
|
|
||||||
if !comment.deleted {
|
if !comment.deleted {
|
||||||
Ok(create_apub_response(&comment.to_apub(&db).await?))
|
Ok(create_apub_response(
|
||||||
|
&comment.to_apub(context.pool()).await?,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(create_apub_tombstone_response(&comment.to_tombstone()?))
|
Ok(create_apub_tombstone_response(&comment.to_tombstone()?))
|
||||||
}
|
}
|
||||||
|
@ -110,7 +111,7 @@ impl ToApub for Comment {
|
||||||
|
|
||||||
comment
|
comment
|
||||||
// Not needed when the Post is embedded in a collection (like for community outbox)
|
// Not needed when the Post is embedded in a collection (like for community outbox)
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(Url::parse(&self.ap_id)?)
|
.set_id(Url::parse(&self.ap_id)?)
|
||||||
.set_published(convert_datetime(self.published))
|
.set_published(convert_datetime(self.published))
|
||||||
.set_to(community.actor_id)
|
.set_to(community.actor_id)
|
||||||
|
@ -137,8 +138,7 @@ impl FromApub for CommentForm {
|
||||||
/// Parse an ActivityPub note received from another instance into a Lemmy comment
|
/// Parse an ActivityPub note received from another instance into a Lemmy comment
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
note: &Note,
|
note: &Note,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<CommentForm, LemmyError> {
|
) -> Result<CommentForm, LemmyError> {
|
||||||
let creator_actor_id = ¬e
|
let creator_actor_id = ¬e
|
||||||
|
@ -147,7 +147,7 @@ impl FromApub for CommentForm {
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let creator = get_or_fetch_and_upsert_user(creator_actor_id, client, pool).await?;
|
let creator = get_or_fetch_and_upsert_user(creator_actor_id, context).await?;
|
||||||
|
|
||||||
let mut in_reply_tos = note
|
let mut in_reply_tos = note
|
||||||
.in_reply_to()
|
.in_reply_to()
|
||||||
|
@ -160,7 +160,7 @@ impl FromApub for CommentForm {
|
||||||
let post_ap_id = in_reply_tos.next().context(location_info!())??;
|
let post_ap_id = in_reply_tos.next().context(location_info!())??;
|
||||||
|
|
||||||
// This post, or the parent comment might not yet exist on this server yet, fetch them.
|
// This post, or the parent comment might not yet exist on this server yet, fetch them.
|
||||||
let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
|
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
|
||||||
|
|
||||||
// The 2nd item, if it exists, is the parent comment apub_id
|
// The 2nd item, if it exists, is the parent comment apub_id
|
||||||
// For deeply nested comments, FromApub automatically gets called recursively
|
// For deeply nested comments, FromApub automatically gets called recursively
|
||||||
|
@ -168,7 +168,7 @@ impl FromApub for CommentForm {
|
||||||
Some(parent_comment_uri) => {
|
Some(parent_comment_uri) => {
|
||||||
let parent_comment_ap_id = &parent_comment_uri?;
|
let parent_comment_ap_id = &parent_comment_uri?;
|
||||||
let parent_comment =
|
let parent_comment =
|
||||||
get_or_fetch_and_insert_comment(&parent_comment_ap_id, client, pool).await?;
|
get_or_fetch_and_insert_comment(&parent_comment_ap_id, context).await?;
|
||||||
|
|
||||||
Some(parent_comment.id)
|
Some(parent_comment.id)
|
||||||
}
|
}
|
||||||
|
@ -201,26 +201,23 @@ impl FromApub for CommentForm {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ApubObjectType for Comment {
|
impl ApubObjectType for Comment {
|
||||||
/// Send out information about a newly created comment, to the followers of the community.
|
/// Send out information about a newly created comment, to the followers of the community.
|
||||||
async fn send_create(
|
async fn send_create(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let maa =
|
let maa = collect_non_local_mentions_and_addresses(&self.content, &community, context).await?;
|
||||||
collect_non_local_mentions_and_addresses(&self.content, &community, client, pool).await?;
|
|
||||||
|
|
||||||
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
create
|
create
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(CreateType::Create)?)
|
.set_id(generate_activity_id(CreateType::Create)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(maa.addressed_ccs.to_owned())
|
.set_many_ccs(maa.addressed_ccs.to_owned())
|
||||||
|
@ -232,34 +229,30 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
maa.inboxes,
|
maa.inboxes,
|
||||||
create.into_any_base()?,
|
create.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send out information about an edited post, to the followers of the community.
|
/// Send out information about an edited post, to the followers of the community.
|
||||||
async fn send_update(
|
async fn send_update(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let maa =
|
let maa = collect_non_local_mentions_and_addresses(&self.content, &community, context).await?;
|
||||||
collect_non_local_mentions_and_addresses(&self.content, &community, client, pool).await?;
|
|
||||||
|
|
||||||
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
update
|
update
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UpdateType::Update)?)
|
.set_id(generate_activity_id(UpdateType::Update)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(maa.addressed_ccs.to_owned())
|
.set_many_ccs(maa.addressed_ccs.to_owned())
|
||||||
|
@ -271,30 +264,27 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
maa.inboxes,
|
maa.inboxes,
|
||||||
update.into_any_base()?,
|
update.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -304,8 +294,7 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
delete.into_any_base()?,
|
delete.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -314,21 +303,23 @@ impl ApubObjectType for Comment {
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let note = self.to_apub(pool).await?;
|
let note = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Generate a fake delete activity, with the correct object
|
// Generate a fake delete activity, with the correct object
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -336,7 +327,7 @@ impl ApubObjectType for Comment {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -346,30 +337,27 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -379,31 +367,28 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
remove.into_any_base()?,
|
remove.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_remove(
|
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Generate a fake delete activity, with the correct object
|
// Generate a fake delete activity, with the correct object
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), note.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -411,7 +396,7 @@ impl ApubObjectType for Comment {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -421,8 +406,7 @@ impl ApubObjectType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -431,23 +415,21 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ApubLikeableType for Comment {
|
impl ApubLikeableType for Comment {
|
||||||
async fn send_like(
|
async fn send_like(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
like
|
like
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(LikeType::Like)?)
|
.set_id(generate_activity_id(LikeType::Like)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -457,30 +439,27 @@ impl ApubLikeableType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
like.into_any_base()?,
|
like.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_dislike(
|
async fn send_dislike(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut dislike = Dislike::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut dislike = Dislike::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
dislike
|
dislike
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -490,8 +469,7 @@ impl ApubLikeableType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
dislike.into_any_base()?,
|
dislike.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -500,20 +478,22 @@ impl ApubLikeableType for Comment {
|
||||||
async fn send_undo_like(
|
async fn send_undo_like(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let note = self.to_apub(pool).await?;
|
let note = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let post_id = self.post_id;
|
let post_id = self.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let community_id = post.community_id;
|
let community_id = post.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut like = Like::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
like
|
like
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -521,7 +501,7 @@ impl ApubLikeableType for Comment {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -531,8 +511,7 @@ impl ApubLikeableType for Comment {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -561,8 +540,7 @@ impl MentionsAndAddresses {
|
||||||
async fn collect_non_local_mentions_and_addresses(
|
async fn collect_non_local_mentions_and_addresses(
|
||||||
content: &str,
|
content: &str,
|
||||||
community: &Community,
|
community: &Community,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<MentionsAndAddresses, LemmyError> {
|
) -> Result<MentionsAndAddresses, LemmyError> {
|
||||||
let mut addressed_ccs = vec![community.get_followers_url()?];
|
let mut addressed_ccs = vec![community.get_followers_url()?];
|
||||||
|
|
||||||
|
@ -579,11 +557,11 @@ async fn collect_non_local_mentions_and_addresses(
|
||||||
let mut mention_inboxes: Vec<Url> = Vec::new();
|
let mut mention_inboxes: Vec<Url> = Vec::new();
|
||||||
for mention in &mentions {
|
for mention in &mentions {
|
||||||
// TODO should it be fetching it every time?
|
// TODO should it be fetching it every time?
|
||||||
if let Ok(actor_id) = fetch_webfinger_url(mention, client).await {
|
if let Ok(actor_id) = fetch_webfinger_url(mention, context.client()).await {
|
||||||
debug!("mention actor_id: {}", actor_id);
|
debug!("mention actor_id: {}", actor_id);
|
||||||
addressed_ccs.push(actor_id.to_owned().to_string().parse()?);
|
addressed_ccs.push(actor_id.to_owned().to_string().parse()?);
|
||||||
|
|
||||||
let mention_user = get_or_fetch_and_upsert_user(&actor_id, client, pool).await?;
|
let mention_user = get_or_fetch_and_upsert_user(&actor_id, context).await?;
|
||||||
let shared_inbox = mention_user.get_shared_inbox_url()?;
|
let shared_inbox = mention_user.get_shared_inbox_url()?;
|
||||||
|
|
||||||
mention_inboxes.push(shared_inbox);
|
mention_inboxes.push(shared_inbox);
|
||||||
|
|
|
@ -15,8 +15,8 @@ use crate::{
|
||||||
ToApub,
|
ToApub,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::DbPoolParam,
|
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -32,13 +32,12 @@ use activitystreams::{
|
||||||
actor::{kind::GroupType, ApActor, Endpoints, Group},
|
actor::{kind::GroupType, ApActor, Endpoints, Group},
|
||||||
base::{AnyBase, BaseExt},
|
base::{AnyBase, BaseExt},
|
||||||
collection::{OrderedCollection, UnorderedCollection},
|
collection::{OrderedCollection, UnorderedCollection},
|
||||||
context,
|
|
||||||
object::{Image, Tombstone},
|
object::{Image, Tombstone},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext2;
|
use activitystreams_ext::Ext2;
|
||||||
use actix_web::{body::Body, client::Client, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
|
@ -76,7 +75,7 @@ impl ToApub for Community {
|
||||||
|
|
||||||
let mut group = Group::new();
|
let mut group = Group::new();
|
||||||
group
|
group
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(Url::parse(&self.actor_id)?)
|
.set_id(Url::parse(&self.actor_id)?)
|
||||||
.set_name(self.name.to_owned())
|
.set_name(self.name.to_owned())
|
||||||
.set_published(convert_datetime(self.published))
|
.set_published(convert_datetime(self.published))
|
||||||
|
@ -139,124 +138,107 @@ impl ActorType for Community {
|
||||||
async fn send_accept_follow(
|
async fn send_accept_follow(
|
||||||
&self,
|
&self,
|
||||||
follow: Follow,
|
follow: Follow,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let actor_uri = follow
|
let actor_uri = follow
|
||||||
.actor()?
|
.actor()?
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let actor = get_or_fetch_and_upsert_actor(actor_uri, client, pool).await?;
|
let actor = get_or_fetch_and_upsert_actor(actor_uri, context).await?;
|
||||||
|
|
||||||
let mut accept = Accept::new(self.actor_id.to_owned(), follow.into_any_base()?);
|
let mut accept = Accept::new(self.actor_id.to_owned(), follow.into_any_base()?);
|
||||||
let to = actor.get_inbox_url()?;
|
let to = actor.get_inbox_url()?;
|
||||||
accept
|
accept
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(AcceptType::Accept)?)
|
.set_id(generate_activity_id(AcceptType::Accept)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
insert_activity(self.creator_id, accept.clone(), true, pool).await?;
|
insert_activity(self.creator_id, accept.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &accept.into_any_base()?, self, vec![to]).await?;
|
send_activity(context.client(), &accept.into_any_base()?, self, vec![to]).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let group = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let group = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
insert_activity(self.creator_id, delete.clone(), true, pool).await?;
|
insert_activity(self.creator_id, delete.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
let inboxes = self.get_follower_inboxes(pool).await?;
|
let inboxes = self.get_follower_inboxes(context.pool()).await?;
|
||||||
|
|
||||||
// Note: For an accept, since it was automatic, no one pushed a button,
|
// Note: For an accept, since it was automatic, no one pushed a button,
|
||||||
// the community was the actor.
|
// the community was the actor.
|
||||||
// But for delete, the creator is the actor, and does the signing
|
// But for delete, the creator is the actor, and does the signing
|
||||||
send_activity(client, &delete.into_any_base()?, creator, inboxes).await?;
|
send_activity(context.client(), &delete.into_any_base()?, creator, inboxes).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let group = self.to_apub(pool).await?;
|
let group = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), group.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
insert_activity(self.creator_id, undo.clone(), true, pool).await?;
|
insert_activity(self.creator_id, undo.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
let inboxes = self.get_follower_inboxes(pool).await?;
|
let inboxes = self.get_follower_inboxes(context.pool()).await?;
|
||||||
|
|
||||||
// Note: For an accept, since it was automatic, no one pushed a button,
|
// Note: For an accept, since it was automatic, no one pushed a button,
|
||||||
// the community was the actor.
|
// the community was the actor.
|
||||||
// But for delete, the creator is the actor, and does the signing
|
// But for delete, the creator is the actor, and does the signing
|
||||||
send_activity(client, &undo.into_any_base()?, creator, inboxes).await?;
|
send_activity(context.client(), &undo.into_any_base()?, creator, inboxes).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let group = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let group = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
insert_activity(mod_.id, remove.clone(), true, pool).await?;
|
insert_activity(mod_.id, remove.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
let inboxes = self.get_follower_inboxes(pool).await?;
|
let inboxes = self.get_follower_inboxes(context.pool()).await?;
|
||||||
|
|
||||||
// Note: For an accept, since it was automatic, no one pushed a button,
|
// Note: For an accept, since it was automatic, no one pushed a button,
|
||||||
// the community was the actor.
|
// the community was the actor.
|
||||||
// But for delete, the creator is the actor, and does the signing
|
// But for delete, the creator is the actor, and does the signing
|
||||||
send_activity(client, &remove.into_any_base()?, mod_, inboxes).await?;
|
send_activity(context.client(), &remove.into_any_base()?, mod_, inboxes).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_remove(
|
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let group = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let group = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), group.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
@ -264,19 +246,19 @@ impl ActorType for Community {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(LikeType::Like)?)
|
.set_id(generate_activity_id(LikeType::Like)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![self.get_followers_url()?]);
|
.set_many_ccs(vec![self.get_followers_url()?]);
|
||||||
|
|
||||||
insert_activity(mod_.id, undo.clone(), true, pool).await?;
|
insert_activity(mod_.id, undo.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
let inboxes = self.get_follower_inboxes(pool).await?;
|
let inboxes = self.get_follower_inboxes(context.pool()).await?;
|
||||||
|
|
||||||
// Note: For an accept, since it was automatic, no one pushed a button,
|
// Note: For an accept, since it was automatic, no one pushed a button,
|
||||||
// the community was the actor.
|
// the community was the actor.
|
||||||
// But for remove , the creator is the actor, and does the signing
|
// But for remove , the creator is the actor, and does the signing
|
||||||
send_activity(client, &undo.into_any_base()?, mod_, inboxes).await?;
|
send_activity(context.client(), &undo.into_any_base()?, mod_, inboxes).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +300,7 @@ impl ActorType for Community {
|
||||||
async fn send_follow(
|
async fn send_follow(
|
||||||
&self,
|
&self,
|
||||||
_follow_actor_id: &Url,
|
_follow_actor_id: &Url,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -327,8 +308,7 @@ impl ActorType for Community {
|
||||||
async fn send_unfollow(
|
async fn send_unfollow(
|
||||||
&self,
|
&self,
|
||||||
_follow_actor_id: &Url,
|
_follow_actor_id: &Url,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -345,8 +325,7 @@ impl FromApub for CommunityForm {
|
||||||
/// Parse an ActivityPub group received from another instance into a Lemmy community.
|
/// Parse an ActivityPub group received from another instance into a Lemmy community.
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
group: &GroupExt,
|
group: &GroupExt,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<Self, LemmyError> {
|
) -> Result<Self, LemmyError> {
|
||||||
let creator_and_moderator_uris = group.inner.attributed_to().context(location_info!())?;
|
let creator_and_moderator_uris = group.inner.attributed_to().context(location_info!())?;
|
||||||
|
@ -359,7 +338,7 @@ impl FromApub for CommunityForm {
|
||||||
.as_xsd_any_uri()
|
.as_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let creator = get_or_fetch_and_upsert_user(creator_uri, client, pool).await?;
|
let creator = get_or_fetch_and_upsert_user(creator_uri, context).await?;
|
||||||
let name = group
|
let name = group
|
||||||
.inner
|
.inner
|
||||||
.name()
|
.name()
|
||||||
|
@ -437,15 +416,15 @@ impl FromApub for CommunityForm {
|
||||||
/// Return the community json over HTTP.
|
/// Return the community json over HTTP.
|
||||||
pub async fn get_apub_community_http(
|
pub async fn get_apub_community_http(
|
||||||
info: web::Path<CommunityQuery>,
|
info: web::Path<CommunityQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let community = blocking(&db, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_name(conn, &info.community_name)
|
Community::read_from_name(conn, &info.community_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
if !community.deleted {
|
if !community.deleted {
|
||||||
let apub = community.to_apub(&db).await?;
|
let apub = community.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
Ok(create_apub_response(&apub))
|
Ok(create_apub_response(&apub))
|
||||||
} else {
|
} else {
|
||||||
|
@ -456,22 +435,22 @@ pub 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 async fn get_apub_community_followers(
|
pub async fn get_apub_community_followers(
|
||||||
info: web::Path<CommunityQuery>,
|
info: web::Path<CommunityQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let community = blocking(&db, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_name(&conn, &info.community_name)
|
Community::read_from_name(&conn, &info.community_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let community_followers = blocking(&db, move |conn| {
|
let community_followers = blocking(context.pool(), move |conn| {
|
||||||
CommunityFollowerView::for_community(&conn, community_id)
|
CommunityFollowerView::for_community(&conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let mut collection = UnorderedCollection::new();
|
let mut collection = UnorderedCollection::new();
|
||||||
collection
|
collection
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(community.get_followers_url()?)
|
.set_id(community.get_followers_url()?)
|
||||||
.set_total_items(community_followers.len() as u64);
|
.set_total_items(community_followers.len() as u64);
|
||||||
Ok(create_apub_response(&collection))
|
Ok(create_apub_response(&collection))
|
||||||
|
@ -479,29 +458,29 @@ pub async fn get_apub_community_followers(
|
||||||
|
|
||||||
pub async fn get_apub_community_outbox(
|
pub async fn get_apub_community_outbox(
|
||||||
info: web::Path<CommunityQuery>,
|
info: web::Path<CommunityQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let community = blocking(&db, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_name(&conn, &info.community_name)
|
Community::read_from_name(&conn, &info.community_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let posts = blocking(&db, move |conn| {
|
let posts = blocking(context.pool(), move |conn| {
|
||||||
Post::list_for_community(conn, community_id)
|
Post::list_for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let mut pages: Vec<AnyBase> = vec![];
|
let mut pages: Vec<AnyBase> = vec![];
|
||||||
for p in posts {
|
for p in posts {
|
||||||
pages.push(p.to_apub(&db).await?.into_any_base()?);
|
pages.push(p.to_apub(context.pool()).await?.into_any_base()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let len = pages.len();
|
let len = pages.len();
|
||||||
let mut collection = OrderedCollection::new();
|
let mut collection = OrderedCollection::new();
|
||||||
collection
|
collection
|
||||||
.set_many_items(pages)
|
.set_many_items(pages)
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(community.get_outbox_url()?)
|
.set_id(community.get_outbox_url()?)
|
||||||
.set_total_items(len as u64);
|
.set_total_items(len as u64);
|
||||||
Ok(create_apub_response(&collection))
|
Ok(create_apub_response(&collection))
|
||||||
|
@ -511,19 +490,18 @@ pub async fn do_announce(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
community: &Community,
|
community: &Community,
|
||||||
sender: &User_,
|
sender: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let mut announce = Announce::new(community.actor_id.to_owned(), activity);
|
let mut announce = Announce::new(community.actor_id.to_owned(), activity);
|
||||||
announce
|
announce
|
||||||
.set_context(context())
|
.set_context(activitystreams::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![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
|
||||||
insert_activity(community.creator_id, announce.clone(), true, pool).await?;
|
insert_activity(community.creator_id, announce.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
let mut to: Vec<Url> = community.get_follower_inboxes(pool).await?;
|
let mut to: Vec<Url> = community.get_follower_inboxes(context.pool()).await?;
|
||||||
|
|
||||||
// dont send to the local instance, nor to the instance where the activity originally came from,
|
// dont send to the local instance, nor to the instance where the activity originally came from,
|
||||||
// because that would result in a database error (same data inserted twice)
|
// because that would result in a database error (same data inserted twice)
|
||||||
|
@ -533,7 +511,7 @@ pub async fn do_announce(
|
||||||
let community_shared_inbox = community.get_shared_inbox_url()?;
|
let community_shared_inbox = community.get_shared_inbox_url()?;
|
||||||
to.retain(|x| x != &community_shared_inbox);
|
to.retain(|x| x != &community_shared_inbox);
|
||||||
|
|
||||||
send_activity(client, &announce.into_any_base()?, community, to).await?;
|
send_activity(context.client(), &announce.into_any_base()?, community, to).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
request::{retry, RecvError},
|
request::{retry, RecvError},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{base::BaseExt, collection::OrderedCollection, object::Note, prelude::*};
|
use activitystreams::{base::BaseExt, collection::OrderedCollection, object::Note, prelude::*};
|
||||||
|
@ -92,8 +92,7 @@ pub enum SearchAcceptedObjects {
|
||||||
/// http://lemmy_alpha:8540/comment/2
|
/// http://lemmy_alpha:8540/comment/2
|
||||||
pub async fn search_by_apub_id(
|
pub async fn search_by_apub_id(
|
||||||
query: &str,
|
query: &str,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<SearchResponse, LemmyError> {
|
) -> Result<SearchResponse, LemmyError> {
|
||||||
// Parse the shorthand query url
|
// Parse the shorthand query url
|
||||||
let query_url = if query.contains('@') {
|
let query_url = if query.contains('@') {
|
||||||
|
@ -130,62 +129,74 @@ pub async fn search_by_apub_id(
|
||||||
};
|
};
|
||||||
|
|
||||||
let domain = query_url.domain().context("url has no domain")?;
|
let domain = query_url.domain().context("url has no domain")?;
|
||||||
let response = match fetch_remote_object::<SearchAcceptedObjects>(client, &query_url).await? {
|
let response =
|
||||||
SearchAcceptedObjects::Person(p) => {
|
match fetch_remote_object::<SearchAcceptedObjects>(context.client(), &query_url).await? {
|
||||||
let user_uri = p.inner.id(domain)?.context("person has no id")?;
|
SearchAcceptedObjects::Person(p) => {
|
||||||
|
let user_uri = p.inner.id(domain)?.context("person has no id")?;
|
||||||
|
|
||||||
let user = get_or_fetch_and_upsert_user(&user_uri, client, pool).await?;
|
let user = get_or_fetch_and_upsert_user(&user_uri, context).await?;
|
||||||
|
|
||||||
response.users =
|
response.users = vec![
|
||||||
vec![blocking(pool, move |conn| UserView::get_user_secure(conn, user.id)).await??];
|
blocking(context.pool(), move |conn| {
|
||||||
|
UserView::get_user_secure(conn, user.id)
|
||||||
|
})
|
||||||
|
.await??,
|
||||||
|
];
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
SearchAcceptedObjects::Group(g) => {
|
SearchAcceptedObjects::Group(g) => {
|
||||||
let community_uri = g.inner.id(domain)?.context("group has no id")?;
|
let community_uri = g.inner.id(domain)?.context("group has no id")?;
|
||||||
|
|
||||||
let community = get_or_fetch_and_upsert_community(community_uri, client, pool).await?;
|
let community = get_or_fetch_and_upsert_community(community_uri, context).await?;
|
||||||
|
|
||||||
response.communities = vec![
|
response.communities = vec![
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community.id, None)
|
CommunityView::read(conn, community.id, None)
|
||||||
|
})
|
||||||
|
.await??,
|
||||||
|
];
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
|
SearchAcceptedObjects::Page(p) => {
|
||||||
|
let post_form = PostForm::from_apub(&p, context, Some(query_url)).await?;
|
||||||
|
|
||||||
|
let p = blocking(context.pool(), move |conn| Post::upsert(conn, &post_form)).await??;
|
||||||
|
response.posts =
|
||||||
|
vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??];
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
|
SearchAcceptedObjects::Comment(c) => {
|
||||||
|
let comment_form = CommentForm::from_apub(&c, context, Some(query_url)).await?;
|
||||||
|
|
||||||
|
let c = blocking(context.pool(), move |conn| {
|
||||||
|
Comment::upsert(conn, &comment_form)
|
||||||
})
|
})
|
||||||
.await??,
|
.await??;
|
||||||
];
|
response.comments = vec![
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
CommentView::read(conn, c.id, None)
|
||||||
|
})
|
||||||
|
.await??,
|
||||||
|
];
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
SearchAcceptedObjects::Page(p) => {
|
};
|
||||||
let post_form = PostForm::from_apub(&p, client, pool, Some(query_url)).await?;
|
|
||||||
|
|
||||||
let p = blocking(pool, move |conn| Post::upsert(conn, &post_form)).await??;
|
|
||||||
response.posts = vec![blocking(pool, move |conn| PostView::read(conn, p.id, None)).await??];
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
|
||||||
SearchAcceptedObjects::Comment(c) => {
|
|
||||||
let comment_form = CommentForm::from_apub(&c, client, pool, Some(query_url)).await?;
|
|
||||||
|
|
||||||
let c = blocking(pool, move |conn| Comment::upsert(conn, &comment_form)).await??;
|
|
||||||
response.comments =
|
|
||||||
vec![blocking(pool, move |conn| CommentView::read(conn, c.id, None)).await??];
|
|
||||||
|
|
||||||
response
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_or_fetch_and_upsert_actor(
|
pub async fn get_or_fetch_and_upsert_actor(
|
||||||
apub_id: &Url,
|
apub_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Box<dyn ActorType>, LemmyError> {
|
) -> Result<Box<dyn ActorType>, LemmyError> {
|
||||||
let user = get_or_fetch_and_upsert_user(apub_id, client, pool).await;
|
let user = get_or_fetch_and_upsert_user(apub_id, context).await;
|
||||||
let actor: Box<dyn ActorType> = match user {
|
let actor: Box<dyn ActorType> = match user {
|
||||||
Ok(u) => Box::new(u),
|
Ok(u) => Box::new(u),
|
||||||
Err(_) => Box::new(get_or_fetch_and_upsert_community(apub_id, client, pool).await?),
|
Err(_) => Box::new(get_or_fetch_and_upsert_community(apub_id, context).await?),
|
||||||
};
|
};
|
||||||
Ok(actor)
|
Ok(actor)
|
||||||
}
|
}
|
||||||
|
@ -193,11 +204,10 @@ pub async fn get_or_fetch_and_upsert_actor(
|
||||||
/// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user.
|
/// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user.
|
||||||
pub async fn get_or_fetch_and_upsert_user(
|
pub async fn get_or_fetch_and_upsert_user(
|
||||||
apub_id: &Url,
|
apub_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<User_, LemmyError> {
|
) -> Result<User_, LemmyError> {
|
||||||
let apub_id_owned = apub_id.to_owned();
|
let apub_id_owned = apub_id.to_owned();
|
||||||
let user = blocking(pool, move |conn| {
|
let user = blocking(context.pool(), move |conn| {
|
||||||
User_::read_from_actor_id(conn, apub_id_owned.as_ref())
|
User_::read_from_actor_id(conn, apub_id_owned.as_ref())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -206,21 +216,21 @@ pub async fn get_or_fetch_and_upsert_user(
|
||||||
// If its older than a day, re-fetch it
|
// If its older than a day, re-fetch it
|
||||||
Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
|
Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
|
||||||
debug!("Fetching and updating from remote user: {}", apub_id);
|
debug!("Fetching and updating from remote user: {}", apub_id);
|
||||||
let person = fetch_remote_object::<PersonExt>(client, apub_id).await?;
|
let person = fetch_remote_object::<PersonExt>(context.client(), apub_id).await?;
|
||||||
|
|
||||||
let mut uf = UserForm::from_apub(&person, client, pool, Some(apub_id.to_owned())).await?;
|
let mut uf = UserForm::from_apub(&person, context, Some(apub_id.to_owned())).await?;
|
||||||
uf.last_refreshed_at = Some(naive_now());
|
uf.last_refreshed_at = Some(naive_now());
|
||||||
let user = blocking(pool, move |conn| User_::update(conn, u.id, &uf)).await??;
|
let user = blocking(context.pool(), move |conn| User_::update(conn, u.id, &uf)).await??;
|
||||||
|
|
||||||
Ok(user)
|
Ok(user)
|
||||||
}
|
}
|
||||||
Ok(u) => Ok(u),
|
Ok(u) => Ok(u),
|
||||||
Err(NotFound {}) => {
|
Err(NotFound {}) => {
|
||||||
debug!("Fetching and creating remote user: {}", apub_id);
|
debug!("Fetching and creating remote user: {}", apub_id);
|
||||||
let person = fetch_remote_object::<PersonExt>(client, apub_id).await?;
|
let person = fetch_remote_object::<PersonExt>(context.client(), apub_id).await?;
|
||||||
|
|
||||||
let uf = UserForm::from_apub(&person, client, pool, Some(apub_id.to_owned())).await?;
|
let uf = UserForm::from_apub(&person, context, Some(apub_id.to_owned())).await?;
|
||||||
let user = blocking(pool, move |conn| User_::create(conn, &uf)).await??;
|
let user = blocking(context.pool(), move |conn| User_::create(conn, &uf)).await??;
|
||||||
|
|
||||||
Ok(user)
|
Ok(user)
|
||||||
}
|
}
|
||||||
|
@ -246,11 +256,10 @@ fn should_refetch_actor(last_refreshed: NaiveDateTime) -> bool {
|
||||||
/// Check if a remote community exists, create if not found, if its too old update it.Fetch a community, insert/update it in the database and return the community.
|
/// Check if a remote community exists, create if not found, if its too old update it.Fetch a community, insert/update it in the database and return the community.
|
||||||
pub async fn get_or_fetch_and_upsert_community(
|
pub async fn get_or_fetch_and_upsert_community(
|
||||||
apub_id: &Url,
|
apub_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Community, LemmyError> {
|
) -> Result<Community, LemmyError> {
|
||||||
let apub_id_owned = apub_id.to_owned();
|
let apub_id_owned = apub_id.to_owned();
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, apub_id_owned.as_str())
|
Community::read_from_actor_id(conn, apub_id_owned.as_str())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -258,12 +267,12 @@ pub async fn get_or_fetch_and_upsert_community(
|
||||||
match community {
|
match community {
|
||||||
Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => {
|
Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => {
|
||||||
debug!("Fetching and updating from remote community: {}", apub_id);
|
debug!("Fetching and updating from remote community: {}", apub_id);
|
||||||
fetch_remote_community(apub_id, client, pool, Some(c.id)).await
|
fetch_remote_community(apub_id, context, Some(c.id)).await
|
||||||
}
|
}
|
||||||
Ok(c) => Ok(c),
|
Ok(c) => Ok(c),
|
||||||
Err(NotFound {}) => {
|
Err(NotFound {}) => {
|
||||||
debug!("Fetching and creating remote community: {}", apub_id);
|
debug!("Fetching and creating remote community: {}", apub_id);
|
||||||
fetch_remote_community(apub_id, client, pool, None).await
|
fetch_remote_community(apub_id, context, None).await
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
}
|
}
|
||||||
|
@ -271,14 +280,13 @@ pub async fn get_or_fetch_and_upsert_community(
|
||||||
|
|
||||||
async fn fetch_remote_community(
|
async fn fetch_remote_community(
|
||||||
apub_id: &Url,
|
apub_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
community_id: Option<i32>,
|
community_id: Option<i32>,
|
||||||
) -> Result<Community, LemmyError> {
|
) -> Result<Community, LemmyError> {
|
||||||
let group = fetch_remote_object::<GroupExt>(client, apub_id).await?;
|
let group = fetch_remote_object::<GroupExt>(context.client(), apub_id).await?;
|
||||||
|
|
||||||
let cf = CommunityForm::from_apub(&group, client, pool, Some(apub_id.to_owned())).await?;
|
let cf = CommunityForm::from_apub(&group, context, Some(apub_id.to_owned())).await?;
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
if let Some(cid) = community_id {
|
if let Some(cid) = community_id {
|
||||||
Community::update(conn, cid, &cf)
|
Community::update(conn, cid, &cf)
|
||||||
} else {
|
} else {
|
||||||
|
@ -299,7 +307,7 @@ async fn fetch_remote_community(
|
||||||
let mut creator_and_moderators = Vec::new();
|
let mut creator_and_moderators = Vec::new();
|
||||||
|
|
||||||
for uri in creator_and_moderator_uris {
|
for uri in creator_and_moderator_uris {
|
||||||
let c_or_m = get_or_fetch_and_upsert_user(uri, client, pool).await?;
|
let c_or_m = get_or_fetch_and_upsert_user(uri, context).await?;
|
||||||
|
|
||||||
creator_and_moderators.push(c_or_m);
|
creator_and_moderators.push(c_or_m);
|
||||||
}
|
}
|
||||||
|
@ -307,7 +315,7 @@ async fn fetch_remote_community(
|
||||||
// TODO: need to make this work to update mods of existing communities
|
// TODO: need to make this work to update mods of existing communities
|
||||||
if community_id.is_none() {
|
if community_id.is_none() {
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
for mod_ in creator_and_moderators {
|
for mod_ in creator_and_moderators {
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
community_id,
|
community_id,
|
||||||
|
@ -323,7 +331,8 @@ async fn fetch_remote_community(
|
||||||
|
|
||||||
// fetch outbox (maybe make this conditional)
|
// fetch outbox (maybe make this conditional)
|
||||||
let outbox =
|
let outbox =
|
||||||
fetch_remote_object::<OrderedCollection>(client, &community.get_outbox_url()?).await?;
|
fetch_remote_object::<OrderedCollection>(context.client(), &community.get_outbox_url()?)
|
||||||
|
.await?;
|
||||||
let outbox_items = outbox.items().context(location_info!())?.clone();
|
let outbox_items = outbox.items().context(location_info!())?.clone();
|
||||||
let mut outbox_items = outbox_items.many().context(location_info!())?;
|
let mut outbox_items = outbox_items.many().context(location_info!())?;
|
||||||
if outbox_items.len() > 20 {
|
if outbox_items.len() > 20 {
|
||||||
|
@ -331,13 +340,16 @@ async fn fetch_remote_community(
|
||||||
}
|
}
|
||||||
for o in outbox_items {
|
for o in outbox_items {
|
||||||
let page = PageExt::from_any_base(o)?.context(location_info!())?;
|
let page = PageExt::from_any_base(o)?.context(location_info!())?;
|
||||||
let post = PostForm::from_apub(&page, client, pool, None).await?;
|
let post = PostForm::from_apub(&page, context, None).await?;
|
||||||
let post_ap_id = post.ap_id.clone();
|
let post_ap_id = post.ap_id.clone();
|
||||||
// Check whether the post already exists in the local db
|
// Check whether the post already exists in the local db
|
||||||
let existing = blocking(pool, move |conn| Post::read_from_apub_id(conn, &post_ap_id)).await?;
|
let existing = blocking(context.pool(), move |conn| {
|
||||||
|
Post::read_from_apub_id(conn, &post_ap_id)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
match existing {
|
match existing {
|
||||||
Ok(e) => blocking(pool, move |conn| Post::update(conn, e.id, &post)).await??,
|
Ok(e) => blocking(context.pool(), move |conn| Post::update(conn, e.id, &post)).await??,
|
||||||
Err(_) => blocking(pool, move |conn| Post::create(conn, &post)).await??,
|
Err(_) => blocking(context.pool(), move |conn| Post::create(conn, &post)).await??,
|
||||||
};
|
};
|
||||||
// TODO: we need to send a websocket update here
|
// TODO: we need to send a websocket update here
|
||||||
}
|
}
|
||||||
|
@ -347,11 +359,10 @@ async fn fetch_remote_community(
|
||||||
|
|
||||||
pub async fn get_or_fetch_and_insert_post(
|
pub async fn get_or_fetch_and_insert_post(
|
||||||
post_ap_id: &Url,
|
post_ap_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Post, LemmyError> {
|
) -> Result<Post, LemmyError> {
|
||||||
let post_ap_id_owned = post_ap_id.to_owned();
|
let post_ap_id_owned = post_ap_id.to_owned();
|
||||||
let post = blocking(pool, move |conn| {
|
let post = blocking(context.pool(), move |conn| {
|
||||||
Post::read_from_apub_id(conn, post_ap_id_owned.as_str())
|
Post::read_from_apub_id(conn, post_ap_id_owned.as_str())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -360,10 +371,10 @@ pub async fn get_or_fetch_and_insert_post(
|
||||||
Ok(p) => Ok(p),
|
Ok(p) => Ok(p),
|
||||||
Err(NotFound {}) => {
|
Err(NotFound {}) => {
|
||||||
debug!("Fetching and creating remote post: {}", post_ap_id);
|
debug!("Fetching and creating remote post: {}", post_ap_id);
|
||||||
let post = fetch_remote_object::<PageExt>(client, post_ap_id).await?;
|
let post = fetch_remote_object::<PageExt>(context.client(), post_ap_id).await?;
|
||||||
let post_form = PostForm::from_apub(&post, client, pool, Some(post_ap_id.to_owned())).await?;
|
let post_form = PostForm::from_apub(&post, context, Some(post_ap_id.to_owned())).await?;
|
||||||
|
|
||||||
let post = blocking(pool, move |conn| Post::create(conn, &post_form)).await??;
|
let post = blocking(context.pool(), move |conn| Post::create(conn, &post_form)).await??;
|
||||||
|
|
||||||
Ok(post)
|
Ok(post)
|
||||||
}
|
}
|
||||||
|
@ -373,11 +384,10 @@ pub async fn get_or_fetch_and_insert_post(
|
||||||
|
|
||||||
pub async fn get_or_fetch_and_insert_comment(
|
pub async fn get_or_fetch_and_insert_comment(
|
||||||
comment_ap_id: &Url,
|
comment_ap_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Comment, LemmyError> {
|
) -> Result<Comment, LemmyError> {
|
||||||
let comment_ap_id_owned = comment_ap_id.to_owned();
|
let comment_ap_id_owned = comment_ap_id.to_owned();
|
||||||
let comment = blocking(pool, move |conn| {
|
let comment = blocking(context.pool(), move |conn| {
|
||||||
Comment::read_from_apub_id(conn, comment_ap_id_owned.as_str())
|
Comment::read_from_apub_id(conn, comment_ap_id_owned.as_str())
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -389,11 +399,14 @@ pub async fn get_or_fetch_and_insert_comment(
|
||||||
"Fetching and creating remote comment and its parents: {}",
|
"Fetching and creating remote comment and its parents: {}",
|
||||||
comment_ap_id
|
comment_ap_id
|
||||||
);
|
);
|
||||||
let comment = fetch_remote_object::<Note>(client, comment_ap_id).await?;
|
let comment = fetch_remote_object::<Note>(context.client(), comment_ap_id).await?;
|
||||||
let comment_form =
|
let comment_form =
|
||||||
CommentForm::from_apub(&comment, client, pool, Some(comment_ap_id.to_owned())).await?;
|
CommentForm::from_apub(&comment, context, Some(comment_ap_id.to_owned())).await?;
|
||||||
|
|
||||||
let comment = blocking(pool, move |conn| Comment::create(conn, &comment_form)).await??;
|
let comment = blocking(context.pool(), move |conn| {
|
||||||
|
Comment::create(conn, &comment_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
Ok(comment)
|
Ok(comment)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
shared_inbox::{get_community_id_from_activity, receive_unhandled_activity},
|
shared_inbox::{get_community_id_from_activity, receive_unhandled_activity},
|
||||||
},
|
},
|
||||||
routes::ChatServerParam,
|
LemmyContext,
|
||||||
DbPool,
|
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -20,15 +19,13 @@ use activitystreams::{
|
||||||
base::{AnyBase, BaseExt},
|
base::{AnyBase, BaseExt},
|
||||||
prelude::ExtendsExt,
|
prelude::ExtendsExt,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_utils::location_info;
|
use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_announce(
|
pub async fn receive_announce(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let announce = Announce::from_any_base(activity)?.context(location_info!())?;
|
let announce = Announce::from_any_base(activity)?.context(location_info!())?;
|
||||||
|
|
||||||
|
@ -40,13 +37,13 @@ pub async fn receive_announce(
|
||||||
let object = announce.object();
|
let object = announce.object();
|
||||||
let object2 = object.clone().one().context(location_info!())?;
|
let object2 = object.clone().one().context(location_info!())?;
|
||||||
match kind {
|
match kind {
|
||||||
Some("Create") => receive_create(object2, client, pool, chat_server).await,
|
Some("Create") => receive_create(object2, context).await,
|
||||||
Some("Update") => receive_update(object2, client, pool, chat_server).await,
|
Some("Update") => receive_update(object2, context).await,
|
||||||
Some("Like") => receive_like(object2, client, pool, chat_server).await,
|
Some("Like") => receive_like(object2, context).await,
|
||||||
Some("Dislike") => receive_dislike(object2, client, pool, chat_server).await,
|
Some("Dislike") => receive_dislike(object2, context).await,
|
||||||
Some("Delete") => receive_delete(object2, client, pool, chat_server).await,
|
Some("Delete") => receive_delete(object2, context).await,
|
||||||
Some("Remove") => receive_remove(object2, client, pool, chat_server).await,
|
Some("Remove") => receive_remove(object2, context).await,
|
||||||
Some("Undo") => receive_undo(object2, client, pool, chat_server).await,
|
Some("Undo") => receive_undo(object2, context).await,
|
||||||
_ => receive_unhandled_activity(announce),
|
_ => receive_unhandled_activity(announce),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendPost},
|
server::{SendComment, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Create, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Create, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
@ -35,85 +34,87 @@ use lemmy_utils::{location_info, scrape_text_for_mentions};
|
||||||
|
|
||||||
pub async fn receive_create(
|
pub async fn receive_create(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
||||||
|
|
||||||
// ensure that create and actor come from the same instance
|
// ensure that create and actor come from the same instance
|
||||||
let user = get_user_from_activity(&create, client, pool).await?;
|
let user = get_user_from_activity(&create, context).await?;
|
||||||
create.id(user.actor_id()?.domain().context(location_info!())?)?;
|
create.id(user.actor_id()?.domain().context(location_info!())?)?;
|
||||||
|
|
||||||
match create.object().as_single_kind_str() {
|
match create.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_create_post(create, client, pool, chat_server).await,
|
Some("Page") => receive_create_post(create, context).await,
|
||||||
Some("Note") => receive_create_comment(create, client, pool, chat_server).await,
|
Some("Note") => receive_create_comment(create, context).await,
|
||||||
_ => receive_unhandled_activity(create),
|
_ => receive_unhandled_activity(create),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_create_post(
|
async fn receive_create_post(
|
||||||
create: Create,
|
create: Create,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&create, client, pool).await?;
|
let user = get_user_from_activity(&create, context).await?;
|
||||||
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 = PostForm::from_apub(&page, client, pool, Some(user.actor_id()?)).await?;
|
let post = PostForm::from_apub(&page, context, Some(user.actor_id()?)).await?;
|
||||||
|
|
||||||
// Using an upsert, since likes (which fetch the post), sometimes come in before the create
|
// Using an upsert, since likes (which fetch the post), sometimes come in before the create
|
||||||
// resulting in double posts.
|
// resulting in double posts.
|
||||||
let inserted_post = blocking(pool, move |conn| Post::upsert(conn, &post)).await??;
|
let inserted_post = blocking(context.pool(), move |conn| Post::upsert(conn, &post)).await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let inserted_post_id = inserted_post.id;
|
let inserted_post_id = inserted_post.id;
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, inserted_post_id, None)
|
PostView::read(conn, inserted_post_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::CreatePost,
|
op: UserOperation::CreatePost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(create, &user, client, pool).await?;
|
announce_if_community_is_local(create, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_create_comment(
|
async fn receive_create_comment(
|
||||||
create: Create,
|
create: Create,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&create, client, pool).await?;
|
let user = get_user_from_activity(&create, context).await?;
|
||||||
let note = Note::from_any_base(create.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(create.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, Some(user.actor_id()?)).await?;
|
let comment = CommentForm::from_apub(¬e, context, Some(user.actor_id()?)).await?;
|
||||||
|
|
||||||
let inserted_comment = blocking(pool, move |conn| Comment::upsert(conn, &comment)).await??;
|
let inserted_comment =
|
||||||
|
blocking(context.pool(), move |conn| Comment::upsert(conn, &comment)).await??;
|
||||||
|
|
||||||
let post_id = inserted_comment.post_id;
|
let post_id = inserted_comment.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
// Note:
|
// Note:
|
||||||
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
||||||
// Its much easier to scrape them from the comment body, since the API has to do that
|
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||||
// anyway.
|
// anyway.
|
||||||
let mentions = scrape_text_for_mentions(&inserted_comment.content);
|
let mentions = scrape_text_for_mentions(&inserted_comment.content);
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, inserted_comment.clone(), &user, post, pool, true).await?;
|
mentions,
|
||||||
|
inserted_comment.clone(),
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, inserted_comment.id, None)
|
CommentView::read(conn, inserted_comment.id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -124,12 +125,12 @@ async fn receive_create_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::CreateComment,
|
op: UserOperation::CreateComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(create, &user, client, pool).await?;
|
announce_if_community_is_local(create, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
@ -38,34 +37,30 @@ use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_delete(
|
pub async fn receive_delete(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let delete = Delete::from_any_base(activity)?.context(location_info!())?;
|
let delete = Delete::from_any_base(activity)?.context(location_info!())?;
|
||||||
match delete.object().as_single_kind_str() {
|
match delete.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_delete_post(delete, client, pool, chat_server).await,
|
Some("Page") => receive_delete_post(delete, context).await,
|
||||||
Some("Note") => receive_delete_comment(delete, client, pool, chat_server).await,
|
Some("Note") => receive_delete_comment(delete, context).await,
|
||||||
Some("Group") => receive_delete_community(delete, client, pool, chat_server).await,
|
Some("Group") => receive_delete_community(delete, context).await,
|
||||||
_ => receive_unhandled_activity(delete),
|
_ => receive_unhandled_activity(delete),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_delete_post(
|
async fn receive_delete_post(
|
||||||
delete: Delete,
|
delete: Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&delete, client, pool).await?;
|
let user = get_user_from_activity(&delete, context).await?;
|
||||||
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post_ap_id = PostForm::from_apub(&page, client, pool, Some(user.actor_id()?))
|
let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
|
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: post.name.to_owned(),
|
name: post.name.to_owned(),
|
||||||
|
@ -88,39 +83,43 @@ async fn receive_delete_post(
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
Post::update(conn, post_id, &post_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::EditPost,
|
op: UserOperation::EditPost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(delete, &user, client, pool).await?;
|
announce_if_community_is_local(delete, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_delete_comment(
|
async fn receive_delete_comment(
|
||||||
delete: Delete,
|
delete: Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&delete, client, pool).await?;
|
let user = get_user_from_activity(&delete, context).await?;
|
||||||
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment_ap_id = CommentForm::from_apub(¬e, client, pool, Some(user.actor_id()?))
|
let comment_ap_id = CommentForm::from_apub(¬e, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
|
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
|
||||||
|
|
||||||
let comment_form = CommentForm {
|
let comment_form = CommentForm {
|
||||||
content: comment.content.to_owned(),
|
content: comment.content.to_owned(),
|
||||||
|
@ -136,15 +135,17 @@ async fn receive_delete_comment(
|
||||||
local: comment.local,
|
local: comment.local,
|
||||||
};
|
};
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Comment::update(conn, comment_id, &comment_form)
|
Comment::update(conn, comment_id, &comment_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -154,31 +155,29 @@ async fn receive_delete_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::EditComment,
|
op: UserOperation::EditComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(delete, &user, client, pool).await?;
|
announce_if_community_is_local(delete, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_delete_community(
|
async fn receive_delete_community(
|
||||||
delete: Delete,
|
delete: Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let user = get_user_from_activity(&delete, client, pool).await?;
|
let user = get_user_from_activity(&delete, context).await?;
|
||||||
|
|
||||||
let community_actor_id = CommunityForm::from_apub(&group, client, pool, Some(user.actor_id()?))
|
let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.actor_id;
|
.actor_id;
|
||||||
|
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, &community_actor_id)
|
Community::read_from_actor_id(conn, &community_actor_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -204,14 +203,14 @@ async fn receive_delete_community(
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, community_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let res = CommunityResponse {
|
let res = CommunityResponse {
|
||||||
community: blocking(pool, move |conn| {
|
community: blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, None)
|
CommunityView::read(conn, community_id, None)
|
||||||
})
|
})
|
||||||
.await??,
|
.await??,
|
||||||
|
@ -219,13 +218,13 @@ async fn receive_delete_community(
|
||||||
|
|
||||||
let community_id = res.community.id;
|
let community_id = res.community.id;
|
||||||
|
|
||||||
chat_server.do_send(SendCommunityRoomMessage {
|
context.chat_server().do_send(SendCommunityRoomMessage {
|
||||||
op: UserOperation::EditCommunity,
|
op: UserOperation::EditCommunity,
|
||||||
response: res,
|
response: res,
|
||||||
community_id,
|
community_id,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(delete, &user, client, pool).await?;
|
announce_if_community_is_local(delete, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendPost},
|
server::{SendComment, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Dislike, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Dislike, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{CommentForm, CommentLike, CommentLikeForm},
|
comment::{CommentForm, CommentLike, CommentLikeForm},
|
||||||
|
@ -33,25 +32,21 @@ use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_dislike(
|
pub async fn receive_dislike(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let dislike = Dislike::from_any_base(activity)?.context(location_info!())?;
|
let dislike = Dislike::from_any_base(activity)?.context(location_info!())?;
|
||||||
match dislike.object().as_single_kind_str() {
|
match dislike.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_dislike_post(dislike, client, pool, chat_server).await,
|
Some("Page") => receive_dislike_post(dislike, context).await,
|
||||||
Some("Note") => receive_dislike_comment(dislike, client, pool, chat_server).await,
|
Some("Note") => receive_dislike_comment(dislike, context).await,
|
||||||
_ => receive_unhandled_activity(dislike),
|
_ => receive_unhandled_activity(dislike),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_dislike_post(
|
async fn receive_dislike_post(
|
||||||
dislike: Dislike,
|
dislike: Dislike,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&dislike, client, pool).await?;
|
let user = get_user_from_activity(&dislike, context).await?;
|
||||||
let page = PageExt::from_any_base(
|
let page = PageExt::from_any_base(
|
||||||
dislike
|
dislike
|
||||||
.object()
|
.object()
|
||||||
|
@ -61,9 +56,9 @@ async fn receive_dislike_post(
|
||||||
)?
|
)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post = PostForm::from_apub(&page, client, pool, None).await?;
|
let post = PostForm::from_apub(&page, context, None).await?;
|
||||||
|
|
||||||
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
|
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
|
@ -73,32 +68,33 @@ async fn receive_dislike_post(
|
||||||
score: -1,
|
score: -1,
|
||||||
};
|
};
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
PostLike::remove(conn, user_id, post_id)?;
|
PostLike::remove(conn, user_id, post_id)?;
|
||||||
PostLike::like(conn, &like_form)
|
PostLike::like(conn, &like_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::CreatePostLike,
|
op: UserOperation::CreatePostLike,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(dislike, &user, client, pool).await?;
|
announce_if_community_is_local(dislike, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_dislike_comment(
|
async fn receive_dislike_comment(
|
||||||
dislike: Dislike,
|
dislike: Dislike,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let note = Note::from_any_base(
|
let note = Note::from_any_base(
|
||||||
dislike
|
dislike
|
||||||
|
@ -108,11 +104,11 @@ async fn receive_dislike_comment(
|
||||||
.context(location_info!())?,
|
.context(location_info!())?,
|
||||||
)?
|
)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let user = get_user_from_activity(&dislike, client, pool).await?;
|
let user = get_user_from_activity(&dislike, context).await?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, None).await?;
|
let comment = CommentForm::from_apub(¬e, context, None).await?;
|
||||||
|
|
||||||
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
|
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
|
@ -123,15 +119,17 @@ async fn receive_dislike_comment(
|
||||||
score: -1,
|
score: -1,
|
||||||
};
|
};
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommentLike::remove(conn, user_id, comment_id)?;
|
CommentLike::remove(conn, user_id, comment_id)?;
|
||||||
CommentLike::like(conn, &like_form)
|
CommentLike::like(conn, &like_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -141,12 +139,12 @@ async fn receive_dislike_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::CreateCommentLike,
|
op: UserOperation::CreateCommentLike,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(dislike, &user, client, pool).await?;
|
announce_if_community_is_local(dislike, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendPost},
|
server::{SendComment, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{CommentForm, CommentLike, CommentLikeForm},
|
comment::{CommentForm, CommentLike, CommentLikeForm},
|
||||||
|
@ -33,31 +32,24 @@ use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_like(
|
pub async fn receive_like(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let like = Like::from_any_base(activity)?.context(location_info!())?;
|
let like = Like::from_any_base(activity)?.context(location_info!())?;
|
||||||
match like.object().as_single_kind_str() {
|
match like.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_like_post(like, client, pool, chat_server).await,
|
Some("Page") => receive_like_post(like, context).await,
|
||||||
Some("Note") => receive_like_comment(like, client, pool, chat_server).await,
|
Some("Note") => receive_like_comment(like, context).await,
|
||||||
_ => receive_unhandled_activity(like),
|
_ => receive_unhandled_activity(like),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_like_post(
|
async fn receive_like_post(like: Like, context: &LemmyContext) -> Result<HttpResponse, LemmyError> {
|
||||||
like: Like,
|
let user = get_user_from_activity(&like, context).await?;
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
|
||||||
let user = get_user_from_activity(&like, client, pool).await?;
|
|
||||||
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post = PostForm::from_apub(&page, client, pool, None).await?;
|
let post = PostForm::from_apub(&page, context, None).await?;
|
||||||
|
|
||||||
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
|
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
|
@ -67,40 +59,41 @@ async fn receive_like_post(
|
||||||
score: 1,
|
score: 1,
|
||||||
};
|
};
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
PostLike::remove(conn, user_id, post_id)?;
|
PostLike::remove(conn, user_id, post_id)?;
|
||||||
PostLike::like(conn, &like_form)
|
PostLike::like(conn, &like_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::CreatePostLike,
|
op: UserOperation::CreatePostLike,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(like, &user, client, pool).await?;
|
announce_if_community_is_local(like, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_like_comment(
|
async fn receive_like_comment(
|
||||||
like: Like,
|
like: Like,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let note = Note::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let user = get_user_from_activity(&like, client, pool).await?;
|
let user = get_user_from_activity(&like, context).await?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, None).await?;
|
let comment = CommentForm::from_apub(¬e, context, None).await?;
|
||||||
|
|
||||||
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
|
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
|
@ -111,15 +104,17 @@ async fn receive_like_comment(
|
||||||
score: 1,
|
score: 1,
|
||||||
};
|
};
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommentLike::remove(conn, user_id, comment_id)?;
|
CommentLike::remove(conn, user_id, comment_id)?;
|
||||||
CommentLike::like(conn, &like_form)
|
CommentLike::like(conn, &like_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -129,12 +124,12 @@ async fn receive_like_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::CreateCommentLike,
|
op: UserOperation::CreateCommentLike,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(like, &user, client, pool).await?;
|
announce_if_community_is_local(like, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
@ -39,40 +38,36 @@ use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_remove(
|
pub async fn receive_remove(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let remove = Remove::from_any_base(activity)?.context(location_info!())?;
|
let remove = Remove::from_any_base(activity)?.context(location_info!())?;
|
||||||
let actor = get_user_from_activity(&remove, client, pool).await?;
|
let actor = get_user_from_activity(&remove, context).await?;
|
||||||
let community = get_community_id_from_activity(&remove)?;
|
let community = get_community_id_from_activity(&remove)?;
|
||||||
if actor.actor_id()?.domain() != community.domain() {
|
if actor.actor_id()?.domain() != community.domain() {
|
||||||
return Err(anyhow!("Remove activities are only allowed on local objects").into());
|
return Err(anyhow!("Remove activities are only allowed on local objects").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
match remove.object().as_single_kind_str() {
|
match remove.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_remove_post(remove, client, pool, chat_server).await,
|
Some("Page") => receive_remove_post(remove, context).await,
|
||||||
Some("Note") => receive_remove_comment(remove, client, pool, chat_server).await,
|
Some("Note") => receive_remove_comment(remove, context).await,
|
||||||
Some("Group") => receive_remove_community(remove, client, pool, chat_server).await,
|
Some("Group") => receive_remove_community(remove, context).await,
|
||||||
_ => receive_unhandled_activity(remove),
|
_ => receive_unhandled_activity(remove),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_remove_post(
|
async fn receive_remove_post(
|
||||||
remove: Remove,
|
remove: Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(&remove, client, pool).await?;
|
let mod_ = get_user_from_activity(&remove, context).await?;
|
||||||
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post_ap_id = PostForm::from_apub(&page, client, pool, None)
|
let post_ap_id = PostForm::from_apub(&page, context, None)
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
|
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: post.name.to_owned(),
|
name: post.name.to_owned(),
|
||||||
|
@ -95,39 +90,43 @@ async fn receive_remove_post(
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
Post::update(conn, post_id, &post_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::EditPost,
|
op: UserOperation::EditPost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(remove, &mod_, client, pool).await?;
|
announce_if_community_is_local(remove, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_remove_comment(
|
async fn receive_remove_comment(
|
||||||
remove: Remove,
|
remove: Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(&remove, client, pool).await?;
|
let mod_ = get_user_from_activity(&remove, context).await?;
|
||||||
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment_ap_id = CommentForm::from_apub(¬e, client, pool, None)
|
let comment_ap_id = CommentForm::from_apub(¬e, context, None)
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
|
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
|
||||||
|
|
||||||
let comment_form = CommentForm {
|
let comment_form = CommentForm {
|
||||||
content: comment.content.to_owned(),
|
content: comment.content.to_owned(),
|
||||||
|
@ -143,15 +142,17 @@ async fn receive_remove_comment(
|
||||||
local: comment.local,
|
local: comment.local,
|
||||||
};
|
};
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Comment::update(conn, comment_id, &comment_form)
|
Comment::update(conn, comment_id, &comment_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -161,31 +162,29 @@ async fn receive_remove_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::EditComment,
|
op: UserOperation::EditComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(remove, &mod_, client, pool).await?;
|
announce_if_community_is_local(remove, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_remove_community(
|
async fn receive_remove_community(
|
||||||
remove: Remove,
|
remove: Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(&remove, client, pool).await?;
|
let mod_ = get_user_from_activity(&remove, context).await?;
|
||||||
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let community_actor_id = CommunityForm::from_apub(&group, client, pool, Some(mod_.actor_id()?))
|
let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.actor_id;
|
.actor_id;
|
||||||
|
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, &community_actor_id)
|
Community::read_from_actor_id(conn, &community_actor_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -211,14 +210,14 @@ async fn receive_remove_community(
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, community_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let res = CommunityResponse {
|
let res = CommunityResponse {
|
||||||
community: blocking(pool, move |conn| {
|
community: blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, None)
|
CommunityView::read(conn, community_id, None)
|
||||||
})
|
})
|
||||||
.await??,
|
.await??,
|
||||||
|
@ -226,13 +225,13 @@ async fn receive_remove_community(
|
||||||
|
|
||||||
let community_id = res.community.id;
|
let community_id = res.community.id;
|
||||||
|
|
||||||
chat_server.do_send(SendCommunityRoomMessage {
|
context.chat_server().do_send(SendCommunityRoomMessage {
|
||||||
op: UserOperation::EditCommunity,
|
op: UserOperation::EditCommunity,
|
||||||
response: res,
|
response: res,
|
||||||
community_id,
|
community_id,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(remove, &mod_, client, pool).await?;
|
announce_if_community_is_local(remove, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,11 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
server::{SendComment, SendCommunityRoomMessage, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -27,7 +26,7 @@ use activitystreams::{
|
||||||
object::Note,
|
object::Note,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm, CommentLike},
|
comment::{Comment, CommentForm, CommentLike},
|
||||||
|
@ -44,16 +43,14 @@ use lemmy_utils::location_info;
|
||||||
|
|
||||||
pub async fn receive_undo(
|
pub async fn receive_undo(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
||||||
match undo.object().as_single_kind_str() {
|
match undo.object().as_single_kind_str() {
|
||||||
Some("Delete") => receive_undo_delete(undo, client, pool, chat_server).await,
|
Some("Delete") => receive_undo_delete(undo, context).await,
|
||||||
Some("Remove") => receive_undo_remove(undo, client, pool, chat_server).await,
|
Some("Remove") => receive_undo_remove(undo, context).await,
|
||||||
Some("Like") => receive_undo_like(undo, client, pool, chat_server).await,
|
Some("Like") => receive_undo_like(undo, context).await,
|
||||||
Some("Dislike") => receive_undo_dislike(undo, client, pool, chat_server).await,
|
Some("Dislike") => receive_undo_dislike(undo, context).await,
|
||||||
_ => receive_unhandled_activity(undo),
|
_ => receive_unhandled_activity(undo),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,9 +78,7 @@ where
|
||||||
|
|
||||||
async fn receive_undo_delete(
|
async fn receive_undo_delete(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
let delete = Delete::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
@ -93,18 +88,16 @@ async fn receive_undo_delete(
|
||||||
.as_single_kind_str()
|
.as_single_kind_str()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match type_ {
|
match type_ {
|
||||||
"Note" => receive_undo_delete_comment(undo, &delete, client, pool, chat_server).await,
|
"Note" => receive_undo_delete_comment(undo, &delete, context).await,
|
||||||
"Page" => receive_undo_delete_post(undo, &delete, client, pool, chat_server).await,
|
"Page" => receive_undo_delete_post(undo, &delete, context).await,
|
||||||
"Group" => receive_undo_delete_community(undo, &delete, client, pool, chat_server).await,
|
"Group" => receive_undo_delete_community(undo, &delete, context).await,
|
||||||
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_remove(
|
async fn receive_undo_remove(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let remove = Remove::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
let remove = Remove::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
@ -115,19 +108,14 @@ async fn receive_undo_remove(
|
||||||
.as_single_kind_str()
|
.as_single_kind_str()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match type_ {
|
match type_ {
|
||||||
"Note" => receive_undo_remove_comment(undo, &remove, client, pool, chat_server).await,
|
"Note" => receive_undo_remove_comment(undo, &remove, context).await,
|
||||||
"Page" => receive_undo_remove_post(undo, &remove, client, pool, chat_server).await,
|
"Page" => receive_undo_remove_post(undo, &remove, context).await,
|
||||||
"Group" => receive_undo_remove_community(undo, &remove, client, pool, chat_server).await,
|
"Group" => receive_undo_remove_community(undo, &remove, context).await,
|
||||||
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_like(
|
async fn receive_undo_like(undo: Undo, context: &LemmyContext) -> Result<HttpResponse, LemmyError> {
|
||||||
undo: Undo,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
|
||||||
let like = Like::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
let like = Like::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
check_is_undo_valid(&undo, &like)?;
|
check_is_undo_valid(&undo, &like)?;
|
||||||
|
@ -137,17 +125,15 @@ async fn receive_undo_like(
|
||||||
.as_single_kind_str()
|
.as_single_kind_str()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match type_ {
|
match type_ {
|
||||||
"Note" => receive_undo_like_comment(undo, &like, client, pool, chat_server).await,
|
"Note" => receive_undo_like_comment(undo, &like, context).await,
|
||||||
"Page" => receive_undo_like_post(undo, &like, client, pool, chat_server).await,
|
"Page" => receive_undo_like_post(undo, &like, context).await,
|
||||||
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_dislike(
|
async fn receive_undo_dislike(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let dislike = Dislike::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
let dislike = Dislike::from_any_base(undo.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
@ -158,8 +144,8 @@ async fn receive_undo_dislike(
|
||||||
.as_single_kind_str()
|
.as_single_kind_str()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
match type_ {
|
match type_ {
|
||||||
"Note" => receive_undo_dislike_comment(undo, &dislike, client, pool, chat_server).await,
|
"Note" => receive_undo_dislike_comment(undo, &dislike, context).await,
|
||||||
"Page" => receive_undo_dislike_post(undo, &dislike, client, pool, chat_server).await,
|
"Page" => receive_undo_dislike_post(undo, &dislike, context).await,
|
||||||
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
d => Err(anyhow!("Undo Delete type {} not supported", d).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,19 +153,17 @@ async fn receive_undo_dislike(
|
||||||
async fn receive_undo_delete_comment(
|
async fn receive_undo_delete_comment(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
delete: &Delete,
|
delete: &Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(delete, client, pool).await?;
|
let user = get_user_from_activity(delete, context).await?;
|
||||||
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment_ap_id = CommentForm::from_apub(¬e, client, pool, Some(user.actor_id()?))
|
let comment_ap_id = CommentForm::from_apub(¬e, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
|
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
|
||||||
|
|
||||||
let comment_form = CommentForm {
|
let comment_form = CommentForm {
|
||||||
content: comment.content.to_owned(),
|
content: comment.content.to_owned(),
|
||||||
|
@ -195,15 +179,17 @@ async fn receive_undo_delete_comment(
|
||||||
local: comment.local,
|
local: comment.local,
|
||||||
};
|
};
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Comment::update(conn, comment_id, &comment_form)
|
Comment::update(conn, comment_id, &comment_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -213,32 +199,30 @@ async fn receive_undo_delete_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::EditComment,
|
op: UserOperation::EditComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_remove_comment(
|
async fn receive_undo_remove_comment(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
remove: &Remove,
|
remove: &Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(remove, client, pool).await?;
|
let mod_ = get_user_from_activity(remove, context).await?;
|
||||||
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment_ap_id = CommentForm::from_apub(¬e, client, pool, None)
|
let comment_ap_id = CommentForm::from_apub(¬e, context, None)
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, client, pool).await?;
|
let comment = get_or_fetch_and_insert_comment(&comment_ap_id, context).await?;
|
||||||
|
|
||||||
let comment_form = CommentForm {
|
let comment_form = CommentForm {
|
||||||
content: comment.content.to_owned(),
|
content: comment.content.to_owned(),
|
||||||
|
@ -254,15 +238,17 @@ async fn receive_undo_remove_comment(
|
||||||
local: comment.local,
|
local: comment.local,
|
||||||
};
|
};
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Comment::update(conn, comment_id, &comment_form)
|
Comment::update(conn, comment_id, &comment_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_id = comment.id;
|
let comment_id = comment.id;
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -272,32 +258,30 @@ async fn receive_undo_remove_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::EditComment,
|
op: UserOperation::EditComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &mod_, client, pool).await?;
|
announce_if_community_is_local(undo, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_delete_post(
|
async fn receive_undo_delete_post(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
delete: &Delete,
|
delete: &Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(delete, client, pool).await?;
|
let user = get_user_from_activity(delete, context).await?;
|
||||||
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post_ap_id = PostForm::from_apub(&page, client, pool, Some(user.actor_id()?))
|
let post_ap_id = PostForm::from_apub(&page, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
|
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: post.name.to_owned(),
|
name: post.name.to_owned(),
|
||||||
|
@ -320,40 +304,44 @@ async fn receive_undo_delete_post(
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
Post::update(conn, post_id, &post_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::EditPost,
|
op: UserOperation::EditPost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_remove_post(
|
async fn receive_undo_remove_post(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
remove: &Remove,
|
remove: &Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(remove, client, pool).await?;
|
let mod_ = get_user_from_activity(remove, context).await?;
|
||||||
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post_ap_id = PostForm::from_apub(&page, client, pool, None)
|
let post_ap_id = PostForm::from_apub(&page, context, None)
|
||||||
.await?
|
.await?
|
||||||
.get_ap_id()?;
|
.get_ap_id()?;
|
||||||
|
|
||||||
let post = get_or_fetch_and_insert_post(&post_ap_id, client, pool).await?;
|
let post = get_or_fetch_and_insert_post(&post_ap_id, context).await?;
|
||||||
|
|
||||||
let post_form = PostForm {
|
let post_form = PostForm {
|
||||||
name: post.name.to_owned(),
|
name: post.name.to_owned(),
|
||||||
|
@ -376,40 +364,44 @@ async fn receive_undo_remove_post(
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
blocking(pool, move |conn| Post::update(conn, post_id, &post_form)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
Post::update(conn, post_id, &post_form)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::EditPost,
|
op: UserOperation::EditPost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &mod_, client, pool).await?;
|
announce_if_community_is_local(undo, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_delete_community(
|
async fn receive_undo_delete_community(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
delete: &Delete,
|
delete: &Delete,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(delete, client, pool).await?;
|
let user = get_user_from_activity(delete, context).await?;
|
||||||
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
let group = GroupExt::from_any_base(delete.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let community_actor_id = CommunityForm::from_apub(&group, client, pool, Some(user.actor_id()?))
|
let community_actor_id = CommunityForm::from_apub(&group, context, Some(user.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.actor_id;
|
.actor_id;
|
||||||
|
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, &community_actor_id)
|
Community::read_from_actor_id(conn, &community_actor_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -435,14 +427,14 @@ async fn receive_undo_delete_community(
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, community_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let res = CommunityResponse {
|
let res = CommunityResponse {
|
||||||
community: blocking(pool, move |conn| {
|
community: blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, None)
|
CommunityView::read(conn, community_id, None)
|
||||||
})
|
})
|
||||||
.await??,
|
.await??,
|
||||||
|
@ -450,33 +442,31 @@ async fn receive_undo_delete_community(
|
||||||
|
|
||||||
let community_id = res.community.id;
|
let community_id = res.community.id;
|
||||||
|
|
||||||
chat_server.do_send(SendCommunityRoomMessage {
|
context.chat_server().do_send(SendCommunityRoomMessage {
|
||||||
op: UserOperation::EditCommunity,
|
op: UserOperation::EditCommunity,
|
||||||
response: res,
|
response: res,
|
||||||
community_id,
|
community_id,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_remove_community(
|
async fn receive_undo_remove_community(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
remove: &Remove,
|
remove: &Remove,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let mod_ = get_user_from_activity(remove, client, pool).await?;
|
let mod_ = get_user_from_activity(remove, context).await?;
|
||||||
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
let group = GroupExt::from_any_base(remove.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let community_actor_id = CommunityForm::from_apub(&group, client, pool, Some(mod_.actor_id()?))
|
let community_actor_id = CommunityForm::from_apub(&group, context, Some(mod_.actor_id()?))
|
||||||
.await?
|
.await?
|
||||||
.actor_id;
|
.actor_id;
|
||||||
|
|
||||||
let community = blocking(pool, move |conn| {
|
let community = blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_actor_id(conn, &community_actor_id)
|
Community::read_from_actor_id(conn, &community_actor_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -502,14 +492,14 @@ async fn receive_undo_remove_community(
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, community_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let res = CommunityResponse {
|
let res = CommunityResponse {
|
||||||
community: blocking(pool, move |conn| {
|
community: blocking(context.pool(), move |conn| {
|
||||||
CommunityView::read(conn, community_id, None)
|
CommunityView::read(conn, community_id, None)
|
||||||
})
|
})
|
||||||
.await??,
|
.await??,
|
||||||
|
@ -517,43 +507,43 @@ async fn receive_undo_remove_community(
|
||||||
|
|
||||||
let community_id = res.community.id;
|
let community_id = res.community.id;
|
||||||
|
|
||||||
chat_server.do_send(SendCommunityRoomMessage {
|
context.chat_server().do_send(SendCommunityRoomMessage {
|
||||||
op: UserOperation::EditCommunity,
|
op: UserOperation::EditCommunity,
|
||||||
response: res,
|
response: res,
|
||||||
community_id,
|
community_id,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &mod_, client, pool).await?;
|
announce_if_community_is_local(undo, &mod_, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_like_comment(
|
async fn receive_undo_like_comment(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
like: &Like,
|
like: &Like,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(like, client, pool).await?;
|
let user = get_user_from_activity(like, context).await?;
|
||||||
let note = Note::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, None).await?;
|
let comment = CommentForm::from_apub(¬e, context, None).await?;
|
||||||
|
|
||||||
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
|
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommentLike::remove(conn, user_id, comment_id)
|
CommentLike::remove(conn, user_id, comment_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -563,59 +553,61 @@ async fn receive_undo_like_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::CreateCommentLike,
|
op: UserOperation::CreateCommentLike,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_like_post(
|
async fn receive_undo_like_post(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
like: &Like,
|
like: &Like,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(like, client, pool).await?;
|
let user = get_user_from_activity(like, context).await?;
|
||||||
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post = PostForm::from_apub(&page, client, pool, None).await?;
|
let post = PostForm::from_apub(&page, context, None).await?;
|
||||||
|
|
||||||
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
|
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| PostLike::remove(conn, user_id, post_id)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
PostLike::remove(conn, user_id, post_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::CreatePostLike,
|
op: UserOperation::CreatePostLike,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_dislike_comment(
|
async fn receive_undo_dislike_comment(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
dislike: &Dislike,
|
dislike: &Dislike,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(dislike, client, pool).await?;
|
let user = get_user_from_activity(dislike, context).await?;
|
||||||
let note = Note::from_any_base(
|
let note = Note::from_any_base(
|
||||||
dislike
|
dislike
|
||||||
.object()
|
.object()
|
||||||
|
@ -625,21 +617,23 @@ async fn receive_undo_dislike_comment(
|
||||||
)?
|
)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, None).await?;
|
let comment = CommentForm::from_apub(¬e, context, None).await?;
|
||||||
|
|
||||||
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
|
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
CommentLike::remove(conn, user_id, comment_id)
|
CommentLike::remove(conn, user_id, comment_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view =
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
blocking(pool, move |conn| CommentView::read(conn, comment_id, None)).await??;
|
CommentView::read(conn, comment_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
// TODO get those recipient actor ids from somewhere
|
||||||
let recipient_ids = vec![];
|
let recipient_ids = vec![];
|
||||||
|
@ -649,24 +643,22 @@ async fn receive_undo_dislike_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::CreateCommentLike,
|
op: UserOperation::CreateCommentLike,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_undo_dislike_post(
|
async fn receive_undo_dislike_post(
|
||||||
undo: Undo,
|
undo: Undo,
|
||||||
dislike: &Dislike,
|
dislike: &Dislike,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(dislike, client, pool).await?;
|
let user = get_user_from_activity(dislike, context).await?;
|
||||||
let page = PageExt::from_any_base(
|
let page = PageExt::from_any_base(
|
||||||
dislike
|
dislike
|
||||||
.object()
|
.object()
|
||||||
|
@ -676,26 +668,32 @@ async fn receive_undo_dislike_post(
|
||||||
)?
|
)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post = PostForm::from_apub(&page, client, pool, None).await?;
|
let post = PostForm::from_apub(&page, context, None).await?;
|
||||||
|
|
||||||
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
|
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
blocking(pool, move |conn| PostLike::remove(conn, user_id, post_id)).await??;
|
blocking(context.pool(), move |conn| {
|
||||||
|
PostLike::remove(conn, user_id, post_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_view = blocking(pool, move |conn| PostView::read(conn, post_id, None)).await??;
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
|
PostView::read(conn, post_id, None)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::CreatePostLike,
|
op: UserOperation::CreatePostLike,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(undo, &user, client, pool).await?;
|
announce_if_community_is_local(undo, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,15 @@ use crate::{
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::ChatServerParam,
|
|
||||||
websocket::{
|
websocket::{
|
||||||
server::{SendComment, SendPost},
|
server::{SendComment, SendPost},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
},
|
},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::{client::Client, HttpResponse};
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
@ -37,92 +36,93 @@ use lemmy_utils::{location_info, scrape_text_for_mentions};
|
||||||
|
|
||||||
pub async fn receive_update(
|
pub async fn receive_update(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
||||||
|
|
||||||
// ensure that update and actor come from the same instance
|
// ensure that update and actor come from the same instance
|
||||||
let user = get_user_from_activity(&update, client, pool).await?;
|
let user = get_user_from_activity(&update, context).await?;
|
||||||
update.id(user.actor_id()?.domain().context(location_info!())?)?;
|
update.id(user.actor_id()?.domain().context(location_info!())?)?;
|
||||||
|
|
||||||
match update.object().as_single_kind_str() {
|
match update.object().as_single_kind_str() {
|
||||||
Some("Page") => receive_update_post(update, client, pool, chat_server).await,
|
Some("Page") => receive_update_post(update, context).await,
|
||||||
Some("Note") => receive_update_comment(update, client, pool, chat_server).await,
|
Some("Note") => receive_update_comment(update, context).await,
|
||||||
_ => receive_unhandled_activity(update),
|
_ => receive_unhandled_activity(update),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_update_post(
|
async fn receive_update_post(
|
||||||
update: Update,
|
update: Update,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let user = get_user_from_activity(&update, client, pool).await?;
|
let user = get_user_from_activity(&update, context).await?;
|
||||||
let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
|
let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let post = PostForm::from_apub(&page, client, pool, Some(user.actor_id()?)).await?;
|
let post = PostForm::from_apub(&page, context, Some(user.actor_id()?)).await?;
|
||||||
|
|
||||||
let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, client, pool)
|
let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
blocking(pool, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Post::update(conn, original_post_id, &post)
|
Post::update(conn, original_post_id, &post)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let post_view = blocking(pool, move |conn| {
|
let post_view = blocking(context.pool(), move |conn| {
|
||||||
PostView::read(conn, original_post_id, None)
|
PostView::read(conn, original_post_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let res = PostResponse { post: post_view };
|
let res = PostResponse { post: post_view };
|
||||||
|
|
||||||
chat_server.do_send(SendPost {
|
context.chat_server().do_send(SendPost {
|
||||||
op: UserOperation::EditPost,
|
op: UserOperation::EditPost,
|
||||||
post: res,
|
post: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(update, &user, client, pool).await?;
|
announce_if_community_is_local(update, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_update_comment(
|
async fn receive_update_comment(
|
||||||
update: Update,
|
update: Update,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let note = Note::from_any_base(update.object().to_owned().one().context(location_info!())?)?
|
let note = Note::from_any_base(update.object().to_owned().one().context(location_info!())?)?
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let user = get_user_from_activity(&update, client, pool).await?;
|
let user = get_user_from_activity(&update, context).await?;
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, client, pool, Some(user.actor_id()?)).await?;
|
let comment = CommentForm::from_apub(¬e, context, Some(user.actor_id()?)).await?;
|
||||||
|
|
||||||
let original_comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, client, pool)
|
let original_comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context)
|
||||||
.await?
|
.await?
|
||||||
.id;
|
.id;
|
||||||
|
|
||||||
let updated_comment = blocking(pool, move |conn| {
|
let updated_comment = blocking(context.pool(), move |conn| {
|
||||||
Comment::update(conn, original_comment_id, &comment)
|
Comment::update(conn, original_comment_id, &comment)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let post_id = updated_comment.post_id;
|
let post_id = updated_comment.post_id;
|
||||||
let post = blocking(pool, move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
|
||||||
let mentions = scrape_text_for_mentions(&updated_comment.content);
|
let mentions = scrape_text_for_mentions(&updated_comment.content);
|
||||||
let recipient_ids =
|
let recipient_ids = send_local_notifs(
|
||||||
send_local_notifs(mentions, updated_comment, &user, post, pool, false).await?;
|
mentions,
|
||||||
|
updated_comment,
|
||||||
|
&user,
|
||||||
|
post,
|
||||||
|
context.pool(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view = blocking(pool, move |conn| {
|
let comment_view = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(conn, original_comment_id, None)
|
CommentView::read(conn, original_comment_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -133,12 +133,12 @@ async fn receive_update_comment(
|
||||||
form_id: None,
|
form_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
chat_server.do_send(SendComment {
|
context.chat_server().do_send(SendComment {
|
||||||
op: UserOperation::EditComment,
|
op: UserOperation::EditComment,
|
||||||
comment: res,
|
comment: res,
|
||||||
my_id: None,
|
my_id: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
announce_if_community_is_local(update, &user, client, pool).await?;
|
announce_if_community_is_local(update, &user, context).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
ActorType,
|
ActorType,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::{ChatServerParam, DbPoolParam},
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -15,7 +15,7 @@ use activitystreams::{
|
||||||
base::AnyBase,
|
base::AnyBase,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
|
@ -41,14 +41,15 @@ pub async fn community_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
input: web::Json<AcceptedActivities>,
|
input: web::Json<AcceptedActivities>,
|
||||||
path: web::Path<String>,
|
path: web::Path<String>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
client: web::Data<Client>,
|
|
||||||
_chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let activity = input.into_inner();
|
let activity = input.into_inner();
|
||||||
|
|
||||||
let path = path.into_inner();
|
let path = path.into_inner();
|
||||||
let community = blocking(&db, move |conn| Community::read_from_name(&conn, &path)).await??;
|
let community = blocking(&context.pool(), move |conn| {
|
||||||
|
Community::read_from_name(&conn, &path)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
if !community.local {
|
if !community.local {
|
||||||
return Err(
|
return Err(
|
||||||
|
@ -69,7 +70,7 @@ pub async fn community_inbox(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
check_is_apub_id_valid(user_uri)?;
|
check_is_apub_id_valid(user_uri)?;
|
||||||
|
|
||||||
let user = get_or_fetch_and_upsert_user(&user_uri, &client, &db).await?;
|
let user = get_or_fetch_and_upsert_user(&user_uri, &context).await?;
|
||||||
|
|
||||||
verify(&request, &user)?;
|
verify(&request, &user)?;
|
||||||
|
|
||||||
|
@ -77,11 +78,11 @@ pub async fn community_inbox(
|
||||||
let kind = activity.kind().context(location_info!())?;
|
let kind = activity.kind().context(location_info!())?;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let res = match kind {
|
let res = match kind {
|
||||||
ValidTypes::Follow => handle_follow(any_base, user, community, &client, &db).await,
|
ValidTypes::Follow => handle_follow(any_base, user, community, &context).await,
|
||||||
ValidTypes::Undo => handle_undo_follow(any_base, user, community, &db).await,
|
ValidTypes::Undo => handle_undo_follow(any_base, user, community, &context).await,
|
||||||
};
|
};
|
||||||
|
|
||||||
insert_activity(user_id, activity.clone(), false, &db).await?;
|
insert_activity(user_id, activity.clone(), false, context.pool()).await?;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +92,7 @@ async fn handle_follow(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
user: User_,
|
user: User_,
|
||||||
community: Community,
|
community: Community,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
db: &DbPoolParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let follow = Follow::from_any_base(activity)?.context(location_info!())?;
|
let follow = Follow::from_any_base(activity)?.context(location_info!())?;
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
@ -101,12 +101,12 @@ async fn handle_follow(
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will fail if they're already a follower, but ignore the error.
|
// This will fail if they're already a follower, but ignore the error.
|
||||||
blocking(db, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
CommunityFollower::follow(&conn, &community_follower_form).ok()
|
CommunityFollower::follow(&conn, &community_follower_form).ok()
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
community.send_accept_follow(follow, &client, db).await?;
|
community.send_accept_follow(follow, context).await?;
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ async fn handle_undo_follow(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
user: User_,
|
user: User_,
|
||||||
community: Community,
|
community: Community,
|
||||||
db: &DbPoolParam,
|
context: &LemmyContext,
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let _undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
let _undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ async fn handle_undo_follow(
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will fail if they aren't a follower, but ignore the error.
|
// This will fail if they aren't a follower, but ignore the error.
|
||||||
blocking(db, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
CommunityFollower::unfollow(&conn, &community_follower_form).ok()
|
CommunityFollower::unfollow(&conn, &community_follower_form).ok()
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -20,8 +20,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
insert_activity,
|
insert_activity,
|
||||||
},
|
},
|
||||||
routes::{ChatServerParam, DbPoolParam},
|
LemmyContext,
|
||||||
DbPool,
|
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -30,7 +29,7 @@ use activitystreams::{
|
||||||
object::AsObject,
|
object::AsObject,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::user::User_;
|
use lemmy_db::user::User_;
|
||||||
use lemmy_utils::location_info;
|
use lemmy_utils::location_info;
|
||||||
|
@ -60,9 +59,7 @@ pub type AcceptedActivities = ActorAndObject<ValidTypes>;
|
||||||
pub async fn shared_inbox(
|
pub async fn shared_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
input: web::Json<AcceptedActivities>,
|
input: web::Json<AcceptedActivities>,
|
||||||
client: web::Data<Client>,
|
context: web::Data<LemmyContext>,
|
||||||
pool: DbPoolParam,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let activity = input.into_inner();
|
let activity = input.into_inner();
|
||||||
|
|
||||||
|
@ -79,23 +76,23 @@ pub async fn shared_inbox(
|
||||||
check_is_apub_id_valid(sender)?;
|
check_is_apub_id_valid(sender)?;
|
||||||
check_is_apub_id_valid(&community)?;
|
check_is_apub_id_valid(&community)?;
|
||||||
|
|
||||||
let actor = get_or_fetch_and_upsert_actor(sender, &client, &pool).await?;
|
let actor = get_or_fetch_and_upsert_actor(sender, &context).await?;
|
||||||
verify(&request, actor.as_ref())?;
|
verify(&request, actor.as_ref())?;
|
||||||
|
|
||||||
let any_base = activity.clone().into_any_base()?;
|
let any_base = activity.clone().into_any_base()?;
|
||||||
let kind = activity.kind().context(location_info!())?;
|
let kind = activity.kind().context(location_info!())?;
|
||||||
let res = match kind {
|
let res = match kind {
|
||||||
ValidTypes::Announce => receive_announce(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Announce => receive_announce(any_base, &context).await,
|
||||||
ValidTypes::Create => receive_create(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Create => receive_create(any_base, &context).await,
|
||||||
ValidTypes::Update => receive_update(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Update => receive_update(any_base, &context).await,
|
||||||
ValidTypes::Like => receive_like(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Like => receive_like(any_base, &context).await,
|
||||||
ValidTypes::Dislike => receive_dislike(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Dislike => receive_dislike(any_base, &context).await,
|
||||||
ValidTypes::Remove => receive_remove(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Remove => receive_remove(any_base, &context).await,
|
||||||
ValidTypes::Delete => receive_delete(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Delete => receive_delete(any_base, &context).await,
|
||||||
ValidTypes::Undo => receive_undo(any_base, &client, &pool, chat_server).await,
|
ValidTypes::Undo => receive_undo(any_base, &context).await,
|
||||||
};
|
};
|
||||||
|
|
||||||
insert_activity(actor.user_id(), activity.clone(), false, &pool).await?;
|
insert_activity(actor.user_id(), activity.clone(), false, context.pool()).await?;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,15 +108,14 @@ where
|
||||||
|
|
||||||
pub(in crate::apub::inbox) async fn get_user_from_activity<T, A>(
|
pub(in crate::apub::inbox) async fn get_user_from_activity<T, A>(
|
||||||
activity: &T,
|
activity: &T,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<User_, LemmyError>
|
) -> Result<User_, LemmyError>
|
||||||
where
|
where
|
||||||
T: AsBase<A> + ActorAndObjectRef,
|
T: AsBase<A> + ActorAndObjectRef,
|
||||||
{
|
{
|
||||||
let actor = activity.actor()?;
|
let actor = activity.actor()?;
|
||||||
let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
|
let user_uri = actor.as_single_xsd_any_uri().context(location_info!())?;
|
||||||
get_or_fetch_and_upsert_user(&user_uri, client, pool).await
|
get_or_fetch_and_upsert_user(&user_uri, context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::apub::inbox) fn get_community_id_from_activity<T, A>(
|
pub(in crate::apub::inbox) fn get_community_id_from_activity<T, A>(
|
||||||
|
@ -142,8 +138,7 @@ where
|
||||||
pub(in crate::apub::inbox) async fn announce_if_community_is_local<T, Kind>(
|
pub(in crate::apub::inbox) async fn announce_if_community_is_local<T, Kind>(
|
||||||
activity: T,
|
activity: T,
|
||||||
user: &User_,
|
user: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>
|
) -> Result<(), LemmyError>
|
||||||
where
|
where
|
||||||
T: AsObject<Kind>,
|
T: AsObject<Kind>,
|
||||||
|
@ -162,11 +157,10 @@ where
|
||||||
let community_uri = community_followers_uri
|
let community_uri = community_followers_uri
|
||||||
.to_string()
|
.to_string()
|
||||||
.replace("/followers", "");
|
.replace("/followers", "");
|
||||||
let community =
|
let community = get_or_fetch_and_upsert_community(&Url::parse(&community_uri)?, context).await?;
|
||||||
get_or_fetch_and_upsert_community(&Url::parse(&community_uri)?, client, pool).await?;
|
|
||||||
|
|
||||||
if community.local {
|
if community.local {
|
||||||
do_announce(activity.into_any_base()?, &community, &user, client, pool).await?;
|
do_announce(activity.into_any_base()?, &community, &user, context).await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,8 @@ use crate::{
|
||||||
FromApub,
|
FromApub,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::{ChatServerParam, DbPoolParam},
|
|
||||||
websocket::{server::SendUserRoomMessage, UserOperation},
|
websocket::{server::SendUserRoomMessage, UserOperation},
|
||||||
DbPool,
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -19,7 +18,7 @@ use activitystreams::{
|
||||||
object::Note,
|
object::Note,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{CommunityFollower, CommunityFollowerForm},
|
community::{CommunityFollower, CommunityFollowerForm},
|
||||||
|
@ -52,9 +51,7 @@ pub async fn user_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
input: web::Json<AcceptedActivities>,
|
input: web::Json<AcceptedActivities>,
|
||||||
path: web::Path<String>,
|
path: web::Path<String>,
|
||||||
client: web::Data<Client>,
|
context: web::Data<LemmyContext>,
|
||||||
pool: DbPoolParam,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let activity = input.into_inner();
|
let activity = input.into_inner();
|
||||||
let username = path.into_inner();
|
let username = path.into_inner();
|
||||||
|
@ -67,28 +64,20 @@ pub async fn user_inbox(
|
||||||
|
|
||||||
check_is_apub_id_valid(actor_uri)?;
|
check_is_apub_id_valid(actor_uri)?;
|
||||||
|
|
||||||
let actor = get_or_fetch_and_upsert_actor(actor_uri, &client, &pool).await?;
|
let actor = get_or_fetch_and_upsert_actor(actor_uri, &context).await?;
|
||||||
verify(&request, actor.as_ref())?;
|
verify(&request, actor.as_ref())?;
|
||||||
|
|
||||||
let any_base = activity.clone().into_any_base()?;
|
let any_base = activity.clone().into_any_base()?;
|
||||||
let kind = activity.kind().context(location_info!())?;
|
let kind = activity.kind().context(location_info!())?;
|
||||||
let res = match kind {
|
let res = match kind {
|
||||||
ValidTypes::Accept => receive_accept(any_base, username, &client, &pool).await,
|
ValidTypes::Accept => receive_accept(any_base, username, &context).await,
|
||||||
ValidTypes::Create => {
|
ValidTypes::Create => receive_create_private_message(any_base, &context).await,
|
||||||
receive_create_private_message(any_base, &client, &pool, chat_server).await
|
ValidTypes::Update => receive_update_private_message(any_base, &context).await,
|
||||||
}
|
ValidTypes::Delete => receive_delete_private_message(any_base, &context).await,
|
||||||
ValidTypes::Update => {
|
ValidTypes::Undo => receive_undo_delete_private_message(any_base, &context).await,
|
||||||
receive_update_private_message(any_base, &client, &pool, chat_server).await
|
|
||||||
}
|
|
||||||
ValidTypes::Delete => {
|
|
||||||
receive_delete_private_message(any_base, &client, &pool, chat_server).await
|
|
||||||
}
|
|
||||||
ValidTypes::Undo => {
|
|
||||||
receive_undo_delete_private_message(any_base, &client, &pool, chat_server).await
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
insert_activity(actor.user_id(), activity.clone(), false, &pool).await?;
|
insert_activity(actor.user_id(), activity.clone(), false, context.pool()).await?;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +85,7 @@ pub async fn user_inbox(
|
||||||
async fn receive_accept(
|
async fn receive_accept(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
username: String,
|
username: String,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let accept = Accept::from_any_base(activity)?.context(location_info!())?;
|
let accept = Accept::from_any_base(activity)?.context(location_info!())?;
|
||||||
let community_uri = accept
|
let community_uri = accept
|
||||||
|
@ -106,9 +94,12 @@ async fn receive_accept(
|
||||||
.single_xsd_any_uri()
|
.single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let community = get_or_fetch_and_upsert_community(&community_uri, client, pool).await?;
|
let community = get_or_fetch_and_upsert_community(&community_uri, context).await?;
|
||||||
|
|
||||||
let user = blocking(pool, move |conn| User_::read_from_name(conn, &username)).await??;
|
let user = blocking(&context.pool(), move |conn| {
|
||||||
|
User_::read_from_name(conn, &username)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
// Now you need to add this to the community follower
|
// Now you need to add this to the community follower
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
@ -117,7 +108,7 @@ async fn receive_accept(
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will fail if they're already a follower
|
// This will fail if they're already a follower
|
||||||
blocking(pool, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
CommunityFollower::follow(conn, &community_follower_form).ok()
|
CommunityFollower::follow(conn, &community_follower_form).ok()
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -128,9 +119,7 @@ async fn receive_accept(
|
||||||
|
|
||||||
async fn receive_create_private_message(
|
async fn receive_create_private_message(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
let create = Create::from_any_base(activity)?.context(location_info!())?;
|
||||||
let note = Note::from_any_base(
|
let note = Note::from_any_base(
|
||||||
|
@ -143,14 +132,14 @@ async fn receive_create_private_message(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let domain = Some(create.id_unchecked().context(location_info!())?.to_owned());
|
let domain = Some(create.id_unchecked().context(location_info!())?.to_owned());
|
||||||
let private_message = PrivateMessageForm::from_apub(¬e, client, pool, domain).await?;
|
let private_message = PrivateMessageForm::from_apub(¬e, context, domain).await?;
|
||||||
|
|
||||||
let inserted_private_message = blocking(pool, move |conn| {
|
let inserted_private_message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::create(conn, &private_message)
|
PrivateMessage::create(conn, &private_message)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let message = blocking(pool, move |conn| {
|
let message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, inserted_private_message.id)
|
PrivateMessageView::read(conn, inserted_private_message.id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -159,7 +148,7 @@ async fn receive_create_private_message(
|
||||||
|
|
||||||
let recipient_id = res.message.recipient_id;
|
let recipient_id = res.message.recipient_id;
|
||||||
|
|
||||||
chat_server.do_send(SendUserRoomMessage {
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
op: UserOperation::CreatePrivateMessage,
|
op: UserOperation::CreatePrivateMessage,
|
||||||
response: res,
|
response: res,
|
||||||
recipient_id,
|
recipient_id,
|
||||||
|
@ -171,9 +160,7 @@ async fn receive_create_private_message(
|
||||||
|
|
||||||
async fn receive_update_private_message(
|
async fn receive_update_private_message(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
let update = Update::from_any_base(activity)?.context(location_info!())?;
|
||||||
let note = Note::from_any_base(
|
let note = Note::from_any_base(
|
||||||
|
@ -186,22 +173,22 @@ async fn receive_update_private_message(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let domain = Some(update.id_unchecked().context(location_info!())?.to_owned());
|
let domain = Some(update.id_unchecked().context(location_info!())?.to_owned());
|
||||||
let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool, domain).await?;
|
let private_message_form = PrivateMessageForm::from_apub(¬e, context, domain).await?;
|
||||||
|
|
||||||
let private_message_ap_id = private_message_form.ap_id.clone();
|
let private_message_ap_id = private_message_form.ap_id.clone();
|
||||||
let private_message = blocking(pool, move |conn| {
|
let private_message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
|
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let private_message_id = private_message.id;
|
let private_message_id = private_message.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let private_message_id = private_message.id;
|
let private_message_id = private_message.id;
|
||||||
let message = blocking(pool, move |conn| {
|
let message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, private_message_id)
|
PrivateMessageView::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -210,7 +197,7 @@ async fn receive_update_private_message(
|
||||||
|
|
||||||
let recipient_id = res.message.recipient_id;
|
let recipient_id = res.message.recipient_id;
|
||||||
|
|
||||||
chat_server.do_send(SendUserRoomMessage {
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
op: UserOperation::EditPrivateMessage,
|
op: UserOperation::EditPrivateMessage,
|
||||||
response: res,
|
response: res,
|
||||||
recipient_id,
|
recipient_id,
|
||||||
|
@ -222,9 +209,7 @@ async fn receive_update_private_message(
|
||||||
|
|
||||||
async fn receive_delete_private_message(
|
async fn receive_delete_private_message(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let delete = Delete::from_any_base(activity)?.context(location_info!())?;
|
let delete = Delete::from_any_base(activity)?.context(location_info!())?;
|
||||||
let note = Note::from_any_base(
|
let note = Note::from_any_base(
|
||||||
|
@ -237,10 +222,10 @@ async fn receive_delete_private_message(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let domain = Some(delete.id_unchecked().context(location_info!())?.to_owned());
|
let domain = Some(delete.id_unchecked().context(location_info!())?.to_owned());
|
||||||
let private_message_form = PrivateMessageForm::from_apub(¬e, client, pool, domain).await?;
|
let private_message_form = PrivateMessageForm::from_apub(¬e, context, domain).await?;
|
||||||
|
|
||||||
let private_message_ap_id = private_message_form.ap_id;
|
let private_message_ap_id = private_message_form.ap_id;
|
||||||
let private_message = blocking(pool, move |conn| {
|
let private_message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
|
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -258,13 +243,13 @@ async fn receive_delete_private_message(
|
||||||
};
|
};
|
||||||
|
|
||||||
let private_message_id = private_message.id;
|
let private_message_id = private_message.id;
|
||||||
blocking(pool, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let private_message_id = private_message.id;
|
let private_message_id = private_message.id;
|
||||||
let message = blocking(pool, move |conn| {
|
let message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(&conn, private_message_id)
|
PrivateMessageView::read(&conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -273,7 +258,7 @@ async fn receive_delete_private_message(
|
||||||
|
|
||||||
let recipient_id = res.message.recipient_id;
|
let recipient_id = res.message.recipient_id;
|
||||||
|
|
||||||
chat_server.do_send(SendUserRoomMessage {
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
op: UserOperation::EditPrivateMessage,
|
op: UserOperation::EditPrivateMessage,
|
||||||
response: res,
|
response: res,
|
||||||
recipient_id,
|
recipient_id,
|
||||||
|
@ -285,9 +270,7 @@ async fn receive_delete_private_message(
|
||||||
|
|
||||||
async fn receive_undo_delete_private_message(
|
async fn receive_undo_delete_private_message(
|
||||||
activity: AnyBase,
|
activity: AnyBase,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, LemmyError> {
|
) -> Result<HttpResponse, LemmyError> {
|
||||||
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
let undo = Undo::from_any_base(activity)?.context(location_info!())?;
|
||||||
let delete = Delete::from_any_base(undo.object().as_one().context(location_info!())?.to_owned())?
|
let delete = Delete::from_any_base(undo.object().as_one().context(location_info!())?.to_owned())?
|
||||||
|
@ -302,10 +285,10 @@ async fn receive_undo_delete_private_message(
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let domain = Some(undo.id_unchecked().context(location_info!())?.to_owned());
|
let domain = Some(undo.id_unchecked().context(location_info!())?.to_owned());
|
||||||
let private_message = PrivateMessageForm::from_apub(¬e, client, pool, domain).await?;
|
let private_message = PrivateMessageForm::from_apub(¬e, context, domain).await?;
|
||||||
|
|
||||||
let private_message_ap_id = private_message.ap_id.clone();
|
let private_message_ap_id = private_message.ap_id.clone();
|
||||||
let private_message_id = blocking(pool, move |conn| {
|
let private_message_id = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id).map(|pm| pm.id)
|
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id).map(|pm| pm.id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -322,12 +305,12 @@ async fn receive_undo_delete_private_message(
|
||||||
updated: Some(naive_now()),
|
updated: Some(naive_now()),
|
||||||
};
|
};
|
||||||
|
|
||||||
blocking(pool, move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
PrivateMessage::update(conn, private_message_id, &private_message_form)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let message = blocking(pool, move |conn| {
|
let message = blocking(&context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(&conn, private_message_id)
|
PrivateMessageView::read(&conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -336,7 +319,7 @@ async fn receive_undo_delete_private_message(
|
||||||
|
|
||||||
let recipient_id = res.message.recipient_id;
|
let recipient_id = res.message.recipient_id;
|
||||||
|
|
||||||
chat_server.do_send(SendUserRoomMessage {
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
op: UserOperation::EditPrivateMessage,
|
op: UserOperation::EditPrivateMessage,
|
||||||
response: res,
|
response: res,
|
||||||
recipient_id,
|
recipient_id,
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::{
|
||||||
request::{retry, RecvError},
|
request::{retry, RecvError},
|
||||||
routes::webfinger::WebFingerResponse,
|
routes::webfinger::WebFingerResponse,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -162,15 +163,13 @@ pub trait FromApub {
|
||||||
/// Converts an object from ActivityPub type to Lemmy internal type.
|
/// Converts an object from ActivityPub type to Lemmy internal type.
|
||||||
///
|
///
|
||||||
/// * `apub` The object to read from
|
/// * `apub` The object to read from
|
||||||
/// * `client` Web client to fetch remote actors with
|
/// * `context` LemmyContext which holds DB pool, HTTP client etc
|
||||||
/// * `pool` Database connection
|
|
||||||
/// * `expected_domain` If present, ensure that the apub object comes from the same domain as
|
/// * `expected_domain` If present, ensure that the apub object comes from the same domain as
|
||||||
/// this URL
|
/// this URL
|
||||||
///
|
///
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: &Self::ApubType,
|
apub: &Self::ApubType,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<Self, LemmyError>
|
) -> Result<Self, LemmyError>
|
||||||
where
|
where
|
||||||
|
@ -179,42 +178,16 @@ pub trait FromApub {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait ApubObjectType {
|
pub trait ApubObjectType {
|
||||||
async fn send_create(
|
async fn send_create(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
&self,
|
async fn send_update(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
creator: &User_,
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_update(
|
|
||||||
&self,
|
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_delete(
|
|
||||||
&self,
|
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_remove(
|
|
||||||
&self,
|
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_undo_remove(
|
|
||||||
&self,
|
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
) -> Result<(), LemmyError>;
|
||||||
|
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
|
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::apub) fn check_actor_domain<T, Kind>(
|
pub(in crate::apub) fn check_actor_domain<T, Kind>(
|
||||||
|
@ -237,24 +210,10 @@ where
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait ApubLikeableType {
|
pub trait ApubLikeableType {
|
||||||
async fn send_like(
|
async fn send_like(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
&self,
|
async fn send_dislike(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
creator: &User_,
|
async fn send_undo_like(&self, creator: &User_, context: &LemmyContext)
|
||||||
client: &Client,
|
-> Result<(), LemmyError>;
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_dislike(
|
|
||||||
&self,
|
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_undo_like(
|
|
||||||
&self,
|
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
|
@ -274,49 +233,30 @@ pub trait ActorType {
|
||||||
async fn send_follow(
|
async fn send_follow(
|
||||||
&self,
|
&self,
|
||||||
follow_actor_id: &Url,
|
follow_actor_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
) -> Result<(), LemmyError>;
|
||||||
async fn send_unfollow(
|
async fn send_unfollow(
|
||||||
&self,
|
&self,
|
||||||
follow_actor_id: &Url,
|
follow_actor_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
) -> Result<(), LemmyError>;
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
async fn send_accept_follow(
|
async fn send_accept_follow(
|
||||||
&self,
|
&self,
|
||||||
follow: Follow,
|
follow: Follow,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
) -> Result<(), LemmyError>;
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
&self,
|
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
) -> Result<(), LemmyError>;
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
&self,
|
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError>;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
async fn send_undo_remove(
|
|
||||||
&self,
|
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError>;
|
|
||||||
|
|
||||||
/// For a given community, returns the inboxes of all followers.
|
/// For a given community, returns the inboxes of all followers.
|
||||||
async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError>;
|
async fn get_follower_inboxes(&self, pool: &DbPool) -> Result<Vec<Url>, LemmyError>;
|
||||||
|
|
|
@ -16,8 +16,8 @@ use crate::{
|
||||||
ToApub,
|
ToApub,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::DbPoolParam,
|
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -31,13 +31,12 @@ use activitystreams::{
|
||||||
Undo,
|
Undo,
|
||||||
Update,
|
Update,
|
||||||
},
|
},
|
||||||
context,
|
|
||||||
object::{kind::PageType, Image, Object, Page, Tombstone},
|
object::{kind::PageType, Image, Object, Page, Tombstone},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
public,
|
public,
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use actix_web::{body::Body, client::Client, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::Community,
|
community::Community,
|
||||||
|
@ -57,13 +56,13 @@ pub struct PostQuery {
|
||||||
/// Return the post json over HTTP.
|
/// Return the post json over HTTP.
|
||||||
pub async fn get_apub_post(
|
pub async fn get_apub_post(
|
||||||
info: web::Path<PostQuery>,
|
info: web::Path<PostQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let id = info.post_id.parse::<i32>()?;
|
let id = info.post_id.parse::<i32>()?;
|
||||||
let post = blocking(&db, move |conn| Post::read(conn, id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, id)).await??;
|
||||||
|
|
||||||
if !post.deleted {
|
if !post.deleted {
|
||||||
Ok(create_apub_response(&post.to_apub(&db).await?))
|
Ok(create_apub_response(&post.to_apub(context.pool()).await?))
|
||||||
} else {
|
} else {
|
||||||
Ok(create_apub_tombstone_response(&post.to_tombstone()?))
|
Ok(create_apub_tombstone_response(&post.to_tombstone()?))
|
||||||
}
|
}
|
||||||
|
@ -87,7 +86,7 @@ impl ToApub for Post {
|
||||||
// Not needed when the Post is embedded in a collection (like for community outbox)
|
// Not needed when the Post is embedded in a collection (like for community outbox)
|
||||||
// TODO: need to set proper context defining sensitive/commentsEnabled fields
|
// TODO: need to set proper context defining sensitive/commentsEnabled fields
|
||||||
// https://git.asonix.dog/Aardwolf/activitystreams/issues/5
|
// https://git.asonix.dog/Aardwolf/activitystreams/issues/5
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(self.ap_id.parse::<Url>()?)
|
.set_id(self.ap_id.parse::<Url>()?)
|
||||||
// Use summary field to be consistent with mastodon content warning.
|
// Use summary field to be consistent with mastodon content warning.
|
||||||
// https://mastodon.xyz/@Louisa/103987265222901387.json
|
// https://mastodon.xyz/@Louisa/103987265222901387.json
|
||||||
|
@ -199,8 +198,7 @@ impl FromApub for PostForm {
|
||||||
/// Parse an ActivityPub page received from another instance into a Lemmy post.
|
/// Parse an ActivityPub page received from another instance into a Lemmy post.
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
page: &PageExt,
|
page: &PageExt,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<PostForm, LemmyError> {
|
) -> Result<PostForm, LemmyError> {
|
||||||
let ext = &page.ext_one;
|
let ext = &page.ext_one;
|
||||||
|
@ -212,7 +210,7 @@ impl FromApub for PostForm {
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let creator = get_or_fetch_and_upsert_user(creator_actor_id, client, pool).await?;
|
let creator = get_or_fetch_and_upsert_user(creator_actor_id, context).await?;
|
||||||
|
|
||||||
let community_actor_id = page
|
let community_actor_id = page
|
||||||
.inner
|
.inner
|
||||||
|
@ -222,7 +220,7 @@ impl FromApub for PostForm {
|
||||||
.as_single_xsd_any_uri()
|
.as_single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let community = get_or_fetch_and_upsert_community(community_actor_id, client, pool).await?;
|
let community = get_or_fetch_and_upsert_community(community_actor_id, context).await?;
|
||||||
|
|
||||||
let thumbnail_url = match &page.inner.image() {
|
let thumbnail_url = match &page.inner.image() {
|
||||||
Some(any_image) => Image::from_any_base(
|
Some(any_image) => Image::from_any_base(
|
||||||
|
@ -300,20 +298,18 @@ impl FromApub for PostForm {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ApubObjectType for Post {
|
impl ApubObjectType for Post {
|
||||||
/// Send out information about a newly created post, to the followers of the community.
|
/// Send out information about a newly created post, to the followers of the community.
|
||||||
async fn send_create(
|
async fn send_create(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut create = Create::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut create = Create::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
create
|
create
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(CreateType::Create)?)
|
.set_id(generate_activity_id(CreateType::Create)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -323,28 +319,25 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
create.into_any_base()?,
|
create.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send out information about an edited post, to the followers of the community.
|
/// Send out information about an edited post, to the followers of the community.
|
||||||
async fn send_update(
|
async fn send_update(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut update = Update::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut update = Update::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
update
|
update
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UpdateType::Update)?)
|
.set_id(generate_activity_id(UpdateType::Update)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -354,27 +347,24 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
update.into_any_base()?,
|
update.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -384,8 +374,7 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
delete.into_any_base()?,
|
delete.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -394,17 +383,19 @@ impl ApubObjectType for Post {
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let page = self.to_apub(pool).await?;
|
let page = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -412,7 +403,7 @@ impl ApubObjectType for Post {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -422,27 +413,24 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -452,27 +440,24 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
remove.into_any_base()?,
|
remove.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_remove(
|
async fn send_undo_remove(&self, mod_: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
mod_: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
|
let mut remove = Remove::new(mod_.actor_id.to_owned(), page.into_any_base()?);
|
||||||
remove
|
remove
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(RemoveType::Remove)?)
|
.set_id(generate_activity_id(RemoveType::Remove)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -480,7 +465,7 @@ impl ApubObjectType for Post {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
let mut undo = Undo::new(mod_.actor_id.to_owned(), remove.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -490,8 +475,7 @@ impl ApubObjectType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -500,20 +484,18 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ApubLikeableType for Post {
|
impl ApubLikeableType for Post {
|
||||||
async fn send_like(
|
async fn send_like(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
like
|
like
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(LikeType::Like)?)
|
.set_id(generate_activity_id(LikeType::Like)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -523,27 +505,24 @@ impl ApubLikeableType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
like.into_any_base()?,
|
like.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_dislike(
|
async fn send_dislike(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let page = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let page = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut dislike = Dislike::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut dislike = Dislike::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
dislike
|
dislike
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
.set_id(generate_activity_id(DislikeType::Dislike)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -553,8 +532,7 @@ impl ApubLikeableType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
dislike.into_any_base()?,
|
dislike.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -563,17 +541,19 @@ impl ApubLikeableType for Post {
|
||||||
async fn send_undo_like(
|
async fn send_undo_like(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let page = self.to_apub(pool).await?;
|
let page = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let community_id = self.community_id;
|
let community_id = self.community_id;
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id)).await??;
|
let community = blocking(context.pool(), move |conn| {
|
||||||
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
let mut like = Like::new(creator.actor_id.to_owned(), page.into_any_base()?);
|
||||||
like
|
like
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(LikeType::Like)?)
|
.set_id(generate_activity_id(LikeType::Like)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -581,7 +561,7 @@ impl ApubLikeableType for Post {
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), like.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(public())
|
.set_to(public())
|
||||||
.set_many_ccs(vec![community.get_followers_url()?]);
|
.set_many_ccs(vec![community.get_followers_url()?]);
|
||||||
|
@ -591,8 +571,7 @@ impl ApubLikeableType for Post {
|
||||||
&community,
|
&community,
|
||||||
vec![community.get_shared_inbox_url()?],
|
vec![community.get_shared_inbox_url()?],
|
||||||
undo.into_any_base()?,
|
undo.into_any_base()?,
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -23,11 +24,9 @@ use activitystreams::{
|
||||||
Undo,
|
Undo,
|
||||||
Update,
|
Update,
|
||||||
},
|
},
|
||||||
context,
|
|
||||||
object::{kind::NoteType, Note, Tombstone},
|
object::{kind::NoteType, Note, Tombstone},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
private_message::{PrivateMessage, PrivateMessageForm},
|
private_message::{PrivateMessage, PrivateMessageForm},
|
||||||
|
@ -51,7 +50,7 @@ impl ToApub for PrivateMessage {
|
||||||
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
|
|
||||||
private_message
|
private_message
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(Url::parse(&self.ap_id.to_owned())?)
|
.set_id(Url::parse(&self.ap_id.to_owned())?)
|
||||||
.set_published(convert_datetime(self.published))
|
.set_published(convert_datetime(self.published))
|
||||||
.set_content(self.content.to_owned())
|
.set_content(self.content.to_owned())
|
||||||
|
@ -77,8 +76,7 @@ impl FromApub for PrivateMessageForm {
|
||||||
/// Parse an ActivityPub note received from another instance into a Lemmy Private message
|
/// Parse an ActivityPub note received from another instance into a Lemmy Private message
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
note: &Note,
|
note: &Note,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<PrivateMessageForm, LemmyError> {
|
) -> Result<PrivateMessageForm, LemmyError> {
|
||||||
let creator_actor_id = note
|
let creator_actor_id = note
|
||||||
|
@ -88,14 +86,14 @@ impl FromApub for PrivateMessageForm {
|
||||||
.single_xsd_any_uri()
|
.single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
|
|
||||||
let creator = get_or_fetch_and_upsert_user(&creator_actor_id, client, pool).await?;
|
let creator = get_or_fetch_and_upsert_user(&creator_actor_id, context).await?;
|
||||||
let recipient_actor_id = note
|
let recipient_actor_id = note
|
||||||
.to()
|
.to()
|
||||||
.context(location_info!())?
|
.context(location_info!())?
|
||||||
.clone()
|
.clone()
|
||||||
.single_xsd_any_uri()
|
.single_xsd_any_uri()
|
||||||
.context(location_info!())?;
|
.context(location_info!())?;
|
||||||
let recipient = get_or_fetch_and_upsert_user(&recipient_actor_id, client, pool).await?;
|
let recipient = get_or_fetch_and_upsert_user(&recipient_actor_id, context).await?;
|
||||||
let ap_id = note.id_unchecked().context(location_info!())?.to_string();
|
let ap_id = note.id_unchecked().context(location_info!())?.to_string();
|
||||||
check_is_apub_id_valid(&Url::parse(&ap_id)?)?;
|
check_is_apub_id_valid(&Url::parse(&ap_id)?)?;
|
||||||
|
|
||||||
|
@ -121,124 +119,120 @@ impl FromApub for PrivateMessageForm {
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl ApubObjectType for PrivateMessage {
|
impl ApubObjectType for PrivateMessage {
|
||||||
/// Send out information about a newly created private message
|
/// Send out information about a newly created private message
|
||||||
async fn send_create(
|
async fn send_create(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let recipient_id = self.recipient_id;
|
let recipient_id = self.recipient_id;
|
||||||
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
|
|
||||||
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut create = Create::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
let to = recipient.get_inbox_url()?;
|
let to = recipient.get_inbox_url()?;
|
||||||
create
|
create
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(CreateType::Create)?)
|
.set_id(generate_activity_id(CreateType::Create)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
insert_activity(creator.id, create.clone(), true, pool).await?;
|
insert_activity(creator.id, create.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &create.into_any_base()?, creator, vec![to]).await?;
|
send_activity(
|
||||||
|
context.client(),
|
||||||
|
&create.into_any_base()?,
|
||||||
|
creator,
|
||||||
|
vec![to],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send out information about an edited post, to the followers of the community.
|
/// Send out information about an edited post, to the followers of the community.
|
||||||
async fn send_update(
|
async fn send_update(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let recipient_id = self.recipient_id;
|
let recipient_id = self.recipient_id;
|
||||||
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
|
|
||||||
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut update = Update::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
let to = recipient.get_inbox_url()?;
|
let to = recipient.get_inbox_url()?;
|
||||||
update
|
update
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UpdateType::Update)?)
|
.set_id(generate_activity_id(UpdateType::Update)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
insert_activity(creator.id, update.clone(), true, pool).await?;
|
insert_activity(creator.id, update.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &update.into_any_base()?, creator, vec![to]).await?;
|
send_activity(
|
||||||
|
context.client(),
|
||||||
|
&update.into_any_base()?,
|
||||||
|
creator,
|
||||||
|
vec![to],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, creator: &User_, context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
let note = self.to_apub(context.pool()).await?;
|
||||||
creator: &User_,
|
|
||||||
client: &Client,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
let note = self.to_apub(pool).await?;
|
|
||||||
|
|
||||||
let recipient_id = self.recipient_id;
|
let recipient_id = self.recipient_id;
|
||||||
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
let to = recipient.get_inbox_url()?;
|
let to = recipient.get_inbox_url()?;
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
insert_activity(creator.id, delete.clone(), true, pool).await?;
|
insert_activity(creator.id, delete.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &delete.into_any_base()?, creator, vec![to]).await?;
|
send_activity(
|
||||||
|
context.client(),
|
||||||
|
&delete.into_any_base()?,
|
||||||
|
creator,
|
||||||
|
vec![to],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
creator: &User_,
|
creator: &User_,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let note = self.to_apub(pool).await?;
|
let note = self.to_apub(context.pool()).await?;
|
||||||
|
|
||||||
let recipient_id = self.recipient_id;
|
let recipient_id = self.recipient_id;
|
||||||
let recipient = blocking(pool, move |conn| User_::read(conn, recipient_id)).await??;
|
let recipient = blocking(context.pool(), move |conn| User_::read(conn, recipient_id)).await??;
|
||||||
|
|
||||||
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
let mut delete = Delete::new(creator.actor_id.to_owned(), note.into_any_base()?);
|
||||||
let to = recipient.get_inbox_url()?;
|
let to = recipient.get_inbox_url()?;
|
||||||
delete
|
delete
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(DeleteType::Delete)?)
|
.set_id(generate_activity_id(DeleteType::Delete)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
let mut undo = Undo::new(creator.actor_id.to_owned(), delete.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?)
|
.set_id(generate_activity_id(UndoType::Undo)?)
|
||||||
.set_to(to.clone());
|
.set_to(to.clone());
|
||||||
|
|
||||||
insert_activity(creator.id, undo.clone(), true, pool).await?;
|
insert_activity(creator.id, undo.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &undo.into_any_base()?, creator, vec![to]).await?;
|
send_activity(context.client(), &undo.into_any_base()?, creator, vec![to]).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, _mod_: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
|
||||||
_mod_: &User_,
|
|
||||||
_client: &Client,
|
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_remove(
|
async fn send_undo_remove(
|
||||||
&self,
|
&self,
|
||||||
_mod_: &User_,
|
_mod_: &User_,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ use crate::{
|
||||||
ToApub,
|
ToApub,
|
||||||
},
|
},
|
||||||
blocking,
|
blocking,
|
||||||
routes::DbPoolParam,
|
|
||||||
DbPool,
|
DbPool,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -23,12 +23,11 @@ use activitystreams::{
|
||||||
Undo,
|
Undo,
|
||||||
},
|
},
|
||||||
actor::{ApActor, Endpoints, Person},
|
actor::{ApActor, Endpoints, Person},
|
||||||
context,
|
|
||||||
object::{Image, Tombstone},
|
object::{Image, Tombstone},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use actix_web::{body::Body, client::Client, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
naive_now,
|
naive_now,
|
||||||
|
@ -52,7 +51,7 @@ impl ToApub for User_ {
|
||||||
// TODO go through all these to_string and to_owned()
|
// TODO go through all these to_string and to_owned()
|
||||||
let mut person = Person::new();
|
let mut person = Person::new();
|
||||||
person
|
person
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(Url::parse(&self.actor_id)?)
|
.set_id(Url::parse(&self.actor_id)?)
|
||||||
.set_name(self.name.to_owned())
|
.set_name(self.name.to_owned())
|
||||||
.set_published(convert_datetime(self.published));
|
.set_published(convert_datetime(self.published));
|
||||||
|
@ -117,80 +116,66 @@ impl ActorType for User_ {
|
||||||
async fn send_follow(
|
async fn send_follow(
|
||||||
&self,
|
&self,
|
||||||
follow_actor_id: &Url,
|
follow_actor_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id.as_str());
|
let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id.as_str());
|
||||||
follow
|
follow
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(FollowType::Follow)?);
|
.set_id(generate_activity_id(FollowType::Follow)?);
|
||||||
let follow_actor = get_or_fetch_and_upsert_actor(follow_actor_id, client, pool).await?;
|
let follow_actor = get_or_fetch_and_upsert_actor(follow_actor_id, context).await?;
|
||||||
let to = follow_actor.get_inbox_url()?;
|
let to = follow_actor.get_inbox_url()?;
|
||||||
|
|
||||||
insert_activity(self.id, follow.clone(), true, pool).await?;
|
insert_activity(self.id, follow.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &follow.into_any_base()?, self, vec![to]).await?;
|
send_activity(context.client(), &follow.into_any_base()?, self, vec![to]).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_unfollow(
|
async fn send_unfollow(
|
||||||
&self,
|
&self,
|
||||||
follow_actor_id: &Url,
|
follow_actor_id: &Url,
|
||||||
client: &Client,
|
context: &LemmyContext,
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id.as_str());
|
let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id.as_str());
|
||||||
follow
|
follow
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(FollowType::Follow)?);
|
.set_id(generate_activity_id(FollowType::Follow)?);
|
||||||
let follow_actor = get_or_fetch_and_upsert_actor(follow_actor_id, client, pool).await?;
|
let follow_actor = get_or_fetch_and_upsert_actor(follow_actor_id, context).await?;
|
||||||
|
|
||||||
let to = follow_actor.get_inbox_url()?;
|
let to = follow_actor.get_inbox_url()?;
|
||||||
|
|
||||||
// Undo that fake activity
|
// Undo that fake activity
|
||||||
let mut undo = Undo::new(Url::parse(&self.actor_id)?, follow.into_any_base()?);
|
let mut undo = Undo::new(Url::parse(&self.actor_id)?, follow.into_any_base()?);
|
||||||
undo
|
undo
|
||||||
.set_context(context())
|
.set_context(activitystreams::context())
|
||||||
.set_id(generate_activity_id(UndoType::Undo)?);
|
.set_id(generate_activity_id(UndoType::Undo)?);
|
||||||
|
|
||||||
insert_activity(self.id, undo.clone(), true, pool).await?;
|
insert_activity(self.id, undo.clone(), true, context.pool()).await?;
|
||||||
|
|
||||||
send_activity(client, &undo.into_any_base()?, self, vec![to]).await?;
|
send_activity(context.client(), &undo.into_any_base()?, self, vec![to]).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_delete(
|
async fn send_delete(&self, _creator: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
|
||||||
_creator: &User_,
|
|
||||||
_client: &Client,
|
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_delete(
|
async fn send_undo_delete(
|
||||||
&self,
|
&self,
|
||||||
_creator: &User_,
|
_creator: &User_,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_remove(
|
async fn send_remove(&self, _creator: &User_, _context: &LemmyContext) -> Result<(), LemmyError> {
|
||||||
&self,
|
|
||||||
_creator: &User_,
|
|
||||||
_client: &Client,
|
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_undo_remove(
|
async fn send_undo_remove(
|
||||||
&self,
|
&self,
|
||||||
_creator: &User_,
|
_creator: &User_,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -198,8 +183,7 @@ impl ActorType for User_ {
|
||||||
async fn send_accept_follow(
|
async fn send_accept_follow(
|
||||||
&self,
|
&self,
|
||||||
_follow: Follow,
|
_follow: Follow,
|
||||||
_client: &Client,
|
_context: &LemmyContext,
|
||||||
_pool: &DbPool,
|
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -219,8 +203,7 @@ impl FromApub for UserForm {
|
||||||
/// Parse an ActivityPub person received from another instance into a Lemmy user.
|
/// Parse an ActivityPub person received from another instance into a Lemmy user.
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
person: &PersonExt,
|
person: &PersonExt,
|
||||||
_: &Client,
|
_context: &LemmyContext,
|
||||||
_: &DbPool,
|
|
||||||
expected_domain: Option<Url>,
|
expected_domain: Option<Url>,
|
||||||
) -> Result<Self, LemmyError> {
|
) -> Result<Self, LemmyError> {
|
||||||
let avatar = match person.icon() {
|
let avatar = match person.icon() {
|
||||||
|
@ -298,13 +281,13 @@ impl FromApub for UserForm {
|
||||||
/// Return the user json over HTTP.
|
/// Return the user json over HTTP.
|
||||||
pub async fn get_apub_user_http(
|
pub async fn get_apub_user_http(
|
||||||
info: web::Path<UserQuery>,
|
info: web::Path<UserQuery>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse<Body>, LemmyError> {
|
) -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
let user_name = info.into_inner().user_name;
|
let user_name = info.into_inner().user_name;
|
||||||
let user = blocking(&db, move |conn| {
|
let user = blocking(context.pool(), move |conn| {
|
||||||
User_::find_by_email_or_username(conn, &user_name)
|
User_::find_by_email_or_username(conn, &user_name)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let u = user.to_apub(&db).await?;
|
let u = user.to_apub(context.pool()).await?;
|
||||||
Ok(create_apub_response(&u))
|
Ok(create_apub_response(&u))
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,11 @@ pub mod routes;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
use crate::request::{retry, RecvError};
|
use crate::{
|
||||||
|
request::{retry, RecvError},
|
||||||
|
websocket::server::ChatServer,
|
||||||
|
};
|
||||||
|
use actix::Addr;
|
||||||
use actix_web::{client::Client, dev::ConnectionInfo};
|
use actix_web::{client::Client, dev::ConnectionInfo};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_utils::{get_apub_protocol_string, settings::Settings};
|
use lemmy_utils::{get_apub_protocol_string, settings::Settings};
|
||||||
|
@ -67,6 +71,41 @@ impl std::fmt::Display for LemmyError {
|
||||||
|
|
||||||
impl actix_web::error::ResponseError for LemmyError {}
|
impl actix_web::error::ResponseError for LemmyError {}
|
||||||
|
|
||||||
|
pub struct LemmyContext {
|
||||||
|
pub pool: DbPool,
|
||||||
|
pub chat_server: Addr<ChatServer>,
|
||||||
|
pub client: Client,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LemmyContext {
|
||||||
|
pub fn create(pool: DbPool, chat_server: Addr<ChatServer>, client: Client) -> LemmyContext {
|
||||||
|
LemmyContext {
|
||||||
|
pool,
|
||||||
|
chat_server,
|
||||||
|
client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn pool(&self) -> &DbPool {
|
||||||
|
&self.pool
|
||||||
|
}
|
||||||
|
pub fn chat_server(&self) -> &Addr<ChatServer> {
|
||||||
|
&self.chat_server
|
||||||
|
}
|
||||||
|
pub fn client(&self) -> &Client {
|
||||||
|
&self.client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for LemmyContext {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
LemmyContext {
|
||||||
|
pool: self.pool.clone(),
|
||||||
|
chat_server: self.chat_server.clone(),
|
||||||
|
client: self.client.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct IframelyResponse {
|
pub struct IframelyResponse {
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
|
|
|
@ -25,6 +25,7 @@ use lemmy_server::{
|
||||||
rate_limit::{rate_limiter::RateLimiter, RateLimit},
|
rate_limit::{rate_limiter::RateLimiter, RateLimit},
|
||||||
routes::*,
|
routes::*,
|
||||||
websocket::server::*,
|
websocket::server::*,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{settings::Settings, CACHE_CONTROL_REGEX};
|
use lemmy_utils::{settings::Settings, CACHE_CONTROL_REGEX};
|
||||||
|
@ -68,9 +69,6 @@ async fn main() -> Result<(), LemmyError> {
|
||||||
rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
|
rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set up websocket server
|
|
||||||
let server = ChatServer::startup(pool.clone(), rate_limiter.clone(), Client::default()).start();
|
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Starting http server at {}:{}",
|
"Starting http server at {}:{}",
|
||||||
settings.bind, settings.port
|
settings.bind, settings.port
|
||||||
|
@ -78,14 +76,15 @@ async fn main() -> Result<(), LemmyError> {
|
||||||
|
|
||||||
// Create Http server with websocket support
|
// Create Http server with websocket support
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
let chat_server =
|
||||||
|
ChatServer::startup(pool.clone(), rate_limiter.clone(), Client::default()).start();
|
||||||
|
let context = LemmyContext::create(pool.clone(), chat_server, Client::default());
|
||||||
let settings = Settings::get();
|
let settings = Settings::get();
|
||||||
let rate_limiter = rate_limiter.clone();
|
let rate_limiter = rate_limiter.clone();
|
||||||
App::new()
|
App::new()
|
||||||
.wrap_fn(add_cache_headers)
|
.wrap_fn(add_cache_headers)
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.data(pool.clone())
|
.data(context)
|
||||||
.data(server.clone())
|
|
||||||
.data(Client::default())
|
|
||||||
// The routes
|
// The routes
|
||||||
.configure(|cfg| api::config(cfg, &rate_limiter))
|
.configure(|cfg| api::config(cfg, &rate_limiter))
|
||||||
.configure(federation::config)
|
.configure(federation::config)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{comment::*, community::*, post::*, site::*, user::*, Perform},
|
api::{comment::*, community::*, post::*, site::*, user::*, Perform},
|
||||||
rate_limit::RateLimit,
|
rate_limit::RateLimit,
|
||||||
routes::{ChatServerParam, DbPoolParam},
|
|
||||||
websocket::WebsocketInfo,
|
websocket::WebsocketInfo,
|
||||||
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::{client::Client, error::ErrorBadRequest, *};
|
use actix_web::{error::ErrorBadRequest, *};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
||||||
|
@ -174,21 +174,19 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
||||||
|
|
||||||
async fn perform<Request>(
|
async fn perform<Request>(
|
||||||
data: Request,
|
data: Request,
|
||||||
client: &Client,
|
context: web::Data<LemmyContext>,
|
||||||
db: DbPoolParam,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, Error>
|
) -> Result<HttpResponse, Error>
|
||||||
where
|
where
|
||||||
Request: Perform,
|
Request: Perform,
|
||||||
Request: Send + 'static,
|
Request: Send + 'static,
|
||||||
{
|
{
|
||||||
let ws_info = WebsocketInfo {
|
let ws_info = WebsocketInfo {
|
||||||
chatserver: chat_server.get_ref().to_owned(),
|
chatserver: context.chat_server().to_owned(),
|
||||||
id: None,
|
id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = data
|
let res = data
|
||||||
.perform(&db, Some(ws_info), client.clone())
|
.perform(&context, Some(ws_info))
|
||||||
.await
|
.await
|
||||||
.map(|json| HttpResponse::Ok().json(json))
|
.map(|json| HttpResponse::Ok().json(json))
|
||||||
.map_err(ErrorBadRequest)?;
|
.map_err(ErrorBadRequest)?;
|
||||||
|
@ -197,24 +195,20 @@ where
|
||||||
|
|
||||||
async fn route_get<Data>(
|
async fn route_get<Data>(
|
||||||
data: web::Query<Data>,
|
data: web::Query<Data>,
|
||||||
client: web::Data<Client>,
|
context: web::Data<LemmyContext>,
|
||||||
db: DbPoolParam,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, Error>
|
) -> Result<HttpResponse, Error>
|
||||||
where
|
where
|
||||||
Data: Serialize + Send + 'static + Perform,
|
Data: Serialize + Send + 'static + Perform,
|
||||||
{
|
{
|
||||||
perform::<Data>(data.0, &client, db, chat_server).await
|
perform::<Data>(data.0, context).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn route_post<Data>(
|
async fn route_post<Data>(
|
||||||
data: web::Json<Data>,
|
data: web::Json<Data>,
|
||||||
client: web::Data<Client>,
|
context: web::Data<LemmyContext>,
|
||||||
db: DbPoolParam,
|
|
||||||
chat_server: ChatServerParam,
|
|
||||||
) -> Result<HttpResponse, Error>
|
) -> Result<HttpResponse, Error>
|
||||||
where
|
where
|
||||||
Data: Serialize + Send + 'static + Perform,
|
Data: Serialize + Send + 'static + Perform,
|
||||||
{
|
{
|
||||||
perform::<Data>(data.0, &client, db, chat_server).await
|
perform::<Data>(data.0, context).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use crate::{api::claims::Claims, blocking, routes::DbPoolParam, LemmyError};
|
use crate::{api::claims::Claims, blocking, LemmyContext, LemmyError};
|
||||||
use actix_web::{error::ErrorBadRequest, *};
|
use actix_web::{error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use diesel::{
|
use diesel::PgConnection;
|
||||||
r2d2::{ConnectionManager, Pool},
|
|
||||||
PgConnection,
|
|
||||||
};
|
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_view::{ReplyQueryBuilder, ReplyView},
|
comment_view::{ReplyQueryBuilder, ReplyView},
|
||||||
community::Community,
|
community::Community,
|
||||||
|
@ -40,12 +37,17 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
.route("/feeds/all.xml", web::get().to(get_all_feed));
|
.route("/feeds/all.xml", web::get().to(get_all_feed));
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_all_feed(info: web::Query<Params>, db: DbPoolParam) -> Result<HttpResponse, Error> {
|
async fn get_all_feed(
|
||||||
|
info: web::Query<Params>,
|
||||||
|
context: web::Data<LemmyContext>,
|
||||||
|
) -> Result<HttpResponse, Error> {
|
||||||
let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
|
let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
|
||||||
|
|
||||||
let rss = blocking(&db, move |conn| get_feed_all_data(conn, &sort_type))
|
let rss = blocking(context.pool(), move |conn| {
|
||||||
.await?
|
get_feed_all_data(conn, &sort_type)
|
||||||
.map_err(ErrorBadRequest)?;
|
})
|
||||||
|
.await?
|
||||||
|
.map_err(ErrorBadRequest)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
|
@ -80,7 +82,7 @@ fn get_feed_all_data(conn: &PgConnection, sort_type: &SortType) -> Result<String
|
||||||
async fn get_feed(
|
async fn get_feed(
|
||||||
path: web::Path<(String, String)>,
|
path: web::Path<(String, String)>,
|
||||||
info: web::Query<Params>,
|
info: web::Query<Params>,
|
||||||
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
|
let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ async fn get_feed(
|
||||||
|
|
||||||
let param = path.1.to_owned();
|
let param = path.1.to_owned();
|
||||||
|
|
||||||
let builder = blocking(&db, move |conn| match request_type {
|
let builder = blocking(context.pool(), move |conn| match request_type {
|
||||||
RequestType::User => get_feed_user(conn, &sort_type, param),
|
RequestType::User => get_feed_user(conn, &sort_type, param),
|
||||||
RequestType::Community => get_feed_community(conn, &sort_type, param),
|
RequestType::Community => get_feed_community(conn, &sort_type, param),
|
||||||
RequestType::Front => get_feed_front(conn, &sort_type, param),
|
RequestType::Front => get_feed_front(conn, &sort_type, param),
|
||||||
|
|
|
@ -6,14 +6,3 @@ pub mod index;
|
||||||
pub mod nodeinfo;
|
pub mod nodeinfo;
|
||||||
pub mod webfinger;
|
pub mod webfinger;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
use crate::websocket::server::ChatServer;
|
|
||||||
use actix::prelude::*;
|
|
||||||
use actix_web::*;
|
|
||||||
use diesel::{
|
|
||||||
r2d2::{ConnectionManager, Pool},
|
|
||||||
PgConnection,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub type DbPoolParam = web::Data<Pool<ConnectionManager<PgConnection>>>;
|
|
||||||
pub type ChatServerParam = web::Data<Addr<ChatServer>>;
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{blocking, routes::DbPoolParam, version, LemmyError};
|
use crate::{blocking, version, LemmyContext, LemmyError};
|
||||||
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_db::site_view::SiteView;
|
use lemmy_db::site_view::SiteView;
|
||||||
|
@ -26,8 +26,8 @@ async fn node_info_well_known() -> Result<HttpResponse<Body>, LemmyError> {
|
||||||
Ok(HttpResponse::Ok().json(node_info))
|
Ok(HttpResponse::Ok().json(node_info))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn node_info(db: DbPoolParam) -> Result<HttpResponse, Error> {
|
async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Error> {
|
||||||
let site_view = blocking(&db, SiteView::read)
|
let site_view = blocking(context.pool(), SiteView::read)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
|
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{blocking, routes::DbPoolParam, LemmyError};
|
use crate::{blocking, LemmyContext, LemmyError};
|
||||||
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_db::{community::Community, user::User_};
|
use lemmy_db::{community::Community, user::User_};
|
||||||
|
@ -44,7 +44,7 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
/// https://radical.town/.well-known/webfinger?resource=acct:felix@radical.town
|
/// https://radical.town/.well-known/webfinger?resource=acct:felix@radical.town
|
||||||
async fn get_webfinger_response(
|
async fn get_webfinger_response(
|
||||||
info: Query<Params>,
|
info: Query<Params>,
|
||||||
db: DbPoolParam,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let community_regex_parsed = WEBFINGER_COMMUNITY_REGEX
|
let community_regex_parsed = WEBFINGER_COMMUNITY_REGEX
|
||||||
.captures(&info.resource)
|
.captures(&info.resource)
|
||||||
|
@ -59,7 +59,7 @@ async fn get_webfinger_response(
|
||||||
let url = if let Some(community_name) = community_regex_parsed {
|
let url = if let Some(community_name) = community_regex_parsed {
|
||||||
let community_name = community_name.as_str().to_owned();
|
let community_name = community_name.as_str().to_owned();
|
||||||
// Make sure the requested community exists.
|
// Make sure the requested community exists.
|
||||||
blocking(&db, move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_name(conn, &community_name)
|
Community::read_from_name(conn, &community_name)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
|
@ -68,10 +68,12 @@ async fn get_webfinger_response(
|
||||||
} else if let Some(user_name) = user_regex_parsed {
|
} else if let Some(user_name) = user_regex_parsed {
|
||||||
let user_name = user_name.as_str().to_owned();
|
let user_name = user_name.as_str().to_owned();
|
||||||
// Make sure the requested user exists.
|
// Make sure the requested user exists.
|
||||||
blocking(&db, move |conn| User_::read_from_name(conn, &user_name))
|
blocking(context.pool(), move |conn| {
|
||||||
.await?
|
User_::read_from_name(conn, &user_name)
|
||||||
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?
|
})
|
||||||
.actor_id
|
.await?
|
||||||
|
.map_err(|_| ErrorBadRequest(LemmyError::from(anyhow!("not_found"))))?
|
||||||
|
.actor_id
|
||||||
} else {
|
} else {
|
||||||
return Err(ErrorBadRequest(LemmyError::from(anyhow!("not_found"))));
|
return Err(ErrorBadRequest(LemmyError::from(anyhow!("not_found"))));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
get_ip,
|
get_ip,
|
||||||
websocket::server::{ChatServer, *},
|
websocket::server::{ChatServer, *},
|
||||||
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
|
@ -17,11 +18,11 @@ const CLIENT_TIMEOUT: Duration = Duration::from_secs(10);
|
||||||
pub async fn chat_route(
|
pub async fn chat_route(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
stream: web::Payload,
|
stream: web::Payload,
|
||||||
chat_server: web::Data<Addr<ChatServer>>,
|
context: web::Data<LemmyContext>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
ws::start(
|
ws::start(
|
||||||
WSSession {
|
WSSession {
|
||||||
cs_addr: chat_server.get_ref().to_owned(),
|
cs_addr: context.chat_server().to_owned(),
|
||||||
id: 0,
|
id: 0,
|
||||||
hb: Instant::now(),
|
hb: Instant::now(),
|
||||||
ip: get_ip(&req.connection_info()),
|
ip: get_ip(&req.connection_info()),
|
||||||
|
|
|
@ -9,13 +9,13 @@ use crate::{
|
||||||
websocket::UserOperation,
|
websocket::UserOperation,
|
||||||
CommunityId,
|
CommunityId,
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
DbPool,
|
|
||||||
IPAddr,
|
IPAddr,
|
||||||
|
LemmyContext,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
PostId,
|
PostId,
|
||||||
UserId,
|
UserId,
|
||||||
};
|
};
|
||||||
use actix_web::client::Client;
|
use actix_web::{client::Client, web};
|
||||||
use anyhow::Context as acontext;
|
use anyhow::Context as acontext;
|
||||||
use lemmy_db::naive_now;
|
use lemmy_db::naive_now;
|
||||||
use lemmy_utils::location_info;
|
use lemmy_utils::location_info;
|
||||||
|
@ -465,11 +465,14 @@ impl ChatServer {
|
||||||
|
|
||||||
let user_operation: UserOperation = UserOperation::from_str(&op)?;
|
let user_operation: UserOperation = UserOperation::from_str(&op)?;
|
||||||
|
|
||||||
let args = Args {
|
let context = LemmyContext {
|
||||||
client,
|
|
||||||
pool,
|
pool,
|
||||||
|
chat_server: addr,
|
||||||
|
client,
|
||||||
|
};
|
||||||
|
let args = Args {
|
||||||
|
context: &context,
|
||||||
rate_limiter,
|
rate_limiter,
|
||||||
chatserver: addr,
|
|
||||||
id: msg.id,
|
id: msg.id,
|
||||||
ip,
|
ip,
|
||||||
op: user_operation.clone(),
|
op: user_operation.clone(),
|
||||||
|
@ -562,10 +565,8 @@ impl ChatServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Args<'a> {
|
struct Args<'a> {
|
||||||
client: Client,
|
context: &'a LemmyContext,
|
||||||
pool: DbPool,
|
|
||||||
rate_limiter: RateLimit,
|
rate_limiter: RateLimit,
|
||||||
chatserver: Addr<ChatServer>,
|
|
||||||
id: ConnectionId,
|
id: ConnectionId,
|
||||||
ip: IPAddr,
|
ip: IPAddr,
|
||||||
op: UserOperation,
|
op: UserOperation,
|
||||||
|
@ -578,10 +579,8 @@ where
|
||||||
Data: Perform,
|
Data: Perform,
|
||||||
{
|
{
|
||||||
let Args {
|
let Args {
|
||||||
client,
|
context,
|
||||||
pool,
|
|
||||||
rate_limiter,
|
rate_limiter,
|
||||||
chatserver,
|
|
||||||
id,
|
id,
|
||||||
ip,
|
ip,
|
||||||
op,
|
op,
|
||||||
|
@ -589,18 +588,18 @@ where
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
let ws_info = WebsocketInfo {
|
let ws_info = WebsocketInfo {
|
||||||
chatserver,
|
chatserver: context.chat_server().to_owned(),
|
||||||
id: Some(id),
|
id: Some(id),
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = data.to_string();
|
let data = data.to_string();
|
||||||
let op2 = op.clone();
|
let op2 = op.clone();
|
||||||
|
|
||||||
let client = client.clone();
|
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let pool = pool.clone();
|
|
||||||
let parsed_data: Data = serde_json::from_str(&data)?;
|
let parsed_data: Data = serde_json::from_str(&data)?;
|
||||||
let res = parsed_data.perform(&pool, Some(ws_info), client).await?;
|
let res = parsed_data
|
||||||
|
.perform(&web::Data::new(context.to_owned()), Some(ws_info))
|
||||||
|
.await?;
|
||||||
to_json_string(&op, &res)
|
to_json_string(&op, &res)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue