mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 03:11:08 +00:00
Rewrite some API handlers to remove Perform trait (#3735)
* Rewrite some API handlers to remove Perform trait * Convert CreateComment * ci
This commit is contained in:
parent
db76c5b7ff
commit
37998b3398
36 changed files with 858 additions and 963 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2573,6 +2573,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
name = "lemmy_api"
|
name = "lemmy_api"
|
||||||
version = "0.18.1"
|
version = "0.18.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|
|
@ -20,6 +20,7 @@ lemmy_db_views = { workspace = true, features = ["full"] }
|
||||||
lemmy_db_views_moderator = { workspace = true, features = ["full"] }
|
lemmy_db_views_moderator = { workspace = true, features = ["full"] }
|
||||||
lemmy_db_views_actor = { workspace = true, features = ["full"] }
|
lemmy_db_views_actor = { workspace = true, features = ["full"] }
|
||||||
lemmy_api_common = { workspace = true, features = ["full"] }
|
lemmy_api_common = { workspace = true, features = ["full"] }
|
||||||
|
activitypub_federation = { workspace = true }
|
||||||
bcrypt = { workspace = true }
|
bcrypt = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
actix-web = { workspace = true }
|
actix-web = { workspace = true }
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
comment::{CommentResponse, DistinguishComment},
|
comment::{CommentResponse, DistinguishComment},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -12,50 +11,47 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::CommentView;
|
use lemmy_db_views::structs::CommentView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for DistinguishComment {
|
pub async fn distinguish_comment(
|
||||||
type Response = CommentResponse;
|
data: Json<DistinguishComment>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let comment_id = data.comment_id;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommentResponse, LemmyError> {
|
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None).await?;
|
||||||
let data: &DistinguishComment = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
check_community_ban(
|
||||||
let orig_comment = CommentView::read(&mut context.pool(), comment_id, None).await?;
|
local_user_view.person.id,
|
||||||
|
orig_comment.community.id,
|
||||||
|
&mut context.pool(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
check_community_ban(
|
// Verify that only a mod or admin can distinguish a comment
|
||||||
local_user_view.person.id,
|
is_mod_or_admin(
|
||||||
orig_comment.community.id,
|
&mut context.pool(),
|
||||||
&mut context.pool(),
|
local_user_view.person.id,
|
||||||
)
|
orig_comment.community.id,
|
||||||
.await?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Verify that only a mod or admin can distinguish a comment
|
// Update the Comment
|
||||||
is_mod_or_admin(
|
let comment_id = data.comment_id;
|
||||||
&mut context.pool(),
|
let form = CommentUpdateForm::builder()
|
||||||
local_user_view.person.id,
|
.distinguished(Some(data.distinguished))
|
||||||
orig_comment.community.id,
|
.build();
|
||||||
)
|
Comment::update(&mut context.pool(), comment_id, &form)
|
||||||
.await?;
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
// Update the Comment
|
let comment_id = data.comment_id;
|
||||||
let comment_id = data.comment_id;
|
let person_id = local_user_view.person.id;
|
||||||
let form = CommentUpdateForm::builder()
|
let comment_view = CommentView::read(&mut context.pool(), comment_id, Some(person_id)).await?;
|
||||||
.distinguished(Some(data.distinguished))
|
|
||||||
.build();
|
|
||||||
Comment::update(&mut context.pool(), comment_id, &form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
Ok(Json(CommentResponse {
|
||||||
let person_id = local_user_view.person.id;
|
comment_view,
|
||||||
let comment_view = CommentView::read(&mut context.pool(), comment_id, Some(person_id)).await?;
|
recipient_ids: Vec::new(),
|
||||||
|
form_id: None,
|
||||||
Ok(CommentResponse {
|
}))
|
||||||
comment_view,
|
|
||||||
recipient_ids: Vec::new(),
|
|
||||||
form_id: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
mod distinguish;
|
pub mod distinguish;
|
||||||
mod like;
|
pub mod like;
|
||||||
mod save;
|
pub mod save;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
comment::{CommentResponse, SaveComment},
|
comment::{CommentResponse, SaveComment},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -12,38 +11,35 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::CommentView;
|
use lemmy_db_views::structs::CommentView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for SaveComment {
|
pub async fn save_comment(
|
||||||
type Response = CommentResponse;
|
data: Json<SaveComment>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let comment_saved_form = CommentSavedForm {
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommentResponse, LemmyError> {
|
comment_id: data.comment_id,
|
||||||
let data: &SaveComment = self;
|
person_id: local_user_view.person.id,
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
};
|
||||||
|
|
||||||
let comment_saved_form = CommentSavedForm {
|
if data.save {
|
||||||
comment_id: data.comment_id,
|
CommentSaved::save(&mut context.pool(), &comment_saved_form)
|
||||||
person_id: local_user_view.person.id,
|
.await
|
||||||
};
|
.with_lemmy_type(LemmyErrorType::CouldntSaveComment)?;
|
||||||
|
} else {
|
||||||
if data.save {
|
CommentSaved::unsave(&mut context.pool(), &comment_saved_form)
|
||||||
CommentSaved::save(&mut context.pool(), &comment_saved_form)
|
.await
|
||||||
.await
|
.with_lemmy_type(LemmyErrorType::CouldntSaveComment)?;
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSaveComment)?;
|
|
||||||
} else {
|
|
||||||
CommentSaved::unsave(&mut context.pool(), &comment_saved_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSaveComment)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let comment_view = CommentView::read(&mut context.pool(), comment_id, Some(person_id)).await?;
|
|
||||||
|
|
||||||
Ok(CommentResponse {
|
|
||||||
comment_view,
|
|
||||||
recipient_ids: Vec::new(),
|
|
||||||
form_id: None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let comment_id = data.comment_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let comment_view = CommentView::read(&mut context.pool(), comment_id, Some(person_id)).await?;
|
||||||
|
|
||||||
|
Ok(Json(CommentResponse {
|
||||||
|
comment_view,
|
||||||
|
recipient_ids: Vec::new(),
|
||||||
|
form_id: None,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
comment::{ListCommentReports, ListCommentReportsResponse},
|
comment::{ListCommentReports, ListCommentReportsResponse},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -10,32 +9,26 @@ use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
/// Lists comment reports for a community if an id is supplied
|
/// Lists comment reports for a community if an id is supplied
|
||||||
/// or returns all comment reports for communities a user moderates
|
/// or returns all comment reports for communities a user moderates
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ListCommentReports {
|
pub async fn list_comment_reports(
|
||||||
type Response = ListCommentReportsResponse;
|
data: Query<ListCommentReports>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<ListCommentReportsResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let community_id = data.community_id;
|
||||||
async fn perform(
|
let unresolved_only = data.unresolved_only;
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<ListCommentReportsResponse, LemmyError> {
|
|
||||||
let data: &ListCommentReports = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let page = data.page;
|
||||||
let unresolved_only = data.unresolved_only;
|
let limit = data.limit;
|
||||||
|
let comment_reports = CommentReportQuery {
|
||||||
let page = data.page;
|
community_id,
|
||||||
let limit = data.limit;
|
unresolved_only,
|
||||||
let comment_reports = CommentReportQuery {
|
page,
|
||||||
community_id,
|
limit,
|
||||||
unresolved_only,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool(), &local_user_view.person)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(ListCommentReportsResponse { comment_reports })
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool(), &local_user_view.person)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(ListCommentReportsResponse { comment_reports }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
mod create;
|
pub mod create;
|
||||||
mod list;
|
pub mod list;
|
||||||
mod resolve;
|
pub mod resolve;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
comment::{CommentReportResponse, ResolveCommentReport},
|
comment::{CommentReportResponse, ResolveCommentReport},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -10,41 +9,35 @@ use lemmy_db_views::structs::CommentReportView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
/// Resolves or unresolves a comment report and notifies the moderators of the community
|
/// Resolves or unresolves a comment report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ResolveCommentReport {
|
pub async fn resolve_comment_report(
|
||||||
type Response = CommentReportResponse;
|
data: Json<ResolveCommentReport>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentReportResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let report_id = data.report_id;
|
||||||
async fn perform(
|
let person_id = local_user_view.person.id;
|
||||||
&self,
|
let report = CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<CommentReportResponse, LemmyError> {
|
|
||||||
let data: &ResolveCommentReport = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let report_id = data.report_id;
|
let person_id = local_user_view.person.id;
|
||||||
let person_id = local_user_view.person.id;
|
is_mod_or_admin(&mut context.pool(), person_id, report.community.id).await?;
|
||||||
let report = CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
if data.resolved {
|
||||||
is_mod_or_admin(&mut context.pool(), person_id, report.community.id).await?;
|
CommentReport::resolve(&mut context.pool(), report_id, person_id)
|
||||||
|
.await
|
||||||
if data.resolved {
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
CommentReport::resolve(&mut context.pool(), report_id, person_id)
|
} else {
|
||||||
.await
|
CommentReport::unresolve(&mut context.pool(), report_id, person_id)
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
.await
|
||||||
} else {
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
CommentReport::unresolve(&mut context.pool(), report_id, person_id)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let report_id = data.report_id;
|
|
||||||
let comment_report_view =
|
|
||||||
CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
|
||||||
|
|
||||||
Ok(CommentReportResponse {
|
|
||||||
comment_report_view,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let report_id = data.report_id;
|
||||||
|
let comment_report_view =
|
||||||
|
CommentReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
|
|
||||||
|
Ok(Json(CommentReportResponse {
|
||||||
|
comment_report_view,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,15 @@ use lemmy_utils::{
|
||||||
};
|
};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
mod comment;
|
pub mod comment;
|
||||||
mod comment_report;
|
pub mod comment_report;
|
||||||
mod community;
|
pub mod community;
|
||||||
mod local_user;
|
pub mod local_user;
|
||||||
mod post;
|
pub mod post;
|
||||||
mod post_report;
|
pub mod post_report;
|
||||||
mod private_message;
|
pub mod private_message;
|
||||||
mod private_message_report;
|
pub mod private_message_report;
|
||||||
mod site;
|
pub mod site;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait Perform {
|
pub trait Perform {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
mod add_admin;
|
pub mod add_admin;
|
||||||
mod ban_person;
|
pub mod ban_person;
|
||||||
mod block;
|
pub mod block;
|
||||||
mod change_password;
|
pub mod change_password;
|
||||||
mod change_password_after_reset;
|
pub mod change_password_after_reset;
|
||||||
mod get_captcha;
|
pub mod get_captcha;
|
||||||
mod list_banned;
|
pub mod list_banned;
|
||||||
mod login;
|
pub mod login;
|
||||||
mod notifications;
|
pub mod notifications;
|
||||||
mod report_count;
|
pub mod report_count;
|
||||||
mod reset_password;
|
pub mod reset_password;
|
||||||
mod save_settings;
|
pub mod save_settings;
|
||||||
mod verify_email;
|
pub mod verify_email;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{CommentReplyResponse, MarkCommentReplyAsRead},
|
person::{CommentReplyResponse, MarkCommentReplyAsRead},
|
||||||
|
@ -12,41 +11,35 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views_actor::structs::CommentReplyView;
|
use lemmy_db_views_actor::structs::CommentReplyView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for MarkCommentReplyAsRead {
|
pub async fn mark_reply_as_read(
|
||||||
type Response = CommentReplyResponse;
|
data: Json<MarkCommentReplyAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentReplyResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let comment_reply_id = data.comment_reply_id;
|
||||||
async fn perform(
|
let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id).await?;
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<CommentReplyResponse, LemmyError> {
|
|
||||||
let data = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let comment_reply_id = data.comment_reply_id;
|
if local_user_view.person.id != read_comment_reply.recipient_id {
|
||||||
let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id).await?;
|
return Err(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
if local_user_view.person.id != read_comment_reply.recipient_id {
|
|
||||||
return Err(LemmyErrorType::CouldntUpdateComment)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let comment_reply_id = read_comment_reply.id;
|
|
||||||
let read = Some(data.read);
|
|
||||||
|
|
||||||
CommentReply::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
comment_reply_id,
|
|
||||||
&CommentReplyUpdateForm { read },
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
|
||||||
|
|
||||||
let comment_reply_id = read_comment_reply.id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let comment_reply_view =
|
|
||||||
CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id)).await?;
|
|
||||||
|
|
||||||
Ok(CommentReplyResponse { comment_reply_view })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let comment_reply_id = read_comment_reply.id;
|
||||||
|
let read = Some(data.read);
|
||||||
|
|
||||||
|
CommentReply::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
comment_reply_id,
|
||||||
|
&CommentReplyUpdateForm { read },
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
|
let comment_reply_id = read_comment_reply.id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let comment_reply_view =
|
||||||
|
CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id)).await?;
|
||||||
|
|
||||||
|
Ok(Json(CommentReplyResponse { comment_reply_view }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
mod list_mentions;
|
pub mod list_mentions;
|
||||||
mod list_replies;
|
pub mod list_replies;
|
||||||
mod mark_all_read;
|
pub mod mark_all_read;
|
||||||
mod mark_mention_read;
|
pub mod mark_mention_read;
|
||||||
mod mark_reply_read;
|
pub mod mark_reply_read;
|
||||||
mod unread_count;
|
pub mod unread_count;
|
||||||
|
|
|
@ -23,7 +23,7 @@ use lemmy_db_views_actor::structs::CommunityView;
|
||||||
use lemmy_utils::{error::LemmyError, utils::mention::MentionData};
|
use lemmy_utils::{error::LemmyError, utils::mention::MentionData};
|
||||||
|
|
||||||
pub async fn build_comment_response(
|
pub async fn build_comment_response(
|
||||||
context: &Data<LemmyContext>,
|
context: &LemmyContext,
|
||||||
comment_id: CommentId,
|
comment_id: CommentId,
|
||||||
local_user_view: Option<LocalUserView>,
|
local_user_view: Option<LocalUserView>,
|
||||||
form_id: Option<String>,
|
form_id: Option<String>,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::context::LemmyContext;
|
use crate::context::LemmyContext;
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use futures::future::BoxFuture;
|
use futures::future::BoxFuture;
|
||||||
use lemmy_db_schema::source::post::Post;
|
use lemmy_db_schema::source::{comment::Comment, post::Post};
|
||||||
use lemmy_utils::{error::LemmyResult, SYNCHRONOUS_FEDERATION};
|
use lemmy_utils::{error::LemmyResult, SYNCHRONOUS_FEDERATION};
|
||||||
use once_cell::sync::{Lazy, OnceCell};
|
use once_cell::sync::{Lazy, OnceCell};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
|
@ -22,6 +22,7 @@ pub static MATCH_OUTGOING_ACTIVITIES: OnceCell<MatchOutgoingActivitiesBoxed> = O
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SendActivityData {
|
pub enum SendActivityData {
|
||||||
CreatePost(Post),
|
CreatePost(Post),
|
||||||
|
CreateComment(Comment),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: instead of static, move this into LemmyContext. make sure that stopping the process with
|
// TODO: instead of static, move this into LemmyContext. make sure that stopping the process with
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::PerformCrud;
|
use activitypub_federation::config::Data;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Json;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
build_response::{build_comment_response, send_local_notifs},
|
build_response::{build_comment_response, send_local_notifs},
|
||||||
comment::{CommentResponse, CreateComment},
|
comment::{CommentResponse, CreateComment},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
send_activity::{ActivityChannel, SendActivityData},
|
||||||
utils::{
|
utils::{
|
||||||
check_community_ban,
|
check_community_ban,
|
||||||
check_community_deleted_or_removed,
|
check_community_deleted_or_removed,
|
||||||
|
@ -35,169 +36,174 @@ use lemmy_utils::{
|
||||||
validation::is_valid_body_field,
|
validation::is_valid_body_field,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
const MAX_COMMENT_DEPTH_LIMIT: usize = 100;
|
const MAX_COMMENT_DEPTH_LIMIT: usize = 100;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for CreateComment {
|
pub async fn create_comment(
|
||||||
type Response = CommentResponse;
|
data: Json<CreateComment>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let content = remove_slurs(
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommentResponse, LemmyError> {
|
&data.content.clone(),
|
||||||
let data: &CreateComment = self;
|
&local_site_to_slur_regex(&local_site),
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
);
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
is_valid_body_field(&Some(content.clone()), false)?;
|
||||||
|
let content = sanitize_html(&content);
|
||||||
|
|
||||||
let content = remove_slurs(
|
// Check for a community ban
|
||||||
&data.content.clone(),
|
let post_id = data.post_id;
|
||||||
&local_site_to_slur_regex(&local_site),
|
let post = get_post(post_id, &mut context.pool()).await?;
|
||||||
);
|
let community_id = post.community_id;
|
||||||
is_valid_body_field(&Some(content.clone()), false)?;
|
|
||||||
let content = sanitize_html(&content);
|
|
||||||
|
|
||||||
// Check for a community ban
|
check_community_ban(local_user_view.person.id, community_id, &mut context.pool()).await?;
|
||||||
let post_id = data.post_id;
|
check_community_deleted_or_removed(community_id, &mut context.pool()).await?;
|
||||||
let post = get_post(post_id, &mut context.pool()).await?;
|
check_post_deleted_or_removed(&post)?;
|
||||||
let community_id = post.community_id;
|
|
||||||
|
|
||||||
check_community_ban(local_user_view.person.id, community_id, &mut context.pool()).await?;
|
// Check if post is locked, no new comments
|
||||||
check_community_deleted_or_removed(community_id, &mut context.pool()).await?;
|
if post.locked {
|
||||||
check_post_deleted_or_removed(&post)?;
|
return Err(LemmyErrorType::Locked)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if post is locked, no new comments
|
// Fetch the parent, if it exists
|
||||||
if post.locked {
|
let parent_opt = if let Some(parent_id) = data.parent_id {
|
||||||
return Err(LemmyErrorType::Locked)?;
|
Comment::read(&mut context.pool(), parent_id).await.ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// If there's a parent_id, check to make sure that comment is in that post
|
||||||
|
// Strange issue where sometimes the post ID of the parent comment is incorrect
|
||||||
|
if let Some(parent) = parent_opt.as_ref() {
|
||||||
|
if parent.post_id != post_id {
|
||||||
|
return Err(LemmyErrorType::CouldntCreateComment)?;
|
||||||
}
|
}
|
||||||
|
check_comment_depth(parent)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the parent, if it exists
|
CommunityLanguage::is_allowed_community_language(
|
||||||
let parent_opt = if let Some(parent_id) = data.parent_id {
|
&mut context.pool(),
|
||||||
Comment::read(&mut context.pool(), parent_id).await.ok()
|
data.language_id,
|
||||||
} else {
|
community_id,
|
||||||
None
|
)
|
||||||
};
|
.await?;
|
||||||
|
|
||||||
// If there's a parent_id, check to make sure that comment is in that post
|
// attempt to set default language if none was provided
|
||||||
// Strange issue where sometimes the post ID of the parent comment is incorrect
|
let language_id = match data.language_id {
|
||||||
if let Some(parent) = parent_opt.as_ref() {
|
Some(lid) => Some(lid),
|
||||||
if parent.post_id != post_id {
|
None => {
|
||||||
return Err(LemmyErrorType::CouldntCreateComment)?;
|
default_post_language(
|
||||||
}
|
&mut context.pool(),
|
||||||
check_comment_depth(parent)?;
|
community_id,
|
||||||
|
local_user_view.local_user.id,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
CommunityLanguage::is_allowed_community_language(
|
let comment_form = CommentInsertForm::builder()
|
||||||
&mut context.pool(),
|
.content(content.clone())
|
||||||
data.language_id,
|
.post_id(data.post_id)
|
||||||
community_id,
|
.creator_id(local_user_view.person.id)
|
||||||
)
|
.language_id(language_id)
|
||||||
.await?;
|
.build();
|
||||||
|
|
||||||
// attempt to set default language if none was provided
|
// Create the comment
|
||||||
let language_id = match data.language_id {
|
let parent_path = parent_opt.clone().map(|t| t.path);
|
||||||
Some(lid) => Some(lid),
|
let inserted_comment = Comment::create(&mut context.pool(), &comment_form, parent_path.as_ref())
|
||||||
None => {
|
|
||||||
default_post_language(
|
|
||||||
&mut context.pool(),
|
|
||||||
community_id,
|
|
||||||
local_user_view.local_user.id,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let comment_form = CommentInsertForm::builder()
|
|
||||||
.content(content.clone())
|
|
||||||
.post_id(data.post_id)
|
|
||||||
.creator_id(local_user_view.person.id)
|
|
||||||
.language_id(language_id)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Create the comment
|
|
||||||
let parent_path = parent_opt.clone().map(|t| t.path);
|
|
||||||
let inserted_comment =
|
|
||||||
Comment::create(&mut context.pool(), &comment_form, parent_path.as_ref())
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateComment)?;
|
|
||||||
|
|
||||||
// Necessary to update the ap_id
|
|
||||||
let inserted_comment_id = inserted_comment.id;
|
|
||||||
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
|
||||||
|
|
||||||
let apub_id = generate_local_apub_endpoint(
|
|
||||||
EndpointType::Comment,
|
|
||||||
&inserted_comment_id.to_string(),
|
|
||||||
&protocol_and_hostname,
|
|
||||||
)?;
|
|
||||||
let updated_comment = Comment::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
inserted_comment_id,
|
|
||||||
&CommentUpdateForm::builder().ap_id(Some(apub_id)).build(),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntCreateComment)?;
|
||||||
|
|
||||||
// Scan the comment for user mentions, add those rows
|
// Necessary to update the ap_id
|
||||||
let mentions = scrape_text_for_mentions(&content);
|
let inserted_comment_id = inserted_comment.id;
|
||||||
let recipient_ids = send_local_notifs(
|
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
||||||
mentions,
|
|
||||||
&updated_comment,
|
|
||||||
&local_user_view.person,
|
|
||||||
&post,
|
|
||||||
true,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// You like your own comment by default
|
let apub_id = generate_local_apub_endpoint(
|
||||||
let like_form = CommentLikeForm {
|
EndpointType::Comment,
|
||||||
comment_id: inserted_comment.id,
|
&inserted_comment_id.to_string(),
|
||||||
post_id: post.id,
|
&protocol_and_hostname,
|
||||||
person_id: local_user_view.person.id,
|
)?;
|
||||||
score: 1,
|
let updated_comment = Comment::update(
|
||||||
};
|
&mut context.pool(),
|
||||||
|
inserted_comment_id,
|
||||||
|
&CommentUpdateForm::builder().ap_id(Some(apub_id)).build(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntCreateComment)?;
|
||||||
|
|
||||||
CommentLike::like(&mut context.pool(), &like_form)
|
// Scan the comment for user mentions, add those rows
|
||||||
|
let mentions = scrape_text_for_mentions(&content);
|
||||||
|
let recipient_ids = send_local_notifs(
|
||||||
|
mentions,
|
||||||
|
&updated_comment,
|
||||||
|
&local_user_view.person,
|
||||||
|
&post,
|
||||||
|
true,
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// You like your own comment by default
|
||||||
|
let like_form = CommentLikeForm {
|
||||||
|
comment_id: inserted_comment.id,
|
||||||
|
post_id: post.id,
|
||||||
|
person_id: local_user_view.person.id,
|
||||||
|
score: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
CommentLike::like(&mut context.pool(), &like_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntLikeComment)?;
|
||||||
|
|
||||||
|
ActivityChannel::submit_activity(
|
||||||
|
SendActivityData::CreateComment(updated_comment.clone()),
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// If its a reply, mark the parent as read
|
||||||
|
if let Some(parent) = parent_opt {
|
||||||
|
let parent_id = parent.id;
|
||||||
|
let comment_reply = CommentReply::read_by_comment(&mut context.pool(), parent_id).await;
|
||||||
|
if let Ok(reply) = comment_reply {
|
||||||
|
CommentReply::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
reply.id,
|
||||||
|
&CommentReplyUpdateForm { read: Some(true) },
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntLikeComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateReplies)?;
|
||||||
|
|
||||||
// If its a reply, mark the parent as read
|
|
||||||
if let Some(parent) = parent_opt {
|
|
||||||
let parent_id = parent.id;
|
|
||||||
let comment_reply = CommentReply::read_by_comment(&mut context.pool(), parent_id).await;
|
|
||||||
if let Ok(reply) = comment_reply {
|
|
||||||
CommentReply::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
reply.id,
|
|
||||||
&CommentReplyUpdateForm { read: Some(true) },
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateReplies)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the parent has PersonMentions mark them as read too
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let person_mention =
|
|
||||||
PersonMention::read_by_comment_and_person(&mut context.pool(), parent_id, person_id).await;
|
|
||||||
if let Ok(mention) = person_mention {
|
|
||||||
PersonMention::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
mention.id,
|
|
||||||
&PersonMentionUpdateForm { read: Some(true) },
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePersonMentions)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the parent has PersonMentions mark them as read too
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let person_mention =
|
||||||
|
PersonMention::read_by_comment_and_person(&mut context.pool(), parent_id, person_id).await;
|
||||||
|
if let Ok(mention) = person_mention {
|
||||||
|
PersonMention::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
mention.id,
|
||||||
|
&PersonMentionUpdateForm { read: Some(true) },
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePersonMentions)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Json(
|
||||||
build_comment_response(
|
build_comment_response(
|
||||||
context,
|
context.deref(),
|
||||||
inserted_comment.id,
|
inserted_comment.id,
|
||||||
Some(local_user_view),
|
Some(local_user_view),
|
||||||
self.form_id.clone(),
|
data.form_id.clone(),
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
)
|
)
|
||||||
.await
|
.await?,
|
||||||
}
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_comment_depth(comment: &Comment) -> Result<(), LemmyError> {
|
pub fn check_comment_depth(comment: &Comment) -> Result<(), LemmyError> {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::CommentView;
|
use lemmy_db_views::structs::CommentView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for DeleteComment {
|
impl PerformCrud for DeleteComment {
|
||||||
|
@ -68,7 +69,7 @@ impl PerformCrud for DeleteComment {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
build_comment_response(
|
build_comment_response(
|
||||||
context,
|
context.deref(),
|
||||||
updated_comment.id,
|
updated_comment.id,
|
||||||
Some(local_user_view),
|
Some(local_user_view),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod create;
|
pub mod create;
|
||||||
mod delete;
|
pub mod delete;
|
||||||
mod read;
|
pub mod read;
|
||||||
mod remove;
|
pub mod remove;
|
||||||
mod update;
|
pub mod update;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::PerformCrud;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
build_response::build_comment_response,
|
build_response::build_comment_response,
|
||||||
comment::{CommentResponse, GetComment},
|
comment::{CommentResponse, GetComment},
|
||||||
|
@ -8,19 +7,19 @@ use lemmy_api_common::{
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::source::local_site::LocalSite;
|
use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for GetComment {
|
pub async fn get_comment(
|
||||||
type Response = CommentResponse;
|
data: Query<GetComment>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<CommentResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
|
||||||
let data = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), context).await;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
Ok(Json(
|
||||||
|
build_comment_response(context.deref(), data.id, local_user_view, None, vec![]).await?,
|
||||||
build_comment_response(context, data.id, local_user_view, None, vec![]).await
|
))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::CommentView;
|
use lemmy_db_views::structs::CommentView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for RemoveComment {
|
impl PerformCrud for RemoveComment {
|
||||||
|
@ -76,7 +77,7 @@ impl PerformCrud for RemoveComment {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
build_comment_response(
|
build_comment_response(
|
||||||
context,
|
context.deref(),
|
||||||
updated_comment.id,
|
updated_comment.id,
|
||||||
Some(local_user_view),
|
Some(local_user_view),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -29,6 +29,7 @@ use lemmy_utils::{
|
||||||
validation::is_valid_body_field,
|
validation::is_valid_body_field,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl PerformCrud for EditComment {
|
impl PerformCrud for EditComment {
|
||||||
|
@ -95,7 +96,7 @@ impl PerformCrud for EditComment {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
build_comment_response(
|
build_comment_response(
|
||||||
context,
|
context.deref(),
|
||||||
updated_comment.id,
|
updated_comment.id,
|
||||||
Some(local_user_view),
|
Some(local_user_view),
|
||||||
self.form_id.clone(),
|
self.form_id.clone(),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::PerformCrud;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
community::{ListCommunities, ListCommunitiesResponse},
|
community::{ListCommunities, ListCommunitiesResponse},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -9,42 +8,36 @@ use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_db_views_actor::community_view::CommunityQuery;
|
use lemmy_db_views_actor::community_view::CommunityQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for ListCommunities {
|
pub async fn list_communities(
|
||||||
type Response = ListCommunitiesResponse;
|
data: Query<ListCommunities>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<ListCommunitiesResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
async fn perform(
|
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<ListCommunitiesResponse, LemmyError> {
|
|
||||||
let data: &ListCommunities = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), context).await;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
let sort = data.sort;
|
||||||
|
let listing_type = data.type_;
|
||||||
let sort = data.sort;
|
let show_nsfw = data.show_nsfw;
|
||||||
let listing_type = data.type_;
|
let page = data.page;
|
||||||
let show_nsfw = data.show_nsfw;
|
let limit = data.limit;
|
||||||
let page = data.page;
|
let local_user = local_user_view.map(|l| l.local_user);
|
||||||
let limit = data.limit;
|
let communities = CommunityQuery {
|
||||||
let local_user = local_user_view.map(|l| l.local_user);
|
listing_type,
|
||||||
let communities = CommunityQuery {
|
show_nsfw,
|
||||||
listing_type,
|
sort,
|
||||||
show_nsfw,
|
local_user: local_user.as_ref(),
|
||||||
sort,
|
page,
|
||||||
local_user: local_user.as_ref(),
|
limit,
|
||||||
page,
|
is_mod_or_admin: is_admin,
|
||||||
limit,
|
..Default::default()
|
||||||
is_mod_or_admin: is_admin,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(ListCommunitiesResponse { communities })
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Return the jwt
|
||||||
|
Ok(Json(ListCommunitiesResponse { communities }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod create;
|
pub mod create;
|
||||||
mod delete;
|
pub mod delete;
|
||||||
mod list;
|
pub mod list;
|
||||||
mod remove;
|
pub mod remove;
|
||||||
mod update;
|
pub mod update;
|
||||||
|
|
|
@ -2,13 +2,13 @@ use actix_web::web::Data;
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::context::LemmyContext;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
mod comment;
|
pub mod comment;
|
||||||
mod community;
|
pub mod community;
|
||||||
mod custom_emoji;
|
pub mod custom_emoji;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
mod private_message;
|
pub mod private_message;
|
||||||
mod site;
|
pub mod site;
|
||||||
mod user;
|
pub mod user;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait PerformCrud {
|
pub trait PerformCrud {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod create;
|
pub mod create;
|
||||||
mod delete;
|
pub mod delete;
|
||||||
mod read;
|
pub mod read;
|
||||||
mod remove;
|
pub mod remove;
|
||||||
mod update;
|
pub mod update;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::PerformCrud;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
post::{GetPost, GetPostResponse},
|
post::{GetPost, GetPostResponse},
|
||||||
|
@ -19,107 +18,103 @@ use lemmy_db_views::{post_view::PostQuery, structs::PostView};
|
||||||
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for GetPost {
|
pub async fn get_post(
|
||||||
type Response = GetPostResponse;
|
data: Query<GetPost>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetPostResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
check_private_instance(&local_user_view, &local_site)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<GetPostResponse, LemmyError> {
|
|
||||||
let data: &GetPost = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), context).await;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
let person_id = local_user_view.as_ref().map(|u| u.person.id);
|
||||||
|
|
||||||
let person_id = local_user_view.as_ref().map(|u| u.person.id);
|
// I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate
|
||||||
|
let post_id = if let Some(id) = data.id {
|
||||||
|
id
|
||||||
|
} else if let Some(comment_id) = data.comment_id {
|
||||||
|
Comment::read(&mut context.pool(), comment_id)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?
|
||||||
|
.post_id
|
||||||
|
} else {
|
||||||
|
Err(LemmyErrorType::CouldntFindPost)?
|
||||||
|
};
|
||||||
|
|
||||||
// I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate
|
// Check to see if the person is a mod or admin, to show deleted / removed
|
||||||
let post_id = if let Some(id) = data.id {
|
let community_id = Post::read(&mut context.pool(), post_id).await?.community_id;
|
||||||
id
|
let is_mod_or_admin = is_mod_or_admin_opt(
|
||||||
} else if let Some(comment_id) = data.comment_id {
|
&mut context.pool(),
|
||||||
Comment::read(&mut context.pool(), comment_id)
|
local_user_view.as_ref(),
|
||||||
.await
|
Some(community_id),
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?
|
)
|
||||||
.post_id
|
.await
|
||||||
} else {
|
.is_ok();
|
||||||
Err(LemmyErrorType::CouldntFindPost)?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check to see if the person is a mod or admin, to show deleted / removed
|
let post_view = PostView::read(
|
||||||
let community_id = Post::read(&mut context.pool(), post_id).await?.community_id;
|
&mut context.pool(),
|
||||||
let is_mod_or_admin = is_mod_or_admin_opt(
|
post_id,
|
||||||
&mut context.pool(),
|
person_id,
|
||||||
local_user_view.as_ref(),
|
Some(is_mod_or_admin),
|
||||||
Some(community_id),
|
)
|
||||||
)
|
.await
|
||||||
.await
|
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?;
|
||||||
.is_ok();
|
|
||||||
|
|
||||||
let post_view = PostView::read(
|
// Mark the post as read
|
||||||
&mut context.pool(),
|
let post_id = post_view.post.id;
|
||||||
post_id,
|
if let Some(person_id) = person_id {
|
||||||
person_id,
|
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
Some(is_mod_or_admin),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
|
|
||||||
// Mark the post as read
|
|
||||||
let post_id = post_view.post.id;
|
|
||||||
if let Some(person_id) = person_id {
|
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Necessary for the sidebar subscribed
|
|
||||||
let community_view = CommunityView::read(
|
|
||||||
&mut context.pool(),
|
|
||||||
community_id,
|
|
||||||
person_id,
|
|
||||||
Some(is_mod_or_admin),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
|
||||||
|
|
||||||
// Insert into PersonPostAggregates
|
|
||||||
// to update the read_comments count
|
|
||||||
if let Some(person_id) = person_id {
|
|
||||||
let read_comments = post_view.counts.comments;
|
|
||||||
let person_post_agg_form = PersonPostAggregatesForm {
|
|
||||||
person_id,
|
|
||||||
post_id,
|
|
||||||
read_comments,
|
|
||||||
..PersonPostAggregatesForm::default()
|
|
||||||
};
|
|
||||||
PersonPostAggregates::upsert(&mut context.pool(), &person_post_agg_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let moderators =
|
|
||||||
CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
|
||||||
|
|
||||||
// Fetch the cross_posts
|
|
||||||
let cross_posts = if let Some(url) = &post_view.post.url {
|
|
||||||
let mut x_posts = PostQuery {
|
|
||||||
url_search: Some(url.inner().as_str().into()),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Don't return this post as one of the cross_posts
|
|
||||||
x_posts.retain(|x| x.post.id != post_id);
|
|
||||||
x_posts
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(GetPostResponse {
|
|
||||||
post_view,
|
|
||||||
community_view,
|
|
||||||
moderators,
|
|
||||||
cross_posts,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Necessary for the sidebar subscribed
|
||||||
|
let community_view = CommunityView::read(
|
||||||
|
&mut context.pool(),
|
||||||
|
community_id,
|
||||||
|
person_id,
|
||||||
|
Some(is_mod_or_admin),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
||||||
|
|
||||||
|
// Insert into PersonPostAggregates
|
||||||
|
// to update the read_comments count
|
||||||
|
if let Some(person_id) = person_id {
|
||||||
|
let read_comments = post_view.counts.comments;
|
||||||
|
let person_post_agg_form = PersonPostAggregatesForm {
|
||||||
|
person_id,
|
||||||
|
post_id,
|
||||||
|
read_comments,
|
||||||
|
..PersonPostAggregatesForm::default()
|
||||||
|
};
|
||||||
|
PersonPostAggregates::upsert(&mut context.pool(), &person_post_agg_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntFindPost)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
|
// Fetch the cross_posts
|
||||||
|
let cross_posts = if let Some(url) = &post_view.post.url {
|
||||||
|
let mut x_posts = PostQuery {
|
||||||
|
url_search: Some(url.inner().as_str().into()),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Don't return this post as one of the cross_posts
|
||||||
|
x_posts.retain(|x| x.post.id != post_id);
|
||||||
|
x_posts
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the jwt
|
||||||
|
Ok(Json(GetPostResponse {
|
||||||
|
post_view,
|
||||||
|
community_view,
|
||||||
|
moderators,
|
||||||
|
cross_posts,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
mod create;
|
pub mod create;
|
||||||
mod delete;
|
pub mod delete;
|
||||||
mod read;
|
pub mod read;
|
||||||
mod update;
|
pub mod update;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::PerformCrud;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
private_message::{GetPrivateMessages, PrivateMessagesResponse},
|
private_message::{GetPrivateMessages, PrivateMessagesResponse},
|
||||||
|
@ -8,40 +7,34 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views::private_message_view::PrivateMessageQuery;
|
use lemmy_db_views::private_message_view::PrivateMessageQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for GetPrivateMessages {
|
pub async fn get_private_message(
|
||||||
type Response = PrivateMessagesResponse;
|
data: Query<GetPrivateMessages>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PrivateMessagesResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(data.auth.as_ref(), &context).await?;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, context))]
|
let page = data.page;
|
||||||
async fn perform(
|
let limit = data.limit;
|
||||||
&self,
|
let unread_only = data.unread_only;
|
||||||
context: &Data<LemmyContext>,
|
let mut messages = PrivateMessageQuery {
|
||||||
) -> Result<PrivateMessagesResponse, LemmyError> {
|
page,
|
||||||
let data: &GetPrivateMessages = self;
|
limit,
|
||||||
let local_user_view = local_user_view_from_jwt(data.auth.as_ref(), context).await?;
|
unread_only,
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
|
|
||||||
let page = data.page;
|
|
||||||
let limit = data.limit;
|
|
||||||
let unread_only = data.unread_only;
|
|
||||||
let mut messages = PrivateMessageQuery {
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
unread_only,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool(), person_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Messages sent by ourselves should be marked as read. The `read` column in database is only
|
|
||||||
// for the recipient, and shouldnt be exposed to sender.
|
|
||||||
messages.iter_mut().for_each(|pmv| {
|
|
||||||
if pmv.creator.id == person_id {
|
|
||||||
pmv.private_message.read = true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(PrivateMessagesResponse {
|
|
||||||
private_messages: messages,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool(), person_id)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Messages sent by ourselves should be marked as read. The `read` column in database is only
|
||||||
|
// for the recipient, and shouldnt be exposed to sender.
|
||||||
|
messages.iter_mut().for_each(|pmv| {
|
||||||
|
if pmv.creator.id == person_id {
|
||||||
|
pmv.private_message.read = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(Json(PrivateMessagesResponse {
|
||||||
|
private_messages: messages,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use crate::{
|
use crate::site::{application_question_check, site_default_post_listing_type_check};
|
||||||
site::{application_question_check, site_default_post_listing_type_check},
|
|
||||||
PerformCrud,
|
|
||||||
};
|
|
||||||
use activitypub_federation::http_signatures::generate_actor_keypair;
|
use activitypub_federation::http_signatures::generate_actor_keypair;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::{Data, Json};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{CreateSite, SiteResponse},
|
site::{CreateSite, SiteResponse},
|
||||||
|
@ -43,108 +40,105 @@ use lemmy_utils::{
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for CreateSite {
|
pub async fn create_site(
|
||||||
type Response = SiteResponse;
|
data: Json<CreateSite>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<SiteResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Make sure user is an admin; other types of users should not create site data...
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<SiteResponse, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &CreateSite = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
// Make sure user is an admin; other types of users should not create site data...
|
validate_create_payload(&local_site, &data)?;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
validate_create_payload(&local_site, data)?;
|
let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
|
||||||
|
let inbox_url = Some(generate_site_inbox_url(&actor_id)?);
|
||||||
|
let keypair = generate_actor_keypair()?;
|
||||||
|
let name = sanitize_html(&data.name);
|
||||||
|
let sidebar = sanitize_html_opt(&data.sidebar);
|
||||||
|
let description = sanitize_html_opt(&data.description);
|
||||||
|
|
||||||
let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
|
let site_form = SiteUpdateForm::builder()
|
||||||
let inbox_url = Some(generate_site_inbox_url(&actor_id)?);
|
.name(Some(name))
|
||||||
let keypair = generate_actor_keypair()?;
|
.sidebar(diesel_option_overwrite(sidebar))
|
||||||
let name = sanitize_html(&data.name);
|
.description(diesel_option_overwrite(description))
|
||||||
let sidebar = sanitize_html_opt(&data.sidebar);
|
.icon(diesel_option_overwrite_to_url(&data.icon)?)
|
||||||
let description = sanitize_html_opt(&data.description);
|
.banner(diesel_option_overwrite_to_url(&data.banner)?)
|
||||||
|
.actor_id(Some(actor_id))
|
||||||
|
.last_refreshed_at(Some(naive_now()))
|
||||||
|
.inbox_url(inbox_url)
|
||||||
|
.private_key(Some(Some(keypair.private_key)))
|
||||||
|
.public_key(Some(keypair.public_key))
|
||||||
|
.build();
|
||||||
|
|
||||||
let site_form = SiteUpdateForm::builder()
|
let site_id = local_site.site_id;
|
||||||
.name(Some(name))
|
|
||||||
.sidebar(diesel_option_overwrite(sidebar))
|
|
||||||
.description(diesel_option_overwrite(description))
|
|
||||||
.icon(diesel_option_overwrite_to_url(&data.icon)?)
|
|
||||||
.banner(diesel_option_overwrite_to_url(&data.banner)?)
|
|
||||||
.actor_id(Some(actor_id))
|
|
||||||
.last_refreshed_at(Some(naive_now()))
|
|
||||||
.inbox_url(inbox_url)
|
|
||||||
.private_key(Some(Some(keypair.private_key)))
|
|
||||||
.public_key(Some(keypair.public_key))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let site_id = local_site.site_id;
|
Site::update(&mut context.pool(), site_id, &site_form).await?;
|
||||||
|
|
||||||
Site::update(&mut context.pool(), site_id, &site_form).await?;
|
let application_question = sanitize_html_opt(&data.application_question);
|
||||||
|
let default_theme = sanitize_html_opt(&data.default_theme);
|
||||||
|
let legal_information = sanitize_html_opt(&data.legal_information);
|
||||||
|
|
||||||
let application_question = sanitize_html_opt(&data.application_question);
|
let local_site_form = LocalSiteUpdateForm::builder()
|
||||||
let default_theme = sanitize_html_opt(&data.default_theme);
|
// Set the site setup to true
|
||||||
let legal_information = sanitize_html_opt(&data.legal_information);
|
.site_setup(Some(true))
|
||||||
|
.enable_downvotes(data.enable_downvotes)
|
||||||
|
.registration_mode(data.registration_mode)
|
||||||
|
.enable_nsfw(data.enable_nsfw)
|
||||||
|
.community_creation_admin_only(data.community_creation_admin_only)
|
||||||
|
.require_email_verification(data.require_email_verification)
|
||||||
|
.application_question(diesel_option_overwrite(application_question))
|
||||||
|
.private_instance(data.private_instance)
|
||||||
|
.default_theme(default_theme)
|
||||||
|
.default_post_listing_type(data.default_post_listing_type)
|
||||||
|
.legal_information(diesel_option_overwrite(legal_information))
|
||||||
|
.application_email_admins(data.application_email_admins)
|
||||||
|
.hide_modlog_mod_names(data.hide_modlog_mod_names)
|
||||||
|
.updated(Some(Some(naive_now())))
|
||||||
|
.slur_filter_regex(diesel_option_overwrite(data.slur_filter_regex.clone()))
|
||||||
|
.actor_name_max_length(data.actor_name_max_length)
|
||||||
|
.federation_enabled(data.federation_enabled)
|
||||||
|
.captcha_enabled(data.captcha_enabled)
|
||||||
|
.captcha_difficulty(data.captcha_difficulty.clone())
|
||||||
|
.build();
|
||||||
|
|
||||||
let local_site_form = LocalSiteUpdateForm::builder()
|
LocalSite::update(&mut context.pool(), &local_site_form).await?;
|
||||||
// Set the site setup to true
|
|
||||||
.site_setup(Some(true))
|
|
||||||
.enable_downvotes(data.enable_downvotes)
|
|
||||||
.registration_mode(data.registration_mode)
|
|
||||||
.enable_nsfw(data.enable_nsfw)
|
|
||||||
.community_creation_admin_only(data.community_creation_admin_only)
|
|
||||||
.require_email_verification(data.require_email_verification)
|
|
||||||
.application_question(diesel_option_overwrite(application_question))
|
|
||||||
.private_instance(data.private_instance)
|
|
||||||
.default_theme(default_theme)
|
|
||||||
.default_post_listing_type(data.default_post_listing_type)
|
|
||||||
.legal_information(diesel_option_overwrite(legal_information))
|
|
||||||
.application_email_admins(data.application_email_admins)
|
|
||||||
.hide_modlog_mod_names(data.hide_modlog_mod_names)
|
|
||||||
.updated(Some(Some(naive_now())))
|
|
||||||
.slur_filter_regex(diesel_option_overwrite(data.slur_filter_regex.clone()))
|
|
||||||
.actor_name_max_length(data.actor_name_max_length)
|
|
||||||
.federation_enabled(data.federation_enabled)
|
|
||||||
.captcha_enabled(data.captcha_enabled)
|
|
||||||
.captcha_difficulty(data.captcha_difficulty.clone())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
LocalSite::update(&mut context.pool(), &local_site_form).await?;
|
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
||||||
|
.message(data.rate_limit_message)
|
||||||
|
.message_per_second(data.rate_limit_message_per_second)
|
||||||
|
.post(data.rate_limit_post)
|
||||||
|
.post_per_second(data.rate_limit_post_per_second)
|
||||||
|
.register(data.rate_limit_register)
|
||||||
|
.register_per_second(data.rate_limit_register_per_second)
|
||||||
|
.image(data.rate_limit_image)
|
||||||
|
.image_per_second(data.rate_limit_image_per_second)
|
||||||
|
.comment(data.rate_limit_comment)
|
||||||
|
.comment_per_second(data.rate_limit_comment_per_second)
|
||||||
|
.search(data.rate_limit_search)
|
||||||
|
.search_per_second(data.rate_limit_search_per_second)
|
||||||
|
.build();
|
||||||
|
|
||||||
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
LocalSiteRateLimit::update(&mut context.pool(), &local_site_rate_limit_form).await?;
|
||||||
.message(data.rate_limit_message)
|
|
||||||
.message_per_second(data.rate_limit_message_per_second)
|
|
||||||
.post(data.rate_limit_post)
|
|
||||||
.post_per_second(data.rate_limit_post_per_second)
|
|
||||||
.register(data.rate_limit_register)
|
|
||||||
.register_per_second(data.rate_limit_register_per_second)
|
|
||||||
.image(data.rate_limit_image)
|
|
||||||
.image_per_second(data.rate_limit_image_per_second)
|
|
||||||
.comment(data.rate_limit_comment)
|
|
||||||
.comment_per_second(data.rate_limit_comment_per_second)
|
|
||||||
.search(data.rate_limit_search)
|
|
||||||
.search_per_second(data.rate_limit_search_per_second)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
LocalSiteRateLimit::update(&mut context.pool(), &local_site_rate_limit_form).await?;
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
let new_taglines = data.taglines.clone();
|
||||||
|
let taglines = Tagline::replace(&mut context.pool(), local_site.id, new_taglines).await?;
|
||||||
|
|
||||||
let new_taglines = data.taglines.clone();
|
let rate_limit_config =
|
||||||
let taglines = Tagline::replace(&mut context.pool(), local_site.id, new_taglines).await?;
|
local_site_rate_limit_to_rate_limit_config(&site_view.local_site_rate_limit);
|
||||||
|
context
|
||||||
|
.settings_updated_channel()
|
||||||
|
.send(rate_limit_config)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let rate_limit_config =
|
Ok(Json(SiteResponse {
|
||||||
local_site_rate_limit_to_rate_limit_config(&site_view.local_site_rate_limit);
|
site_view,
|
||||||
context
|
taglines,
|
||||||
.settings_updated_channel()
|
}))
|
||||||
.send(rate_limit_config)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(SiteResponse {
|
|
||||||
site_view,
|
|
||||||
taglines,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_create_payload(local_site: &LocalSite, create_site: &CreateSite) -> LemmyResult<()> {
|
fn validate_create_payload(local_site: &LocalSite, create_site: &CreateSite) -> LemmyResult<()> {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use lemmy_db_schema::{ListingType, RegistrationMode};
|
use lemmy_db_schema::{ListingType, RegistrationMode};
|
||||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
|
|
||||||
mod create;
|
pub mod create;
|
||||||
mod read;
|
pub mod read;
|
||||||
mod update;
|
pub mod update;
|
||||||
|
|
||||||
/// Checks whether the default post listing type is valid for a site.
|
/// Checks whether the default post listing type is valid for a site.
|
||||||
pub fn site_default_post_listing_type_check(
|
pub fn site_default_post_listing_type_check(
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::PerformCrud;
|
use actix_web::web::{Data, Json, Query};
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
sensitive::Sensitive,
|
sensitive::Sensitive,
|
||||||
|
@ -28,76 +27,72 @@ use lemmy_utils::{
|
||||||
version,
|
version,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for GetSite {
|
pub async fn get_site(
|
||||||
type Response = GetSiteResponse;
|
data: Query<GetSite>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetSiteResponse>, LemmyError> {
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let admins = PersonView::admins(&mut context.pool()).await?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<GetSiteResponse, LemmyError> {
|
|
||||||
let data: &GetSite = self;
|
|
||||||
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
// Build the local user
|
||||||
|
let my_user = if let Some(local_user_view) =
|
||||||
|
local_user_settings_view_from_jwt_opt(data.auth.as_ref(), &context).await
|
||||||
|
{
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let local_user_id = local_user_view.local_user.id;
|
||||||
|
|
||||||
let admins = PersonView::admins(&mut context.pool()).await?;
|
let follows = CommunityFollowerView::for_person(&mut context.pool(), person_id)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||||
|
|
||||||
// Build the local user
|
let person_id = local_user_view.person.id;
|
||||||
let my_user = if let Some(local_user_view) =
|
let community_blocks = CommunityBlockView::for_person(&mut context.pool(), person_id)
|
||||||
local_user_settings_view_from_jwt_opt(data.auth.as_ref(), context).await
|
.await
|
||||||
{
|
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let local_user_id = local_user_view.local_user.id;
|
|
||||||
|
|
||||||
let follows = CommunityFollowerView::for_person(&mut context.pool(), person_id)
|
let person_id = local_user_view.person.id;
|
||||||
.await
|
let person_blocks = PersonBlockView::for_person(&mut context.pool(), person_id)
|
||||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let moderates = CommunityModeratorView::for_person(&mut context.pool(), person_id)
|
||||||
let community_blocks = CommunityBlockView::for_person(&mut context.pool(), person_id)
|
.await
|
||||||
.await
|
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let discussion_languages = LocalUserLanguage::read(&mut context.pool(), local_user_id)
|
||||||
let person_blocks = PersonBlockView::for_person(&mut context.pool(), person_id)
|
.await
|
||||||
.await
|
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
|
||||||
|
|
||||||
let moderates = CommunityModeratorView::for_person(&mut context.pool(), person_id)
|
Some(MyUserInfo {
|
||||||
.await
|
local_user_view,
|
||||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
follows,
|
||||||
|
moderates,
|
||||||
let discussion_languages = LocalUserLanguage::read(&mut context.pool(), local_user_id)
|
community_blocks,
|
||||||
.await
|
person_blocks,
|
||||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
|
||||||
|
|
||||||
Some(MyUserInfo {
|
|
||||||
local_user_view,
|
|
||||||
follows,
|
|
||||||
moderates,
|
|
||||||
community_blocks,
|
|
||||||
person_blocks,
|
|
||||||
discussion_languages,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let all_languages = Language::read_all(&mut context.pool()).await?;
|
|
||||||
let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?;
|
|
||||||
let taglines = Tagline::get_all(&mut context.pool(), site_view.local_site.id).await?;
|
|
||||||
let custom_emojis =
|
|
||||||
CustomEmojiView::get_all(&mut context.pool(), site_view.local_site.id).await?;
|
|
||||||
|
|
||||||
Ok(GetSiteResponse {
|
|
||||||
site_view,
|
|
||||||
admins,
|
|
||||||
version: version::VERSION.to_string(),
|
|
||||||
my_user,
|
|
||||||
all_languages,
|
|
||||||
discussion_languages,
|
discussion_languages,
|
||||||
taglines,
|
|
||||||
custom_emojis,
|
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let all_languages = Language::read_all(&mut context.pool()).await?;
|
||||||
|
let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?;
|
||||||
|
let taglines = Tagline::get_all(&mut context.pool(), site_view.local_site.id).await?;
|
||||||
|
let custom_emojis =
|
||||||
|
CustomEmojiView::get_all(&mut context.pool(), site_view.local_site.id).await?;
|
||||||
|
|
||||||
|
Ok(Json(GetSiteResponse {
|
||||||
|
site_view,
|
||||||
|
admins,
|
||||||
|
version: version::VERSION.to_string(),
|
||||||
|
my_user,
|
||||||
|
all_languages,
|
||||||
|
discussion_languages,
|
||||||
|
taglines,
|
||||||
|
custom_emojis,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::{
|
use crate::site::{application_question_check, site_default_post_listing_type_check};
|
||||||
site::{application_question_check, site_default_post_listing_type_check},
|
use actix_web::web::{Data, Json};
|
||||||
PerformCrud,
|
|
||||||
};
|
|
||||||
use actix_web::web::Data;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{EditSite, SiteResponse},
|
site::{EditSite, SiteResponse},
|
||||||
|
@ -43,147 +40,142 @@ use lemmy_utils::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl PerformCrud for EditSite {
|
pub async fn update_site(
|
||||||
type Response = SiteResponse;
|
data: Json<EditSite>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<SiteResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
let local_site = site_view.local_site;
|
||||||
|
let site = site_view.site;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Make sure user is an admin; other types of users should not update site data...
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<SiteResponse, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &EditSite = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
|
||||||
let local_site = site_view.local_site;
|
|
||||||
let site = site_view.site;
|
|
||||||
|
|
||||||
// Make sure user is an admin; other types of users should not update site data...
|
validate_update_payload(&local_site, &data)?;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
validate_update_payload(&local_site, data)?;
|
if let Some(discussion_languages) = data.discussion_languages.clone() {
|
||||||
|
SiteLanguage::update(&mut context.pool(), discussion_languages.clone(), &site).await?;
|
||||||
if let Some(discussion_languages) = data.discussion_languages.clone() {
|
|
||||||
SiteLanguage::update(&mut context.pool(), discussion_languages.clone(), &site).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = sanitize_html_opt(&data.name);
|
|
||||||
let sidebar = sanitize_html_opt(&data.sidebar);
|
|
||||||
let description = sanitize_html_opt(&data.description);
|
|
||||||
|
|
||||||
let site_form = SiteUpdateForm::builder()
|
|
||||||
.name(name)
|
|
||||||
.sidebar(diesel_option_overwrite(sidebar))
|
|
||||||
.description(diesel_option_overwrite(description))
|
|
||||||
.icon(diesel_option_overwrite_to_url(&data.icon)?)
|
|
||||||
.banner(diesel_option_overwrite_to_url(&data.banner)?)
|
|
||||||
.updated(Some(Some(naive_now())))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Site::update(&mut context.pool(), site.id, &site_form)
|
|
||||||
.await
|
|
||||||
// Ignore errors for all these, so as to not throw errors if no update occurs
|
|
||||||
// Diesel will throw an error for empty update forms
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let application_question = sanitize_html_opt(&data.application_question);
|
|
||||||
let default_theme = sanitize_html_opt(&data.default_theme);
|
|
||||||
let legal_information = sanitize_html_opt(&data.legal_information);
|
|
||||||
|
|
||||||
let local_site_form = LocalSiteUpdateForm::builder()
|
|
||||||
.enable_downvotes(data.enable_downvotes)
|
|
||||||
.registration_mode(data.registration_mode)
|
|
||||||
.enable_nsfw(data.enable_nsfw)
|
|
||||||
.community_creation_admin_only(data.community_creation_admin_only)
|
|
||||||
.require_email_verification(data.require_email_verification)
|
|
||||||
.application_question(diesel_option_overwrite(application_question))
|
|
||||||
.private_instance(data.private_instance)
|
|
||||||
.default_theme(default_theme)
|
|
||||||
.default_post_listing_type(data.default_post_listing_type)
|
|
||||||
.legal_information(diesel_option_overwrite(legal_information))
|
|
||||||
.application_email_admins(data.application_email_admins)
|
|
||||||
.hide_modlog_mod_names(data.hide_modlog_mod_names)
|
|
||||||
.updated(Some(Some(naive_now())))
|
|
||||||
.slur_filter_regex(diesel_option_overwrite(data.slur_filter_regex.clone()))
|
|
||||||
.actor_name_max_length(data.actor_name_max_length)
|
|
||||||
.federation_enabled(data.federation_enabled)
|
|
||||||
.captcha_enabled(data.captcha_enabled)
|
|
||||||
.captcha_difficulty(data.captcha_difficulty.clone())
|
|
||||||
.reports_email_admins(data.reports_email_admins)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let update_local_site = LocalSite::update(&mut context.pool(), &local_site_form)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
|
||||||
.message(data.rate_limit_message)
|
|
||||||
.message_per_second(data.rate_limit_message_per_second)
|
|
||||||
.post(data.rate_limit_post)
|
|
||||||
.post_per_second(data.rate_limit_post_per_second)
|
|
||||||
.register(data.rate_limit_register)
|
|
||||||
.register_per_second(data.rate_limit_register_per_second)
|
|
||||||
.image(data.rate_limit_image)
|
|
||||||
.image_per_second(data.rate_limit_image_per_second)
|
|
||||||
.comment(data.rate_limit_comment)
|
|
||||||
.comment_per_second(data.rate_limit_comment_per_second)
|
|
||||||
.search(data.rate_limit_search)
|
|
||||||
.search_per_second(data.rate_limit_search_per_second)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
LocalSiteRateLimit::update(&mut context.pool(), &local_site_rate_limit_form)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
// Replace the blocked and allowed instances
|
|
||||||
let allowed = data.allowed_instances.clone();
|
|
||||||
FederationAllowList::replace(&mut context.pool(), allowed).await?;
|
|
||||||
let blocked = data.blocked_instances.clone();
|
|
||||||
FederationBlockList::replace(&mut context.pool(), blocked).await?;
|
|
||||||
|
|
||||||
// TODO can't think of a better way to do this.
|
|
||||||
// If the server suddenly requires email verification, or required applications, no old users
|
|
||||||
// will be able to log in. It really only wants this to be a requirement for NEW signups.
|
|
||||||
// So if it was set from false, to true, you need to update all current users columns to be verified.
|
|
||||||
|
|
||||||
let old_require_application =
|
|
||||||
local_site.registration_mode == RegistrationMode::RequireApplication;
|
|
||||||
let new_require_application = update_local_site
|
|
||||||
.as_ref()
|
|
||||||
.map(|ols| ols.registration_mode == RegistrationMode::RequireApplication)
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !old_require_application && new_require_application {
|
|
||||||
LocalUser::set_all_users_registration_applications_accepted(&mut context.pool())
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSetAllRegistrationsAccepted)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_require_email_verification = update_local_site
|
|
||||||
.as_ref()
|
|
||||||
.map(|ols| ols.require_email_verification)
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !local_site.require_email_verification && new_require_email_verification {
|
|
||||||
LocalUser::set_all_users_email_verified(&mut context.pool())
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSetAllEmailVerified)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_taglines = data.taglines.clone();
|
|
||||||
let taglines = Tagline::replace(&mut context.pool(), local_site.id, new_taglines).await?;
|
|
||||||
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
let rate_limit_config =
|
|
||||||
local_site_rate_limit_to_rate_limit_config(&site_view.local_site_rate_limit);
|
|
||||||
context
|
|
||||||
.settings_updated_channel()
|
|
||||||
.send(rate_limit_config)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let res = SiteResponse {
|
|
||||||
site_view,
|
|
||||||
taglines,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let name = sanitize_html_opt(&data.name);
|
||||||
|
let sidebar = sanitize_html_opt(&data.sidebar);
|
||||||
|
let description = sanitize_html_opt(&data.description);
|
||||||
|
|
||||||
|
let site_form = SiteUpdateForm::builder()
|
||||||
|
.name(name)
|
||||||
|
.sidebar(diesel_option_overwrite(sidebar))
|
||||||
|
.description(diesel_option_overwrite(description))
|
||||||
|
.icon(diesel_option_overwrite_to_url(&data.icon)?)
|
||||||
|
.banner(diesel_option_overwrite_to_url(&data.banner)?)
|
||||||
|
.updated(Some(Some(naive_now())))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Site::update(&mut context.pool(), site.id, &site_form)
|
||||||
|
.await
|
||||||
|
// Ignore errors for all these, so as to not throw errors if no update occurs
|
||||||
|
// Diesel will throw an error for empty update forms
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let application_question = sanitize_html_opt(&data.application_question);
|
||||||
|
let default_theme = sanitize_html_opt(&data.default_theme);
|
||||||
|
let legal_information = sanitize_html_opt(&data.legal_information);
|
||||||
|
|
||||||
|
let local_site_form = LocalSiteUpdateForm::builder()
|
||||||
|
.enable_downvotes(data.enable_downvotes)
|
||||||
|
.registration_mode(data.registration_mode)
|
||||||
|
.enable_nsfw(data.enable_nsfw)
|
||||||
|
.community_creation_admin_only(data.community_creation_admin_only)
|
||||||
|
.require_email_verification(data.require_email_verification)
|
||||||
|
.application_question(diesel_option_overwrite(application_question))
|
||||||
|
.private_instance(data.private_instance)
|
||||||
|
.default_theme(default_theme)
|
||||||
|
.default_post_listing_type(data.default_post_listing_type)
|
||||||
|
.legal_information(diesel_option_overwrite(legal_information))
|
||||||
|
.application_email_admins(data.application_email_admins)
|
||||||
|
.hide_modlog_mod_names(data.hide_modlog_mod_names)
|
||||||
|
.updated(Some(Some(naive_now())))
|
||||||
|
.slur_filter_regex(diesel_option_overwrite(data.slur_filter_regex.clone()))
|
||||||
|
.actor_name_max_length(data.actor_name_max_length)
|
||||||
|
.federation_enabled(data.federation_enabled)
|
||||||
|
.captcha_enabled(data.captcha_enabled)
|
||||||
|
.captcha_difficulty(data.captcha_difficulty.clone())
|
||||||
|
.reports_email_admins(data.reports_email_admins)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let update_local_site = LocalSite::update(&mut context.pool(), &local_site_form)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let local_site_rate_limit_form = LocalSiteRateLimitUpdateForm::builder()
|
||||||
|
.message(data.rate_limit_message)
|
||||||
|
.message_per_second(data.rate_limit_message_per_second)
|
||||||
|
.post(data.rate_limit_post)
|
||||||
|
.post_per_second(data.rate_limit_post_per_second)
|
||||||
|
.register(data.rate_limit_register)
|
||||||
|
.register_per_second(data.rate_limit_register_per_second)
|
||||||
|
.image(data.rate_limit_image)
|
||||||
|
.image_per_second(data.rate_limit_image_per_second)
|
||||||
|
.comment(data.rate_limit_comment)
|
||||||
|
.comment_per_second(data.rate_limit_comment_per_second)
|
||||||
|
.search(data.rate_limit_search)
|
||||||
|
.search_per_second(data.rate_limit_search_per_second)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
LocalSiteRateLimit::update(&mut context.pool(), &local_site_rate_limit_form)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
// Replace the blocked and allowed instances
|
||||||
|
let allowed = data.allowed_instances.clone();
|
||||||
|
FederationAllowList::replace(&mut context.pool(), allowed).await?;
|
||||||
|
let blocked = data.blocked_instances.clone();
|
||||||
|
FederationBlockList::replace(&mut context.pool(), blocked).await?;
|
||||||
|
|
||||||
|
// TODO can't think of a better way to do this.
|
||||||
|
// If the server suddenly requires email verification, or required applications, no old users
|
||||||
|
// will be able to log in. It really only wants this to be a requirement for NEW signups.
|
||||||
|
// So if it was set from false, to true, you need to update all current users columns to be verified.
|
||||||
|
|
||||||
|
let old_require_application =
|
||||||
|
local_site.registration_mode == RegistrationMode::RequireApplication;
|
||||||
|
let new_require_application = update_local_site
|
||||||
|
.as_ref()
|
||||||
|
.map(|ols| ols.registration_mode == RegistrationMode::RequireApplication)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !old_require_application && new_require_application {
|
||||||
|
LocalUser::set_all_users_registration_applications_accepted(&mut context.pool())
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntSetAllRegistrationsAccepted)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_require_email_verification = update_local_site
|
||||||
|
.as_ref()
|
||||||
|
.map(|ols| ols.require_email_verification)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !local_site.require_email_verification && new_require_email_verification {
|
||||||
|
LocalUser::set_all_users_email_verified(&mut context.pool())
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntSetAllEmailVerified)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_taglines = data.taglines.clone();
|
||||||
|
let taglines = Tagline::replace(&mut context.pool(), local_site.id, new_taglines).await?;
|
||||||
|
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
|
||||||
|
let rate_limit_config =
|
||||||
|
local_site_rate_limit_to_rate_limit_config(&site_view.local_site_rate_limit);
|
||||||
|
context
|
||||||
|
.settings_updated_channel()
|
||||||
|
.send(rate_limit_config)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(SiteResponse {
|
||||||
|
site_view,
|
||||||
|
taglines,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_update_payload(local_site: &LocalSite, edit_site: &EditSite) -> LemmyResult<()> {
|
fn validate_update_payload(local_site: &LocalSite, edit_site: &EditSite) -> LemmyResult<()> {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use activitypub_federation::{
|
||||||
};
|
};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
build_response::send_local_notifs,
|
build_response::send_local_notifs,
|
||||||
comment::{CommentResponse, CreateComment, EditComment},
|
comment::{CommentResponse, EditComment},
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{check_post_deleted_or_removed, is_mod_or_admin},
|
utils::{check_post_deleted_or_removed, is_mod_or_admin},
|
||||||
};
|
};
|
||||||
|
@ -43,25 +43,6 @@ use lemmy_db_schema::{
|
||||||
use lemmy_utils::{error::LemmyError, utils::mention::scrape_text_for_mentions};
|
use lemmy_utils::{error::LemmyError, utils::mention::scrape_text_for_mentions};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
|
||||||
impl SendActivity for CreateComment {
|
|
||||||
type Response = CommentResponse;
|
|
||||||
|
|
||||||
async fn send_activity(
|
|
||||||
_request: &Self,
|
|
||||||
response: &Self::Response,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
CreateOrUpdateNote::send(
|
|
||||||
&response.comment_view.comment,
|
|
||||||
response.comment_view.creator.id,
|
|
||||||
CreateOrUpdateType::Create,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl SendActivity for EditComment {
|
impl SendActivity for EditComment {
|
||||||
type Response = CommentResponse;
|
type Response = CommentResponse;
|
||||||
|
@ -72,10 +53,10 @@ impl SendActivity for EditComment {
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
CreateOrUpdateNote::send(
|
CreateOrUpdateNote::send(
|
||||||
&response.comment_view.comment,
|
response.comment_view.comment.clone(),
|
||||||
response.comment_view.creator.id,
|
response.comment_view.creator.id,
|
||||||
CreateOrUpdateType::Update,
|
CreateOrUpdateType::Update,
|
||||||
context,
|
context.reset_request_count(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -83,11 +64,11 @@ impl SendActivity for EditComment {
|
||||||
|
|
||||||
impl CreateOrUpdateNote {
|
impl CreateOrUpdateNote {
|
||||||
#[tracing::instrument(skip(comment, person_id, kind, context))]
|
#[tracing::instrument(skip(comment, person_id, kind, context))]
|
||||||
async fn send(
|
pub(crate) async fn send(
|
||||||
comment: &Comment,
|
comment: Comment,
|
||||||
person_id: PersonId,
|
person_id: PersonId,
|
||||||
kind: CreateOrUpdateType,
|
kind: CreateOrUpdateType,
|
||||||
context: &Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
) -> Result<(), LemmyError> {
|
) -> Result<(), LemmyError> {
|
||||||
// TODO: might be helpful to add a comment method to retrieve community directly
|
// TODO: might be helpful to add a comment method to retrieve community directly
|
||||||
let post_id = comment.post_id;
|
let post_id = comment.post_id;
|
||||||
|
@ -102,7 +83,7 @@ impl CreateOrUpdateNote {
|
||||||
kind.clone(),
|
kind.clone(),
|
||||||
&context.settings().get_protocol_and_hostname(),
|
&context.settings().get_protocol_and_hostname(),
|
||||||
)?;
|
)?;
|
||||||
let note = ApubComment(comment.clone()).into_json(context).await?;
|
let note = ApubComment(comment).into_json(&context).await?;
|
||||||
|
|
||||||
let create_or_update = CreateOrUpdateNote {
|
let create_or_update = CreateOrUpdateNote {
|
||||||
actor: person.id().into(),
|
actor: person.id().into(),
|
||||||
|
@ -130,12 +111,12 @@ impl CreateOrUpdateNote {
|
||||||
.collect();
|
.collect();
|
||||||
let mut inboxes = vec![];
|
let mut inboxes = vec![];
|
||||||
for t in tagged_users {
|
for t in tagged_users {
|
||||||
let person = t.dereference(context).await?;
|
let person = t.dereference(&context).await?;
|
||||||
inboxes.push(person.shared_inbox_or_inbox());
|
inboxes.push(person.shared_inbox_or_inbox());
|
||||||
}
|
}
|
||||||
|
|
||||||
let activity = AnnouncableActivities::CreateOrUpdateComment(create_or_update);
|
let activity = AnnouncableActivities::CreateOrUpdateComment(create_or_update);
|
||||||
send_activity_in_community(activity, &person, &community, inboxes, false, context).await
|
send_activity_in_community(activity, &person, &community, inboxes, false, &context).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{community::ApubCommunity, person::ApubPerson},
|
objects::{community::ApubCommunity, person::ApubPerson},
|
||||||
protocol::activities::{create_or_update::page::CreateOrUpdatePage, CreateOrUpdateType},
|
protocol::activities::{
|
||||||
|
create_or_update::{note::CreateOrUpdateNote, page::CreateOrUpdatePage},
|
||||||
|
CreateOrUpdateType,
|
||||||
|
},
|
||||||
CONTEXT,
|
CONTEXT,
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
|
@ -217,15 +220,17 @@ pub async fn match_outgoing_activities(
|
||||||
data: SendActivityData,
|
data: SendActivityData,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> LemmyResult<()> {
|
) -> LemmyResult<()> {
|
||||||
let fed_task = match data {
|
let context = context.reset_request_count();
|
||||||
SendActivityData::CreatePost(post) => {
|
let fed_task = async {
|
||||||
let creator_id = post.creator_id;
|
match data {
|
||||||
CreateOrUpdatePage::send(
|
SendActivityData::CreatePost(post) => {
|
||||||
post,
|
let creator_id = post.creator_id;
|
||||||
creator_id,
|
CreateOrUpdatePage::send(post, creator_id, CreateOrUpdateType::Create, context).await
|
||||||
CreateOrUpdateType::Create,
|
}
|
||||||
context.reset_request_count(),
|
SendActivityData::CreateComment(comment) => {
|
||||||
)
|
let creator_id = comment.creator_id;
|
||||||
|
CreateOrUpdateNote::send(comment, creator_id, CreateOrUpdateType::Create, context).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if *SYNCHRONOUS_FEDERATION {
|
if *SYNCHRONOUS_FEDERATION {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorExt2, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorExt2, LemmyErrorType};
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
#[tracing::instrument(skip(context))]
|
||||||
pub async fn read_community(
|
pub async fn get_community(
|
||||||
data: Query<GetCommunity>,
|
data: Query<GetCommunity>,
|
||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
) -> Result<Json<GetCommunityResponse>, LemmyError> {
|
) -> Result<Json<GetCommunityResponse>, LemmyError> {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 713ceed9c7ef84deaa222e68361e670e0763cd83
|
Subproject commit 1c42c579460871de7b4ea18e58dc25543b80d289
|
|
@ -1,19 +1,12 @@
|
||||||
use actix_web::{guard, web, Error, HttpResponse, Result};
|
use actix_web::{guard, web, Error, HttpResponse, Result};
|
||||||
use lemmy_api::Perform;
|
use lemmy_api::{
|
||||||
|
comment::{distinguish::distinguish_comment, save::save_comment},
|
||||||
|
comment_report::{list::list_comment_reports, resolve::resolve_comment_report},
|
||||||
|
local_user::notifications::mark_reply_read::mark_reply_as_read,
|
||||||
|
Perform,
|
||||||
|
};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
comment::{
|
comment::{CreateCommentLike, CreateCommentReport, DeleteComment, EditComment, RemoveComment},
|
||||||
CreateComment,
|
|
||||||
CreateCommentLike,
|
|
||||||
CreateCommentReport,
|
|
||||||
DeleteComment,
|
|
||||||
DistinguishComment,
|
|
||||||
EditComment,
|
|
||||||
GetComment,
|
|
||||||
ListCommentReports,
|
|
||||||
RemoveComment,
|
|
||||||
ResolveCommentReport,
|
|
||||||
SaveComment,
|
|
||||||
},
|
|
||||||
community::{
|
community::{
|
||||||
AddModToCommunity,
|
AddModToCommunity,
|
||||||
BanFromCommunity,
|
BanFromCommunity,
|
||||||
|
@ -23,7 +16,6 @@ use lemmy_api_common::{
|
||||||
EditCommunity,
|
EditCommunity,
|
||||||
FollowCommunity,
|
FollowCommunity,
|
||||||
HideCommunity,
|
HideCommunity,
|
||||||
ListCommunities,
|
|
||||||
RemoveCommunity,
|
RemoveCommunity,
|
||||||
TransferCommunity,
|
TransferCommunity,
|
||||||
},
|
},
|
||||||
|
@ -43,7 +35,6 @@ use lemmy_api_common::{
|
||||||
GetUnreadCount,
|
GetUnreadCount,
|
||||||
Login,
|
Login,
|
||||||
MarkAllAsRead,
|
MarkAllAsRead,
|
||||||
MarkCommentReplyAsRead,
|
|
||||||
MarkPersonMentionAsRead,
|
MarkPersonMentionAsRead,
|
||||||
PasswordChangeAfterReset,
|
PasswordChangeAfterReset,
|
||||||
PasswordReset,
|
PasswordReset,
|
||||||
|
@ -57,7 +48,6 @@ use lemmy_api_common::{
|
||||||
DeletePost,
|
DeletePost,
|
||||||
EditPost,
|
EditPost,
|
||||||
FeaturePost,
|
FeaturePost,
|
||||||
GetPost,
|
|
||||||
GetSiteMetadata,
|
GetSiteMetadata,
|
||||||
ListPostReports,
|
ListPostReports,
|
||||||
LockPost,
|
LockPost,
|
||||||
|
@ -71,18 +61,14 @@ use lemmy_api_common::{
|
||||||
CreatePrivateMessageReport,
|
CreatePrivateMessageReport,
|
||||||
DeletePrivateMessage,
|
DeletePrivateMessage,
|
||||||
EditPrivateMessage,
|
EditPrivateMessage,
|
||||||
GetPrivateMessages,
|
|
||||||
ListPrivateMessageReports,
|
ListPrivateMessageReports,
|
||||||
MarkPrivateMessageAsRead,
|
MarkPrivateMessageAsRead,
|
||||||
ResolvePrivateMessageReport,
|
ResolvePrivateMessageReport,
|
||||||
},
|
},
|
||||||
site::{
|
site::{
|
||||||
ApproveRegistrationApplication,
|
ApproveRegistrationApplication,
|
||||||
CreateSite,
|
|
||||||
EditSite,
|
|
||||||
GetFederatedInstances,
|
GetFederatedInstances,
|
||||||
GetModlog,
|
GetModlog,
|
||||||
GetSite,
|
|
||||||
GetUnreadRegistrationApplicationCount,
|
GetUnreadRegistrationApplicationCount,
|
||||||
LeaveAdmin,
|
LeaveAdmin,
|
||||||
ListRegistrationApplications,
|
ListRegistrationApplications,
|
||||||
|
@ -92,12 +78,19 @@ use lemmy_api_common::{
|
||||||
PurgePost,
|
PurgePost,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use lemmy_api_crud::{post::create::create_post, PerformCrud};
|
use lemmy_api_crud::{
|
||||||
|
comment::{create::create_comment, read::get_comment},
|
||||||
|
community::list::list_communities,
|
||||||
|
post::{create::create_post, read::get_post},
|
||||||
|
private_message::read::get_private_message,
|
||||||
|
site::{create::create_site, read::get_site, update::update_site},
|
||||||
|
PerformCrud,
|
||||||
|
};
|
||||||
use lemmy_apub::{
|
use lemmy_apub::{
|
||||||
api::{
|
api::{
|
||||||
list_comments::list_comments,
|
list_comments::list_comments,
|
||||||
list_posts::list_posts,
|
list_posts::list_posts,
|
||||||
read_community::read_community,
|
read_community::get_community,
|
||||||
read_person::read_person,
|
read_person::read_person,
|
||||||
resolve_object::resolve_object,
|
resolve_object::resolve_object,
|
||||||
search::search,
|
search::search,
|
||||||
|
@ -114,10 +107,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.service(
|
.service(
|
||||||
web::scope("/site")
|
web::scope("/site")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(route_get_crud::<GetSite>))
|
.route("", web::get().to(get_site))
|
||||||
// Admin Actions
|
// Admin Actions
|
||||||
.route("", web::post().to(route_post_crud::<CreateSite>))
|
.route("", web::post().to(create_site))
|
||||||
.route("", web::put().to(route_post_crud::<EditSite>)),
|
.route("", web::put().to(update_site)),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/modlog")
|
web::resource("/modlog")
|
||||||
|
@ -144,10 +137,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.service(
|
.service(
|
||||||
web::scope("/community")
|
web::scope("/community")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(read_community))
|
.route("", web::get().to(get_community))
|
||||||
.route("", web::put().to(route_post_crud::<EditCommunity>))
|
.route("", web::put().to(route_post_crud::<EditCommunity>))
|
||||||
.route("/hide", web::put().to(route_post::<HideCommunity>))
|
.route("/hide", web::put().to(route_post::<HideCommunity>))
|
||||||
.route("/list", web::get().to(route_get_crud::<ListCommunities>))
|
.route("/list", web::get().to(list_communities))
|
||||||
.route("/follow", web::post().to(route_post::<FollowCommunity>))
|
.route("/follow", web::post().to(route_post::<FollowCommunity>))
|
||||||
.route("/block", web::post().to(route_post::<BlockCommunity>))
|
.route("/block", web::post().to(route_post::<BlockCommunity>))
|
||||||
.route(
|
.route(
|
||||||
|
@ -179,7 +172,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.service(
|
.service(
|
||||||
web::scope("/post")
|
web::scope("/post")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(route_get_crud::<GetPost>))
|
.route("", web::get().to(get_post))
|
||||||
.route("", web::put().to(route_post_crud::<EditPost>))
|
.route("", web::put().to(route_post_crud::<EditPost>))
|
||||||
.route("/delete", web::post().to(route_post_crud::<DeletePost>))
|
.route("/delete", web::post().to(route_post_crud::<DeletePost>))
|
||||||
.route("/remove", web::post().to(route_post_crud::<RemovePost>))
|
.route("/remove", web::post().to(route_post_crud::<RemovePost>))
|
||||||
|
@ -209,41 +202,29 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
web::resource("/comment")
|
web::resource("/comment")
|
||||||
.guard(guard::Post())
|
.guard(guard::Post())
|
||||||
.wrap(rate_limit.comment())
|
.wrap(rate_limit.comment())
|
||||||
.route(web::post().to(route_post_crud::<CreateComment>)),
|
.route(web::post().to(create_comment)),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/comment")
|
web::scope("/comment")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(route_get_crud::<GetComment>))
|
.route("", web::get().to(get_comment))
|
||||||
.route("", web::put().to(route_post_crud::<EditComment>))
|
.route("", web::put().to(route_post_crud::<EditComment>))
|
||||||
.route("/delete", web::post().to(route_post_crud::<DeleteComment>))
|
.route("/delete", web::post().to(route_post_crud::<DeleteComment>))
|
||||||
.route("/remove", web::post().to(route_post_crud::<RemoveComment>))
|
.route("/remove", web::post().to(route_post_crud::<RemoveComment>))
|
||||||
.route(
|
.route("/mark_as_read", web::post().to(mark_reply_as_read))
|
||||||
"/mark_as_read",
|
.route("/distinguish", web::post().to(distinguish_comment))
|
||||||
web::post().to(route_post::<MarkCommentReplyAsRead>),
|
|
||||||
)
|
|
||||||
.route(
|
|
||||||
"/distinguish",
|
|
||||||
web::post().to(route_post::<DistinguishComment>),
|
|
||||||
)
|
|
||||||
.route("/like", web::post().to(route_post::<CreateCommentLike>))
|
.route("/like", web::post().to(route_post::<CreateCommentLike>))
|
||||||
.route("/save", web::put().to(route_post::<SaveComment>))
|
.route("/save", web::put().to(save_comment))
|
||||||
.route("/list", web::get().to(list_comments))
|
.route("/list", web::get().to(list_comments))
|
||||||
.route("/report", web::post().to(route_post::<CreateCommentReport>))
|
.route("/report", web::post().to(route_post::<CreateCommentReport>))
|
||||||
.route(
|
.route("/report/resolve", web::put().to(resolve_comment_report))
|
||||||
"/report/resolve",
|
.route("/report/list", web::get().to(list_comment_reports)),
|
||||||
web::put().to(route_post::<ResolveCommentReport>),
|
|
||||||
)
|
|
||||||
.route(
|
|
||||||
"/report/list",
|
|
||||||
web::get().to(route_get::<ListCommentReports>),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
// Private Message
|
// Private Message
|
||||||
.service(
|
.service(
|
||||||
web::scope("/private_message")
|
web::scope("/private_message")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("/list", web::get().to(route_get_crud::<GetPrivateMessages>))
|
.route("/list", web::get().to(get_private_message))
|
||||||
.route("", web::post().to(route_post_crud::<CreatePrivateMessage>))
|
.route("", web::post().to(route_post_crud::<CreatePrivateMessage>))
|
||||||
.route("", web::put().to(route_post_crud::<EditPrivateMessage>))
|
.route("", web::put().to(route_post_crud::<EditPrivateMessage>))
|
||||||
.route(
|
.route(
|
||||||
|
@ -447,22 +428,6 @@ where
|
||||||
Ok(HttpResponse::Ok().json(&res))
|
Ok(HttpResponse::Ok().json(&res))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn route_get_crud<'a, Data>(
|
|
||||||
data: web::Query<Data>,
|
|
||||||
context: web::Data<LemmyContext>,
|
|
||||||
apub_data: activitypub_federation::config::Data<LemmyContext>,
|
|
||||||
) -> Result<HttpResponse, Error>
|
|
||||||
where
|
|
||||||
Data: PerformCrud
|
|
||||||
+ SendActivity<Response = <Data as PerformCrud>::Response>
|
|
||||||
+ Clone
|
|
||||||
+ Deserialize<'a>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
{
|
|
||||||
perform_crud::<Data>(data.0, context, apub_data).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn route_post_crud<'a, Data>(
|
async fn route_post_crud<'a, Data>(
|
||||||
data: web::Json<Data>,
|
data: web::Json<Data>,
|
||||||
context: web::Data<LemmyContext>,
|
context: web::Data<LemmyContext>,
|
||||||
|
|
Loading…
Reference in a new issue