mirror of https://github.com/LemmyNet/lemmy.git
Respond directly with LemmyError
Instrument Perform implementations for more precise traces Use ApiError to format JSON errors when messages are present Keep SpanTrace output in LemmyError Display implasonix/better-errors
parent
ad76c75821
commit
6a2871024d
|
@ -1759,6 +1759,7 @@ dependencies = [
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
|
@ -48,5 +48,6 @@ async-trait = "0.1.51"
|
||||||
captcha = "0.0.8"
|
captcha = "0.0.8"
|
||||||
anyhow = "1.0.44"
|
anyhow = "1.0.44"
|
||||||
thiserror = "1.0.29"
|
thiserror = "1.0.29"
|
||||||
|
tracing = "0.1.29"
|
||||||
background-jobs = "0.11.0"
|
background-jobs = "0.11.0"
|
||||||
reqwest = { version = "0.11.4", features = ["json"] }
|
reqwest = { version = "0.11.4", features = ["json"] }
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_schema::{
|
||||||
traits::{Likeable, Saveable},
|
traits::{Likeable, Saveable},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView};
|
use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation};
|
use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation};
|
||||||
|
|
||||||
use crate::Perform;
|
use crate::Perform;
|
||||||
|
@ -32,6 +32,7 @@ use crate::Perform;
|
||||||
impl Perform for MarkCommentAsRead {
|
impl Perform for MarkCommentAsRead {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -56,7 +57,7 @@ impl Perform for MarkCommentAsRead {
|
||||||
|
|
||||||
// Verify that only the recipient can mark as read
|
// Verify that only the recipient can mark as read
|
||||||
if local_user_view.person.id != orig_comment.get_recipient_id() {
|
if local_user_view.person.id != orig_comment.get_recipient_id() {
|
||||||
return Err(ApiError::err_plain("no_comment_edit_allowed").into());
|
return Err(LemmyError::from_message("no_comment_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the mark as read
|
// Do the mark as read
|
||||||
|
@ -65,7 +66,8 @@ impl Perform for MarkCommentAsRead {
|
||||||
Comment::update_read(conn, comment_id, read)
|
Comment::update_read(conn, comment_id, read)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ApiError::err_plain("couldnt_update_comment"))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
|
@ -89,6 +91,7 @@ impl Perform for MarkCommentAsRead {
|
||||||
impl Perform for SaveComment {
|
impl Perform for SaveComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -107,12 +110,14 @@ impl Perform for SaveComment {
|
||||||
let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form);
|
let save_comment = move |conn: &'_ _| CommentSaved::save(conn, &comment_saved_form);
|
||||||
blocking(context.pool(), save_comment)
|
blocking(context.pool(), save_comment)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_save_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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);
|
||||||
blocking(context.pool(), unsave_comment)
|
blocking(context.pool(), unsave_comment)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_save_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_save_comment".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
|
@ -134,6 +139,7 @@ impl Perform for SaveComment {
|
||||||
impl Perform for CreateCommentLike {
|
impl Perform for CreateCommentLike {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -201,7 +207,8 @@ impl Perform for CreateCommentLike {
|
||||||
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2);
|
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form2);
|
||||||
blocking(context.pool(), like)
|
blocking(context.pool(), like)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_like_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_like_comment".into()))?;
|
||||||
|
|
||||||
Vote::send(
|
Vote::send(
|
||||||
&object,
|
&object,
|
||||||
|
|
|
@ -14,7 +14,7 @@ use lemmy_db_views::{
|
||||||
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
||||||
|
|
||||||
/// Creates a comment report and notifies the moderators of the community
|
/// Creates a comment report and notifies the moderators of the community
|
||||||
|
@ -22,6 +22,7 @@ use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}
|
||||||
impl Perform for CreateCommentReport {
|
impl Perform for CreateCommentReport {
|
||||||
type Response = CommentReportResponse;
|
type Response = CommentReportResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -34,10 +35,10 @@ impl Perform for CreateCommentReport {
|
||||||
// check size of report and check for whitespace
|
// check size of report and check for whitespace
|
||||||
let reason = data.reason.trim();
|
let reason = data.reason.trim();
|
||||||
if reason.is_empty() {
|
if reason.is_empty() {
|
||||||
return Err(ApiError::err_plain("report_reason_required").into());
|
return Err(LemmyError::from_message("report_reason_required".into()));
|
||||||
}
|
}
|
||||||
if reason.chars().count() > 1000 {
|
if reason.chars().count() > 1000 {
|
||||||
return Err(ApiError::err_plain("report_too_long").into());
|
return Err(LemmyError::from_message("report_too_long".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
@ -60,7 +61,8 @@ impl Perform for CreateCommentReport {
|
||||||
CommentReport::report(conn, &report_form)
|
CommentReport::report(conn, &report_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_report", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_report".into()))?;
|
||||||
|
|
||||||
let comment_report_view = blocking(context.pool(), move |conn| {
|
let comment_report_view = blocking(context.pool(), move |conn| {
|
||||||
CommentReportView::read(conn, report.id, person_id)
|
CommentReportView::read(conn, report.id, person_id)
|
||||||
|
@ -96,6 +98,7 @@ impl Perform for CreateCommentReport {
|
||||||
impl Perform for ResolveCommentReport {
|
impl Perform for ResolveCommentReport {
|
||||||
type Response = CommentReportResponse;
|
type Response = CommentReportResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -126,7 +129,8 @@ impl Perform for ResolveCommentReport {
|
||||||
|
|
||||||
blocking(context.pool(), resolve_fun)
|
blocking(context.pool(), resolve_fun)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_resolve_report", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_resolve_report".into()))?;
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let report_id = data.report_id;
|
||||||
let comment_report_view = blocking(context.pool(), move |conn| {
|
let comment_report_view = blocking(context.pool(), move |conn| {
|
||||||
|
@ -155,6 +159,7 @@ impl Perform for ResolveCommentReport {
|
||||||
impl Perform for ListCommentReports {
|
impl Perform for ListCommentReports {
|
||||||
type Response = ListCommentReportsResponse;
|
type Response = ListCommentReportsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -54,13 +54,14 @@ use lemmy_db_views_actor::{
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
person_view::PersonViewSafe,
|
person_view::PersonViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{location_info, utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{location_info, utils::naive_from_unix, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for FollowCommunity {
|
impl Perform for FollowCommunity {
|
||||||
type Response = CommunityResponse;
|
type Response = CommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -90,13 +91,15 @@ impl Perform for FollowCommunity {
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
blocking(context.pool(), follow)
|
blocking(context.pool(), follow)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_follower_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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);
|
||||||
blocking(context.pool(), unfollow)
|
blocking(context.pool(), unfollow)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_follower_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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
|
||||||
|
@ -109,7 +112,8 @@ impl Perform for FollowCommunity {
|
||||||
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form);
|
||||||
blocking(context.pool(), unfollow)
|
blocking(context.pool(), unfollow)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_follower_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_follower_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
|
@ -134,6 +138,7 @@ impl Perform for FollowCommunity {
|
||||||
impl Perform for BlockCommunity {
|
impl Perform for BlockCommunity {
|
||||||
type Response = BlockCommunityResponse;
|
type Response = BlockCommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -154,7 +159,8 @@ impl Perform for BlockCommunity {
|
||||||
let block = move |conn: &'_ _| CommunityBlock::block(conn, &community_block_form);
|
let block = move |conn: &'_ _| CommunityBlock::block(conn, &community_block_form);
|
||||||
blocking(context.pool(), block)
|
blocking(context.pool(), block)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_block_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_block_already_exists".into()))?;
|
||||||
|
|
||||||
// Also, unfollow the community, and send a federated unfollow
|
// Also, unfollow the community, and send a federated unfollow
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
@ -176,7 +182,8 @@ impl Perform for BlockCommunity {
|
||||||
let unblock = move |conn: &'_ _| CommunityBlock::unblock(conn, &community_block_form);
|
let unblock = move |conn: &'_ _| CommunityBlock::unblock(conn, &community_block_form);
|
||||||
blocking(context.pool(), unblock)
|
blocking(context.pool(), unblock)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_block_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_block_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let community_view = blocking(context.pool(), move |conn| {
|
let community_view = blocking(context.pool(), move |conn| {
|
||||||
|
@ -195,6 +202,7 @@ impl Perform for BlockCommunity {
|
||||||
impl Perform for BanFromCommunity {
|
impl Perform for BanFromCommunity {
|
||||||
type Response = BanFromCommunityResponse;
|
type Response = BanFromCommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -230,7 +238,8 @@ impl Perform for BanFromCommunity {
|
||||||
let ban = move |conn: &'_ _| CommunityPersonBan::ban(conn, &community_user_ban_form);
|
let ban = move |conn: &'_ _| CommunityPersonBan::ban(conn, &community_user_ban_form);
|
||||||
blocking(context.pool(), ban)
|
blocking(context.pool(), ban)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_user_already_banned", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_user_already_banned".into()))?;
|
||||||
|
|
||||||
// Also unsubscribe them from the community, if they are subscribed
|
// Also unsubscribe them from the community, if they are subscribed
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
@ -255,7 +264,8 @@ impl Perform for BanFromCommunity {
|
||||||
let unban = move |conn: &'_ _| CommunityPersonBan::unban(conn, &community_user_ban_form);
|
let unban = move |conn: &'_ _| CommunityPersonBan::unban(conn, &community_user_ban_form);
|
||||||
blocking(context.pool(), unban)
|
blocking(context.pool(), unban)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_user_already_banned", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_user_already_banned".into()))?;
|
||||||
UndoBlockUserFromCommunity::send(
|
UndoBlockUserFromCommunity::send(
|
||||||
&community,
|
&community,
|
||||||
&banned_person,
|
&banned_person,
|
||||||
|
@ -336,6 +346,7 @@ impl Perform for BanFromCommunity {
|
||||||
impl Perform for AddModToCommunity {
|
impl Perform for AddModToCommunity {
|
||||||
type Response = AddModToCommunityResponse;
|
type Response = AddModToCommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -359,12 +370,14 @@ impl Perform for AddModToCommunity {
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
blocking(context.pool(), join)
|
blocking(context.pool(), join)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_moderator_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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);
|
||||||
blocking(context.pool(), leave)
|
blocking(context.pool(), leave)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_moderator_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_moderator_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
|
@ -434,6 +447,7 @@ impl Perform for AddModToCommunity {
|
||||||
impl Perform for TransferCommunity {
|
impl Perform for TransferCommunity {
|
||||||
type Response = GetCommunityResponse;
|
type Response = GetCommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -472,7 +486,7 @@ impl Perform for TransferCommunity {
|
||||||
.map(|a| a.person.id)
|
.map(|a| a.person.id)
|
||||||
.any(|x| x == local_user_view.person.id)
|
.any(|x| x == local_user_view.person.id)
|
||||||
{
|
{
|
||||||
return Err(ApiError::err_plain("not_an_admin").into());
|
return Err(LemmyError::from_message("not_an_admin".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// You have to re-do the community_moderator table, reordering it.
|
// You have to re-do the community_moderator table, reordering it.
|
||||||
|
@ -502,7 +516,8 @@ impl Perform for TransferCommunity {
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
blocking(context.pool(), join)
|
blocking(context.pool(), join)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_moderator_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_moderator_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
|
@ -523,14 +538,16 @@ impl Perform for TransferCommunity {
|
||||||
CommunityView::read(conn, community_id, Some(person_id))
|
CommunityView::read(conn, community_id, Some(person_id))
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let moderators = blocking(context.pool(), move |conn| {
|
let moderators = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(GetCommunityResponse {
|
Ok(GetCommunityResponse {
|
||||||
|
|
|
@ -49,7 +49,6 @@ use lemmy_utils::{
|
||||||
email::send_email,
|
email::send_email,
|
||||||
location_info,
|
location_info,
|
||||||
utils::{generate_random_string, is_valid_display_name, is_valid_matrix_id, naive_from_unix},
|
utils::{generate_random_string, is_valid_display_name, is_valid_matrix_id, naive_from_unix},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -63,6 +62,7 @@ use lemmy_websocket::{
|
||||||
impl Perform for Login {
|
impl Perform for Login {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -76,7 +76,8 @@ impl Perform for Login {
|
||||||
LocalUserView::find_by_email_or_name(conn, &username_or_email)
|
LocalUserView::find_by_email_or_name(conn, &username_or_email)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_that_username_or_email".into()))?;
|
||||||
|
|
||||||
// Verify the password
|
// Verify the password
|
||||||
let valid: bool = verify(
|
let valid: bool = verify(
|
||||||
|
@ -85,7 +86,7 @@ impl Perform for Login {
|
||||||
)
|
)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if !valid {
|
if !valid {
|
||||||
return Err(ApiError::err_plain("password_incorrect").into());
|
return Err(LemmyError::from_message("password_incorrect".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
|
@ -103,6 +104,7 @@ impl Perform for Login {
|
||||||
impl Perform for GetCaptcha {
|
impl Perform for GetCaptcha {
|
||||||
type Response = GetCaptchaResponse;
|
type Response = GetCaptchaResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -148,6 +150,7 @@ impl Perform for GetCaptcha {
|
||||||
impl Perform for SaveUserSettings {
|
impl Perform for SaveUserSettings {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -167,7 +170,7 @@ impl Perform for SaveUserSettings {
|
||||||
|
|
||||||
if let Some(Some(bio)) = &bio {
|
if let Some(Some(bio)) = &bio {
|
||||||
if bio.chars().count() > 300 {
|
if bio.chars().count() > 300 {
|
||||||
return Err(ApiError::err_plain("bio_length_overflow").into());
|
return Err(LemmyError::from_message("bio_length_overflow".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,13 +179,13 @@ impl Perform for SaveUserSettings {
|
||||||
display_name.trim(),
|
display_name.trim(),
|
||||||
context.settings().actor_name_max_length,
|
context.settings().actor_name_max_length,
|
||||||
) {
|
) {
|
||||||
return Err(ApiError::err_plain("invalid_username").into());
|
return Err(LemmyError::from_message("invalid_username".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Some(matrix_user_id)) = &matrix_user_id {
|
if let Some(Some(matrix_user_id)) = &matrix_user_id {
|
||||||
if !is_valid_matrix_id(matrix_user_id) {
|
if !is_valid_matrix_id(matrix_user_id) {
|
||||||
return Err(ApiError::err_plain("invalid_matrix_id").into());
|
return Err(LemmyError::from_message("invalid_matrix_id".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +222,8 @@ impl Perform for SaveUserSettings {
|
||||||
Person::update(conn, person_id, &person_form)
|
Person::update(conn, person_id, &person_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("user_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("user_already_exists".into()))?;
|
||||||
|
|
||||||
let local_user_form = LocalUserForm {
|
let local_user_form = LocalUserForm {
|
||||||
person_id,
|
person_id,
|
||||||
|
@ -253,7 +257,7 @@ impl Perform for SaveUserSettings {
|
||||||
"user_already_exists"
|
"user_already_exists"
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(ApiError::err(err_type, e).into());
|
return Err(LemmyError::from(e).with_message(err_type.into()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,6 +276,7 @@ impl Perform for SaveUserSettings {
|
||||||
impl Perform for ChangePassword {
|
impl Perform for ChangePassword {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -285,7 +290,7 @@ impl Perform for ChangePassword {
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if data.new_password != data.new_password_verify {
|
if data.new_password != data.new_password_verify {
|
||||||
return Err(ApiError::err_plain("passwords_dont_match").into());
|
return Err(LemmyError::from_message("passwords_dont_match".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the old password
|
// Check the old password
|
||||||
|
@ -295,7 +300,7 @@ impl Perform for ChangePassword {
|
||||||
)
|
)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if !valid {
|
if !valid {
|
||||||
return Err(ApiError::err_plain("password_incorrect").into());
|
return Err(LemmyError::from_message("password_incorrect".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_user_id = local_user_view.local_user.id;
|
let local_user_id = local_user_view.local_user.id;
|
||||||
|
@ -320,6 +325,7 @@ impl Perform for ChangePassword {
|
||||||
impl Perform for AddAdmin {
|
impl Perform for AddAdmin {
|
||||||
type Response = AddAdminResponse;
|
type Response = AddAdminResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -338,7 +344,8 @@ impl Perform for AddAdmin {
|
||||||
Person::add_admin(conn, added_person_id, added)
|
Person::add_admin(conn, added_person_id, added)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_user", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_user".into()))?;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModAddForm {
|
let form = ModAddForm {
|
||||||
|
@ -378,6 +385,7 @@ impl Perform for AddAdmin {
|
||||||
impl Perform for BanPerson {
|
impl Perform for BanPerson {
|
||||||
type Response = BanPersonResponse;
|
type Response = BanPersonResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -395,7 +403,8 @@ impl Perform for BanPerson {
|
||||||
let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban);
|
let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban);
|
||||||
blocking(context.pool(), ban_person)
|
blocking(context.pool(), ban_person)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_user", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_user".into()))?;
|
||||||
|
|
||||||
// Remove their data if that's desired
|
// Remove their data if that's desired
|
||||||
if data.remove_data.unwrap_or(false) {
|
if data.remove_data.unwrap_or(false) {
|
||||||
|
@ -471,6 +480,7 @@ impl Perform for BanPerson {
|
||||||
impl Perform for BlockPerson {
|
impl Perform for BlockPerson {
|
||||||
type Response = BlockPersonResponse;
|
type Response = BlockPersonResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -485,7 +495,7 @@ impl Perform for BlockPerson {
|
||||||
|
|
||||||
// Don't let a person block themselves
|
// Don't let a person block themselves
|
||||||
if target_id == person_id {
|
if target_id == person_id {
|
||||||
return Err(ApiError::err_plain("cant_block_yourself").into());
|
return Err(LemmyError::from_message("cant_block_yourself".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_block_form = PersonBlockForm {
|
let person_block_form = PersonBlockForm {
|
||||||
|
@ -497,12 +507,14 @@ impl Perform for BlockPerson {
|
||||||
let block = move |conn: &'_ _| PersonBlock::block(conn, &person_block_form);
|
let block = move |conn: &'_ _| PersonBlock::block(conn, &person_block_form);
|
||||||
blocking(context.pool(), block)
|
blocking(context.pool(), block)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("person_block_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("person_block_already_exists".into()))?;
|
||||||
} else {
|
} else {
|
||||||
let unblock = move |conn: &'_ _| PersonBlock::unblock(conn, &person_block_form);
|
let unblock = move |conn: &'_ _| PersonBlock::unblock(conn, &person_block_form);
|
||||||
blocking(context.pool(), unblock)
|
blocking(context.pool(), unblock)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("person_block_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("person_block_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO does any federated stuff need to be done here?
|
// TODO does any federated stuff need to be done here?
|
||||||
|
@ -525,6 +537,7 @@ impl Perform for BlockPerson {
|
||||||
impl Perform for GetReplies {
|
impl Perform for GetReplies {
|
||||||
type Response = GetRepliesResponse;
|
type Response = GetRepliesResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -563,6 +576,7 @@ impl Perform for GetReplies {
|
||||||
impl Perform for GetPersonMentions {
|
impl Perform for GetPersonMentions {
|
||||||
type Response = GetPersonMentionsResponse;
|
type Response = GetPersonMentionsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -598,6 +612,7 @@ impl Perform for GetPersonMentions {
|
||||||
impl Perform for MarkPersonMentionAsRead {
|
impl Perform for MarkPersonMentionAsRead {
|
||||||
type Response = PersonMentionResponse;
|
type Response = PersonMentionResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -614,7 +629,7 @@ impl Perform for MarkPersonMentionAsRead {
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
if local_user_view.person.id != read_person_mention.recipient_id {
|
if local_user_view.person.id != read_person_mention.recipient_id {
|
||||||
return Err(ApiError::err_plain("couldnt_update_comment").into());
|
return Err(LemmyError::from_message("couldnt_update_comment".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
let person_mention_id = read_person_mention.id;
|
||||||
|
@ -623,7 +638,8 @@ impl Perform for MarkPersonMentionAsRead {
|
||||||
move |conn: &'_ _| PersonMention::update_read(conn, person_mention_id, read);
|
move |conn: &'_ _| PersonMention::update_read(conn, person_mention_id, read);
|
||||||
blocking(context.pool(), update_mention)
|
blocking(context.pool(), update_mention)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
let person_mention_id = read_person_mention.id;
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
@ -642,6 +658,7 @@ impl Perform for MarkPersonMentionAsRead {
|
||||||
impl Perform for MarkAllAsRead {
|
impl Perform for MarkAllAsRead {
|
||||||
type Response = GetRepliesResponse;
|
type Response = GetRepliesResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -671,7 +688,8 @@ impl Perform for MarkAllAsRead {
|
||||||
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);
|
||||||
blocking(context.pool(), mark_as_read)
|
blocking(context.pool(), mark_as_read)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark all user mentions as read
|
// Mark all user mentions as read
|
||||||
|
@ -679,13 +697,15 @@ impl Perform for MarkAllAsRead {
|
||||||
move |conn: &'_ _| PersonMention::mark_all_as_read(conn, person_id);
|
move |conn: &'_ _| PersonMention::mark_all_as_read(conn, person_id);
|
||||||
blocking(context.pool(), update_person_mentions)
|
blocking(context.pool(), update_person_mentions)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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, person_id);
|
let update_pm = move |conn: &'_ _| PrivateMessage::mark_all_as_read(conn, person_id);
|
||||||
blocking(context.pool(), update_pm)
|
blocking(context.pool(), update_pm)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_private_message", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_private_message".into()))?;
|
||||||
|
|
||||||
Ok(GetRepliesResponse { replies: vec![] })
|
Ok(GetRepliesResponse { replies: vec![] })
|
||||||
}
|
}
|
||||||
|
@ -695,6 +715,7 @@ impl Perform for MarkAllAsRead {
|
||||||
impl Perform for PasswordReset {
|
impl Perform for PasswordReset {
|
||||||
type Response = PasswordResetResponse;
|
type Response = PasswordResetResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -708,7 +729,8 @@ impl Perform for PasswordReset {
|
||||||
LocalUserView::find_by_email(conn, &email)
|
LocalUserView::find_by_email(conn, &email)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_that_username_or_email".into()))?;
|
||||||
|
|
||||||
// Generate a random token
|
// Generate a random token
|
||||||
let token = generate_random_string();
|
let token = generate_random_string();
|
||||||
|
@ -734,7 +756,8 @@ impl Perform for PasswordReset {
|
||||||
html,
|
html,
|
||||||
&context.settings(),
|
&context.settings(),
|
||||||
)
|
)
|
||||||
.map_err(|e| ApiError::err("email_send_failed", e))?;
|
.map_err(LemmyError::from_message)
|
||||||
|
.map_err(|e| e.with_message("email_send_failed".into()))?;
|
||||||
|
|
||||||
Ok(PasswordResetResponse {})
|
Ok(PasswordResetResponse {})
|
||||||
}
|
}
|
||||||
|
@ -744,6 +767,7 @@ impl Perform for PasswordReset {
|
||||||
impl Perform for PasswordChange {
|
impl Perform for PasswordChange {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -762,7 +786,7 @@ impl Perform for PasswordChange {
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if data.password != data.password_verify {
|
if data.password != data.password_verify {
|
||||||
return Err(ApiError::err_plain("passwords_dont_match").into());
|
return Err(LemmyError::from_message("passwords_dont_match".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the user with the new password
|
// Update the user with the new password
|
||||||
|
@ -771,7 +795,8 @@ impl Perform for PasswordChange {
|
||||||
LocalUser::update_password(conn, local_user_id, &password)
|
LocalUser::update_password(conn, local_user_id, &password)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_user", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_user".into()))?;
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(LoginResponse {
|
Ok(LoginResponse {
|
||||||
|
@ -788,6 +813,7 @@ impl Perform for PasswordChange {
|
||||||
impl Perform for GetReportCount {
|
impl Perform for GetReportCount {
|
||||||
type Response = GetReportCountResponse;
|
type Response = GetReportCountResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -825,6 +851,7 @@ impl Perform for GetReportCount {
|
||||||
impl Perform for GetUnreadCount {
|
impl Perform for GetUnreadCount {
|
||||||
type Response = GetUnreadCountResponse;
|
type Response = GetUnreadCountResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -29,7 +29,7 @@ use lemmy_db_schema::{
|
||||||
traits::{Crud, Likeable, Saveable},
|
traits::{Crud, Likeable, Saveable},
|
||||||
};
|
};
|
||||||
use lemmy_db_views::post_view::PostView;
|
use lemmy_db_views::post_view::PostView;
|
||||||
use lemmy_utils::{request::fetch_site_metadata, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{request::fetch_site_metadata, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation};
|
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ use std::convert::TryInto;
|
||||||
impl Perform for CreatePostLike {
|
impl Perform for CreatePostLike {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -83,7 +84,8 @@ impl Perform for CreatePostLike {
|
||||||
let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
|
let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
|
||||||
blocking(context.pool(), like)
|
blocking(context.pool(), like)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_like_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_like_post".into()))?;
|
||||||
|
|
||||||
Vote::send(
|
Vote::send(
|
||||||
&object,
|
&object,
|
||||||
|
@ -123,6 +125,7 @@ impl Perform for CreatePostLike {
|
||||||
impl Perform for MarkPostAsRead {
|
impl Perform for MarkPostAsRead {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -158,6 +161,7 @@ impl Perform for MarkPostAsRead {
|
||||||
impl Perform for LockPost {
|
impl Perform for LockPost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -227,6 +231,7 @@ impl Perform for LockPost {
|
||||||
impl Perform for StickyPost {
|
impl Perform for StickyPost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -300,6 +305,7 @@ impl Perform for StickyPost {
|
||||||
impl Perform for SavePost {
|
impl Perform for SavePost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -318,12 +324,14 @@ impl Perform for SavePost {
|
||||||
let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form);
|
let save = move |conn: &'_ _| PostSaved::save(conn, &post_saved_form);
|
||||||
blocking(context.pool(), save)
|
blocking(context.pool(), save)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_save_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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);
|
||||||
blocking(context.pool(), unsave)
|
blocking(context.pool(), unsave)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_save_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_save_post".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
|
@ -344,6 +352,7 @@ impl Perform for SavePost {
|
||||||
impl Perform for GetSiteMetadata {
|
impl Perform for GetSiteMetadata {
|
||||||
type Response = GetSiteMetadataResponse;
|
type Response = GetSiteMetadataResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_views::{
|
||||||
post_report_view::{PostReportQueryBuilder, PostReportView},
|
post_report_view::{PostReportQueryBuilder, PostReportView},
|
||||||
post_view::PostView,
|
post_view::PostView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
|
||||||
|
|
||||||
/// Creates a post report and notifies the moderators of the community
|
/// Creates a post report and notifies the moderators of the community
|
||||||
|
@ -31,6 +31,7 @@ use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation}
|
||||||
impl Perform for CreatePostReport {
|
impl Perform for CreatePostReport {
|
||||||
type Response = PostReportResponse;
|
type Response = PostReportResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -43,10 +44,10 @@ impl Perform for CreatePostReport {
|
||||||
// check size of report and check for whitespace
|
// check size of report and check for whitespace
|
||||||
let reason = data.reason.trim();
|
let reason = data.reason.trim();
|
||||||
if reason.is_empty() {
|
if reason.is_empty() {
|
||||||
return Err(ApiError::err_plain("report_reason_required").into());
|
return Err(LemmyError::from_message("report_reason_required".into()));
|
||||||
}
|
}
|
||||||
if reason.chars().count() > 1000 {
|
if reason.chars().count() > 1000 {
|
||||||
return Err(ApiError::err_plain("report_too_long").into());
|
return Err(LemmyError::from_message("report_too_long".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
@ -71,7 +72,8 @@ impl Perform for CreatePostReport {
|
||||||
PostReport::report(conn, &report_form)
|
PostReport::report(conn, &report_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_report", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_report".into()))?;
|
||||||
|
|
||||||
let post_report_view = blocking(context.pool(), move |conn| {
|
let post_report_view = blocking(context.pool(), move |conn| {
|
||||||
PostReportView::read(conn, report.id, person_id)
|
PostReportView::read(conn, report.id, person_id)
|
||||||
|
@ -105,6 +107,7 @@ impl Perform for CreatePostReport {
|
||||||
impl Perform for ResolvePostReport {
|
impl Perform for ResolvePostReport {
|
||||||
type Response = PostReportResponse;
|
type Response = PostReportResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -135,7 +138,8 @@ impl Perform for ResolvePostReport {
|
||||||
|
|
||||||
blocking(context.pool(), resolve_fun)
|
blocking(context.pool(), resolve_fun)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_resolve_report", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_resolve_report".into()))?;
|
||||||
|
|
||||||
let post_report_view = blocking(context.pool(), move |conn| {
|
let post_report_view = blocking(context.pool(), move |conn| {
|
||||||
PostReportView::read(conn, report_id, person_id)
|
PostReportView::read(conn, report_id, person_id)
|
||||||
|
@ -161,6 +165,7 @@ impl Perform for ResolvePostReport {
|
||||||
impl Perform for ListPostReports {
|
impl Perform for ListPostReports {
|
||||||
type Response = ListPostReportsResponse;
|
type Response = ListPostReportsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -6,13 +6,14 @@ use lemmy_api_common::{
|
||||||
person::{MarkPrivateMessageAsRead, PrivateMessageResponse},
|
person::{MarkPrivateMessageAsRead, PrivateMessageResponse},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperation};
|
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperation};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for MarkPrivateMessageAsRead {
|
impl Perform for MarkPrivateMessageAsRead {
|
||||||
type Response = PrivateMessageResponse;
|
type Response = PrivateMessageResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -29,7 +30,9 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if local_user_view.person.id != orig_private_message.recipient_id {
|
if local_user_view.person.id != orig_private_message.recipient_id {
|
||||||
return Err(ApiError::err_plain("couldnt_update_private_message").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"couldnt_update_private_message".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
|
@ -39,7 +42,8 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
PrivateMessage::update_read(conn, private_message_id, read)
|
PrivateMessage::update_read(conn, private_message_id, read)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_private_message", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_private_message".into()))?;
|
||||||
|
|
||||||
// No need to send an apub update
|
// No need to send an apub update
|
||||||
let op = UserOperation::MarkPrivateMessageAsRead;
|
let op = UserOperation::MarkPrivateMessageAsRead;
|
||||||
|
|
|
@ -49,20 +49,14 @@ use lemmy_db_views_moderator::{
|
||||||
mod_sticky_post_view::ModStickyPostView,
|
mod_sticky_post_view::ModStickyPostView,
|
||||||
mod_transfer_community_view::ModTransferCommunityView,
|
mod_transfer_community_view::ModTransferCommunityView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{location_info, settings::structs::Settings, version, ConnectionId, LemmyError};
|
||||||
location_info,
|
|
||||||
settings::structs::Settings,
|
|
||||||
version,
|
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
|
||||||
LemmyError,
|
|
||||||
};
|
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for GetModlog {
|
impl Perform for GetModlog {
|
||||||
type Response = GetModlogResponse;
|
type Response = GetModlogResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -143,6 +137,7 @@ impl Perform for GetModlog {
|
||||||
impl Perform for Search {
|
impl Perform for Search {
|
||||||
type Response = SearchResponse;
|
type Response = SearchResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -383,6 +378,7 @@ impl Perform for Search {
|
||||||
impl Perform for ResolveObject {
|
impl Perform for ResolveObject {
|
||||||
type Response = ResolveObjectResponse;
|
type Response = ResolveObjectResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -392,10 +388,12 @@ impl Perform for ResolveObject {
|
||||||
get_local_user_view_from_jwt_opt(&self.auth, context.pool(), context.secret()).await?;
|
get_local_user_view_from_jwt_opt(&self.auth, context.pool(), context.secret()).await?;
|
||||||
let res = search_by_apub_id(&self.q, context)
|
let res = search_by_apub_id(&self.q, context)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::err("couldnt_find_object", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_object".into()))?;
|
||||||
convert_response(res, local_user_view.map(|l| l.person.id), context.pool())
|
convert_response(res, local_user_view.map(|l| l.person.id), context.pool())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::err("couldnt_find_object", e).into())
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_object".into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +440,7 @@ async fn convert_response(
|
||||||
impl Perform for TransferSite {
|
impl Perform for TransferSite {
|
||||||
type Response = GetSiteResponse;
|
type Response = GetSiteResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -457,14 +456,15 @@ impl Perform for TransferSite {
|
||||||
|
|
||||||
// Make sure user is the creator
|
// Make sure user is the creator
|
||||||
if read_site.creator_id != local_user_view.person.id {
|
if read_site.creator_id != local_user_view.person.id {
|
||||||
return Err(ApiError::err_plain("not_an_admin").into());
|
return Err(LemmyError::from_message("not_an_admin".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_creator_id = data.person_id;
|
let new_creator_id = data.person_id;
|
||||||
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
|
let transfer_site = move |conn: &'_ _| Site::transfer(conn, new_creator_id);
|
||||||
blocking(context.pool(), transfer_site)
|
blocking(context.pool(), transfer_site)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_site", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_site".into()))?;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModAddForm {
|
let form = ModAddForm {
|
||||||
|
@ -509,6 +509,7 @@ impl Perform for TransferSite {
|
||||||
impl Perform for GetSiteConfig {
|
impl Perform for GetSiteConfig {
|
||||||
type Response = GetSiteConfigResponse;
|
type Response = GetSiteConfigResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -531,6 +532,7 @@ impl Perform for GetSiteConfig {
|
||||||
impl Perform for SaveSiteConfig {
|
impl Perform for SaveSiteConfig {
|
||||||
type Response = GetSiteConfigResponse;
|
type Response = GetSiteConfigResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -545,7 +547,8 @@ impl Perform for SaveSiteConfig {
|
||||||
|
|
||||||
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
|
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
|
||||||
let config_hjson = Settings::save_config_file(&data.config_hjson)
|
let config_hjson = Settings::save_config_file(&data.config_hjson)
|
||||||
.map_err(|e| ApiError::err("couldnt_update_site", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_site".into()))?;
|
||||||
|
|
||||||
Ok(GetSiteConfigResponse { config_hjson })
|
Ok(GetSiteConfigResponse { config_hjson })
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use lemmy_websocket::{
|
||||||
impl Perform for UserJoin {
|
impl Perform for UserJoin {
|
||||||
type Response = UserJoinResponse;
|
type Response = UserJoinResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -35,6 +36,7 @@ impl Perform for UserJoin {
|
||||||
impl Perform for CommunityJoin {
|
impl Perform for CommunityJoin {
|
||||||
type Response = CommunityJoinResponse;
|
type Response = CommunityJoinResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -57,6 +59,7 @@ impl Perform for CommunityJoin {
|
||||||
impl Perform for ModJoin {
|
impl Perform for ModJoin {
|
||||||
type Response = ModJoinResponse;
|
type Response = ModJoinResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -79,6 +82,7 @@ impl Perform for ModJoin {
|
||||||
impl Perform for PostJoin {
|
impl Perform for PostJoin {
|
||||||
type Response = PostJoinResponse;
|
type Response = PostJoinResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_views_actor::{
|
||||||
community_person_ban_view::CommunityPersonBanView,
|
community_person_ban_view::CommunityPersonBanView,
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{claims::Claims, settings::structs::FederationConfig, ApiError, LemmyError};
|
use lemmy_utils::{claims::Claims, settings::structs::FederationConfig, LemmyError};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
|
pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
|
||||||
|
@ -52,14 +52,14 @@ pub async fn is_mod_or_admin(
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
if !is_mod_or_admin {
|
if !is_mod_or_admin {
|
||||||
return Err(ApiError::err_plain("not_a_mod_or_admin").into());
|
return Err(LemmyError::from_message("not_a_mod_or_admin".into()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
|
pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
|
||||||
if !local_user_view.person.admin {
|
if !local_user_view.person.admin {
|
||||||
return Err(ApiError::err_plain("not_an_admin").into());
|
return Err(LemmyError::from_message("not_an_admin".into()));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,8 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
|
||||||
pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
|
pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
|
||||||
blocking(pool, move |conn| Post::read(conn, post_id))
|
blocking(pool, move |conn| Post::read(conn, post_id))
|
||||||
.await?
|
.await?
|
||||||
.map_err(|_| ApiError::err_plain("couldnt_find_post").into())
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_post".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_post_as_read(
|
pub async fn mark_post_as_read(
|
||||||
|
@ -81,7 +82,8 @@ pub async fn mark_post_as_read(
|
||||||
PostRead::mark_as_read(conn, &post_read_form)
|
PostRead::mark_as_read(conn, &post_read_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_mark_post_as_read", e).into())
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_mark_post_as_read".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mark_post_as_unread(
|
pub async fn mark_post_as_unread(
|
||||||
|
@ -95,7 +97,8 @@ pub async fn mark_post_as_unread(
|
||||||
PostRead::mark_as_unread(conn, &post_read_form)
|
PostRead::mark_as_unread(conn, &post_read_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_mark_post_as_read", e).into())
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_mark_post_as_read".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_local_user_view_from_jwt(
|
pub async fn get_local_user_view_from_jwt(
|
||||||
|
@ -104,19 +107,20 @@ pub async fn get_local_user_view_from_jwt(
|
||||||
secret: &Secret,
|
secret: &Secret,
|
||||||
) -> Result<LocalUserView, LemmyError> {
|
) -> Result<LocalUserView, LemmyError> {
|
||||||
let claims = Claims::decode(jwt, &secret.jwt_secret)
|
let claims = Claims::decode(jwt, &secret.jwt_secret)
|
||||||
.map_err(|e| ApiError::err("not_logged_in", e))?
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("not_logged_in".into()))?
|
||||||
.claims;
|
.claims;
|
||||||
let local_user_id = LocalUserId(claims.sub);
|
let local_user_id = LocalUserId(claims.sub);
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??;
|
blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??;
|
||||||
// Check for a site ban
|
// Check for a site ban
|
||||||
if local_user_view.person.banned {
|
if local_user_view.person.banned {
|
||||||
return Err(ApiError::err_plain("site_ban").into());
|
return Err(LemmyError::from_message("site_ban".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for user deletion
|
// Check for user deletion
|
||||||
if local_user_view.person.deleted {
|
if local_user_view.person.deleted {
|
||||||
return Err(ApiError::err_plain("deleted").into());
|
return Err(LemmyError::from_message("deleted".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
|
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
|
||||||
|
@ -131,7 +135,7 @@ pub fn check_validator_time(
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let user_validation_time = validator_time.timestamp();
|
let user_validation_time = validator_time.timestamp();
|
||||||
if user_validation_time > claims.iat {
|
if user_validation_time > claims.iat {
|
||||||
Err(ApiError::err_plain("not_logged_in").into())
|
Err(LemmyError::from_message("not_logged_in".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -154,7 +158,8 @@ pub async fn get_local_user_settings_view_from_jwt(
|
||||||
secret: &Secret,
|
secret: &Secret,
|
||||||
) -> Result<LocalUserSettingsView, LemmyError> {
|
) -> Result<LocalUserSettingsView, LemmyError> {
|
||||||
let claims = Claims::decode(jwt, &secret.jwt_secret)
|
let claims = Claims::decode(jwt, &secret.jwt_secret)
|
||||||
.map_err(|e| ApiError::err("not_logged_in", e))?
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("not_logged_in".into()))?
|
||||||
.claims;
|
.claims;
|
||||||
let local_user_id = LocalUserId(claims.sub);
|
let local_user_id = LocalUserId(claims.sub);
|
||||||
let local_user_view = blocking(pool, move |conn| {
|
let local_user_view = blocking(pool, move |conn| {
|
||||||
|
@ -163,7 +168,7 @@ pub async fn get_local_user_settings_view_from_jwt(
|
||||||
.await??;
|
.await??;
|
||||||
// Check for a site ban
|
// Check for a site ban
|
||||||
if local_user_view.person.banned {
|
if local_user_view.person.banned {
|
||||||
return Err(ApiError::err_plain("site_ban").into());
|
return Err(LemmyError::from_message("site_ban".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
|
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
|
||||||
|
@ -192,7 +197,7 @@ pub async fn check_community_ban(
|
||||||
let is_banned =
|
let is_banned =
|
||||||
move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
|
||||||
if blocking(pool, is_banned).await? {
|
if blocking(pool, is_banned).await? {
|
||||||
Err(ApiError::err_plain("community_ban").into())
|
Err(LemmyError::from_message("community_ban".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -204,9 +209,10 @@ pub async fn check_community_deleted_or_removed(
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let community = blocking(pool, move |conn| Community::read(conn, community_id))
|
let community = blocking(pool, move |conn| Community::read(conn, community_id))
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
if community.deleted || community.removed {
|
if community.deleted || community.removed {
|
||||||
Err(ApiError::err_plain("deleted").into())
|
Err(LemmyError::from_message("deleted".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -214,7 +220,7 @@ pub async fn check_community_deleted_or_removed(
|
||||||
|
|
||||||
pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
|
pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
|
||||||
if post.deleted || post.removed {
|
if post.deleted || post.removed {
|
||||||
Err(ApiError::err_plain("deleted").into())
|
Err(LemmyError::from_message("deleted".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -227,7 +233,7 @@ pub async fn check_person_block(
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
let is_blocked = move |conn: &'_ _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok();
|
let is_blocked = move |conn: &'_ _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok();
|
||||||
if blocking(pool, is_blocked).await? {
|
if blocking(pool, is_blocked).await? {
|
||||||
Err(ApiError::err_plain("person_block").into())
|
Err(LemmyError::from_message("person_block".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -237,7 +243,7 @@ pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), Le
|
||||||
if score == -1 {
|
if score == -1 {
|
||||||
let site = blocking(pool, Site::read_simple).await??;
|
let site = blocking(pool, Site::read_simple).await??;
|
||||||
if !site.enable_downvotes {
|
if !site.enable_downvotes {
|
||||||
return Err(ApiError::err_plain("downvotes_disabled").into());
|
return Err(LemmyError::from_message("downvotes_disabled".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -288,7 +294,7 @@ pub async fn build_federated_instances(
|
||||||
/// Checks the password length
|
/// Checks the password length
|
||||||
pub fn password_length_check(pass: &str) -> Result<(), LemmyError> {
|
pub fn password_length_check(pass: &str) -> Result<(), LemmyError> {
|
||||||
if !(10..=60).contains(&pass.len()) {
|
if !(10..=60).contains(&pass.len()) {
|
||||||
Err(ApiError::err_plain("invalid_password").into())
|
Err(LemmyError::from_message("invalid_password".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -297,7 +303,9 @@ pub fn password_length_check(pass: &str) -> Result<(), LemmyError> {
|
||||||
/// Checks the site description length
|
/// Checks the site description length
|
||||||
pub fn site_description_length_check(description: &str) -> Result<(), LemmyError> {
|
pub fn site_description_length_check(description: &str) -> Result<(), LemmyError> {
|
||||||
if description.len() > 150 {
|
if description.len() > 150 {
|
||||||
Err(ApiError::err_plain("site_description_length_overflow").into())
|
Err(LemmyError::from_message(
|
||||||
|
"site_description_length_overflow".into(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -306,7 +314,7 @@ pub fn site_description_length_check(description: &str) -> Result<(), LemmyError
|
||||||
/// Checks for a honeypot. If this field is filled, fail the rest of the function
|
/// Checks for a honeypot. If this field is filled, fail the rest of the function
|
||||||
pub fn honeypot_check(honeypot: &Option<String>) -> Result<(), LemmyError> {
|
pub fn honeypot_check(honeypot: &Option<String>) -> Result<(), LemmyError> {
|
||||||
if honeypot.is_some() {
|
if honeypot.is_some() {
|
||||||
Err(ApiError::err_plain("honeypot_fail").into())
|
Err(LemmyError::from_message("honeypot_fail".into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
use lemmy_db_views::comment_view::CommentView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
utils::{remove_slurs, scrape_text_for_mentions},
|
utils::{remove_slurs, scrape_text_for_mentions},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -45,6 +44,7 @@ use lemmy_websocket::{
|
||||||
impl PerformCrud for CreateComment {
|
impl PerformCrud for CreateComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -70,7 +70,7 @@ impl PerformCrud for CreateComment {
|
||||||
|
|
||||||
// Check if post is locked, no new comments
|
// Check if post is locked, no new comments
|
||||||
if post.locked {
|
if post.locked {
|
||||||
return Err(ApiError::err_plain("locked").into());
|
return Err(LemmyError::from_message("locked".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's a parent_id, check to make sure that comment is in that post
|
// If there's a parent_id, check to make sure that comment is in that post
|
||||||
|
@ -78,13 +78,14 @@ impl PerformCrud for CreateComment {
|
||||||
// Make sure the parent comment exists
|
// Make sure the parent comment exists
|
||||||
let parent = blocking(context.pool(), move |conn| Comment::read(conn, parent_id))
|
let parent = blocking(context.pool(), move |conn| Comment::read(conn, parent_id))
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_comment".into()))?;
|
||||||
|
|
||||||
check_person_block(local_user_view.person.id, parent.creator_id, context.pool()).await?;
|
check_person_block(local_user_view.person.id, parent.creator_id, context.pool()).await?;
|
||||||
|
|
||||||
// Strange issue where sometimes the post ID is incorrect
|
// Strange issue where sometimes the post ID is incorrect
|
||||||
if parent.post_id != post_id {
|
if parent.post_id != post_id {
|
||||||
return Err(ApiError::err_plain("couldnt_create_comment").into());
|
return Err(LemmyError::from_message("couldnt_create_comment".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +103,8 @@ impl PerformCrud for CreateComment {
|
||||||
Comment::create(conn, &comment_form2)
|
Comment::create(conn, &comment_form2)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("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;
|
||||||
|
@ -118,7 +120,8 @@ impl PerformCrud for CreateComment {
|
||||||
Ok(Comment::update_ap_id(conn, inserted_comment_id, apub_id)?)
|
Ok(Comment::update_ap_id(conn, inserted_comment_id, apub_id)?)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_comment".into()))?;
|
||||||
|
|
||||||
// Scan the comment for user mentions, add those rows
|
// Scan the comment for user mentions, add those rows
|
||||||
let post_id = post.id;
|
let post_id = post.id;
|
||||||
|
@ -144,7 +147,8 @@ impl PerformCrud for CreateComment {
|
||||||
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form);
|
let like = move |conn: &'_ _| CommentLike::like(conn, &like_form);
|
||||||
blocking(context.pool(), like)
|
blocking(context.pool(), like)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_like_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_like_comment".into()))?;
|
||||||
|
|
||||||
let apub_comment: ApubComment = updated_comment.into();
|
let apub_comment: ApubComment = updated_comment.into();
|
||||||
CreateOrUpdateComment::send(
|
CreateOrUpdateComment::send(
|
||||||
|
@ -179,7 +183,8 @@ impl PerformCrud for CreateComment {
|
||||||
Comment::update_read(conn, comment_id, true)
|
Comment::update_read(conn, comment_id, true)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
}
|
}
|
||||||
// If its a reply, mark the parent as read
|
// If its a reply, mark the parent as read
|
||||||
if let Some(parent_id) = data.parent_id {
|
if let Some(parent_id) = data.parent_id {
|
||||||
|
@ -192,7 +197,8 @@ impl PerformCrud for CreateComment {
|
||||||
Comment::update_read(conn, parent_id, true)
|
Comment::update_read(conn, parent_id, true)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_parent_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_parent_comment".into()))?;
|
||||||
}
|
}
|
||||||
// If the parent has PersonMentions mark them as read too
|
// If the parent has PersonMentions mark them as read too
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
@ -205,7 +211,8 @@ impl PerformCrud for CreateComment {
|
||||||
PersonMention::update_read(conn, mention.id, true)
|
PersonMention::update_read(conn, mention.id, true)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_person_mentions", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_person_mentions".into()))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use lemmy_db_schema::{
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
use lemmy_db_views::comment_view::CommentView;
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
send::{send_comment_ws_message, send_local_notifs},
|
send::{send_comment_ws_message, send_local_notifs},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
|
@ -29,6 +29,7 @@ use lemmy_websocket::{
|
||||||
impl PerformCrud for DeleteComment {
|
impl PerformCrud for DeleteComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -46,7 +47,7 @@ impl PerformCrud for DeleteComment {
|
||||||
|
|
||||||
// Dont delete it if its already been deleted.
|
// Dont delete it if its already been deleted.
|
||||||
if orig_comment.comment.deleted == data.deleted {
|
if orig_comment.comment.deleted == data.deleted {
|
||||||
return Err(ApiError::err_plain("couldnt_update_comment").into());
|
return Err(LemmyError::from_message("couldnt_update_comment".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_community_ban(
|
check_community_ban(
|
||||||
|
@ -58,7 +59,7 @@ impl PerformCrud for DeleteComment {
|
||||||
|
|
||||||
// Verify that only the creator can delete
|
// Verify that only the creator can delete
|
||||||
if local_user_view.person.id != orig_comment.creator.id {
|
if local_user_view.person.id != orig_comment.creator.id {
|
||||||
return Err(ApiError::err_plain("no_comment_edit_allowed").into());
|
return Err(LemmyError::from_message("no_comment_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the delete
|
// Do the delete
|
||||||
|
@ -67,7 +68,8 @@ impl PerformCrud for DeleteComment {
|
||||||
Comment::update_deleted(conn, comment_id, deleted)
|
Comment::update_deleted(conn, comment_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
let post_id = updated_comment.post_id;
|
let post_id = updated_comment.post_id;
|
||||||
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
|
||||||
|
@ -112,6 +114,7 @@ impl PerformCrud for DeleteComment {
|
||||||
impl PerformCrud for RemoveComment {
|
impl PerformCrud for RemoveComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -148,7 +151,8 @@ impl PerformCrud for RemoveComment {
|
||||||
Comment::update_removed(conn, comment_id, removed)
|
Comment::update_removed(conn, comment_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModRemoveCommentForm {
|
let form = ModRemoveCommentForm {
|
||||||
|
|
|
@ -13,13 +13,14 @@ use lemmy_db_schema::{
|
||||||
SortType,
|
SortType,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::comment_view::{CommentQueryBuilder, CommentView};
|
use lemmy_db_views::comment_view::{CommentQueryBuilder, CommentView};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for GetComment {
|
impl PerformCrud for GetComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -35,7 +36,8 @@ impl PerformCrud for GetComment {
|
||||||
CommentView::read(conn, id, person_id)
|
CommentView::read(conn, id, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_comment".into()))?;
|
||||||
|
|
||||||
Ok(Self::Response {
|
Ok(Self::Response {
|
||||||
comment_view,
|
comment_view,
|
||||||
|
@ -49,6 +51,7 @@ impl PerformCrud for GetComment {
|
||||||
impl PerformCrud for GetComments {
|
impl PerformCrud for GetComments {
|
||||||
type Response = GetCommentsResponse;
|
type Response = GetCommentsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -91,7 +94,8 @@ impl PerformCrud for GetComments {
|
||||||
.list()
|
.list()
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_get_comments", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_get_comments".into()))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info
|
// Blank out deleted or removed info
|
||||||
for cv in comments
|
for cv in comments
|
||||||
|
|
|
@ -16,7 +16,6 @@ use lemmy_db_schema::source::comment::Comment;
|
||||||
use lemmy_db_views::comment_view::CommentView;
|
use lemmy_db_views::comment_view::CommentView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
utils::{remove_slurs, scrape_text_for_mentions},
|
utils::{remove_slurs, scrape_text_for_mentions},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -32,6 +31,7 @@ use crate::PerformCrud;
|
||||||
impl PerformCrud for EditComment {
|
impl PerformCrud for EditComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -59,7 +59,7 @@ impl PerformCrud for EditComment {
|
||||||
|
|
||||||
// Verify that only the creator can edit
|
// Verify that only the creator can edit
|
||||||
if local_user_view.person.id != orig_comment.creator.id {
|
if local_user_view.person.id != orig_comment.creator.id {
|
||||||
return Err(ApiError::err_plain("no_comment_edit_allowed").into());
|
return Err(LemmyError::from_message("no_comment_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the update
|
// Do the update
|
||||||
|
@ -70,7 +70,8 @@ impl PerformCrud for EditComment {
|
||||||
Comment::update_content(conn, comment_id, &content_slurs_removed)
|
Comment::update_content(conn, comment_id, &content_slurs_removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
// Do the mentions / recipients
|
// Do the mentions / recipients
|
||||||
let updated_comment_content = updated_comment.content.to_owned();
|
let updated_comment_content = updated_comment.content.to_owned();
|
||||||
|
|
|
@ -34,7 +34,6 @@ use lemmy_db_views_actor::community_view::CommunityView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
apub::generate_actor_keypair,
|
apub::generate_actor_keypair,
|
||||||
utils::{check_slurs, check_slurs_opt, is_valid_actor_name},
|
utils::{check_slurs, check_slurs_opt, is_valid_actor_name},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -44,6 +43,7 @@ use lemmy_websocket::LemmyContext;
|
||||||
impl PerformCrud for CreateCommunity {
|
impl PerformCrud for CreateCommunity {
|
||||||
type Response = CommunityResponse;
|
type Response = CommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -55,7 +55,9 @@ impl PerformCrud for CreateCommunity {
|
||||||
|
|
||||||
let site = blocking(context.pool(), move |conn| Site::read(conn, 0)).await??;
|
let site = blocking(context.pool(), move |conn| Site::read(conn, 0)).await??;
|
||||||
if site.community_creation_admin_only && is_admin(&local_user_view).is_err() {
|
if site.community_creation_admin_only && is_admin(&local_user_view).is_err() {
|
||||||
return Err(ApiError::err_plain("only_admins_can_create_communities").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"only_admins_can_create_communities".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_slurs(&data.name, &context.settings().slur_regex())?;
|
check_slurs(&data.name, &context.settings().slur_regex())?;
|
||||||
|
@ -63,7 +65,7 @@ impl PerformCrud for CreateCommunity {
|
||||||
check_slurs_opt(&data.description, &context.settings().slur_regex())?;
|
check_slurs_opt(&data.description, &context.settings().slur_regex())?;
|
||||||
|
|
||||||
if !is_valid_actor_name(&data.name, context.settings().actor_name_max_length) {
|
if !is_valid_actor_name(&data.name, context.settings().actor_name_max_length) {
|
||||||
return Err(ApiError::err_plain("invalid_community_name").into());
|
return Err(LemmyError::from_message("invalid_community_name".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double check for duplicate community actor_ids
|
// Double check for duplicate community actor_ids
|
||||||
|
@ -75,7 +77,7 @@ impl PerformCrud for CreateCommunity {
|
||||||
let community_actor_id_wrapped = ObjectId::<ApubCommunity>::new(community_actor_id.clone());
|
let community_actor_id_wrapped = ObjectId::<ApubCommunity>::new(community_actor_id.clone());
|
||||||
let community_dupe = community_actor_id_wrapped.dereference_local(context).await;
|
let community_dupe = community_actor_id_wrapped.dereference_local(context).await;
|
||||||
if community_dupe.is_ok() {
|
if community_dupe.is_ok() {
|
||||||
return Err(ApiError::err_plain("community_already_exists").into());
|
return Err(LemmyError::from_message("community_already_exists".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure the icon and banners are urls
|
// Check to make sure the icon and banners are urls
|
||||||
|
@ -105,7 +107,8 @@ impl PerformCrud for CreateCommunity {
|
||||||
Community::create(conn, &community_form)
|
Community::create(conn, &community_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_already_exists".into()))?;
|
||||||
|
|
||||||
// The community creator becomes a moderator
|
// The community creator becomes a moderator
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
|
@ -115,7 +118,9 @@ impl PerformCrud for CreateCommunity {
|
||||||
|
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
if blocking(context.pool(), join).await?.is_err() {
|
if blocking(context.pool(), join).await?.is_err() {
|
||||||
return Err(ApiError::err_plain("community_moderator_already_exists").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"community_moderator_already_exists".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Follow your own community
|
// Follow your own community
|
||||||
|
@ -127,7 +132,9 @@ impl PerformCrud for CreateCommunity {
|
||||||
|
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
if blocking(context.pool(), follow).await?.is_err() {
|
if blocking(context.pool(), follow).await?.is_err() {
|
||||||
return Err(ApiError::err_plain("community_follower_already_exists").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"community_follower_already_exists".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
|
|
@ -10,13 +10,14 @@ use lemmy_db_schema::{
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
||||||
use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for DeleteCommunity {
|
impl PerformCrud for DeleteCommunity {
|
||||||
type Response = CommunityResponse;
|
type Response = CommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -35,7 +36,7 @@ impl PerformCrud for DeleteCommunity {
|
||||||
|
|
||||||
// Make sure deleter is the top mod
|
// Make sure deleter is the top mod
|
||||||
if local_user_view.person.id != community_mods[0].moderator.id {
|
if local_user_view.person.id != community_mods[0].moderator.id {
|
||||||
return Err(ApiError::err_plain("no_community_edit_allowed").into());
|
return Err(LemmyError::from_message("no_community_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the delete
|
// Do the delete
|
||||||
|
@ -45,7 +46,8 @@ impl PerformCrud for DeleteCommunity {
|
||||||
Community::update_deleted(conn, community_id, deleted)
|
Community::update_deleted(conn, community_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_community".into()))?;
|
||||||
|
|
||||||
// Send apub messages
|
// Send apub messages
|
||||||
send_apub_delete(
|
send_apub_delete(
|
||||||
|
@ -72,6 +74,7 @@ impl PerformCrud for DeleteCommunity {
|
||||||
impl PerformCrud for RemoveCommunity {
|
impl PerformCrud for RemoveCommunity {
|
||||||
type Response = CommunityResponse;
|
type Response = CommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -91,7 +94,8 @@ impl PerformCrud for RemoveCommunity {
|
||||||
Community::update_removed(conn, community_id, removed)
|
Community::update_removed(conn, community_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_community".into()))?;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let expires = data.expires.map(naive_from_unix);
|
let expires = data.expires.map(naive_from_unix);
|
||||||
|
|
|
@ -17,13 +17,14 @@ use lemmy_db_views_actor::{
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
community_view::{CommunityQueryBuilder, CommunityView},
|
community_view::{CommunityQueryBuilder, CommunityView},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext};
|
use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for GetCommunity {
|
impl PerformCrud for GetCommunity {
|
||||||
type Response = GetCommunityResponse;
|
type Response = GetCommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -45,7 +46,8 @@ impl PerformCrud for GetCommunity {
|
||||||
ObjectId::<ApubCommunity>::new(community_actor_id)
|
ObjectId::<ApubCommunity>::new(community_actor_id)
|
||||||
.dereference(context, &mut 0)
|
.dereference(context, &mut 0)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?
|
||||||
.id
|
.id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -54,7 +56,8 @@ impl PerformCrud for GetCommunity {
|
||||||
CommunityView::read(conn, community_id, person_id)
|
CommunityView::read(conn, community_id, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
// Blank out deleted or removed info for non-logged in users
|
||||||
if person_id.is_none() && (community_view.community.deleted || community_view.community.removed)
|
if person_id.is_none() && (community_view.community.deleted || community_view.community.removed)
|
||||||
|
@ -66,7 +69,8 @@ impl PerformCrud for GetCommunity {
|
||||||
CommunityModeratorView::for_community(conn, community_id)
|
CommunityModeratorView::for_community(conn, community_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
|
|
||||||
let online = context
|
let online = context
|
||||||
.chat_server()
|
.chat_server()
|
||||||
|
@ -89,6 +93,7 @@ impl PerformCrud for GetCommunity {
|
||||||
impl PerformCrud for ListCommunities {
|
impl PerformCrud for ListCommunities {
|
||||||
type Response = ListCommunitiesResponse;
|
type Response = ListCommunitiesResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -14,13 +14,14 @@ use lemmy_db_schema::{
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
|
||||||
use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{utils::check_slurs_opt, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for EditCommunity {
|
impl PerformCrud for EditCommunity {
|
||||||
type Response = CommunityResponse;
|
type Response = CommunityResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -41,7 +42,7 @@ impl PerformCrud for EditCommunity {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if !mods.contains(&local_user_view.person.id) {
|
if !mods.contains(&local_user_view.person.id) {
|
||||||
return Err(ApiError::err_plain("not_a_moderator").into());
|
return Err(LemmyError::from_message("not_a_moderator".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
|
@ -70,7 +71,8 @@ impl PerformCrud for EditCommunity {
|
||||||
Community::update(conn, community_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_community".into()))?;
|
||||||
|
|
||||||
UpdateCommunity::send(
|
UpdateCommunity::send(
|
||||||
updated_community.into(),
|
updated_community.into(),
|
||||||
|
|
|
@ -27,7 +27,6 @@ use lemmy_db_schema::{
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
request::fetch_site_data,
|
request::fetch_site_data,
|
||||||
utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title},
|
utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -40,6 +39,7 @@ use webmention::{Webmention, WebmentionError};
|
||||||
impl PerformCrud for CreatePost {
|
impl PerformCrud for CreatePost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -55,7 +55,7 @@ impl PerformCrud for CreatePost {
|
||||||
honeypot_check(&data.honeypot)?;
|
honeypot_check(&data.honeypot)?;
|
||||||
|
|
||||||
if !is_valid_post_title(&data.name) {
|
if !is_valid_post_title(&data.name) {
|
||||||
return Err(ApiError::err_plain("invalid_post_title").into());
|
return Err(LemmyError::from_message("invalid_post_title".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_community_ban(local_user_view.person.id, data.community_id, context.pool()).await?;
|
check_community_ban(local_user_view.person.id, data.community_id, context.pool()).await?;
|
||||||
|
@ -93,7 +93,7 @@ impl PerformCrud for CreatePost {
|
||||||
"couldnt_create_post"
|
"couldnt_create_post"
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(ApiError::err(err_type, e).into());
|
return Err(LemmyError::from(e).with_message(err_type.into()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,7 +108,8 @@ impl PerformCrud for CreatePost {
|
||||||
Ok(Post::update_ap_id(conn, inserted_post_id, apub_id)?)
|
Ok(Post::update_ap_id(conn, inserted_post_id, apub_id)?)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_post".into()))?;
|
||||||
|
|
||||||
// They like their own post by default
|
// They like their own post by default
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
|
@ -121,7 +122,7 @@ impl PerformCrud for CreatePost {
|
||||||
|
|
||||||
let like = move |conn: &'_ _| PostLike::like(conn, &like_form);
|
let like = move |conn: &'_ _| PostLike::like(conn, &like_form);
|
||||||
if blocking(context.pool(), like).await?.is_err() {
|
if blocking(context.pool(), like).await?.is_err() {
|
||||||
return Err(ApiError::err_plain("couldnt_like_post").into());
|
return Err(LemmyError::from_message("couldnt_like_post".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the post as read
|
// Mark the post as read
|
||||||
|
|
|
@ -17,13 +17,14 @@ use lemmy_db_schema::{
|
||||||
},
|
},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for DeletePost {
|
impl PerformCrud for DeletePost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -38,7 +39,7 @@ impl PerformCrud for DeletePost {
|
||||||
|
|
||||||
// Dont delete it if its already been deleted.
|
// Dont delete it if its already been deleted.
|
||||||
if orig_post.deleted == data.deleted {
|
if orig_post.deleted == data.deleted {
|
||||||
return Err(ApiError::err_plain("couldnt_update_post").into());
|
return Err(LemmyError::from_message("couldnt_update_post".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
check_community_ban(
|
check_community_ban(
|
||||||
|
@ -51,7 +52,7 @@ impl PerformCrud for DeletePost {
|
||||||
|
|
||||||
// Verify that only the creator can delete
|
// Verify that only the creator can delete
|
||||||
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
||||||
return Err(ApiError::err_plain("no_post_edit_allowed").into());
|
return Err(LemmyError::from_message("no_post_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
|
@ -91,6 +92,7 @@ impl PerformCrud for DeletePost {
|
||||||
impl PerformCrud for RemovePost {
|
impl PerformCrud for RemovePost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -20,13 +20,14 @@ use lemmy_db_views_actor::{
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
community_view::CommunityView,
|
community_view::CommunityView,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
|
use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for GetPost {
|
impl PerformCrud for GetPost {
|
||||||
type Response = GetPostResponse;
|
type Response = GetPostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -46,7 +47,8 @@ impl PerformCrud for GetPost {
|
||||||
PostView::read(conn, id, person_id)
|
PostView::read(conn, id, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_post".into()))?;
|
||||||
|
|
||||||
// Mark the post as read
|
// Mark the post as read
|
||||||
if let Some(person_id) = person_id {
|
if let Some(person_id) = person_id {
|
||||||
|
@ -70,7 +72,8 @@ impl PerformCrud for GetPost {
|
||||||
CommunityView::read(conn, community_id, person_id)
|
CommunityView::read(conn, community_id, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_find_community", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_community".into()))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
// Blank out deleted or removed info for non-logged in users
|
||||||
if person_id.is_none() {
|
if person_id.is_none() {
|
||||||
|
@ -115,6 +118,7 @@ impl PerformCrud for GetPost {
|
||||||
impl PerformCrud for GetPosts {
|
impl PerformCrud for GetPosts {
|
||||||
type Response = GetPostsResponse;
|
type Response = GetPostsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -165,7 +169,8 @@ impl PerformCrud for GetPosts {
|
||||||
.list()
|
.list()
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_get_posts", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_get_posts".into()))?;
|
||||||
|
|
||||||
// Blank out deleted or removed info for non-logged in users
|
// Blank out deleted or removed info for non-logged in users
|
||||||
if person_id.is_none() {
|
if person_id.is_none() {
|
||||||
|
|
|
@ -19,7 +19,6 @@ use lemmy_db_schema::{
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
request::fetch_site_data,
|
request::fetch_site_data,
|
||||||
utils::{check_slurs_opt, clean_url_params, is_valid_post_title},
|
utils::{check_slurs_opt, clean_url_params, is_valid_post_title},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -31,6 +30,7 @@ use crate::PerformCrud;
|
||||||
impl PerformCrud for EditPost {
|
impl PerformCrud for EditPost {
|
||||||
type Response = PostResponse;
|
type Response = PostResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -46,7 +46,7 @@ impl PerformCrud for EditPost {
|
||||||
|
|
||||||
if let Some(name) = &data.name {
|
if let Some(name) = &data.name {
|
||||||
if !is_valid_post_title(name) {
|
if !is_valid_post_title(name) {
|
||||||
return Err(ApiError::err_plain("invalid_post_title").into());
|
return Err(LemmyError::from_message("invalid_post_title".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ impl PerformCrud for EditPost {
|
||||||
|
|
||||||
// Verify that only the creator can edit
|
// Verify that only the creator can edit
|
||||||
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
if !Post::is_post_creator(local_user_view.person.id, orig_post.creator_id) {
|
||||||
return Err(ApiError::err_plain("no_post_edit_allowed").into());
|
return Err(LemmyError::from_message("no_post_edit_allowed".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch post links and Pictrs cached image
|
// Fetch post links and Pictrs cached image
|
||||||
|
@ -103,7 +103,7 @@ impl PerformCrud for EditPost {
|
||||||
"couldnt_update_post"
|
"couldnt_update_post"
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(ApiError::err(err_type, e).into());
|
return Err(LemmyError::from(e).with_message(err_type.into()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use lemmy_db_schema::{
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::local_user_view::LocalUserView;
|
use lemmy_db_views::local_user_view::LocalUserView;
|
||||||
use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{utils::remove_slurs, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
send::{send_email_to_user, send_pm_ws_message},
|
send::{send_email_to_user, send_pm_ws_message},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
|
@ -30,6 +30,7 @@ use lemmy_websocket::{
|
||||||
impl PerformCrud for CreatePrivateMessage {
|
impl PerformCrud for CreatePrivateMessage {
|
||||||
type Response = PrivateMessageResponse;
|
type Response = PrivateMessageResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -58,7 +59,7 @@ impl PerformCrud for CreatePrivateMessage {
|
||||||
{
|
{
|
||||||
Ok(private_message) => private_message,
|
Ok(private_message) => private_message,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(ApiError::err("couldnt_create_private_message", e).into());
|
return Err(LemmyError::from(e).with_message("couldnt_create_private_message".into()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,7 +81,8 @@ impl PerformCrud for CreatePrivateMessage {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_create_private_message", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_create_private_message".into()))?;
|
||||||
|
|
||||||
CreateOrUpdatePrivateMessage::send(
|
CreateOrUpdatePrivateMessage::send(
|
||||||
updated_private_message.into(),
|
updated_private_message.into(),
|
||||||
|
|
|
@ -13,13 +13,14 @@ use lemmy_db_schema::{
|
||||||
source::private_message::PrivateMessage,
|
source::private_message::PrivateMessage,
|
||||||
traits::{Crud, DeleteableOrRemoveable},
|
traits::{Crud, DeleteableOrRemoveable},
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for DeletePrivateMessage {
|
impl PerformCrud for DeletePrivateMessage {
|
||||||
type Response = PrivateMessageResponse;
|
type Response = PrivateMessageResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -36,7 +37,9 @@ impl PerformCrud for DeletePrivateMessage {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if local_user_view.person.id != orig_private_message.creator_id {
|
if local_user_view.person.id != orig_private_message.creator_id {
|
||||||
return Err(ApiError::err_plain("no_private_message_edit_allowed").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"no_private_message_edit_allowed".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
|
@ -46,7 +49,8 @@ impl PerformCrud for DeletePrivateMessage {
|
||||||
PrivateMessage::update_deleted(conn, private_message_id, deleted)
|
PrivateMessage::update_deleted(conn, private_message_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_private_message", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_private_message".into()))?;
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
if data.deleted {
|
if data.deleted {
|
||||||
|
|
|
@ -14,6 +14,7 @@ use lemmy_websocket::LemmyContext;
|
||||||
impl PerformCrud for GetPrivateMessages {
|
impl PerformCrud for GetPrivateMessages {
|
||||||
type Response = PrivateMessagesResponse;
|
type Response = PrivateMessagesResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
|
|
@ -10,13 +10,14 @@ use lemmy_apub::protocol::activities::{
|
||||||
CreateOrUpdateType,
|
CreateOrUpdateType,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
|
||||||
use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{utils::remove_slurs, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for EditPrivateMessage {
|
impl PerformCrud for EditPrivateMessage {
|
||||||
type Response = PrivateMessageResponse;
|
type Response = PrivateMessageResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -33,7 +34,9 @@ impl PerformCrud for EditPrivateMessage {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if local_user_view.person.id != orig_private_message.creator_id {
|
if local_user_view.person.id != orig_private_message.creator_id {
|
||||||
return Err(ApiError::err_plain("no_private_message_edit_allowed").into());
|
return Err(LemmyError::from_message(
|
||||||
|
"no_private_message_edit_allowed".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
|
@ -43,7 +46,8 @@ impl PerformCrud for EditPrivateMessage {
|
||||||
PrivateMessage::update_content(conn, private_message_id, &content_slurs_removed)
|
PrivateMessage::update_content(conn, private_message_id, &content_slurs_removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_private_message", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_private_message".into()))?;
|
||||||
|
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
CreateOrUpdatePrivateMessage::send(
|
CreateOrUpdatePrivateMessage::send(
|
||||||
|
|
|
@ -16,7 +16,6 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::site_view::SiteView;
|
use lemmy_db_views::site_view::SiteView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
utils::{check_slurs, check_slurs_opt},
|
utils::{check_slurs, check_slurs_opt},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -26,6 +25,7 @@ use lemmy_websocket::LemmyContext;
|
||||||
impl PerformCrud for CreateSite {
|
impl PerformCrud for CreateSite {
|
||||||
type Response = SiteResponse;
|
type Response = SiteResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -35,7 +35,7 @@ impl PerformCrud for CreateSite {
|
||||||
|
|
||||||
let read_site = Site::read_simple;
|
let read_site = Site::read_simple;
|
||||||
if blocking(context.pool(), read_site).await?.is_ok() {
|
if blocking(context.pool(), read_site).await?.is_ok() {
|
||||||
return Err(ApiError::err_plain("site_already_exists").into());
|
return Err(LemmyError::from_message("site_already_exists".into()));
|
||||||
};
|
};
|
||||||
|
|
||||||
let local_user_view =
|
let local_user_view =
|
||||||
|
@ -72,7 +72,7 @@ impl PerformCrud for CreateSite {
|
||||||
|
|
||||||
let create_site = move |conn: &'_ _| Site::create(conn, &site_form);
|
let create_site = move |conn: &'_ _| Site::create(conn, &site_form);
|
||||||
if blocking(context.pool(), create_site).await?.is_err() {
|
if blocking(context.pool(), create_site).await?.is_err() {
|
||||||
return Err(ApiError::err_plain("site_already_exists").into());
|
return Err(LemmyError::from_message("site_already_exists".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let site_view = blocking(context.pool(), SiteView::read).await??;
|
let site_view = blocking(context.pool(), SiteView::read).await??;
|
||||||
|
|
|
@ -15,7 +15,7 @@ use lemmy_db_views_actor::{
|
||||||
person_block_view::PersonBlockView,
|
person_block_view::PersonBlockView,
|
||||||
person_view::PersonViewSafe,
|
person_view::PersonViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{version, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{version, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::GetUsersOnline, LemmyContext};
|
use lemmy_websocket::{messages::GetUsersOnline, LemmyContext};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ use tracing::info;
|
||||||
impl PerformCrud for GetSite {
|
impl PerformCrud for GetSite {
|
||||||
type Response = GetSiteResponse;
|
type Response = GetSiteResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -100,27 +101,31 @@ impl PerformCrud for GetSite {
|
||||||
CommunityFollowerView::for_person(conn, person_id)
|
CommunityFollowerView::for_person(conn, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("system_err_login", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("system_err_login".into()))?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let community_blocks = blocking(context.pool(), move |conn| {
|
let community_blocks = blocking(context.pool(), move |conn| {
|
||||||
CommunityBlockView::for_person(conn, person_id)
|
CommunityBlockView::for_person(conn, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("system_err_login", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("system_err_login".into()))?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let person_id = local_user_view.person.id;
|
||||||
let person_blocks = blocking(context.pool(), move |conn| {
|
let person_blocks = blocking(context.pool(), move |conn| {
|
||||||
PersonBlockView::for_person(conn, person_id)
|
PersonBlockView::for_person(conn, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("system_err_login", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("system_err_login".into()))?;
|
||||||
|
|
||||||
let moderates = blocking(context.pool(), move |conn| {
|
let moderates = blocking(context.pool(), move |conn| {
|
||||||
CommunityModeratorView::for_person(conn, person_id)
|
CommunityModeratorView::for_person(conn, person_id)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("system_err_login", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("system_err_login".into()))?;
|
||||||
|
|
||||||
Some(MyUserInfo {
|
Some(MyUserInfo {
|
||||||
local_user_view,
|
local_user_view,
|
||||||
|
|
|
@ -15,12 +15,14 @@ use lemmy_db_schema::{
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::site_view::SiteView;
|
use lemmy_db_views::site_view::SiteView;
|
||||||
use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{utils::check_slurs_opt, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud};
|
use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for EditSite {
|
impl PerformCrud for EditSite {
|
||||||
type Response = SiteResponse;
|
type Response = SiteResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -64,7 +66,8 @@ impl PerformCrud for EditSite {
|
||||||
let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form);
|
let update_site = move |conn: &'_ _| Site::update(conn, 1, &site_form);
|
||||||
blocking(context.pool(), update_site)
|
blocking(context.pool(), update_site)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_site", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_site".into()))?;
|
||||||
|
|
||||||
let site_view = blocking(context.pool(), SiteView::read).await??;
|
let site_view = blocking(context.pool(), SiteView::read).await??;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ use lemmy_utils::{
|
||||||
apub::generate_actor_keypair,
|
apub::generate_actor_keypair,
|
||||||
claims::Claims,
|
claims::Claims,
|
||||||
utils::{check_slurs, is_valid_actor_name},
|
utils::{check_slurs, is_valid_actor_name},
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
|
@ -42,6 +41,7 @@ use lemmy_websocket::{messages::CheckCaptcha, LemmyContext};
|
||||||
impl PerformCrud for Register {
|
impl PerformCrud for Register {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -52,7 +52,7 @@ impl PerformCrud for Register {
|
||||||
// Make sure site has open registration
|
// Make sure site has open registration
|
||||||
if let Ok(site) = blocking(context.pool(), Site::read_simple).await? {
|
if let Ok(site) = blocking(context.pool(), Site::read_simple).await? {
|
||||||
if !site.open_registration {
|
if !site.open_registration {
|
||||||
return Err(ApiError::err_plain("registration_closed").into());
|
return Err(LemmyError::from_message("registration_closed".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ impl PerformCrud for Register {
|
||||||
|
|
||||||
// Make sure passwords match
|
// Make sure passwords match
|
||||||
if data.password != data.password_verify {
|
if data.password != data.password_verify {
|
||||||
return Err(ApiError::err_plain("passwords_dont_match").into());
|
return Err(LemmyError::from_message("passwords_dont_match".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if there are admins. False if admins exist
|
// Check if there are admins. False if admins exist
|
||||||
|
@ -86,7 +86,7 @@ impl PerformCrud for Register {
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
if !check {
|
if !check {
|
||||||
return Err(ApiError::err_plain("captcha_incorrect").into());
|
return Err(LemmyError::from_message("captcha_incorrect".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl PerformCrud for Register {
|
||||||
|
|
||||||
let actor_keypair = generate_actor_keypair()?;
|
let actor_keypair = generate_actor_keypair()?;
|
||||||
if !is_valid_actor_name(&data.username, context.settings().actor_name_max_length) {
|
if !is_valid_actor_name(&data.username, context.settings().actor_name_max_length) {
|
||||||
return Err(ApiError::err_plain("invalid_username").into());
|
return Err(LemmyError::from_message("invalid_username".into()));
|
||||||
}
|
}
|
||||||
let actor_id = generate_local_apub_endpoint(
|
let actor_id = generate_local_apub_endpoint(
|
||||||
EndpointType::Person,
|
EndpointType::Person,
|
||||||
|
@ -121,7 +121,8 @@ impl PerformCrud for Register {
|
||||||
Person::create(conn, &person_form)
|
Person::create(conn, &person_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("user_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("user_already_exists".into()))?;
|
||||||
|
|
||||||
// Create the local user
|
// Create the local user
|
||||||
// TODO some of these could probably use the DB defaults
|
// TODO some of these could probably use the DB defaults
|
||||||
|
@ -163,7 +164,7 @@ impl PerformCrud for Register {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
return Err(ApiError::err(err_type, e).into());
|
return Err(LemmyError::from(e).with_message(err_type.into()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,7 +214,8 @@ impl PerformCrud for Register {
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
blocking(context.pool(), follow)
|
blocking(context.pool(), follow)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_follower_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_follower_already_exists".into()))?;
|
||||||
|
|
||||||
// If its an admin, add them as a mod and follower to main
|
// If its an admin, add them as a mod and follower to main
|
||||||
if no_admins {
|
if no_admins {
|
||||||
|
@ -225,7 +227,8 @@ impl PerformCrud for Register {
|
||||||
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
|
||||||
blocking(context.pool(), join)
|
blocking(context.pool(), join)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("community_moderator_already_exists", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("community_moderator_already_exists".into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
|
|
|
@ -3,13 +3,14 @@ use actix_web::web::Data;
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use lemmy_api_common::{blocking, get_local_user_view_from_jwt, person::*};
|
use lemmy_api_common::{blocking, get_local_user_view_from_jwt, person::*};
|
||||||
use lemmy_db_schema::source::{comment::Comment, person::Person, post::Post};
|
use lemmy_db_schema::source::{comment::Comment, person::Person, post::Post};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for DeleteAccount {
|
impl PerformCrud for DeleteAccount {
|
||||||
type Response = LoginResponse;
|
type Response = LoginResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -26,7 +27,7 @@ impl PerformCrud for DeleteAccount {
|
||||||
)
|
)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if !valid {
|
if !valid {
|
||||||
return Err(ApiError::err_plain("password_incorrect").into());
|
return Err(LemmyError::from_message("password_incorrect".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
|
@ -34,13 +35,15 @@ impl PerformCrud for DeleteAccount {
|
||||||
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id);
|
let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id);
|
||||||
blocking(context.pool(), permadelete)
|
blocking(context.pool(), permadelete)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_comment", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_comment".into()))?;
|
||||||
|
|
||||||
// Posts
|
// Posts
|
||||||
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id);
|
let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id);
|
||||||
blocking(context.pool(), permadelete)
|
blocking(context.pool(), permadelete)
|
||||||
.await?
|
.await?
|
||||||
.map_err(|e| ApiError::err("couldnt_update_post", e))?;
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_update_post".into()))?;
|
||||||
|
|
||||||
blocking(context.pool(), move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Person::delete_account(conn, person_id)
|
Person::delete_account(conn, person_id)
|
||||||
|
|
|
@ -13,13 +13,14 @@ use lemmy_db_views_actor::{
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
person_view::PersonViewSafe,
|
person_view::PersonViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_utils::{ApiError, ConnectionId, LemmyError};
|
use lemmy_utils::{ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for GetPersonDetails {
|
impl PerformCrud for GetPersonDetails {
|
||||||
type Response = GetPersonDetailsResponse;
|
type Response = GetPersonDetailsResponse;
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self, context, _websocket_id))]
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
|
@ -53,7 +54,8 @@ impl PerformCrud for GetPersonDetails {
|
||||||
.dereference(context, &mut 0)
|
.dereference(context, &mut 0)
|
||||||
.await;
|
.await;
|
||||||
person
|
person
|
||||||
.map_err(|e| ApiError::err("couldnt_find_that_username_or_email", e))?
|
.map_err(LemmyError::from)
|
||||||
|
.map_err(|e| e.with_message("couldnt_find_that_username_or_email".into()))?
|
||||||
.id
|
.id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgC
|
||||||
use crate::newtypes::DbUrl;
|
use crate::newtypes::DbUrl;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use diesel::{Connection, PgConnection};
|
use diesel::{Connection, PgConnection};
|
||||||
use lemmy_utils::ApiError;
|
use lemmy_utils::LemmyError;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -100,13 +100,13 @@ pub fn diesel_option_overwrite(opt: &Option<String>) -> Option<Option<String>> {
|
||||||
|
|
||||||
pub fn diesel_option_overwrite_to_url(
|
pub fn diesel_option_overwrite_to_url(
|
||||||
opt: &Option<String>,
|
opt: &Option<String>,
|
||||||
) -> Result<Option<Option<DbUrl>>, ApiError> {
|
) -> Result<Option<Option<DbUrl>>, LemmyError> {
|
||||||
match opt.as_ref().map(|s| s.as_str()) {
|
match opt.as_ref().map(|s| s.as_str()) {
|
||||||
// An empty string is an erase
|
// An empty string is an erase
|
||||||
Some("") => Ok(Some(None)),
|
Some("") => Ok(Some(None)),
|
||||||
Some(str_url) => match Url::parse(str_url) {
|
Some(str_url) => match Url::parse(str_url) {
|
||||||
Ok(url) => Ok(Some(Some(url.into()))),
|
Ok(url) => Ok(Some(Some(url.into()))),
|
||||||
Err(e) => Err(ApiError::err("invalid_url", e)),
|
Err(e) => Err(LemmyError::from(e).with_message("invalid_url".into())),
|
||||||
},
|
},
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,9 @@ mod test;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
|
|
||||||
|
use actix_web::HttpResponse;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use std::{fmt, fmt::Display};
|
use std::{fmt, fmt::Display};
|
||||||
use thiserror::Error;
|
|
||||||
use tracing::warn;
|
|
||||||
use tracing_error::SpanTrace;
|
use tracing_error::SpanTrace;
|
||||||
|
|
||||||
pub type ConnectionId = usize;
|
pub type ConnectionId = usize;
|
||||||
|
@ -44,38 +43,42 @@ macro_rules! location_info {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(serde::Serialize)]
|
||||||
#[error("{{\"error\":\"{message}\"}}")]
|
struct ApiError {
|
||||||
pub struct ApiError {
|
error: String,
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ApiError {
|
|
||||||
pub fn err_plain(msg: &str) -> Self {
|
|
||||||
ApiError {
|
|
||||||
message: msg.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn err<E: Display>(msg: &str, original_error: E) -> Self {
|
|
||||||
warn!("{}", original_error);
|
|
||||||
ApiError {
|
|
||||||
message: msg.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LemmyError {
|
pub struct LemmyError {
|
||||||
|
pub message: Option<String>,
|
||||||
pub inner: anyhow::Error,
|
pub inner: anyhow::Error,
|
||||||
pub context: SpanTrace,
|
pub context: SpanTrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LemmyError {
|
||||||
|
pub fn from_message(message: String) -> Self {
|
||||||
|
let inner = anyhow::anyhow!("{}", message);
|
||||||
|
LemmyError {
|
||||||
|
message: Some(message),
|
||||||
|
inner,
|
||||||
|
context: SpanTrace::capture(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn with_message(self, message: String) -> Self {
|
||||||
|
LemmyError {
|
||||||
|
message: Some(message),
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> From<T> for LemmyError
|
impl<T> From<T> for LemmyError
|
||||||
where
|
where
|
||||||
T: Into<anyhow::Error>,
|
T: Into<anyhow::Error>,
|
||||||
{
|
{
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
LemmyError {
|
LemmyError {
|
||||||
|
message: None,
|
||||||
inner: t.into(),
|
inner: t.into(),
|
||||||
context: SpanTrace::capture(),
|
context: SpanTrace::capture(),
|
||||||
}
|
}
|
||||||
|
@ -93,7 +96,19 @@ impl actix_web::error::ResponseError for LemmyError {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self.inner.downcast_ref::<diesel::result::Error>() {
|
match self.inner.downcast_ref::<diesel::result::Error>() {
|
||||||
Some(diesel::result::Error::NotFound) => StatusCode::NOT_FOUND,
|
Some(diesel::result::Error::NotFound) => StatusCode::NOT_FOUND,
|
||||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
_ => StatusCode::BAD_REQUEST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
if let Some(message) = &self.message {
|
||||||
|
HttpResponse::build(self.status_code()).json(ApiError {
|
||||||
|
error: message.clone(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
HttpResponse::build(self.status_code())
|
||||||
|
.content_type("text/plain")
|
||||||
|
.body(self.inner.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{ApiError, IpAddr, LemmyError};
|
use crate::{IpAddr, LemmyError};
|
||||||
use std::{collections::HashMap, time::SystemTime};
|
use std::{collections::HashMap, time::SystemTime};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
@ -79,18 +79,13 @@ impl RateLimiter {
|
||||||
time_passed,
|
time_passed,
|
||||||
rate_limit.allowance
|
rate_limit.allowance
|
||||||
);
|
);
|
||||||
Err(
|
Err(LemmyError::from_message(format!(
|
||||||
ApiError {
|
"Too many requests. type: {}, IP: {}, {} per {} seconds",
|
||||||
message: format!(
|
type_.as_ref(),
|
||||||
"Too many requests. type: {}, IP: {}, {} per {} seconds",
|
ip,
|
||||||
type_.as_ref(),
|
rate,
|
||||||
ip,
|
per
|
||||||
rate,
|
)))
|
||||||
per
|
|
||||||
),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
if !check_only {
|
if !check_only {
|
||||||
rate_limit.allowance -= 1.0;
|
rate_limit.allowance -= 1.0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{ApiError, IpAddr};
|
use crate::{IpAddr, LemmyError};
|
||||||
use actix_web::dev::ConnectionInfo;
|
use actix_web::dev::ConnectionInfo;
|
||||||
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
use chrono::{DateTime, FixedOffset, NaiveDateTime};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -60,15 +60,18 @@ pub(crate) fn slur_check<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_slurs(text: &str, slur_regex: &Option<Regex>) -> Result<(), ApiError> {
|
pub fn check_slurs(text: &str, slur_regex: &Option<Regex>) -> Result<(), LemmyError> {
|
||||||
if let Err(slurs) = slur_check(text, slur_regex) {
|
if let Err(slurs) = slur_check(text, slur_regex) {
|
||||||
Err(ApiError::err_plain(&slurs_vec_to_str(slurs)))
|
Err(LemmyError::from_message(slurs_vec_to_str(slurs)))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_slurs_opt(text: &Option<String>, slur_regex: &Option<Regex>) -> Result<(), ApiError> {
|
pub fn check_slurs_opt(
|
||||||
|
text: &Option<String>,
|
||||||
|
slur_regex: &Option<Regex>,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
match text {
|
match text {
|
||||||
Some(t) => check_slurs(t, slur_regex),
|
Some(t) => check_slurs(t, slur_regex),
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
|
|
|
@ -22,7 +22,6 @@ use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
rate_limit::RateLimit,
|
rate_limit::RateLimit,
|
||||||
settings::structs::Settings,
|
settings::structs::Settings,
|
||||||
ApiError,
|
|
||||||
ConnectionId,
|
ConnectionId,
|
||||||
IpAddr,
|
IpAddr,
|
||||||
LemmyError,
|
LemmyError,
|
||||||
|
@ -477,7 +476,7 @@ impl ChatServer {
|
||||||
let data = &json["data"].to_string();
|
let data = &json["data"].to_string();
|
||||||
let op = &json["op"]
|
let op = &json["op"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| ApiError::err_plain("missing op"))?;
|
.ok_or_else(|| LemmyError::from_message("missing op".into()))?;
|
||||||
|
|
||||||
if let Ok(user_operation_crud) = UserOperationCrud::from_str(op) {
|
if let Ok(user_operation_crud) = UserOperationCrud::from_str(op) {
|
||||||
let fut = (message_handler_crud)(context, msg.id, user_operation_crud.clone(), data);
|
let fut = (message_handler_crud)(context, msg.id, user_operation_crud.clone(), data);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_web::{error::ErrorBadRequest, *};
|
use actix_web::*;
|
||||||
use lemmy_api::Perform;
|
use lemmy_api::Perform;
|
||||||
use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*};
|
use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*};
|
||||||
use lemmy_api_crud::PerformCrud;
|
use lemmy_api_crud::PerformCrud;
|
||||||
|
@ -232,8 +232,7 @@ where
|
||||||
let res = data
|
let res = data
|
||||||
.perform(&context, None)
|
.perform(&context, None)
|
||||||
.await
|
.await
|
||||||
.map(|json| HttpResponse::Ok().json(json))
|
.map(|json| HttpResponse::Ok().json(json))?;
|
||||||
.map_err(ErrorBadRequest)?;
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +267,7 @@ where
|
||||||
let res = data
|
let res = data
|
||||||
.perform(&context, None)
|
.perform(&context, None)
|
||||||
.await
|
.await
|
||||||
.map(|json| HttpResponse::Ok().json(json))
|
.map(|json| HttpResponse::Ok().json(json))?;
|
||||||
.map_err(ErrorBadRequest)?;
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue