* Get rid of remaining Perform/SendActivity traits (fixes #3670) * fix api tests * ci
This commit is contained in:
parent
a1a9c3e4c0
commit
366d9d1e2e
49 changed files with 1373 additions and 1981 deletions
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
community::{GetCommunityResponse, TransferCommunity},
|
community::{GetCommunityResponse, TransferCommunity},
|
||||||
|
@ -21,84 +20,77 @@ use lemmy_utils::{
|
||||||
|
|
||||||
// TODO: we dont do anything for federation here, it should be updated the next time the community
|
// TODO: we dont do anything for federation here, it should be updated the next time the community
|
||||||
// gets fetched. i hope we can get rid of the community creator role soon.
|
// gets fetched. i hope we can get rid of the community creator role soon.
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for TransferCommunity {
|
pub async fn transfer_community(
|
||||||
type Response = GetCommunityResponse;
|
data: Json<TransferCommunity>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetCommunityResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Fetch the community mods
|
||||||
async fn perform(
|
let community_id = data.community_id;
|
||||||
&self,
|
let mut community_mods =
|
||||||
context: &Data<LemmyContext>,
|
CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
) -> Result<GetCommunityResponse, LemmyError> {
|
|
||||||
let data: &TransferCommunity = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Fetch the community mods
|
// Make sure transferrer is either the top community mod, or an admin
|
||||||
let community_id = data.community_id;
|
if !(is_top_mod(&local_user_view, &community_mods).is_ok() || is_admin(&local_user_view).is_ok())
|
||||||
let mut community_mods =
|
{
|
||||||
CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
Err(LemmyErrorType::NotAnAdmin)?
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure transferrer is either the top community mod, or an admin
|
// You have to re-do the community_moderator table, reordering it.
|
||||||
if !(is_top_mod(&local_user_view, &community_mods).is_ok()
|
// Add the transferee to the top
|
||||||
|| is_admin(&local_user_view).is_ok())
|
let creator_index = community_mods
|
||||||
{
|
.iter()
|
||||||
Err(LemmyErrorType::NotAnAdmin)?
|
.position(|r| r.moderator.id == data.person_id)
|
||||||
}
|
.context(location_info!())?;
|
||||||
|
let creator_person = community_mods.remove(creator_index);
|
||||||
|
community_mods.insert(0, creator_person);
|
||||||
|
|
||||||
// You have to re-do the community_moderator table, reordering it.
|
// Delete all the mods
|
||||||
// Add the transferee to the top
|
let community_id = data.community_id;
|
||||||
let creator_index = community_mods
|
|
||||||
.iter()
|
|
||||||
.position(|r| r.moderator.id == data.person_id)
|
|
||||||
.context(location_info!())?;
|
|
||||||
let creator_person = community_mods.remove(creator_index);
|
|
||||||
community_mods.insert(0, creator_person);
|
|
||||||
|
|
||||||
// Delete all the mods
|
CommunityModerator::delete_for_community(&mut context.pool(), community_id).await?;
|
||||||
let community_id = data.community_id;
|
|
||||||
|
|
||||||
CommunityModerator::delete_for_community(&mut context.pool(), community_id).await?;
|
// TODO: this should probably be a bulk operation
|
||||||
|
// Re-add the mods, in the new order
|
||||||
// TODO: this should probably be a bulk operation
|
for cmod in &community_mods {
|
||||||
// Re-add the mods, in the new order
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
for cmod in &community_mods {
|
community_id: cmod.community.id,
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
person_id: cmod.moderator.id,
|
||||||
community_id: cmod.community.id,
|
|
||||||
person_id: cmod.moderator.id,
|
|
||||||
};
|
|
||||||
|
|
||||||
CommunityModerator::join(&mut context.pool(), &community_moderator_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CommunityModeratorAlreadyExists)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mod tables
|
|
||||||
let form = ModTransferCommunityForm {
|
|
||||||
mod_person_id: local_user_view.person.id,
|
|
||||||
other_person_id: data.person_id,
|
|
||||||
community_id: data.community_id,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ModTransferCommunity::create(&mut context.pool(), &form).await?;
|
CommunityModerator::join(&mut context.pool(), &community_moderator_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CommunityModeratorAlreadyExists)?;
|
||||||
|
}
|
||||||
|
|
||||||
let community_id = data.community_id;
|
// Mod tables
|
||||||
let person_id = local_user_view.person.id;
|
let form = ModTransferCommunityForm {
|
||||||
let community_view =
|
mod_person_id: local_user_view.person.id,
|
||||||
CommunityView::read(&mut context.pool(), community_id, Some(person_id), false)
|
other_person_id: data.person_id,
|
||||||
.await
|
community_id: data.community_id,
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
};
|
||||||
|
|
||||||
let community_id = data.community_id;
|
ModTransferCommunity::create(&mut context.pool(), &form).await?;
|
||||||
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)
|
|
||||||
|
let community_id = data.community_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let community_view =
|
||||||
|
CommunityView::read(&mut context.pool(), community_id, Some(person_id), false)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
||||||
|
|
||||||
// Return the jwt
|
let community_id = data.community_id;
|
||||||
Ok(GetCommunityResponse {
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id)
|
||||||
community_view,
|
.await
|
||||||
site: None,
|
.with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?;
|
||||||
moderators,
|
|
||||||
discussion_languages: vec![],
|
// Return the jwt
|
||||||
})
|
Ok(Json(GetCommunityResponse {
|
||||||
}
|
community_view,
|
||||||
|
site: None,
|
||||||
|
moderators,
|
||||||
|
discussion_languages: vec![],
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use actix_web::web::Data;
|
|
||||||
use base64::{engine::general_purpose::STANDARD_NO_PAD as base64, Engine};
|
use base64::{engine::general_purpose::STANDARD_NO_PAD as base64, Engine};
|
||||||
use captcha::Captcha;
|
use captcha::Captcha;
|
||||||
use lemmy_api_common::{context::LemmyContext, utils::local_site_to_slur_regex};
|
use lemmy_api_common::utils::local_site_to_slur_regex;
|
||||||
use lemmy_db_schema::source::local_site::LocalSite;
|
use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
||||||
|
@ -20,13 +19,6 @@ pub mod private_message_report;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod sitemap;
|
pub mod sitemap;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
pub trait Perform {
|
|
||||||
type Response: serde::ser::Serialize + Send + Clone + Sync;
|
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts the captcha to a base64 encoded wav audio file
|
/// Converts the captcha to a base64 encoded wav audio file
|
||||||
pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> Result<String, LemmyError> {
|
pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> Result<String, LemmyError> {
|
||||||
let letters = captcha.as_wav();
|
let letters = captcha.as_wav();
|
||||||
|
|
|
@ -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::{AddAdmin, AddAdminResponse},
|
person::{AddAdmin, AddAdminResponse},
|
||||||
|
@ -15,40 +14,37 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views_actor::structs::PersonView;
|
use lemmy_db_views_actor::structs::PersonView;
|
||||||
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 AddAdmin {
|
pub async fn add_admin(
|
||||||
type Response = AddAdminResponse;
|
data: Json<AddAdmin>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<AddAdminResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Make sure user is an admin
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<AddAdminResponse, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &AddAdmin = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Make sure user is an admin
|
let added_admin = LocalUser::update(
|
||||||
is_admin(&local_user_view)?;
|
&mut context.pool(),
|
||||||
|
data.local_user_id,
|
||||||
|
&LocalUserUpdateForm {
|
||||||
|
admin: Some(data.added),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateUser)?;
|
||||||
|
|
||||||
let added_admin = LocalUser::update(
|
// Mod tables
|
||||||
&mut context.pool(),
|
let form = ModAddForm {
|
||||||
data.local_user_id,
|
mod_person_id: local_user_view.person.id,
|
||||||
&LocalUserUpdateForm {
|
other_person_id: added_admin.person_id,
|
||||||
admin: Some(data.added),
|
removed: Some(!data.added),
|
||||||
..Default::default()
|
};
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateUser)?;
|
|
||||||
|
|
||||||
// Mod tables
|
ModAdd::create(&mut context.pool(), &form).await?;
|
||||||
let form = ModAddForm {
|
|
||||||
mod_person_id: local_user_view.person.id,
|
|
||||||
other_person_id: added_admin.person_id,
|
|
||||||
removed: Some(!data.added),
|
|
||||||
};
|
|
||||||
|
|
||||||
ModAdd::create(&mut context.pool(), &form).await?;
|
let admins = PersonView::admins(&mut context.pool()).await?;
|
||||||
|
|
||||||
let admins = PersonView::admins(&mut context.pool()).await?;
|
Ok(Json(AddAdminResponse { admins }))
|
||||||
|
|
||||||
Ok(AddAdminResponse { admins })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{BlockPerson, BlockPersonResponse},
|
person::{BlockPerson, BlockPersonResponse},
|
||||||
|
@ -13,47 +12,44 @@ use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_db_views_actor::structs::PersonView;
|
use lemmy_db_views_actor::structs::PersonView;
|
||||||
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 BlockPerson {
|
pub async fn block_person(
|
||||||
type Response = BlockPersonResponse;
|
data: Json<BlockPerson>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<BlockPersonResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let target_id = data.person_id;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<BlockPersonResponse, LemmyError> {
|
let person_id = local_user_view.person.id;
|
||||||
let data: &BlockPerson = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let target_id = data.person_id;
|
// Don't let a person block themselves
|
||||||
let person_id = local_user_view.person.id;
|
if target_id == person_id {
|
||||||
|
Err(LemmyErrorType::CantBlockYourself)?
|
||||||
// Don't let a person block themselves
|
|
||||||
if target_id == person_id {
|
|
||||||
Err(LemmyErrorType::CantBlockYourself)?
|
|
||||||
}
|
|
||||||
|
|
||||||
let person_block_form = PersonBlockForm {
|
|
||||||
person_id,
|
|
||||||
target_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
let target_user = LocalUserView::read_person(&mut context.pool(), target_id).await;
|
|
||||||
if target_user.map(|t| t.local_user.admin) == Ok(true) {
|
|
||||||
Err(LemmyErrorType::CantBlockAdmin)?
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.block {
|
|
||||||
PersonBlock::block(&mut context.pool(), &person_block_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
|
||||||
} else {
|
|
||||||
PersonBlock::unblock(&mut context.pool(), &person_block_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let person_view = PersonView::read(&mut context.pool(), target_id).await?;
|
|
||||||
Ok(BlockPersonResponse {
|
|
||||||
person_view,
|
|
||||||
blocked: data.block,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let person_block_form = PersonBlockForm {
|
||||||
|
person_id,
|
||||||
|
target_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_user = LocalUserView::read_person(&mut context.pool(), target_id).await;
|
||||||
|
if target_user.map(|t| t.local_user.admin) == Ok(true) {
|
||||||
|
Err(LemmyErrorType::CantBlockAdmin)?
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.block {
|
||||||
|
PersonBlock::block(&mut context.pool(), &person_block_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
||||||
|
} else {
|
||||||
|
PersonBlock::unblock(&mut context.pool(), &person_block_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let person_view = PersonView::read(&mut context.pool(), target_id).await?;
|
||||||
|
Ok(Json(BlockPersonResponse {
|
||||||
|
person_view,
|
||||||
|
blocked: data.block,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -12,49 +11,46 @@ use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorType},
|
error::{LemmyError, LemmyErrorType},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ChangePassword {
|
pub async fn change_password(
|
||||||
type Response = LoginResponse;
|
data: Json<ChangePassword>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<LoginResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(data.auth.as_ref(), &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, context))]
|
password_length_check(&data.new_password)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<LoginResponse, LemmyError> {
|
|
||||||
let data: &ChangePassword = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(data.auth.as_ref(), context).await?;
|
|
||||||
|
|
||||||
password_length_check(&data.new_password)?;
|
// Make sure passwords match
|
||||||
|
if data.new_password != data.new_password_verify {
|
||||||
// Make sure passwords match
|
Err(LemmyErrorType::PasswordsDoNotMatch)?
|
||||||
if data.new_password != data.new_password_verify {
|
|
||||||
Err(LemmyErrorType::PasswordsDoNotMatch)?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the old password
|
|
||||||
let valid: bool = verify(
|
|
||||||
&data.old_password,
|
|
||||||
&local_user_view.local_user.password_encrypted,
|
|
||||||
)
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !valid {
|
|
||||||
Err(LemmyErrorType::IncorrectLogin)?
|
|
||||||
}
|
|
||||||
|
|
||||||
let local_user_id = local_user_view.local_user.id;
|
|
||||||
let new_password = data.new_password.clone();
|
|
||||||
let updated_local_user =
|
|
||||||
LocalUser::update_password(&mut context.pool(), local_user_id, &new_password).await?;
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(LoginResponse {
|
|
||||||
jwt: Some(
|
|
||||||
Claims::jwt(
|
|
||||||
updated_local_user.id.0,
|
|
||||||
&context.secret().jwt_secret,
|
|
||||||
&context.settings().hostname,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
verify_email_sent: false,
|
|
||||||
registration_created: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the old password
|
||||||
|
let valid: bool = verify(
|
||||||
|
&data.old_password,
|
||||||
|
&local_user_view.local_user.password_encrypted,
|
||||||
|
)
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !valid {
|
||||||
|
Err(LemmyErrorType::IncorrectLogin)?
|
||||||
|
}
|
||||||
|
|
||||||
|
let local_user_id = local_user_view.local_user.id;
|
||||||
|
let new_password = data.new_password.clone();
|
||||||
|
let updated_local_user =
|
||||||
|
LocalUser::update_password(&mut context.pool(), local_user_id, &new_password).await?;
|
||||||
|
|
||||||
|
// Return the jwt
|
||||||
|
Ok(Json(LoginResponse {
|
||||||
|
jwt: Some(
|
||||||
|
Claims::jwt(
|
||||||
|
updated_local_user.id.0,
|
||||||
|
&context.secret().jwt_secret,
|
||||||
|
&context.settings().hostname,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
verify_email_sent: false,
|
||||||
|
registration_created: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{LoginResponse, PasswordChangeAfterReset},
|
person::{LoginResponse, PasswordChangeAfterReset},
|
||||||
|
@ -11,37 +10,33 @@ use lemmy_db_schema::source::{
|
||||||
};
|
};
|
||||||
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 PasswordChangeAfterReset {
|
pub async fn change_password_after_reset(
|
||||||
type Response = LoginResponse;
|
data: Json<PasswordChangeAfterReset>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<LoginResponse>, LemmyError> {
|
||||||
|
// Fetch the user_id from the token
|
||||||
|
let token = data.token.clone();
|
||||||
|
let local_user_id = PasswordResetRequest::read_from_token(&mut context.pool(), &token)
|
||||||
|
.await
|
||||||
|
.map(|p| p.local_user_id)?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, context))]
|
password_length_check(&data.password)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<LoginResponse, LemmyError> {
|
|
||||||
let data: &PasswordChangeAfterReset = self;
|
|
||||||
|
|
||||||
// Fetch the user_id from the token
|
// Make sure passwords match
|
||||||
let token = data.token.clone();
|
if data.password != data.password_verify {
|
||||||
let local_user_id = PasswordResetRequest::read_from_token(&mut context.pool(), &token)
|
Err(LemmyErrorType::PasswordsDoNotMatch)?
|
||||||
.await
|
|
||||||
.map(|p| p.local_user_id)?;
|
|
||||||
|
|
||||||
password_length_check(&data.password)?;
|
|
||||||
|
|
||||||
// Make sure passwords match
|
|
||||||
if data.password != data.password_verify {
|
|
||||||
Err(LemmyErrorType::PasswordsDoNotMatch)?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the user with the new password
|
|
||||||
let password = data.password.clone();
|
|
||||||
LocalUser::update_password(&mut context.pool(), local_user_id, &password)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateUser)?;
|
|
||||||
|
|
||||||
Ok(LoginResponse {
|
|
||||||
jwt: None,
|
|
||||||
verify_email_sent: false,
|
|
||||||
registration_created: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the user with the new password
|
||||||
|
let password = data.password.clone();
|
||||||
|
LocalUser::update_password(&mut context.pool(), local_user_id, &password)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateUser)?;
|
||||||
|
|
||||||
|
Ok(Json(LoginResponse {
|
||||||
|
jwt: None,
|
||||||
|
verify_email_sent: false,
|
||||||
|
registration_created: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::{captcha_as_wav_base64, Perform};
|
use crate::captcha_as_wav_base64;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::{Data, Json};
|
||||||
use captcha::{gen, Difficulty};
|
use captcha::{gen, Difficulty};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse},
|
person::{CaptchaResponse, GetCaptchaResponse},
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::source::{
|
use lemmy_db_schema::source::{
|
||||||
captcha_answer::{CaptchaAnswer, CaptchaAnswerForm},
|
captcha_answer::{CaptchaAnswer, CaptchaAnswerForm},
|
||||||
|
@ -11,40 +11,37 @@ use lemmy_db_schema::source::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetCaptcha {
|
pub async fn get_captcha(
|
||||||
type Response = GetCaptchaResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetCaptchaResponse>, LemmyError> {
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
if !local_site.captcha_enabled {
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
return Ok(Json(GetCaptchaResponse { ok: None }));
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
if !local_site.captcha_enabled {
|
|
||||||
return Ok(GetCaptchaResponse { ok: None });
|
|
||||||
}
|
|
||||||
|
|
||||||
let captcha = gen(match local_site.captcha_difficulty.as_str() {
|
|
||||||
"easy" => Difficulty::Easy,
|
|
||||||
"hard" => Difficulty::Hard,
|
|
||||||
_ => Difficulty::Medium,
|
|
||||||
});
|
|
||||||
|
|
||||||
let answer = captcha.chars_as_string();
|
|
||||||
|
|
||||||
let png = captcha.as_base64().expect("failed to generate captcha");
|
|
||||||
|
|
||||||
let wav = captcha_as_wav_base64(&captcha)?;
|
|
||||||
|
|
||||||
let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
|
|
||||||
// Stores the captcha item in the db
|
|
||||||
let captcha = CaptchaAnswer::insert(&mut context.pool(), &captcha_form).await?;
|
|
||||||
|
|
||||||
Ok(GetCaptchaResponse {
|
|
||||||
ok: Some(CaptchaResponse {
|
|
||||||
png,
|
|
||||||
wav,
|
|
||||||
uuid: captcha.uuid.to_string(),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let captcha = gen(match local_site.captcha_difficulty.as_str() {
|
||||||
|
"easy" => Difficulty::Easy,
|
||||||
|
"hard" => Difficulty::Hard,
|
||||||
|
_ => Difficulty::Medium,
|
||||||
|
});
|
||||||
|
|
||||||
|
let answer = captcha.chars_as_string();
|
||||||
|
|
||||||
|
let png = captcha.as_base64().expect("failed to generate captcha");
|
||||||
|
|
||||||
|
let wav = captcha_as_wav_base64(&captcha)?;
|
||||||
|
|
||||||
|
let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
|
||||||
|
// Stores the captcha item in the db
|
||||||
|
let captcha = CaptchaAnswer::insert(&mut context.pool(), &captcha_form).await?;
|
||||||
|
|
||||||
|
Ok(Json(GetCaptchaResponse {
|
||||||
|
ok: Some(CaptchaResponse {
|
||||||
|
png,
|
||||||
|
wav,
|
||||||
|
uuid: captcha.uuid.to_string(),
|
||||||
|
}),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{BannedPersonsResponse, GetBannedPersons},
|
person::{BannedPersonsResponse, GetBannedPersons},
|
||||||
|
@ -8,19 +7,16 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views_actor::structs::PersonView;
|
use lemmy_db_views_actor::structs::PersonView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
pub async fn list_banned_users(
|
||||||
impl Perform for GetBannedPersons {
|
data: Query<GetBannedPersons>,
|
||||||
type Response = BannedPersonsResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<BannedPersonsResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
// Make sure user is an admin
|
||||||
let data: &GetBannedPersons = self;
|
is_admin(&local_user_view)?;
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Make sure user is an admin
|
let banned = PersonView::banned(&mut context.pool()).await?;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
let banned = PersonView::banned(&mut context.pool()).await?;
|
Ok(Json(BannedPersonsResponse { banned }))
|
||||||
|
|
||||||
Ok(Self::Response { banned })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::Perform;
|
use actix_web::web::{Data, Json};
|
||||||
use actix_web::web::Data;
|
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
|
@ -13,70 +12,66 @@ use lemmy_utils::{
|
||||||
utils::validation::check_totp_2fa_valid,
|
utils::validation::check_totp_2fa_valid,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for Login {
|
pub async fn login(
|
||||||
type Response = LoginResponse;
|
data: Json<Login>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<LoginResponse>, LemmyError> {
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Fetch that username / email
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<LoginResponse, LemmyError> {
|
let username_or_email = data.username_or_email.clone();
|
||||||
let data: &Login = self;
|
let local_user_view =
|
||||||
|
LocalUserView::find_by_email_or_name(&mut context.pool(), &username_or_email)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
||||||
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
// Verify the password
|
||||||
|
let valid: bool = verify(
|
||||||
// Fetch that username / email
|
&data.password,
|
||||||
let username_or_email = data.username_or_email.clone();
|
&local_user_view.local_user.password_encrypted,
|
||||||
let local_user_view =
|
)
|
||||||
LocalUserView::find_by_email_or_name(&mut context.pool(), &username_or_email)
|
.unwrap_or(false);
|
||||||
.await
|
if !valid {
|
||||||
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
Err(LemmyErrorType::IncorrectLogin)?
|
||||||
|
|
||||||
// Verify the password
|
|
||||||
let valid: bool = verify(
|
|
||||||
&data.password,
|
|
||||||
&local_user_view.local_user.password_encrypted,
|
|
||||||
)
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !valid {
|
|
||||||
Err(LemmyErrorType::IncorrectLogin)?
|
|
||||||
}
|
|
||||||
check_user_valid(
|
|
||||||
local_user_view.person.banned,
|
|
||||||
local_user_view.person.ban_expires,
|
|
||||||
local_user_view.person.deleted,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Check if the user's email is verified if email verification is turned on
|
|
||||||
// However, skip checking verification if the user is an admin
|
|
||||||
if !local_user_view.local_user.admin
|
|
||||||
&& site_view.local_site.require_email_verification
|
|
||||||
&& !local_user_view.local_user.email_verified
|
|
||||||
{
|
|
||||||
Err(LemmyErrorType::EmailNotVerified)?
|
|
||||||
}
|
|
||||||
|
|
||||||
check_registration_application(&local_user_view, &site_view.local_site, &mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Check the totp
|
|
||||||
check_totp_2fa_valid(
|
|
||||||
&local_user_view.local_user.totp_2fa_secret,
|
|
||||||
&data.totp_2fa_token,
|
|
||||||
&site_view.site.name,
|
|
||||||
&local_user_view.person.name,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(LoginResponse {
|
|
||||||
jwt: Some(
|
|
||||||
Claims::jwt(
|
|
||||||
local_user_view.local_user.id.0,
|
|
||||||
&context.secret().jwt_secret,
|
|
||||||
&context.settings().hostname,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
verify_email_sent: false,
|
|
||||||
registration_created: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
check_user_valid(
|
||||||
|
local_user_view.person.banned,
|
||||||
|
local_user_view.person.ban_expires,
|
||||||
|
local_user_view.person.deleted,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Check if the user's email is verified if email verification is turned on
|
||||||
|
// However, skip checking verification if the user is an admin
|
||||||
|
if !local_user_view.local_user.admin
|
||||||
|
&& site_view.local_site.require_email_verification
|
||||||
|
&& !local_user_view.local_user.email_verified
|
||||||
|
{
|
||||||
|
Err(LemmyErrorType::EmailNotVerified)?
|
||||||
|
}
|
||||||
|
|
||||||
|
check_registration_application(&local_user_view, &site_view.local_site, &mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Check the totp
|
||||||
|
check_totp_2fa_valid(
|
||||||
|
&local_user_view.local_user.totp_2fa_secret,
|
||||||
|
&data.totp_2fa_token,
|
||||||
|
&site_view.site.name,
|
||||||
|
&local_user_view.person.name,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Return the jwt
|
||||||
|
Ok(Json(LoginResponse {
|
||||||
|
jwt: Some(
|
||||||
|
Claims::jwt(
|
||||||
|
local_user_view.local_user.id.0,
|
||||||
|
&context.secret().jwt_secret,
|
||||||
|
&context.settings().hostname,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
verify_email_sent: false,
|
||||||
|
registration_created: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{GetPersonMentions, GetPersonMentionsResponse},
|
person::{GetPersonMentions, GetPersonMentionsResponse},
|
||||||
|
@ -8,37 +7,31 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views_actor::person_mention_view::PersonMentionQuery;
|
use lemmy_db_views_actor::person_mention_view::PersonMentionQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetPersonMentions {
|
pub async fn list_mentions(
|
||||||
type Response = GetPersonMentionsResponse;
|
data: Query<GetPersonMentions>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetPersonMentionsResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let sort = data.sort;
|
||||||
async fn perform(
|
let page = data.page;
|
||||||
&self,
|
let limit = data.limit;
|
||||||
context: &Data<LemmyContext>,
|
let unread_only = data.unread_only.unwrap_or_default();
|
||||||
) -> Result<GetPersonMentionsResponse, LemmyError> {
|
let person_id = Some(local_user_view.person.id);
|
||||||
let data: &GetPersonMentions = self;
|
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let sort = data.sort;
|
let mentions = PersonMentionQuery {
|
||||||
let page = data.page;
|
recipient_id: person_id,
|
||||||
let limit = data.limit;
|
my_person_id: person_id,
|
||||||
let unread_only = data.unread_only.unwrap_or_default();
|
sort,
|
||||||
let person_id = Some(local_user_view.person.id);
|
unread_only,
|
||||||
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
show_bot_accounts,
|
||||||
|
page,
|
||||||
let mentions = PersonMentionQuery {
|
limit,
|
||||||
recipient_id: person_id,
|
|
||||||
my_person_id: person_id,
|
|
||||||
sort,
|
|
||||||
unread_only,
|
|
||||||
show_bot_accounts,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(GetPersonMentionsResponse { mentions })
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(GetPersonMentionsResponse { mentions }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{GetReplies, GetRepliesResponse},
|
person::{GetReplies, GetRepliesResponse},
|
||||||
|
@ -8,34 +7,31 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery;
|
use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetReplies {
|
pub async fn list_replies(
|
||||||
type Response = GetRepliesResponse;
|
data: Query<GetReplies>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetRepliesResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let sort = data.sort;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<GetRepliesResponse, LemmyError> {
|
let page = data.page;
|
||||||
let data: &GetReplies = self;
|
let limit = data.limit;
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
let unread_only = data.unread_only.unwrap_or_default();
|
||||||
|
let person_id = Some(local_user_view.person.id);
|
||||||
|
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
||||||
|
|
||||||
let sort = data.sort;
|
let replies = CommentReplyQuery {
|
||||||
let page = data.page;
|
recipient_id: person_id,
|
||||||
let limit = data.limit;
|
my_person_id: person_id,
|
||||||
let unread_only = data.unread_only.unwrap_or_default();
|
sort,
|
||||||
let person_id = Some(local_user_view.person.id);
|
unread_only,
|
||||||
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
|
show_bot_accounts,
|
||||||
|
page,
|
||||||
let replies = CommentReplyQuery {
|
limit,
|
||||||
recipient_id: person_id,
|
|
||||||
my_person_id: person_id,
|
|
||||||
sort,
|
|
||||||
unread_only,
|
|
||||||
show_bot_accounts,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(GetRepliesResponse { replies })
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(GetRepliesResponse { replies }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{GetRepliesResponse, MarkAllAsRead},
|
person::{GetRepliesResponse, MarkAllAsRead},
|
||||||
|
@ -12,31 +11,28 @@ use lemmy_db_schema::source::{
|
||||||
};
|
};
|
||||||
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 MarkAllAsRead {
|
pub async fn mark_all_notifications_read(
|
||||||
type Response = GetRepliesResponse;
|
data: Json<MarkAllAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetRepliesResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Mark all comment_replies as read
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<GetRepliesResponse, LemmyError> {
|
CommentReply::mark_all_as_read(&mut context.pool(), person_id)
|
||||||
let data: &MarkAllAsRead = self;
|
.await
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
|
|
||||||
// Mark all comment_replies as read
|
// Mark all user mentions as read
|
||||||
CommentReply::mark_all_as_read(&mut context.pool(), person_id)
|
PersonMention::mark_all_as_read(&mut context.pool(), person_id)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
// Mark all user mentions as read
|
// Mark all private_messages as read
|
||||||
PersonMention::mark_all_as_read(&mut context.pool(), person_id)
|
PrivateMessage::mark_all_as_read(&mut context.pool(), person_id)
|
||||||
.await
|
.await
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
||||||
|
|
||||||
// Mark all private_messages as read
|
Ok(Json(GetRepliesResponse { replies: vec![] }))
|
||||||
PrivateMessage::mark_all_as_read(&mut context.pool(), person_id)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
|
||||||
|
|
||||||
Ok(GetRepliesResponse { replies: vec![] })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{MarkPersonMentionAsRead, PersonMentionResponse},
|
person::{MarkPersonMentionAsRead, PersonMentionResponse},
|
||||||
|
@ -12,42 +11,36 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views_actor::structs::PersonMentionView;
|
use lemmy_db_views_actor::structs::PersonMentionView;
|
||||||
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 MarkPersonMentionAsRead {
|
pub async fn mark_person_mention_as_read(
|
||||||
type Response = PersonMentionResponse;
|
data: Json<MarkPersonMentionAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PersonMentionResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let person_mention_id = data.person_mention_id;
|
||||||
async fn perform(
|
let read_person_mention = PersonMention::read(&mut context.pool(), person_mention_id).await?;
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<PersonMentionResponse, LemmyError> {
|
|
||||||
let data: &MarkPersonMentionAsRead = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let person_mention_id = data.person_mention_id;
|
if local_user_view.person.id != read_person_mention.recipient_id {
|
||||||
let read_person_mention = PersonMention::read(&mut context.pool(), person_mention_id).await?;
|
Err(LemmyErrorType::CouldntUpdateComment)?
|
||||||
|
|
||||||
if local_user_view.person.id != read_person_mention.recipient_id {
|
|
||||||
Err(LemmyErrorType::CouldntUpdateComment)?
|
|
||||||
}
|
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
|
||||||
let read = Some(data.read);
|
|
||||||
PersonMention::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
person_mention_id,
|
|
||||||
&PersonMentionUpdateForm { read },
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
|
||||||
|
|
||||||
let person_mention_id = read_person_mention.id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let person_mention_view =
|
|
||||||
PersonMentionView::read(&mut context.pool(), person_mention_id, Some(person_id)).await?;
|
|
||||||
|
|
||||||
Ok(PersonMentionResponse {
|
|
||||||
person_mention_view,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let person_mention_id = read_person_mention.id;
|
||||||
|
let read = Some(data.read);
|
||||||
|
PersonMention::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
person_mention_id,
|
||||||
|
&PersonMentionUpdateForm { read },
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
|
||||||
|
|
||||||
|
let person_mention_id = read_person_mention.id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let person_mention_view =
|
||||||
|
PersonMentionView::read(&mut context.pool(), person_mention_id, Some(person_id)).await?;
|
||||||
|
|
||||||
|
Ok(Json(PersonMentionResponse {
|
||||||
|
person_mention_view,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
person::{GetUnreadCount, GetUnreadCountResponse},
|
person::{GetUnreadCount, GetUnreadCountResponse},
|
||||||
|
@ -9,28 +8,25 @@ use lemmy_db_views::structs::PrivateMessageView;
|
||||||
use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView};
|
use lemmy_db_views_actor::structs::{CommentReplyView, PersonMentionView};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetUnreadCount {
|
pub async fn unread_count(
|
||||||
type Response = GetUnreadCountResponse;
|
data: Query<GetUnreadCount>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetUnreadCountResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let person_id = local_user_view.person.id;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
|
||||||
let data = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let replies = CommentReplyView::get_unread_replies(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
let replies = CommentReplyView::get_unread_replies(&mut context.pool(), person_id).await?;
|
let mentions = PersonMentionView::get_unread_mentions(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
let mentions = PersonMentionView::get_unread_mentions(&mut context.pool(), person_id).await?;
|
let private_messages =
|
||||||
|
PrivateMessageView::get_unread_messages(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
let private_messages =
|
Ok(Json(GetUnreadCountResponse {
|
||||||
PrivateMessageView::get_unread_messages(&mut context.pool(), person_id).await?;
|
replies,
|
||||||
|
mentions,
|
||||||
Ok(Self::Response {
|
private_messages,
|
||||||
replies,
|
}))
|
||||||
mentions,
|
|
||||||
private_messages,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{GetReportCount, GetReportCountResponse},
|
person::{GetReportCount, GetReportCountResponse},
|
||||||
|
@ -8,40 +7,34 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views::structs::{CommentReportView, PostReportView, PrivateMessageReportView};
|
use lemmy_db_views::structs::{CommentReportView, PostReportView, PrivateMessageReportView};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetReportCount {
|
pub async fn report_count(
|
||||||
type Response = GetReportCountResponse;
|
data: Json<GetReportCount>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetReportCountResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let person_id = local_user_view.person.id;
|
||||||
async fn perform(
|
let admin = local_user_view.local_user.admin;
|
||||||
&self,
|
let community_id = data.community_id;
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<GetReportCountResponse, LemmyError> {
|
|
||||||
let data: &GetReportCount = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let comment_reports =
|
||||||
let admin = local_user_view.local_user.admin;
|
CommentReportView::get_report_count(&mut context.pool(), person_id, admin, community_id)
|
||||||
let community_id = data.community_id;
|
.await?;
|
||||||
|
|
||||||
let comment_reports =
|
let post_reports =
|
||||||
CommentReportView::get_report_count(&mut context.pool(), person_id, admin, community_id)
|
PostReportView::get_report_count(&mut context.pool(), person_id, admin, community_id).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
let post_reports =
|
let private_message_reports = if admin && community_id.is_none() {
|
||||||
PostReportView::get_report_count(&mut context.pool(), person_id, admin, community_id).await?;
|
Some(PrivateMessageReportView::get_report_count(&mut context.pool()).await?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let private_message_reports = if admin && community_id.is_none() {
|
Ok(Json(GetReportCountResponse {
|
||||||
Some(PrivateMessageReportView::get_report_count(&mut context.pool()).await?)
|
community_id,
|
||||||
} else {
|
comment_reports,
|
||||||
None
|
post_reports,
|
||||||
};
|
private_message_reports,
|
||||||
|
}))
|
||||||
Ok(GetReportCountResponse {
|
|
||||||
community_id,
|
|
||||||
comment_reports,
|
|
||||||
post_reports,
|
|
||||||
private_message_reports,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{PasswordReset, PasswordResetResponse},
|
person::{PasswordReset, PasswordResetResponse},
|
||||||
|
@ -9,35 +8,28 @@ use lemmy_db_schema::source::password_reset_request::PasswordResetRequest;
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
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 PasswordReset {
|
pub async fn reset_password(
|
||||||
type Response = PasswordResetResponse;
|
data: Json<PasswordReset>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PasswordResetResponse>, LemmyError> {
|
||||||
|
// Fetch that email
|
||||||
|
let email = data.email.to_lowercase();
|
||||||
|
let local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(self, context))]
|
// Check for too many attempts (to limit potential abuse)
|
||||||
async fn perform(
|
let recent_resets_count = PasswordResetRequest::get_recent_password_resets_count(
|
||||||
&self,
|
&mut context.pool(),
|
||||||
context: &Data<LemmyContext>,
|
local_user_view.local_user.id,
|
||||||
) -> Result<PasswordResetResponse, LemmyError> {
|
)
|
||||||
let data: &PasswordReset = self;
|
.await?;
|
||||||
|
if recent_resets_count >= 3 {
|
||||||
// Fetch that email
|
Err(LemmyErrorType::PasswordResetLimitReached)?
|
||||||
let email = data.email.to_lowercase();
|
|
||||||
let local_user_view = LocalUserView::find_by_email(&mut context.pool(), &email)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
|
||||||
|
|
||||||
// Check for too many attempts (to limit potential abuse)
|
|
||||||
let recent_resets_count = PasswordResetRequest::get_recent_password_resets_count(
|
|
||||||
&mut context.pool(),
|
|
||||||
local_user_view.local_user.id,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
if recent_resets_count >= 3 {
|
|
||||||
Err(LemmyErrorType::PasswordResetLimitReached)?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email the pure token to the user.
|
|
||||||
send_password_reset_email(&local_user_view, &mut context.pool(), context.settings()).await?;
|
|
||||||
Ok(PasswordResetResponse {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Email the pure token to the user.
|
||||||
|
send_password_reset_email(&local_user_view, &mut context.pool(), context.settings()).await?;
|
||||||
|
Ok(Json(PasswordResetResponse {}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{LoginResponse, SaveUserSettings},
|
person::{LoginResponse, SaveUserSettings},
|
||||||
|
@ -27,152 +26,149 @@ use lemmy_utils::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for SaveUserSettings {
|
pub async fn save_user_settings(
|
||||||
type Response = LoginResponse;
|
data: Json<SaveUserSettings>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<LoginResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let bio = sanitize_html_opt(&data.bio);
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<LoginResponse, LemmyError> {
|
let display_name = sanitize_html_opt(&data.display_name);
|
||||||
let data: &SaveUserSettings = 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 bio = sanitize_html_opt(&data.bio);
|
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
||||||
let display_name = sanitize_html_opt(&data.display_name);
|
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||||
|
let bio = diesel_option_overwrite(bio);
|
||||||
|
let display_name = diesel_option_overwrite(display_name);
|
||||||
|
let matrix_user_id = diesel_option_overwrite(data.matrix_user_id.clone());
|
||||||
|
let email_deref = data.email.as_deref().map(str::to_lowercase);
|
||||||
|
let email = diesel_option_overwrite(email_deref.clone());
|
||||||
|
|
||||||
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
if let Some(Some(email)) = &email {
|
||||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
||||||
let bio = diesel_option_overwrite(bio);
|
// Only send the verification email if there was an email change
|
||||||
let display_name = diesel_option_overwrite(display_name);
|
if previous_email.ne(email) {
|
||||||
let matrix_user_id = diesel_option_overwrite(data.matrix_user_id.clone());
|
send_verification_email(
|
||||||
let email_deref = data.email.as_deref().map(str::to_lowercase);
|
&local_user_view,
|
||||||
let email = diesel_option_overwrite(email_deref.clone());
|
email,
|
||||||
|
&mut context.pool(),
|
||||||
if let Some(Some(email)) = &email {
|
context.settings(),
|
||||||
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
)
|
||||||
// Only send the verification email if there was an email change
|
.await?;
|
||||||
if previous_email.ne(email) {
|
|
||||||
send_verification_email(
|
|
||||||
&local_user_view,
|
|
||||||
email,
|
|
||||||
&mut context.pool(),
|
|
||||||
context.settings(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the site requires email, make sure email is not Some(None). IE, an overwrite to a None value
|
|
||||||
if let Some(email) = &email {
|
|
||||||
if email.is_none() && site_view.local_site.require_email_verification {
|
|
||||||
Err(LemmyErrorType::EmailRequired)?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Some(bio)) = &bio {
|
|
||||||
is_valid_bio_field(bio)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Some(display_name)) = &display_name {
|
|
||||||
is_valid_display_name(
|
|
||||||
display_name.trim(),
|
|
||||||
site_view.local_site.actor_name_max_length as usize,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Some(matrix_user_id)) = &matrix_user_id {
|
|
||||||
is_valid_matrix_id(matrix_user_id)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let local_user_id = local_user_view.local_user.id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let default_listing_type = data.default_listing_type;
|
|
||||||
let default_sort_type = data.default_sort_type;
|
|
||||||
let theme = sanitize_html_opt(&data.theme);
|
|
||||||
|
|
||||||
let person_form = PersonUpdateForm {
|
|
||||||
display_name,
|
|
||||||
bio,
|
|
||||||
matrix_user_id,
|
|
||||||
bot_account: data.bot_account,
|
|
||||||
avatar,
|
|
||||||
banner,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
Person::update(&mut context.pool(), person_id, &person_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::UserAlreadyExists)?;
|
|
||||||
|
|
||||||
if let Some(discussion_languages) = data.discussion_languages.clone() {
|
|
||||||
LocalUserLanguage::update(&mut context.pool(), discussion_languages, local_user_id).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If generate_totp is Some(false), this will clear it out from the database.
|
|
||||||
let (totp_2fa_secret, totp_2fa_url) = if let Some(generate) = data.generate_totp_2fa {
|
|
||||||
if generate {
|
|
||||||
let secret = generate_totp_2fa_secret();
|
|
||||||
let url =
|
|
||||||
build_totp_2fa(&site_view.site.name, &local_user_view.person.name, &secret)?.get_url();
|
|
||||||
(Some(Some(secret)), Some(Some(url)))
|
|
||||||
} else {
|
|
||||||
(Some(None), Some(None))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(None, None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let local_user_form = LocalUserUpdateForm {
|
|
||||||
email,
|
|
||||||
show_avatars: data.show_avatars,
|
|
||||||
show_read_posts: data.show_read_posts,
|
|
||||||
show_new_post_notifs: data.show_new_post_notifs,
|
|
||||||
send_notifications_to_email: data.send_notifications_to_email,
|
|
||||||
show_nsfw: data.show_nsfw,
|
|
||||||
blur_nsfw: data.blur_nsfw,
|
|
||||||
auto_expand: data.auto_expand,
|
|
||||||
show_bot_accounts: data.show_bot_accounts,
|
|
||||||
show_scores: data.show_scores,
|
|
||||||
default_sort_type,
|
|
||||||
default_listing_type,
|
|
||||||
theme,
|
|
||||||
interface_language: data.interface_language.clone(),
|
|
||||||
totp_2fa_secret,
|
|
||||||
totp_2fa_url,
|
|
||||||
open_links_in_new_tab: data.open_links_in_new_tab,
|
|
||||||
infinite_scroll_enabled: data.infinite_scroll_enabled,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let local_user_res =
|
|
||||||
LocalUser::update(&mut context.pool(), local_user_id, &local_user_form).await;
|
|
||||||
let updated_local_user = match local_user_res {
|
|
||||||
Ok(u) => u,
|
|
||||||
Err(e) => {
|
|
||||||
let err_type = if e.to_string()
|
|
||||||
== "duplicate key value violates unique constraint \"local_user_email_key\""
|
|
||||||
{
|
|
||||||
LemmyErrorType::EmailAlreadyExists
|
|
||||||
} else {
|
|
||||||
LemmyErrorType::UserAlreadyExists
|
|
||||||
};
|
|
||||||
|
|
||||||
return Err(e).with_lemmy_type(err_type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(LoginResponse {
|
|
||||||
jwt: Some(
|
|
||||||
Claims::jwt(
|
|
||||||
updated_local_user.id.0,
|
|
||||||
&context.secret().jwt_secret,
|
|
||||||
&context.settings().hostname,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
verify_email_sent: false,
|
|
||||||
registration_created: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When the site requires email, make sure email is not Some(None). IE, an overwrite to a None value
|
||||||
|
if let Some(email) = &email {
|
||||||
|
if email.is_none() && site_view.local_site.require_email_verification {
|
||||||
|
Err(LemmyErrorType::EmailRequired)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Some(bio)) = &bio {
|
||||||
|
is_valid_bio_field(bio)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Some(display_name)) = &display_name {
|
||||||
|
is_valid_display_name(
|
||||||
|
display_name.trim(),
|
||||||
|
site_view.local_site.actor_name_max_length as usize,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Some(matrix_user_id)) = &matrix_user_id {
|
||||||
|
is_valid_matrix_id(matrix_user_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let local_user_id = local_user_view.local_user.id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let default_listing_type = data.default_listing_type;
|
||||||
|
let default_sort_type = data.default_sort_type;
|
||||||
|
let theme = sanitize_html_opt(&data.theme);
|
||||||
|
|
||||||
|
let person_form = PersonUpdateForm {
|
||||||
|
display_name,
|
||||||
|
bio,
|
||||||
|
matrix_user_id,
|
||||||
|
bot_account: data.bot_account,
|
||||||
|
avatar,
|
||||||
|
banner,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
Person::update(&mut context.pool(), person_id, &person_form)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::UserAlreadyExists)?;
|
||||||
|
|
||||||
|
if let Some(discussion_languages) = data.discussion_languages.clone() {
|
||||||
|
LocalUserLanguage::update(&mut context.pool(), discussion_languages, local_user_id).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If generate_totp is Some(false), this will clear it out from the database.
|
||||||
|
let (totp_2fa_secret, totp_2fa_url) = if let Some(generate) = data.generate_totp_2fa {
|
||||||
|
if generate {
|
||||||
|
let secret = generate_totp_2fa_secret();
|
||||||
|
let url =
|
||||||
|
build_totp_2fa(&site_view.site.name, &local_user_view.person.name, &secret)?.get_url();
|
||||||
|
(Some(Some(secret)), Some(Some(url)))
|
||||||
|
} else {
|
||||||
|
(Some(None), Some(None))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(None, None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let local_user_form = LocalUserUpdateForm {
|
||||||
|
email,
|
||||||
|
show_avatars: data.show_avatars,
|
||||||
|
show_read_posts: data.show_read_posts,
|
||||||
|
show_new_post_notifs: data.show_new_post_notifs,
|
||||||
|
send_notifications_to_email: data.send_notifications_to_email,
|
||||||
|
show_nsfw: data.show_nsfw,
|
||||||
|
blur_nsfw: data.blur_nsfw,
|
||||||
|
auto_expand: data.auto_expand,
|
||||||
|
show_bot_accounts: data.show_bot_accounts,
|
||||||
|
show_scores: data.show_scores,
|
||||||
|
default_sort_type,
|
||||||
|
default_listing_type,
|
||||||
|
theme,
|
||||||
|
interface_language: data.interface_language.clone(),
|
||||||
|
totp_2fa_secret,
|
||||||
|
totp_2fa_url,
|
||||||
|
open_links_in_new_tab: data.open_links_in_new_tab,
|
||||||
|
infinite_scroll_enabled: data.infinite_scroll_enabled,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let local_user_res =
|
||||||
|
LocalUser::update(&mut context.pool(), local_user_id, &local_user_form).await;
|
||||||
|
let updated_local_user = match local_user_res {
|
||||||
|
Ok(u) => u,
|
||||||
|
Err(e) => {
|
||||||
|
let err_type = if e.to_string()
|
||||||
|
== "duplicate key value violates unique constraint \"local_user_email_key\""
|
||||||
|
{
|
||||||
|
LemmyErrorType::EmailAlreadyExists
|
||||||
|
} else {
|
||||||
|
LemmyErrorType::UserAlreadyExists
|
||||||
|
};
|
||||||
|
|
||||||
|
return Err(e).with_lemmy_type(err_type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the jwt
|
||||||
|
Ok(Json(LoginResponse {
|
||||||
|
jwt: Some(
|
||||||
|
Claims::jwt(
|
||||||
|
updated_local_user.id.0,
|
||||||
|
&context.secret().jwt_secret,
|
||||||
|
&context.settings().hostname,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
verify_email_sent: false,
|
||||||
|
registration_created: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{VerifyEmail, VerifyEmailResponse},
|
person::{VerifyEmail, VerifyEmailResponse},
|
||||||
|
@ -13,29 +12,27 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
pub async fn verify_email(
|
||||||
impl Perform for VerifyEmail {
|
data: Json<VerifyEmail>,
|
||||||
type Response = VerifyEmailResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<VerifyEmailResponse>, LemmyError> {
|
||||||
|
let token = data.token.clone();
|
||||||
|
let verification = EmailVerification::read_for_token(&mut context.pool(), &token)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::TokenNotFound)?;
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
let form = LocalUserUpdateForm {
|
||||||
let token = self.token.clone();
|
// necessary in case this is a new signup
|
||||||
let verification = EmailVerification::read_for_token(&mut context.pool(), &token)
|
email_verified: Some(true),
|
||||||
.await
|
// necessary in case email of an existing user was changed
|
||||||
.with_lemmy_type(LemmyErrorType::TokenNotFound)?;
|
email: Some(Some(verification.email)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let local_user_id = verification.local_user_id;
|
||||||
|
|
||||||
let form = LocalUserUpdateForm {
|
LocalUser::update(&mut context.pool(), local_user_id, &form).await?;
|
||||||
// necessary in case this is a new signup
|
|
||||||
email_verified: Some(true),
|
|
||||||
// necessary in case email of an existing user was changed
|
|
||||||
email: Some(Some(verification.email)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let local_user_id = verification.local_user_id;
|
|
||||||
|
|
||||||
LocalUser::update(&mut context.pool(), local_user_id, &form).await?;
|
EmailVerification::delete_old_tokens_for_local_user(&mut context.pool(), local_user_id).await?;
|
||||||
|
|
||||||
EmailVerification::delete_old_tokens_for_local_user(&mut context.pool(), local_user_id).await?;
|
Ok(Json(VerifyEmailResponse {}))
|
||||||
|
|
||||||
Ok(VerifyEmailResponse {})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
post::{GetSiteMetadata, GetSiteMetadataResponse},
|
post::{GetSiteMetadata, GetSiteMetadataResponse},
|
||||||
|
@ -7,19 +6,12 @@ use lemmy_api_common::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetSiteMetadata {
|
pub async fn get_link_metadata(
|
||||||
type Response = GetSiteMetadataResponse;
|
data: Json<GetSiteMetadata>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetSiteMetadataResponse>, LemmyError> {
|
||||||
|
let metadata = fetch_site_metadata(context.client(), &data.url).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
Ok(Json(GetSiteMetadataResponse { metadata }))
|
||||||
async fn perform(
|
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<GetSiteMetadataResponse, LemmyError> {
|
|
||||||
let data: &Self = self;
|
|
||||||
|
|
||||||
let metadata = fetch_site_metadata(context.client(), &data.url).await?;
|
|
||||||
|
|
||||||
Ok(GetSiteMetadataResponse { metadata })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,32 @@
|
||||||
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,
|
||||||
post::{MarkPostAsRead, PostResponse},
|
post::{MarkPostAsRead, PostResponse},
|
||||||
utils::{local_user_view_from_jwt, mark_post_as_read, mark_post_as_unread},
|
utils,
|
||||||
|
utils::local_user_view_from_jwt,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::PostView;
|
use lemmy_db_views::structs::PostView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for MarkPostAsRead {
|
pub async fn mark_post_as_read(
|
||||||
type Response = PostResponse;
|
data: Json<MarkPostAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PostResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let post_id = data.post_id;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
let person_id = local_user_view.person.id;
|
||||||
let data = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let post_id = data.post_id;
|
// Mark the post as read / unread
|
||||||
let person_id = local_user_view.person.id;
|
if data.read {
|
||||||
|
utils::mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
// Mark the post as read / unread
|
} else {
|
||||||
if data.read {
|
utils::mark_post_as_unread(person_id, post_id, &mut context.pool()).await?;
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
|
||||||
} else {
|
|
||||||
mark_post_as_unread(person_id, post_id, &mut context.pool()).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch it
|
|
||||||
let post_view = PostView::read(&mut context.pool(), post_id, Some(person_id), false).await?;
|
|
||||||
|
|
||||||
Ok(Self::Response { post_view })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch it
|
||||||
|
let post_view = PostView::read(&mut context.pool(), post_id, Some(person_id), false).await?;
|
||||||
|
|
||||||
|
Ok(Json(PostResponse { post_view }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
post::{PostResponse, SavePost},
|
post::{PostResponse, SavePost},
|
||||||
|
@ -12,37 +11,34 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::PostView;
|
use lemmy_db_views::structs::PostView;
|
||||||
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 SavePost {
|
pub async fn save_post(
|
||||||
type Response = PostResponse;
|
data: Json<SavePost>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PostResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
let post_saved_form = PostSavedForm {
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<PostResponse, LemmyError> {
|
post_id: data.post_id,
|
||||||
let data: &SavePost = self;
|
person_id: local_user_view.person.id,
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
};
|
||||||
|
|
||||||
let post_saved_form = PostSavedForm {
|
if data.save {
|
||||||
post_id: data.post_id,
|
PostSaved::save(&mut context.pool(), &post_saved_form)
|
||||||
person_id: local_user_view.person.id,
|
.await
|
||||||
};
|
.with_lemmy_type(LemmyErrorType::CouldntSavePost)?;
|
||||||
|
} else {
|
||||||
if data.save {
|
PostSaved::unsave(&mut context.pool(), &post_saved_form)
|
||||||
PostSaved::save(&mut context.pool(), &post_saved_form)
|
.await
|
||||||
.await
|
.with_lemmy_type(LemmyErrorType::CouldntSavePost)?;
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSavePost)?;
|
|
||||||
} else {
|
|
||||||
PostSaved::unsave(&mut context.pool(), &post_saved_form)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntSavePost)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let post_id = data.post_id;
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let post_view = PostView::read(&mut context.pool(), post_id, Some(person_id), false).await?;
|
|
||||||
|
|
||||||
// Mark the post as read
|
|
||||||
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
|
||||||
|
|
||||||
Ok(PostResponse { post_view })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let post_id = data.post_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let post_view = PostView::read(&mut context.pool(), post_id, Some(person_id), false).await?;
|
||||||
|
|
||||||
|
// Mark the post as read
|
||||||
|
mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
|
||||||
|
|
||||||
|
Ok(Json(PostResponse { post_view }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
post::{ListPostReports, ListPostReportsResponse},
|
post::{ListPostReports, ListPostReportsResponse},
|
||||||
|
@ -10,32 +9,26 @@ use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
/// Lists post reports for a community if an id is supplied
|
/// Lists post reports for a community if an id is supplied
|
||||||
/// or returns all post reports for communities a user moderates
|
/// or returns all post reports for communities a user moderates
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ListPostReports {
|
pub async fn list_post_reports(
|
||||||
type Response = ListPostReportsResponse;
|
data: Query<ListPostReports>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<ListPostReportsResponse>, 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.unwrap_or_default();
|
||||||
&self,
|
|
||||||
context: &Data<LemmyContext>,
|
|
||||||
) -> Result<ListPostReportsResponse, LemmyError> {
|
|
||||||
let data: &ListPostReports = 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.unwrap_or_default();
|
let limit = data.limit;
|
||||||
|
let post_reports = PostReportQuery {
|
||||||
let page = data.page;
|
community_id,
|
||||||
let limit = data.limit;
|
unresolved_only,
|
||||||
let post_reports = PostReportQuery {
|
page,
|
||||||
community_id,
|
limit,
|
||||||
unresolved_only,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool(), &local_user_view)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(ListPostReportsResponse { post_reports })
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool(), &local_user_view)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(ListPostReportsResponse { post_reports }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
post::{PostReportResponse, ResolvePostReport},
|
post::{PostReportResponse, ResolvePostReport},
|
||||||
|
@ -10,34 +9,31 @@ use lemmy_db_views::structs::PostReportView;
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
||||||
|
|
||||||
/// Resolves or unresolves a post report and notifies the moderators of the community
|
/// Resolves or unresolves a post report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ResolvePostReport {
|
pub async fn resolve_post_report(
|
||||||
type Response = PostReportResponse;
|
data: Json<ResolvePostReport>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PostReportResponse>, 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(&self, context: &Data<LemmyContext>) -> Result<PostReportResponse, LemmyError> {
|
let person_id = local_user_view.person.id;
|
||||||
let data: &ResolvePostReport = self;
|
let report = PostReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
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 = PostReportView::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?;
|
PostReport::resolve(&mut context.pool(), report_id, person_id)
|
||||||
|
.await
|
||||||
if data.resolved {
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
PostReport::resolve(&mut context.pool(), report_id, person_id)
|
} else {
|
||||||
.await
|
PostReport::unresolve(&mut context.pool(), report_id, person_id)
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
.await
|
||||||
} else {
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
PostReport::unresolve(&mut context.pool(), report_id, person_id)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let post_report_view = PostReportView::read(&mut context.pool(), report_id, person_id).await?;
|
|
||||||
|
|
||||||
Ok(PostReportResponse { post_report_view })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let post_report_view = PostReportView::read(&mut context.pool(), report_id, person_id).await?;
|
||||||
|
|
||||||
|
Ok(Json(PostReportResponse { post_report_view }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
private_message::{MarkPrivateMessageAsRead, PrivateMessageResponse},
|
private_message::{MarkPrivateMessageAsRead, PrivateMessageResponse},
|
||||||
|
@ -12,43 +11,36 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::PrivateMessageView;
|
use lemmy_db_views::structs::PrivateMessageView;
|
||||||
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 MarkPrivateMessageAsRead {
|
pub async fn mark_pm_as_read(
|
||||||
type Response = PrivateMessageResponse;
|
data: Json<MarkPrivateMessageAsRead>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PrivateMessageResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Checking permissions
|
||||||
async fn perform(
|
let private_message_id = data.private_message_id;
|
||||||
&self,
|
let orig_private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
context: &Data<LemmyContext>,
|
if local_user_view.person.id != orig_private_message.recipient_id {
|
||||||
) -> Result<PrivateMessageResponse, LemmyError> {
|
Err(LemmyErrorType::CouldntUpdatePrivateMessage)?
|
||||||
let data: &MarkPrivateMessageAsRead = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Checking permissions
|
|
||||||
let private_message_id = data.private_message_id;
|
|
||||||
let orig_private_message =
|
|
||||||
PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
|
||||||
if local_user_view.person.id != orig_private_message.recipient_id {
|
|
||||||
Err(LemmyErrorType::CouldntUpdatePrivateMessage)?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Doing the update
|
|
||||||
let private_message_id = data.private_message_id;
|
|
||||||
let read = data.read;
|
|
||||||
PrivateMessage::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
private_message_id,
|
|
||||||
&PrivateMessageUpdateForm {
|
|
||||||
read: Some(read),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
|
||||||
|
|
||||||
let view = PrivateMessageView::read(&mut context.pool(), private_message_id).await?;
|
|
||||||
Ok(PrivateMessageResponse {
|
|
||||||
private_message_view: view,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Doing the update
|
||||||
|
let private_message_id = data.private_message_id;
|
||||||
|
let read = data.read;
|
||||||
|
PrivateMessage::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
private_message_id,
|
||||||
|
&PrivateMessageUpdateForm {
|
||||||
|
read: Some(read),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::CouldntUpdatePrivateMessage)?;
|
||||||
|
|
||||||
|
let view = PrivateMessageView::read(&mut context.pool(), private_message_id).await?;
|
||||||
|
Ok(Json(PrivateMessageResponse {
|
||||||
|
private_message_view: view,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mod mark_read;
|
pub mod mark_read;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{check_report_reason, Perform};
|
use crate::check_report_reason;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::{Data, Json};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
private_message::{CreatePrivateMessageReport, PrivateMessageReportResponse},
|
private_message::{CreatePrivateMessageReport, PrivateMessageReportResponse},
|
||||||
|
@ -16,51 +16,49 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::PrivateMessageReportView;
|
use lemmy_db_views::structs::PrivateMessageReportView;
|
||||||
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 CreatePrivateMessageReport {
|
pub async fn create_pm_report(
|
||||||
type Response = PrivateMessageReportResponse;
|
data: Json<CreatePrivateMessageReport>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PrivateMessageReportResponse>, 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 reason = sanitize_html(data.reason.trim());
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
check_report_reason(&reason, &local_site)?;
|
||||||
let local_user_view = local_user_view_from_jwt(&self.auth, context).await?;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
let reason = sanitize_html(self.reason.trim());
|
let person_id = local_user_view.person.id;
|
||||||
check_report_reason(&reason, &local_site)?;
|
let private_message_id = data.private_message_id;
|
||||||
|
let private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
||||||
|
|
||||||
let person_id = local_user_view.person.id;
|
let report_form = PrivateMessageReportForm {
|
||||||
let private_message_id = self.private_message_id;
|
creator_id: person_id,
|
||||||
let private_message = PrivateMessage::read(&mut context.pool(), private_message_id).await?;
|
private_message_id,
|
||||||
|
original_pm_text: private_message.content,
|
||||||
|
reason: reason.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
let report_form = PrivateMessageReportForm {
|
let report = PrivateMessageReport::report(&mut context.pool(), &report_form)
|
||||||
creator_id: person_id,
|
.await
|
||||||
private_message_id,
|
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
||||||
original_pm_text: private_message.content,
|
|
||||||
reason: reason.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let report = PrivateMessageReport::report(&mut context.pool(), &report_form)
|
let private_message_report_view =
|
||||||
.await
|
PrivateMessageReportView::read(&mut context.pool(), report.id).await?;
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntCreateReport)?;
|
|
||||||
|
|
||||||
let private_message_report_view =
|
// Email the admins
|
||||||
PrivateMessageReportView::read(&mut context.pool(), report.id).await?;
|
if local_site.reports_email_admins {
|
||||||
|
send_new_report_email_to_admins(
|
||||||
// Email the admins
|
&private_message_report_view.creator.name,
|
||||||
if local_site.reports_email_admins {
|
&private_message_report_view.private_message_creator.name,
|
||||||
send_new_report_email_to_admins(
|
&mut context.pool(),
|
||||||
&private_message_report_view.creator.name,
|
context.settings(),
|
||||||
&private_message_report_view.private_message_creator.name,
|
)
|
||||||
&mut context.pool(),
|
.await?;
|
||||||
context.settings(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: consider federating this
|
|
||||||
|
|
||||||
Ok(PrivateMessageReportResponse {
|
|
||||||
private_message_report_view,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consider federating this
|
||||||
|
|
||||||
|
Ok(Json(PrivateMessageReportResponse {
|
||||||
|
private_message_report_view,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
private_message::{ListPrivateMessageReports, ListPrivateMessageReportsResponse},
|
private_message::{ListPrivateMessageReports, ListPrivateMessageReportsResponse},
|
||||||
|
@ -8,29 +7,27 @@ use lemmy_api_common::{
|
||||||
use lemmy_db_views::private_message_report_view::PrivateMessageReportQuery;
|
use lemmy_db_views::private_message_report_view::PrivateMessageReportQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for ListPrivateMessageReports {
|
pub async fn list_pm_reports(
|
||||||
type Response = ListPrivateMessageReportsResponse;
|
data: Query<ListPrivateMessageReports>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<ListPrivateMessageReportsResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
is_admin(&local_user_view)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
|
||||||
let local_user_view = local_user_view_from_jwt(&self.auth, context).await?;
|
|
||||||
|
|
||||||
is_admin(&local_user_view)?;
|
let unresolved_only = data.unresolved_only.unwrap_or_default();
|
||||||
|
let page = data.page;
|
||||||
let unresolved_only = self.unresolved_only.unwrap_or_default();
|
let limit = data.limit;
|
||||||
let page = self.page;
|
let private_message_reports = PrivateMessageReportQuery {
|
||||||
let limit = self.limit;
|
unresolved_only,
|
||||||
let private_message_reports = PrivateMessageReportQuery {
|
page,
|
||||||
unresolved_only,
|
limit,
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(ListPrivateMessageReportsResponse {
|
|
||||||
private_message_reports,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(ListPrivateMessageReportsResponse {
|
||||||
|
private_message_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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
private_message::{PrivateMessageReportResponse, ResolvePrivateMessageReport},
|
private_message::{PrivateMessageReportResponse, ResolvePrivateMessageReport},
|
||||||
|
@ -9,33 +8,31 @@ use lemmy_db_schema::{source::private_message_report::PrivateMessageReport, trai
|
||||||
use lemmy_db_views::structs::PrivateMessageReportView;
|
use lemmy_db_views::structs::PrivateMessageReportView;
|
||||||
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 ResolvePrivateMessageReport {
|
pub async fn resolve_pm_report(
|
||||||
type Response = PrivateMessageReportResponse;
|
data: Json<ResolvePrivateMessageReport>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PrivateMessageReportResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
is_admin(&local_user_view)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
|
||||||
let local_user_view = local_user_view_from_jwt(&self.auth, context).await?;
|
|
||||||
|
|
||||||
is_admin(&local_user_view)?;
|
let report_id = data.report_id;
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
let report_id = self.report_id;
|
if data.resolved {
|
||||||
let person_id = local_user_view.person.id;
|
PrivateMessageReport::resolve(&mut context.pool(), report_id, person_id)
|
||||||
if self.resolved {
|
.await
|
||||||
PrivateMessageReport::resolve(&mut context.pool(), report_id, person_id)
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
.await
|
} else {
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
PrivateMessageReport::unresolve(&mut context.pool(), report_id, person_id)
|
||||||
} else {
|
.await
|
||||||
PrivateMessageReport::unresolve(&mut context.pool(), report_id, person_id)
|
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntResolveReport)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let private_message_report_view =
|
|
||||||
PrivateMessageReportView::read(&mut context.pool(), report_id).await?;
|
|
||||||
|
|
||||||
Ok(PrivateMessageReportResponse {
|
|
||||||
private_message_report_view,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let private_message_report_view =
|
||||||
|
PrivateMessageReportView::read(&mut context.pool(), report_id).await?;
|
||||||
|
|
||||||
|
Ok(Json(PrivateMessageReportResponse {
|
||||||
|
private_message_report_view,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,21 @@
|
||||||
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,
|
||||||
site::{GetFederatedInstances, GetFederatedInstancesResponse},
|
site::GetFederatedInstancesResponse,
|
||||||
utils::build_federated_instances,
|
utils::build_federated_instances,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::SiteView;
|
use lemmy_db_views::structs::SiteView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetFederatedInstances {
|
pub async fn get_federated_instances(
|
||||||
type Response = GetFederatedInstancesResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetFederatedInstancesResponse>, LemmyError> {
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
let federated_instances =
|
||||||
|
build_federated_instances(&site_view.local_site, &mut context.pool()).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
Ok(Json(GetFederatedInstancesResponse {
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
federated_instances,
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
}))
|
||||||
let federated_instances =
|
|
||||||
build_federated_instances(&site_view.local_site, &mut context.pool()).await?;
|
|
||||||
|
|
||||||
Ok(Self::Response {
|
|
||||||
federated_instances,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
site::{GetSiteResponse, LeaveAdmin},
|
site::{GetSiteResponse, LeaveAdmin},
|
||||||
|
@ -22,62 +21,59 @@ use lemmy_utils::{
|
||||||
version,
|
version,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for LeaveAdmin {
|
pub async fn leave_admin(
|
||||||
type Response = GetSiteResponse;
|
data: Json<LeaveAdmin>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetSiteResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
is_admin(&local_user_view)?;
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<GetSiteResponse, LemmyError> {
|
|
||||||
let data: &LeaveAdmin = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
is_admin(&local_user_view)?;
|
// Make sure there isn't just one admin (so if one leaves, there will still be one left)
|
||||||
|
let admins = PersonView::admins(&mut context.pool()).await?;
|
||||||
// Make sure there isn't just one admin (so if one leaves, there will still be one left)
|
if admins.len() == 1 {
|
||||||
let admins = PersonView::admins(&mut context.pool()).await?;
|
Err(LemmyErrorType::CannotLeaveAdmin)?
|
||||||
if admins.len() == 1 {
|
|
||||||
Err(LemmyErrorType::CannotLeaveAdmin)?
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalUser::update(
|
|
||||||
&mut context.pool(),
|
|
||||||
local_user_view.local_user.id,
|
|
||||||
&LocalUserUpdateForm {
|
|
||||||
admin: Some(false),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Mod tables
|
|
||||||
let person_id = local_user_view.person.id;
|
|
||||||
let form = ModAddForm {
|
|
||||||
mod_person_id: person_id,
|
|
||||||
other_person_id: person_id,
|
|
||||||
removed: Some(true),
|
|
||||||
};
|
|
||||||
|
|
||||||
ModAdd::create(&mut context.pool(), &form).await?;
|
|
||||||
|
|
||||||
// Reread site and admins
|
|
||||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
|
||||||
let admins = PersonView::admins(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
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: None,
|
|
||||||
all_languages,
|
|
||||||
discussion_languages,
|
|
||||||
taglines,
|
|
||||||
custom_emojis,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalUser::update(
|
||||||
|
&mut context.pool(),
|
||||||
|
local_user_view.local_user.id,
|
||||||
|
&LocalUserUpdateForm {
|
||||||
|
admin: Some(false),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Mod tables
|
||||||
|
let person_id = local_user_view.person.id;
|
||||||
|
let form = ModAddForm {
|
||||||
|
mod_person_id: person_id,
|
||||||
|
other_person_id: person_id,
|
||||||
|
removed: Some(true),
|
||||||
|
};
|
||||||
|
|
||||||
|
ModAdd::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
|
// Reread site and admins
|
||||||
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||||
|
let admins = PersonView::admins(&mut context.pool()).await?;
|
||||||
|
|
||||||
|
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: None,
|
||||||
|
all_languages,
|
||||||
|
discussion_languages,
|
||||||
|
taglines,
|
||||||
|
custom_emojis,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod federated_instances;
|
pub mod federated_instances;
|
||||||
mod leave_admin;
|
pub mod leave_admin;
|
||||||
mod mod_log;
|
pub mod mod_log;
|
||||||
mod purge;
|
pub mod purge;
|
||||||
mod registration_applications;
|
pub mod registration_applications;
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{GetModlog, GetModlogResponse},
|
site::{GetModlog, GetModlogResponse},
|
||||||
|
@ -31,167 +30,161 @@ use lemmy_db_views_moderator::structs::{
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
use ModlogActionType::*;
|
use ModlogActionType::*;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for GetModlog {
|
pub async fn get_mod_log(
|
||||||
type Response = GetModlogResponse;
|
data: Query<GetModlog>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetModlogResponse>, 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<GetModlogResponse, LemmyError> {
|
|
||||||
let data: &GetModlog = self;
|
|
||||||
|
|
||||||
let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), context).await;
|
let type_ = data.type_.unwrap_or(All);
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
let community_id = data.community_id;
|
||||||
|
|
||||||
check_private_instance(&local_user_view, &local_site)?;
|
let (local_person_id, is_admin) = match local_user_view {
|
||||||
|
Some(s) => (s.person.id, is_admin(&s).is_ok()),
|
||||||
|
None => (PersonId(-1), false),
|
||||||
|
};
|
||||||
|
let community_id_value = match community_id {
|
||||||
|
Some(s) => s,
|
||||||
|
None => CommunityId(-1),
|
||||||
|
};
|
||||||
|
let is_mod_of_community = data.community_id.is_some()
|
||||||
|
&& is_mod_or_admin(&mut context.pool(), local_person_id, community_id_value)
|
||||||
|
.await
|
||||||
|
.is_ok();
|
||||||
|
let hide_modlog_names = local_site.hide_modlog_mod_names && !is_mod_of_community && !is_admin;
|
||||||
|
|
||||||
let type_ = data.type_.unwrap_or(All);
|
let mod_person_id = if hide_modlog_names {
|
||||||
let community_id = data.community_id;
|
None
|
||||||
|
} else {
|
||||||
|
data.mod_person_id
|
||||||
|
};
|
||||||
|
let other_person_id = data.other_person_id;
|
||||||
|
let params = ModlogListParams {
|
||||||
|
community_id,
|
||||||
|
mod_person_id,
|
||||||
|
other_person_id,
|
||||||
|
page: data.page,
|
||||||
|
limit: data.limit,
|
||||||
|
hide_modlog_names,
|
||||||
|
};
|
||||||
|
let removed_posts = match type_ {
|
||||||
|
All | ModRemovePost => ModRemovePostView::list(&mut context.pool(), params).await?,
|
||||||
|
_ => Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
let (local_person_id, is_admin) = match local_user_view {
|
let locked_posts = match type_ {
|
||||||
Some(s) => (s.person.id, is_admin(&s).is_ok()),
|
All | ModLockPost => ModLockPostView::list(&mut context.pool(), params).await?,
|
||||||
None => (PersonId(-1), false),
|
_ => Default::default(),
|
||||||
};
|
};
|
||||||
let community_id_value = match community_id {
|
|
||||||
Some(s) => s,
|
|
||||||
None => CommunityId(-1),
|
|
||||||
};
|
|
||||||
let is_mod_of_community = data.community_id.is_some()
|
|
||||||
&& is_mod_or_admin(&mut context.pool(), local_person_id, community_id_value)
|
|
||||||
.await
|
|
||||||
.is_ok();
|
|
||||||
let hide_modlog_names = local_site.hide_modlog_mod_names && !is_mod_of_community && !is_admin;
|
|
||||||
|
|
||||||
let mod_person_id = if hide_modlog_names {
|
let featured_posts = match type_ {
|
||||||
None
|
All | ModFeaturePost => ModFeaturePostView::list(&mut context.pool(), params).await?,
|
||||||
} else {
|
_ => Default::default(),
|
||||||
data.mod_person_id
|
};
|
||||||
};
|
|
||||||
let other_person_id = data.other_person_id;
|
|
||||||
let params = ModlogListParams {
|
|
||||||
community_id,
|
|
||||||
mod_person_id,
|
|
||||||
other_person_id,
|
|
||||||
page: data.page,
|
|
||||||
limit: data.limit,
|
|
||||||
hide_modlog_names,
|
|
||||||
};
|
|
||||||
let removed_posts = match type_ {
|
|
||||||
All | ModRemovePost => ModRemovePostView::list(&mut context.pool(), params).await?,
|
|
||||||
_ => Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let locked_posts = match type_ {
|
let removed_comments = match type_ {
|
||||||
All | ModLockPost => ModLockPostView::list(&mut context.pool(), params).await?,
|
All | ModRemoveComment => ModRemoveCommentView::list(&mut context.pool(), params).await?,
|
||||||
_ => Default::default(),
|
_ => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let featured_posts = match type_ {
|
let banned_from_community = match type_ {
|
||||||
All | ModFeaturePost => ModFeaturePostView::list(&mut context.pool(), params).await?,
|
All | ModBanFromCommunity => ModBanFromCommunityView::list(&mut context.pool(), params).await?,
|
||||||
_ => Default::default(),
|
_ => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let removed_comments = match type_ {
|
let added_to_community = match type_ {
|
||||||
All | ModRemoveComment => ModRemoveCommentView::list(&mut context.pool(), params).await?,
|
All | ModAddCommunity => ModAddCommunityView::list(&mut context.pool(), params).await?,
|
||||||
_ => Default::default(),
|
_ => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let banned_from_community = match type_ {
|
let transferred_to_community = match type_ {
|
||||||
All | ModBanFromCommunity => {
|
All | ModTransferCommunity => {
|
||||||
ModBanFromCommunityView::list(&mut context.pool(), params).await?
|
ModTransferCommunityView::list(&mut context.pool(), params).await?
|
||||||
}
|
}
|
||||||
_ => Default::default(),
|
_ => Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let added_to_community = match type_ {
|
let hidden_communities = match type_ {
|
||||||
All | ModAddCommunity => ModAddCommunityView::list(&mut context.pool(), params).await?,
|
All | ModHideCommunity if other_person_id.is_none() => {
|
||||||
_ => Default::default(),
|
ModHideCommunityView::list(&mut context.pool(), params).await?
|
||||||
};
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
let transferred_to_community = match type_ {
|
// These arrays are only for the full modlog, when a community isn't given
|
||||||
All | ModTransferCommunity => {
|
let (
|
||||||
ModTransferCommunityView::list(&mut context.pool(), params).await?
|
banned,
|
||||||
}
|
added,
|
||||||
_ => Default::default(),
|
removed_communities,
|
||||||
};
|
admin_purged_persons,
|
||||||
|
admin_purged_communities,
|
||||||
|
admin_purged_posts,
|
||||||
|
admin_purged_comments,
|
||||||
|
) = if data.community_id.is_none() {
|
||||||
|
(
|
||||||
|
match type_ {
|
||||||
|
All | ModBan => ModBanView::list(&mut context.pool(), params).await?,
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | ModAdd => ModAddView::list(&mut context.pool(), params).await?,
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | ModRemoveCommunity if other_person_id.is_none() => {
|
||||||
|
ModRemoveCommunityView::list(&mut context.pool(), params).await?
|
||||||
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | AdminPurgePerson if other_person_id.is_none() => {
|
||||||
|
AdminPurgePersonView::list(&mut context.pool(), params).await?
|
||||||
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | AdminPurgeCommunity if other_person_id.is_none() => {
|
||||||
|
AdminPurgeCommunityView::list(&mut context.pool(), params).await?
|
||||||
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | AdminPurgePost if other_person_id.is_none() => {
|
||||||
|
AdminPurgePostView::list(&mut context.pool(), params).await?
|
||||||
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
match type_ {
|
||||||
|
All | AdminPurgeComment if other_person_id.is_none() => {
|
||||||
|
AdminPurgeCommentView::list(&mut context.pool(), params).await?
|
||||||
|
}
|
||||||
|
_ => Default::default(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
let hidden_communities = match type_ {
|
// Return the jwt
|
||||||
All | ModHideCommunity if other_person_id.is_none() => {
|
Ok(Json(GetModlogResponse {
|
||||||
ModHideCommunityView::list(&mut context.pool(), params).await?
|
removed_posts,
|
||||||
}
|
locked_posts,
|
||||||
_ => Default::default(),
|
featured_posts,
|
||||||
};
|
removed_comments,
|
||||||
|
removed_communities,
|
||||||
// These arrays are only for the full modlog, when a community isn't given
|
banned_from_community,
|
||||||
let (
|
banned,
|
||||||
banned,
|
added_to_community,
|
||||||
added,
|
added,
|
||||||
removed_communities,
|
transferred_to_community,
|
||||||
admin_purged_persons,
|
admin_purged_persons,
|
||||||
admin_purged_communities,
|
admin_purged_communities,
|
||||||
admin_purged_posts,
|
admin_purged_posts,
|
||||||
admin_purged_comments,
|
admin_purged_comments,
|
||||||
) = if data.community_id.is_none() {
|
hidden_communities,
|
||||||
(
|
}))
|
||||||
match type_ {
|
|
||||||
All | ModBan => ModBanView::list(&mut context.pool(), params).await?,
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | ModAdd => ModAddView::list(&mut context.pool(), params).await?,
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | ModRemoveCommunity if other_person_id.is_none() => {
|
|
||||||
ModRemoveCommunityView::list(&mut context.pool(), params).await?
|
|
||||||
}
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | AdminPurgePerson if other_person_id.is_none() => {
|
|
||||||
AdminPurgePersonView::list(&mut context.pool(), params).await?
|
|
||||||
}
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | AdminPurgeCommunity if other_person_id.is_none() => {
|
|
||||||
AdminPurgeCommunityView::list(&mut context.pool(), params).await?
|
|
||||||
}
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | AdminPurgePost if other_person_id.is_none() => {
|
|
||||||
AdminPurgePostView::list(&mut context.pool(), params).await?
|
|
||||||
}
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
match type_ {
|
|
||||||
All | AdminPurgeComment if other_person_id.is_none() => {
|
|
||||||
AdminPurgeCommentView::list(&mut context.pool(), params).await?
|
|
||||||
}
|
|
||||||
_ => Default::default(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Return the jwt
|
|
||||||
Ok(GetModlogResponse {
|
|
||||||
removed_posts,
|
|
||||||
locked_posts,
|
|
||||||
featured_posts,
|
|
||||||
removed_comments,
|
|
||||||
removed_communities,
|
|
||||||
banned_from_community,
|
|
||||||
banned,
|
|
||||||
added_to_community,
|
|
||||||
added,
|
|
||||||
transferred_to_community,
|
|
||||||
admin_purged_persons,
|
|
||||||
admin_purged_communities,
|
|
||||||
admin_purged_posts,
|
|
||||||
admin_purged_comments,
|
|
||||||
hidden_communities,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
site::{PurgeComment, PurgeItemResponse},
|
site::{PurgeComment, PurgeItemResponse},
|
||||||
|
@ -14,39 +13,36 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for PurgeComment {
|
pub async fn purge_comment(
|
||||||
type Response = PurgeItemResponse;
|
data: Json<PurgeComment>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PurgeItemResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Only let admin purge an item
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &Self = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Only let admin purge an item
|
let comment_id = data.comment_id;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
let comment_id = data.comment_id;
|
// Read the comment to get the post_id
|
||||||
|
let comment = Comment::read(&mut context.pool(), comment_id).await?;
|
||||||
|
|
||||||
// Read the comment to get the post_id
|
let post_id = comment.post_id;
|
||||||
let comment = Comment::read(&mut context.pool(), comment_id).await?;
|
|
||||||
|
|
||||||
let post_id = comment.post_id;
|
// TODO read comments for pictrs images and purge them
|
||||||
|
|
||||||
// TODO read comments for pictrs images and purge them
|
Comment::delete(&mut context.pool(), comment_id).await?;
|
||||||
|
|
||||||
Comment::delete(&mut context.pool(), comment_id).await?;
|
// Mod tables
|
||||||
|
let reason = sanitize_html_opt(&data.reason);
|
||||||
|
let form = AdminPurgeCommentForm {
|
||||||
|
admin_person_id: local_user_view.person.id,
|
||||||
|
reason,
|
||||||
|
post_id,
|
||||||
|
};
|
||||||
|
|
||||||
// Mod tables
|
AdminPurgeComment::create(&mut context.pool(), &form).await?;
|
||||||
let reason = sanitize_html_opt(&data.reason);
|
|
||||||
let form = AdminPurgeCommentForm {
|
|
||||||
admin_person_id: local_user_view.person.id,
|
|
||||||
reason,
|
|
||||||
post_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
AdminPurgeComment::create(&mut context.pool(), &form).await?;
|
Ok(Json(PurgeItemResponse { success: true }))
|
||||||
|
|
||||||
Ok(PurgeItemResponse { success: 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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
request::purge_image_from_pictrs,
|
request::purge_image_from_pictrs,
|
||||||
|
@ -15,44 +14,41 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for PurgeCommunity {
|
pub async fn purge_community(
|
||||||
type Response = PurgeItemResponse;
|
data: Json<PurgeCommunity>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PurgeItemResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Only let admin purge an item
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &Self = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Only let admin purge an item
|
let community_id = data.community_id;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
let community_id = data.community_id;
|
// Read the community to get its images
|
||||||
|
let community = Community::read(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
// Read the community to get its images
|
if let Some(banner) = community.banner {
|
||||||
let community = Community::read(&mut context.pool(), community_id).await?;
|
purge_image_from_pictrs(&banner, &context).await.ok();
|
||||||
|
|
||||||
if let Some(banner) = community.banner {
|
|
||||||
purge_image_from_pictrs(&banner, context).await.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(icon) = community.icon {
|
|
||||||
purge_image_from_pictrs(&icon, context).await.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
purge_image_posts_for_community(community_id, context).await?;
|
|
||||||
|
|
||||||
Community::delete(&mut context.pool(), community_id).await?;
|
|
||||||
|
|
||||||
// Mod tables
|
|
||||||
let reason = sanitize_html_opt(&data.reason);
|
|
||||||
let form = AdminPurgeCommunityForm {
|
|
||||||
admin_person_id: local_user_view.person.id,
|
|
||||||
reason,
|
|
||||||
};
|
|
||||||
|
|
||||||
AdminPurgeCommunity::create(&mut context.pool(), &form).await?;
|
|
||||||
|
|
||||||
Ok(PurgeItemResponse { success: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(icon) = community.icon {
|
||||||
|
purge_image_from_pictrs(&icon, &context).await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
purge_image_posts_for_community(community_id, &context).await?;
|
||||||
|
|
||||||
|
Community::delete(&mut context.pool(), community_id).await?;
|
||||||
|
|
||||||
|
// Mod tables
|
||||||
|
let reason = sanitize_html_opt(&data.reason);
|
||||||
|
let form = AdminPurgeCommunityForm {
|
||||||
|
admin_person_id: local_user_view.person.id,
|
||||||
|
reason,
|
||||||
|
};
|
||||||
|
|
||||||
|
AdminPurgeCommunity::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
|
Ok(Json(PurgeItemResponse { success: true }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
mod comment;
|
pub mod comment;
|
||||||
mod community;
|
pub mod community;
|
||||||
mod person;
|
pub mod person;
|
||||||
mod post;
|
pub mod post;
|
||||||
|
|
|
@ -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,
|
||||||
request::purge_image_from_pictrs,
|
request::purge_image_from_pictrs,
|
||||||
|
@ -15,43 +14,40 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for PurgePerson {
|
pub async fn purge_person(
|
||||||
type Response = PurgeItemResponse;
|
data: Json<PurgePerson>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PurgeItemResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Only let admin purge an item
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &Self = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Only let admin purge an item
|
// Read the person to get their images
|
||||||
is_admin(&local_user_view)?;
|
let person_id = data.person_id;
|
||||||
|
let person = Person::read(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
// Read the person to get their images
|
if let Some(banner) = person.banner {
|
||||||
let person_id = data.person_id;
|
purge_image_from_pictrs(&banner, &context).await.ok();
|
||||||
let person = Person::read(&mut context.pool(), person_id).await?;
|
|
||||||
|
|
||||||
if let Some(banner) = person.banner {
|
|
||||||
purge_image_from_pictrs(&banner, context).await.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(avatar) = person.avatar {
|
|
||||||
purge_image_from_pictrs(&avatar, context).await.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
purge_image_posts_for_person(person_id, context).await?;
|
|
||||||
|
|
||||||
Person::delete(&mut context.pool(), person_id).await?;
|
|
||||||
|
|
||||||
// Mod tables
|
|
||||||
let reason = sanitize_html_opt(&data.reason);
|
|
||||||
let form = AdminPurgePersonForm {
|
|
||||||
admin_person_id: local_user_view.person.id,
|
|
||||||
reason,
|
|
||||||
};
|
|
||||||
|
|
||||||
AdminPurgePerson::create(&mut context.pool(), &form).await?;
|
|
||||||
|
|
||||||
Ok(PurgeItemResponse { success: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(avatar) = person.avatar {
|
||||||
|
purge_image_from_pictrs(&avatar, &context).await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
purge_image_posts_for_person(person_id, &context).await?;
|
||||||
|
|
||||||
|
Person::delete(&mut context.pool(), person_id).await?;
|
||||||
|
|
||||||
|
// Mod tables
|
||||||
|
let reason = sanitize_html_opt(&data.reason);
|
||||||
|
let form = AdminPurgePersonForm {
|
||||||
|
admin_person_id: local_user_view.person.id,
|
||||||
|
reason,
|
||||||
|
};
|
||||||
|
|
||||||
|
AdminPurgePerson::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
|
Ok(Json(PurgeItemResponse { success: 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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
request::purge_image_from_pictrs,
|
request::purge_image_from_pictrs,
|
||||||
|
@ -15,46 +14,43 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[tracing::instrument(skip(context))]
|
||||||
impl Perform for PurgePost {
|
pub async fn purge_post(
|
||||||
type Response = PurgeItemResponse;
|
data: Json<PurgePost>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<PurgeItemResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
#[tracing::instrument(skip(context))]
|
// Only let admin purge an item
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
is_admin(&local_user_view)?;
|
||||||
let data: &Self = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
// Only let admin purge an item
|
let post_id = data.post_id;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
let post_id = data.post_id;
|
// Read the post to get the community_id
|
||||||
|
let post = Post::read(&mut context.pool(), post_id).await?;
|
||||||
|
|
||||||
// Read the post to get the community_id
|
// Purge image
|
||||||
let post = Post::read(&mut context.pool(), post_id).await?;
|
if let Some(url) = post.url {
|
||||||
|
purge_image_from_pictrs(&url, &context).await.ok();
|
||||||
// Purge image
|
|
||||||
if let Some(url) = post.url {
|
|
||||||
purge_image_from_pictrs(&url, context).await.ok();
|
|
||||||
}
|
|
||||||
// Purge thumbnail
|
|
||||||
if let Some(thumbnail_url) = post.thumbnail_url {
|
|
||||||
purge_image_from_pictrs(&thumbnail_url, context).await.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
let community_id = post.community_id;
|
|
||||||
|
|
||||||
Post::delete(&mut context.pool(), post_id).await?;
|
|
||||||
|
|
||||||
// Mod tables
|
|
||||||
let reason = sanitize_html_opt(&data.reason);
|
|
||||||
let form = AdminPurgePostForm {
|
|
||||||
admin_person_id: local_user_view.person.id,
|
|
||||||
reason,
|
|
||||||
community_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
AdminPurgePost::create(&mut context.pool(), &form).await?;
|
|
||||||
|
|
||||||
Ok(PurgeItemResponse { success: true })
|
|
||||||
}
|
}
|
||||||
|
// Purge thumbnail
|
||||||
|
if let Some(thumbnail_url) = post.thumbnail_url {
|
||||||
|
purge_image_from_pictrs(&thumbnail_url, &context).await.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
let community_id = post.community_id;
|
||||||
|
|
||||||
|
Post::delete(&mut context.pool(), post_id).await?;
|
||||||
|
|
||||||
|
// Mod tables
|
||||||
|
let reason = sanitize_html_opt(&data.reason);
|
||||||
|
let form = AdminPurgePostForm {
|
||||||
|
admin_person_id: local_user_view.person.id,
|
||||||
|
reason,
|
||||||
|
community_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
AdminPurgePost::create(&mut context.pool(), &form).await?;
|
||||||
|
|
||||||
|
Ok(Json(PurgeItemResponse { success: 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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{ApproveRegistrationApplication, RegistrationApplicationResponse},
|
site::{ApproveRegistrationApplication, RegistrationApplicationResponse},
|
||||||
|
@ -16,53 +15,50 @@ use lemmy_db_schema::{
|
||||||
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
pub async fn approve_registration_application(
|
||||||
impl Perform for ApproveRegistrationApplication {
|
data: Json<ApproveRegistrationApplication>,
|
||||||
type Response = RegistrationApplicationResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<RegistrationApplicationResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
let app_id = data.id;
|
||||||
let data = self;
|
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
|
|
||||||
let app_id = data.id;
|
// Only let admins do this
|
||||||
|
is_admin(&local_user_view)?;
|
||||||
|
|
||||||
// Only let admins do this
|
// Update the registration with reason, admin_id
|
||||||
is_admin(&local_user_view)?;
|
let deny_reason = diesel_option_overwrite(data.deny_reason.clone());
|
||||||
|
let app_form = RegistrationApplicationUpdateForm {
|
||||||
|
admin_id: Some(Some(local_user_view.person.id)),
|
||||||
|
deny_reason,
|
||||||
|
};
|
||||||
|
|
||||||
// Update the registration with reason, admin_id
|
let registration_application =
|
||||||
let deny_reason = diesel_option_overwrite(data.deny_reason.clone());
|
RegistrationApplication::update(&mut context.pool(), app_id, &app_form).await?;
|
||||||
let app_form = RegistrationApplicationUpdateForm {
|
|
||||||
admin_id: Some(Some(local_user_view.person.id)),
|
|
||||||
deny_reason,
|
|
||||||
};
|
|
||||||
|
|
||||||
let registration_application =
|
// Update the local_user row
|
||||||
RegistrationApplication::update(&mut context.pool(), app_id, &app_form).await?;
|
let local_user_form = LocalUserUpdateForm {
|
||||||
|
accepted_application: Some(data.approve),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
// Update the local_user row
|
let approved_user_id = registration_application.local_user_id;
|
||||||
let local_user_form = LocalUserUpdateForm {
|
LocalUser::update(&mut context.pool(), approved_user_id, &local_user_form).await?;
|
||||||
accepted_application: Some(data.approve),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let approved_user_id = registration_application.local_user_id;
|
if data.approve {
|
||||||
LocalUser::update(&mut context.pool(), approved_user_id, &local_user_form).await?;
|
let approved_local_user_view =
|
||||||
|
LocalUserView::read(&mut context.pool(), approved_user_id).await?;
|
||||||
|
|
||||||
if data.approve {
|
if approved_local_user_view.local_user.email.is_some() {
|
||||||
let approved_local_user_view =
|
send_application_approved_email(&approved_local_user_view, context.settings()).await?;
|
||||||
LocalUserView::read(&mut context.pool(), approved_user_id).await?;
|
|
||||||
|
|
||||||
if approved_local_user_view.local_user.email.is_some() {
|
|
||||||
send_application_approved_email(&approved_local_user_view, context.settings()).await?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the view
|
|
||||||
let registration_application =
|
|
||||||
RegistrationApplicationView::read(&mut context.pool(), app_id).await?;
|
|
||||||
|
|
||||||
Ok(Self::Response {
|
|
||||||
registration_application,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the view
|
||||||
|
let registration_application =
|
||||||
|
RegistrationApplicationView::read(&mut context.pool(), app_id).await?;
|
||||||
|
|
||||||
|
Ok(Json(RegistrationApplicationResponse {
|
||||||
|
registration_application,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{ListRegistrationApplications, ListRegistrationApplicationsResponse},
|
site::{ListRegistrationApplications, ListRegistrationApplicationsResponse},
|
||||||
|
@ -10,34 +9,31 @@ use lemmy_db_views::registration_application_view::RegistrationApplicationQuery;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
/// Lists registration applications, filterable by undenied only.
|
/// Lists registration applications, filterable by undenied only.
|
||||||
#[async_trait::async_trait(?Send)]
|
pub async fn list_registration_applications(
|
||||||
impl Perform for ListRegistrationApplications {
|
data: Query<ListRegistrationApplications>,
|
||||||
type Response = ListRegistrationApplicationsResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<ListRegistrationApplicationsResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
// Make sure user is an admin
|
||||||
let data = self;
|
is_admin(&local_user_view)?;
|
||||||
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
|
let unread_only = data.unread_only.unwrap_or_default();
|
||||||
is_admin(&local_user_view)?;
|
let verified_email_only = local_site.require_email_verification;
|
||||||
|
|
||||||
let unread_only = data.unread_only.unwrap_or_default();
|
let page = data.page;
|
||||||
let verified_email_only = local_site.require_email_verification;
|
let limit = data.limit;
|
||||||
|
let registration_applications = RegistrationApplicationQuery {
|
||||||
let page = data.page;
|
unread_only,
|
||||||
let limit = data.limit;
|
verified_email_only,
|
||||||
let registration_applications = RegistrationApplicationQuery {
|
page,
|
||||||
unread_only,
|
limit,
|
||||||
verified_email_only,
|
|
||||||
page,
|
|
||||||
limit,
|
|
||||||
}
|
|
||||||
.list(&mut context.pool())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(Self::Response {
|
|
||||||
registration_applications,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
.list(&mut context.pool())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Json(ListRegistrationApplicationsResponse {
|
||||||
|
registration_applications,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
mod approve;
|
pub mod approve;
|
||||||
mod list;
|
pub mod list;
|
||||||
mod unread_count;
|
pub mod unread_count;
|
||||||
|
|
|
@ -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::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
site::{GetUnreadRegistrationApplicationCount, GetUnreadRegistrationApplicationCountResponse},
|
site::{GetUnreadRegistrationApplicationCount, GetUnreadRegistrationApplicationCountResponse},
|
||||||
|
@ -9,26 +8,22 @@ use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_db_views::structs::RegistrationApplicationView;
|
use lemmy_db_views::structs::RegistrationApplicationView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::LemmyError;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
pub async fn get_unread_registration_application_count(
|
||||||
impl Perform for GetUnreadRegistrationApplicationCount {
|
data: Query<GetUnreadRegistrationApplicationCount>,
|
||||||
type Response = GetUnreadRegistrationApplicationCountResponse;
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<GetUnreadRegistrationApplicationCountResponse>, LemmyError> {
|
||||||
|
let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
|
||||||
|
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||||
|
|
||||||
async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
|
// Only let admins do this
|
||||||
let data = self;
|
is_admin(&local_user_view)?;
|
||||||
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
|
|
||||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
|
||||||
|
|
||||||
// Only let admins do this
|
let verified_email_only = local_site.require_email_verification;
|
||||||
is_admin(&local_user_view)?;
|
|
||||||
|
|
||||||
let verified_email_only = local_site.require_email_verification;
|
let registration_applications =
|
||||||
|
RegistrationApplicationView::get_unread_count(&mut context.pool(), verified_email_only).await?;
|
||||||
|
|
||||||
let registration_applications =
|
Ok(Json(GetUnreadRegistrationApplicationCountResponse {
|
||||||
RegistrationApplicationView::get_unread_count(&mut context.pool(), verified_email_only)
|
registration_applications,
|
||||||
.await?;
|
}))
|
||||||
|
|
||||||
Ok(Self::Response {
|
|
||||||
registration_applications,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ Here is an example using [reqwest](https://crates.io/crates/reqwest):
|
||||||
print!("{:?}", &json);
|
print!("{:?}", &json);
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, each API endpoint needs a parameter type ( GetPosts), path (/post/list) and response type (GetPostsResponse). You can find the paths and parameter types from [this file](https://github.com/LemmyNet/lemmy/blob/main/src/api_routes_http.rs). For the response types you need to look through the crates [lemmy_api](https://github.com/LemmyNet/lemmy/tree/main/crates/api/src) and [lemmy_api_crud](https://github.com/LemmyNet/lemmy/tree/main/crates/api_crud/src) for the place where Perform/PerformCrud is implemented for the parameter type. The response type is specified as a type parameter on the trait.
|
As you can see, each API endpoint needs a parameter type ( GetPosts), path (/post/list) and response type (GetPostsResponse). You can find the paths and handler methods from [this file](https://github.com/LemmyNet/lemmy/blob/main/src/api_routes_http.rs). The parameter type and response type are defined on each handler method.
|
||||||
|
|
||||||
For a real example of a Lemmy API client, look at [lemmyBB](https://github.com/LemmyNet/lemmyBB/tree/main/src/api).
|
For a real example of a Lemmy API client, look at [lemmyBB](https://github.com/LemmyNet/lemmyBB/tree/main/src/api).
|
||||||
|
|
||||||
|
|
|
@ -51,15 +51,6 @@ pub struct Register {
|
||||||
pub answer: Option<String>,
|
pub answer: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
|
||||||
/// Fetches a Captcha item.
|
|
||||||
pub struct GetCaptcha {
|
|
||||||
pub auth: Option<Sensitive<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
|
|
|
@ -301,15 +301,6 @@ pub struct GetSiteResponse {
|
||||||
pub custom_emojis: Vec<CustomEmojiView>,
|
pub custom_emojis: Vec<CustomEmojiView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
|
||||||
#[cfg_attr(feature = "full", ts(export))]
|
|
||||||
/// Fetches the federated instances for your site.
|
|
||||||
pub struct GetFederatedInstances {
|
|
||||||
pub auth: Option<Sensitive<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "full", derive(TS))]
|
#[cfg_attr(feature = "full", derive(TS))]
|
||||||
|
|
|
@ -65,7 +65,6 @@ pub mod community;
|
||||||
pub mod create_or_update;
|
pub mod create_or_update;
|
||||||
pub mod deletion;
|
pub mod deletion;
|
||||||
pub mod following;
|
pub mod following;
|
||||||
pub mod unfederated;
|
|
||||||
pub mod voting;
|
pub mod voting;
|
||||||
|
|
||||||
/// Amount of time that the list of dead instances is cached. This is only updated once a day,
|
/// Amount of time that the list of dead instances is cached. This is only updated once a day,
|
||||||
|
|
|
@ -1,320 +0,0 @@
|
||||||
use crate::SendActivity;
|
|
||||||
use lemmy_api_common::{
|
|
||||||
comment::{
|
|
||||||
CommentReportResponse,
|
|
||||||
CommentResponse,
|
|
||||||
DistinguishComment,
|
|
||||||
GetComment,
|
|
||||||
ListCommentReports,
|
|
||||||
ListCommentReportsResponse,
|
|
||||||
ResolveCommentReport,
|
|
||||||
SaveComment,
|
|
||||||
},
|
|
||||||
community::{
|
|
||||||
CommunityResponse,
|
|
||||||
CreateCommunity,
|
|
||||||
GetCommunityResponse,
|
|
||||||
ListCommunities,
|
|
||||||
ListCommunitiesResponse,
|
|
||||||
TransferCommunity,
|
|
||||||
},
|
|
||||||
custom_emoji::{
|
|
||||||
CreateCustomEmoji,
|
|
||||||
CustomEmojiResponse,
|
|
||||||
DeleteCustomEmoji,
|
|
||||||
DeleteCustomEmojiResponse,
|
|
||||||
EditCustomEmoji,
|
|
||||||
},
|
|
||||||
person::{
|
|
||||||
AddAdmin,
|
|
||||||
AddAdminResponse,
|
|
||||||
BannedPersonsResponse,
|
|
||||||
BlockPerson,
|
|
||||||
BlockPersonResponse,
|
|
||||||
ChangePassword,
|
|
||||||
CommentReplyResponse,
|
|
||||||
GetBannedPersons,
|
|
||||||
GetCaptcha,
|
|
||||||
GetCaptchaResponse,
|
|
||||||
GetPersonMentions,
|
|
||||||
GetPersonMentionsResponse,
|
|
||||||
GetReplies,
|
|
||||||
GetRepliesResponse,
|
|
||||||
GetReportCount,
|
|
||||||
GetReportCountResponse,
|
|
||||||
GetUnreadCount,
|
|
||||||
GetUnreadCountResponse,
|
|
||||||
Login,
|
|
||||||
LoginResponse,
|
|
||||||
MarkAllAsRead,
|
|
||||||
MarkCommentReplyAsRead,
|
|
||||||
MarkPersonMentionAsRead,
|
|
||||||
PasswordChangeAfterReset,
|
|
||||||
PasswordReset,
|
|
||||||
PasswordResetResponse,
|
|
||||||
PersonMentionResponse,
|
|
||||||
Register,
|
|
||||||
SaveUserSettings,
|
|
||||||
VerifyEmail,
|
|
||||||
VerifyEmailResponse,
|
|
||||||
},
|
|
||||||
post::{
|
|
||||||
GetPost,
|
|
||||||
GetPostResponse,
|
|
||||||
GetSiteMetadata,
|
|
||||||
GetSiteMetadataResponse,
|
|
||||||
ListPostReports,
|
|
||||||
ListPostReportsResponse,
|
|
||||||
MarkPostAsRead,
|
|
||||||
PostReportResponse,
|
|
||||||
PostResponse,
|
|
||||||
ResolvePostReport,
|
|
||||||
SavePost,
|
|
||||||
},
|
|
||||||
private_message::{
|
|
||||||
CreatePrivateMessageReport,
|
|
||||||
GetPrivateMessages,
|
|
||||||
ListPrivateMessageReports,
|
|
||||||
ListPrivateMessageReportsResponse,
|
|
||||||
MarkPrivateMessageAsRead,
|
|
||||||
PrivateMessageReportResponse,
|
|
||||||
PrivateMessageResponse,
|
|
||||||
PrivateMessagesResponse,
|
|
||||||
ResolvePrivateMessageReport,
|
|
||||||
},
|
|
||||||
site::{
|
|
||||||
ApproveRegistrationApplication,
|
|
||||||
CreateSite,
|
|
||||||
EditSite,
|
|
||||||
GetFederatedInstances,
|
|
||||||
GetFederatedInstancesResponse,
|
|
||||||
GetModlog,
|
|
||||||
GetModlogResponse,
|
|
||||||
GetSite,
|
|
||||||
GetSiteResponse,
|
|
||||||
GetUnreadRegistrationApplicationCount,
|
|
||||||
GetUnreadRegistrationApplicationCountResponse,
|
|
||||||
LeaveAdmin,
|
|
||||||
ListRegistrationApplications,
|
|
||||||
ListRegistrationApplicationsResponse,
|
|
||||||
PurgeComment,
|
|
||||||
PurgeCommunity,
|
|
||||||
PurgeItemResponse,
|
|
||||||
PurgePerson,
|
|
||||||
PurgePost,
|
|
||||||
RegistrationApplicationResponse,
|
|
||||||
SiteResponse,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl SendActivity for Register {
|
|
||||||
type Response = LoginResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetPrivateMessages {
|
|
||||||
type Response = PrivateMessagesResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for CreateSite {
|
|
||||||
type Response = SiteResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for EditSite {
|
|
||||||
type Response = SiteResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetSite {
|
|
||||||
type Response = GetSiteResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ListCommunities {
|
|
||||||
type Response = ListCommunitiesResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for CreateCommunity {
|
|
||||||
type Response = CommunityResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetPost {
|
|
||||||
type Response = GetPostResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetComment {
|
|
||||||
type Response = CommentResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for Login {
|
|
||||||
type Response = LoginResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetCaptcha {
|
|
||||||
type Response = GetCaptchaResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetReplies {
|
|
||||||
type Response = GetRepliesResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for AddAdmin {
|
|
||||||
type Response = AddAdminResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetUnreadRegistrationApplicationCount {
|
|
||||||
type Response = GetUnreadRegistrationApplicationCountResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ListRegistrationApplications {
|
|
||||||
type Response = ListRegistrationApplicationsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ApproveRegistrationApplication {
|
|
||||||
type Response = RegistrationApplicationResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetBannedPersons {
|
|
||||||
type Response = BannedPersonsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for BlockPerson {
|
|
||||||
type Response = BlockPersonResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetPersonMentions {
|
|
||||||
type Response = GetPersonMentionsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for MarkPersonMentionAsRead {
|
|
||||||
type Response = PersonMentionResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for MarkCommentReplyAsRead {
|
|
||||||
type Response = CommentReplyResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for MarkAllAsRead {
|
|
||||||
type Response = GetRepliesResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PasswordReset {
|
|
||||||
type Response = PasswordResetResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PasswordChangeAfterReset {
|
|
||||||
type Response = LoginResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for SaveUserSettings {
|
|
||||||
type Response = LoginResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ChangePassword {
|
|
||||||
type Response = LoginResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetReportCount {
|
|
||||||
type Response = GetReportCountResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetUnreadCount {
|
|
||||||
type Response = GetUnreadCountResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for VerifyEmail {
|
|
||||||
type Response = VerifyEmailResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for MarkPrivateMessageAsRead {
|
|
||||||
type Response = PrivateMessageResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for CreatePrivateMessageReport {
|
|
||||||
type Response = PrivateMessageReportResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ResolvePrivateMessageReport {
|
|
||||||
type Response = PrivateMessageReportResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ListPrivateMessageReports {
|
|
||||||
type Response = ListPrivateMessageReportsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetModlog {
|
|
||||||
type Response = GetModlogResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PurgePerson {
|
|
||||||
type Response = PurgeItemResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PurgeCommunity {
|
|
||||||
type Response = PurgeItemResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PurgePost {
|
|
||||||
type Response = PurgeItemResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for PurgeComment {
|
|
||||||
type Response = PurgeItemResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for TransferCommunity {
|
|
||||||
type Response = GetCommunityResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for LeaveAdmin {
|
|
||||||
type Response = GetSiteResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for MarkPostAsRead {
|
|
||||||
type Response = PostResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for SavePost {
|
|
||||||
type Response = PostResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ListPostReports {
|
|
||||||
type Response = ListPostReportsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ResolvePostReport {
|
|
||||||
type Response = PostReportResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetSiteMetadata {
|
|
||||||
type Response = GetSiteMetadataResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for SaveComment {
|
|
||||||
type Response = CommentResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for DistinguishComment {
|
|
||||||
type Response = CommentResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ListCommentReports {
|
|
||||||
type Response = ListCommentReportsResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for ResolveCommentReport {
|
|
||||||
type Response = CommentReportResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for CreateCustomEmoji {
|
|
||||||
type Response = CustomEmojiResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for EditCustomEmoji {
|
|
||||||
type Response = CustomEmojiResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for DeleteCustomEmoji {
|
|
||||||
type Response = DeleteCustomEmojiResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SendActivity for GetFederatedInstances {
|
|
||||||
type Response = GetFederatedInstancesResponse;
|
|
||||||
}
|
|
|
@ -194,16 +194,3 @@ async fn insert_received_activity(
|
||||||
ReceivedActivity::create(&mut data.pool(), &ap_id.clone().into()).await?;
|
ReceivedActivity::create(&mut data.pool(), &ap_id.clone().into()).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
|
||||||
pub trait SendActivity: Sync {
|
|
||||||
type Response: Sync + Send + Clone;
|
|
||||||
|
|
||||||
async fn send_activity(
|
|
||||||
_request: &Self,
|
|
||||||
_response: &Self::Response,
|
|
||||||
_context: &Data<LemmyContext>,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_web::{guard, web, Error, HttpResponse, Result};
|
use actix_web::{guard, web};
|
||||||
use lemmy_api::{
|
use lemmy_api::{
|
||||||
comment::{distinguish::distinguish_comment, like::like_comment, save::save_comment},
|
comment::{distinguish::distinguish_comment, like::like_comment, save::save_comment},
|
||||||
comment_report::{
|
comment_report::{
|
||||||
|
@ -12,53 +12,66 @@ use lemmy_api::{
|
||||||
block::block_community,
|
block::block_community,
|
||||||
follow::follow_community,
|
follow::follow_community,
|
||||||
hide::hide_community,
|
hide::hide_community,
|
||||||
|
transfer::transfer_community,
|
||||||
},
|
},
|
||||||
local_user::{ban_person::ban_from_site, notifications::mark_reply_read::mark_reply_as_read},
|
local_user::{
|
||||||
post::{feature::feature_post, like::like_post, lock::lock_post},
|
add_admin::add_admin,
|
||||||
post_report::create::create_post_report,
|
ban_person::ban_from_site,
|
||||||
sitemap::get_sitemap,
|
block::block_person,
|
||||||
Perform,
|
change_password::change_password,
|
||||||
};
|
change_password_after_reset::change_password_after_reset,
|
||||||
use lemmy_api_common::{
|
get_captcha::get_captcha,
|
||||||
community::TransferCommunity,
|
list_banned::list_banned_users,
|
||||||
context::LemmyContext,
|
login::login,
|
||||||
person::{
|
notifications::{
|
||||||
AddAdmin,
|
list_mentions::list_mentions,
|
||||||
BlockPerson,
|
list_replies::list_replies,
|
||||||
ChangePassword,
|
mark_all_read::mark_all_notifications_read,
|
||||||
GetBannedPersons,
|
mark_mention_read::mark_person_mention_as_read,
|
||||||
GetCaptcha,
|
mark_reply_read::mark_reply_as_read,
|
||||||
GetPersonMentions,
|
unread_count::unread_count,
|
||||||
GetReplies,
|
},
|
||||||
GetReportCount,
|
report_count::report_count,
|
||||||
GetUnreadCount,
|
reset_password::reset_password,
|
||||||
Login,
|
save_settings::save_user_settings,
|
||||||
MarkAllAsRead,
|
verify_email::verify_email,
|
||||||
MarkPersonMentionAsRead,
|
|
||||||
PasswordChangeAfterReset,
|
|
||||||
PasswordReset,
|
|
||||||
SaveUserSettings,
|
|
||||||
VerifyEmail,
|
|
||||||
},
|
},
|
||||||
post::{GetSiteMetadata, ListPostReports, MarkPostAsRead, ResolvePostReport, SavePost},
|
post::{
|
||||||
private_message::{
|
feature::feature_post,
|
||||||
CreatePrivateMessageReport,
|
get_link_metadata::get_link_metadata,
|
||||||
ListPrivateMessageReports,
|
like::like_post,
|
||||||
MarkPrivateMessageAsRead,
|
lock::lock_post,
|
||||||
ResolvePrivateMessageReport,
|
mark_read::mark_post_as_read,
|
||||||
|
save::save_post,
|
||||||
|
},
|
||||||
|
post_report::{
|
||||||
|
create::create_post_report,
|
||||||
|
list::list_post_reports,
|
||||||
|
resolve::resolve_post_report,
|
||||||
|
},
|
||||||
|
private_message::mark_read::mark_pm_as_read,
|
||||||
|
private_message_report::{
|
||||||
|
create::create_pm_report,
|
||||||
|
list::list_pm_reports,
|
||||||
|
resolve::resolve_pm_report,
|
||||||
},
|
},
|
||||||
site::{
|
site::{
|
||||||
ApproveRegistrationApplication,
|
federated_instances::get_federated_instances,
|
||||||
GetFederatedInstances,
|
leave_admin::leave_admin,
|
||||||
GetModlog,
|
mod_log::get_mod_log,
|
||||||
GetUnreadRegistrationApplicationCount,
|
purge::{
|
||||||
LeaveAdmin,
|
comment::purge_comment,
|
||||||
ListRegistrationApplications,
|
community::purge_community,
|
||||||
PurgeComment,
|
person::purge_person,
|
||||||
PurgeCommunity,
|
post::purge_post,
|
||||||
PurgePerson,
|
},
|
||||||
PurgePost,
|
registration_applications::{
|
||||||
|
approve::approve_registration_application,
|
||||||
|
list::list_registration_applications,
|
||||||
|
unread_count::get_unread_registration_application_count,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
sitemap::get_sitemap,
|
||||||
};
|
};
|
||||||
use lemmy_api_crud::{
|
use lemmy_api_crud::{
|
||||||
comment::{
|
comment::{
|
||||||
|
@ -96,19 +109,15 @@ use lemmy_api_crud::{
|
||||||
site::{create::create_site, read::get_site, update::update_site},
|
site::{create::create_site, read::get_site, update::update_site},
|
||||||
user::{create::register, delete::delete_account},
|
user::{create::register, delete::delete_account},
|
||||||
};
|
};
|
||||||
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::get_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,
|
|
||||||
},
|
|
||||||
SendActivity,
|
|
||||||
};
|
};
|
||||||
use lemmy_utils::{rate_limit::RateLimitCell, spawn_try_task, SYNCHRONOUS_FEDERATION};
|
use lemmy_utils::rate_limit::RateLimitCell;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
cfg.service(
|
cfg.service(
|
||||||
|
@ -125,7 +134,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.service(
|
.service(
|
||||||
web::resource("/modlog")
|
web::resource("/modlog")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route(web::get().to(route_get::<GetModlog>)),
|
.route(web::get().to(get_mod_log)),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::resource("/search")
|
web::resource("/search")
|
||||||
|
@ -156,14 +165,14 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("/delete", web::post().to(delete_community))
|
.route("/delete", web::post().to(delete_community))
|
||||||
// Mod Actions
|
// Mod Actions
|
||||||
.route("/remove", web::post().to(remove_community))
|
.route("/remove", web::post().to(remove_community))
|
||||||
.route("/transfer", web::post().to(route_post::<TransferCommunity>))
|
.route("/transfer", web::post().to(transfer_community))
|
||||||
.route("/ban_user", web::post().to(ban_from_community))
|
.route("/ban_user", web::post().to(ban_from_community))
|
||||||
.route("/mod", web::post().to(add_mod_to_community)),
|
.route("/mod", web::post().to(add_mod_to_community)),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/federated_instances")
|
web::scope("/federated_instances")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(route_get::<GetFederatedInstances>)),
|
.route("", web::get().to(get_federated_instances)),
|
||||||
)
|
)
|
||||||
// Post
|
// Post
|
||||||
.service(
|
.service(
|
||||||
|
@ -180,25 +189,16 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("", web::put().to(update_post))
|
.route("", web::put().to(update_post))
|
||||||
.route("/delete", web::post().to(delete_post))
|
.route("/delete", web::post().to(delete_post))
|
||||||
.route("/remove", web::post().to(remove_post))
|
.route("/remove", web::post().to(remove_post))
|
||||||
.route(
|
.route("/mark_as_read", web::post().to(mark_post_as_read))
|
||||||
"/mark_as_read",
|
|
||||||
web::post().to(route_post::<MarkPostAsRead>),
|
|
||||||
)
|
|
||||||
.route("/lock", web::post().to(lock_post))
|
.route("/lock", web::post().to(lock_post))
|
||||||
.route("/feature", web::post().to(feature_post))
|
.route("/feature", web::post().to(feature_post))
|
||||||
.route("/list", web::get().to(list_posts))
|
.route("/list", web::get().to(list_posts))
|
||||||
.route("/like", web::post().to(like_post))
|
.route("/like", web::post().to(like_post))
|
||||||
.route("/save", web::put().to(route_post::<SavePost>))
|
.route("/save", web::put().to(save_post))
|
||||||
.route("/report", web::post().to(create_post_report))
|
.route("/report", web::post().to(create_post_report))
|
||||||
.route(
|
.route("/report/resolve", web::put().to(resolve_post_report))
|
||||||
"/report/resolve",
|
.route("/report/list", web::get().to(list_post_reports))
|
||||||
web::put().to(route_post::<ResolvePostReport>),
|
.route("/site_metadata", web::get().to(get_link_metadata)),
|
||||||
)
|
|
||||||
.route("/report/list", web::get().to(route_get::<ListPostReports>))
|
|
||||||
.route(
|
|
||||||
"/site_metadata",
|
|
||||||
web::get().to(route_get::<GetSiteMetadata>),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
// Comment
|
// Comment
|
||||||
.service(
|
.service(
|
||||||
|
@ -232,22 +232,10 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("", web::post().to(create_private_message))
|
.route("", web::post().to(create_private_message))
|
||||||
.route("", web::put().to(update_private_message))
|
.route("", web::put().to(update_private_message))
|
||||||
.route("/delete", web::post().to(delete_private_message))
|
.route("/delete", web::post().to(delete_private_message))
|
||||||
.route(
|
.route("/mark_as_read", web::post().to(mark_pm_as_read))
|
||||||
"/mark_as_read",
|
.route("/report", web::post().to(create_pm_report))
|
||||||
web::post().to(route_post::<MarkPrivateMessageAsRead>),
|
.route("/report/resolve", web::put().to(resolve_pm_report))
|
||||||
)
|
.route("/report/list", web::get().to(list_pm_reports)),
|
||||||
.route(
|
|
||||||
"/report",
|
|
||||||
web::post().to(route_post::<CreatePrivateMessageReport>),
|
|
||||||
)
|
|
||||||
.route(
|
|
||||||
"/report/resolve",
|
|
||||||
web::put().to(route_post::<ResolvePrivateMessageReport>),
|
|
||||||
)
|
|
||||||
.route(
|
|
||||||
"/report/list",
|
|
||||||
web::get().to(route_get::<ListPrivateMessageReports>),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
// User
|
// User
|
||||||
.service(
|
.service(
|
||||||
|
@ -262,75 +250,66 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
// Handle captcha separately
|
// Handle captcha separately
|
||||||
web::resource("/user/get_captcha")
|
web::resource("/user/get_captcha")
|
||||||
.wrap(rate_limit.post())
|
.wrap(rate_limit.post())
|
||||||
.route(web::get().to(route_get::<GetCaptcha>)),
|
.route(web::get().to(get_captcha)),
|
||||||
)
|
)
|
||||||
// User actions
|
// User actions
|
||||||
.service(
|
.service(
|
||||||
web::scope("/user")
|
web::scope("/user")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("", web::get().to(read_person))
|
.route("", web::get().to(read_person))
|
||||||
.route("/mention", web::get().to(route_get::<GetPersonMentions>))
|
.route("/mention", web::get().to(list_mentions))
|
||||||
.route(
|
.route(
|
||||||
"/mention/mark_as_read",
|
"/mention/mark_as_read",
|
||||||
web::post().to(route_post::<MarkPersonMentionAsRead>),
|
web::post().to(mark_person_mention_as_read),
|
||||||
)
|
)
|
||||||
.route("/replies", web::get().to(route_get::<GetReplies>))
|
.route("/replies", web::get().to(list_replies))
|
||||||
// Admin action. I don't like that it's in /user
|
// Admin action. I don't like that it's in /user
|
||||||
.route("/ban", web::post().to(ban_from_site))
|
.route("/ban", web::post().to(ban_from_site))
|
||||||
.route("/banned", web::get().to(route_get::<GetBannedPersons>))
|
.route("/banned", web::get().to(list_banned_users))
|
||||||
.route("/block", web::post().to(route_post::<BlockPerson>))
|
.route("/block", web::post().to(block_person))
|
||||||
// Account actions. I don't like that they're in /user maybe /accounts
|
// Account actions. I don't like that they're in /user maybe /accounts
|
||||||
.route("/login", web::post().to(route_post::<Login>))
|
.route("/login", web::post().to(login))
|
||||||
.route("/delete_account", web::post().to(delete_account))
|
.route("/delete_account", web::post().to(delete_account))
|
||||||
.route(
|
.route("/password_reset", web::post().to(reset_password))
|
||||||
"/password_reset",
|
|
||||||
web::post().to(route_post::<PasswordReset>),
|
|
||||||
)
|
|
||||||
.route(
|
.route(
|
||||||
"/password_change",
|
"/password_change",
|
||||||
web::post().to(route_post::<PasswordChangeAfterReset>),
|
web::post().to(change_password_after_reset),
|
||||||
)
|
)
|
||||||
// mark_all_as_read feels off being in this section as well
|
// mark_all_as_read feels off being in this section as well
|
||||||
.route(
|
.route(
|
||||||
"/mark_all_as_read",
|
"/mark_all_as_read",
|
||||||
web::post().to(route_post::<MarkAllAsRead>),
|
web::post().to(mark_all_notifications_read),
|
||||||
)
|
)
|
||||||
.route(
|
.route("/save_user_settings", web::put().to(save_user_settings))
|
||||||
"/save_user_settings",
|
.route("/change_password", web::put().to(change_password))
|
||||||
web::put().to(route_post::<SaveUserSettings>),
|
.route("/report_count", web::get().to(report_count))
|
||||||
)
|
.route("/unread_count", web::get().to(unread_count))
|
||||||
.route(
|
.route("/verify_email", web::post().to(verify_email))
|
||||||
"/change_password",
|
.route("/leave_admin", web::post().to(leave_admin)),
|
||||||
web::put().to(route_post::<ChangePassword>),
|
|
||||||
)
|
|
||||||
.route("/report_count", web::get().to(route_get::<GetReportCount>))
|
|
||||||
.route("/unread_count", web::get().to(route_get::<GetUnreadCount>))
|
|
||||||
.route("/verify_email", web::post().to(route_post::<VerifyEmail>))
|
|
||||||
.route("/leave_admin", web::post().to(route_post::<LeaveAdmin>)),
|
|
||||||
)
|
)
|
||||||
// Admin Actions
|
// Admin Actions
|
||||||
.service(
|
.service(
|
||||||
web::scope("/admin")
|
web::scope("/admin")
|
||||||
.wrap(rate_limit.message())
|
.wrap(rate_limit.message())
|
||||||
.route("/add", web::post().to(route_post::<AddAdmin>))
|
.route("/add", web::post().to(add_admin))
|
||||||
.route(
|
.route(
|
||||||
"/registration_application/count",
|
"/registration_application/count",
|
||||||
web::get().to(route_get::<GetUnreadRegistrationApplicationCount>),
|
web::get().to(get_unread_registration_application_count),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/registration_application/list",
|
"/registration_application/list",
|
||||||
web::get().to(route_get::<ListRegistrationApplications>),
|
web::get().to(list_registration_applications),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/registration_application/approve",
|
"/registration_application/approve",
|
||||||
web::put().to(route_post::<ApproveRegistrationApplication>),
|
web::put().to(approve_registration_application),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/purge")
|
web::scope("/purge")
|
||||||
.route("/person", web::post().to(route_post::<PurgePerson>))
|
.route("/person", web::post().to(purge_person))
|
||||||
.route("/community", web::post().to(route_post::<PurgeCommunity>))
|
.route("/community", web::post().to(purge_community))
|
||||||
.route("/post", web::post().to(route_post::<PurgePost>))
|
.route("/post", web::post().to(purge_post))
|
||||||
.route("/comment", web::post().to(route_post::<PurgeComment>)),
|
.route("/comment", web::post().to(purge_comment)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
|
@ -347,59 +326,3 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("", web::get().to(get_sitemap)),
|
.route("", web::get().to(get_sitemap)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn perform<'a, Data>(
|
|
||||||
data: Data,
|
|
||||||
context: web::Data<LemmyContext>,
|
|
||||||
apub_data: activitypub_federation::config::Data<LemmyContext>,
|
|
||||||
) -> Result<HttpResponse, Error>
|
|
||||||
where
|
|
||||||
Data: Perform
|
|
||||||
+ SendActivity<Response = <Data as Perform>::Response>
|
|
||||||
+ Clone
|
|
||||||
+ Deserialize<'a>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
{
|
|
||||||
let res = data.perform(&context).await?;
|
|
||||||
let res_clone = res.clone();
|
|
||||||
let fed_task = async move { SendActivity::send_activity(&data, &res_clone, &apub_data).await };
|
|
||||||
if *SYNCHRONOUS_FEDERATION {
|
|
||||||
fed_task.await?;
|
|
||||||
} else {
|
|
||||||
spawn_try_task(fed_task);
|
|
||||||
}
|
|
||||||
Ok(HttpResponse::Ok().json(&res))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn route_get<'a, Data>(
|
|
||||||
data: web::Query<Data>,
|
|
||||||
context: web::Data<LemmyContext>,
|
|
||||||
apub_data: activitypub_federation::config::Data<LemmyContext>,
|
|
||||||
) -> Result<HttpResponse, Error>
|
|
||||||
where
|
|
||||||
Data: Perform
|
|
||||||
+ SendActivity<Response = <Data as Perform>::Response>
|
|
||||||
+ Clone
|
|
||||||
+ Deserialize<'a>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
{
|
|
||||||
perform::<Data>(data.0, context, apub_data).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn route_post<'a, Data>(
|
|
||||||
data: web::Json<Data>,
|
|
||||||
context: web::Data<LemmyContext>,
|
|
||||||
apub_data: activitypub_federation::config::Data<LemmyContext>,
|
|
||||||
) -> Result<HttpResponse, Error>
|
|
||||||
where
|
|
||||||
Data: Perform
|
|
||||||
+ SendActivity<Response = <Data as Perform>::Response>
|
|
||||||
+ Clone
|
|
||||||
+ Deserialize<'a>
|
|
||||||
+ Send
|
|
||||||
+ 'static,
|
|
||||||
{
|
|
||||||
perform::<Data>(data.0, context, apub_data).await
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue