mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-27 18:30:31 +00:00
Removing a few more Result<bool> . (#4977)
* Removing a few more Result<bool> . * Running taplo fmt. * Running fmt. * Adding email taken test. * Fixing tests. * Adding back in missing admin check. * Rename check_has_local_followers function.
This commit is contained in:
parent
62e1790ae7
commit
d476d32200
25 changed files with 182 additions and 220 deletions
|
@ -21,16 +21,16 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^22.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
||||
"@typescript-eslint/parser": "^8.0.0",
|
||||
"eslint": "^9.8.0",
|
||||
"@types/node": "^22.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.1.0",
|
||||
"@typescript-eslint/parser": "^8.1.0",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"jest": "^29.5.0",
|
||||
"lemmy-js-client": "0.20.0-alpha.11",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.5.4",
|
||||
"typescript-eslint": "^8.0.0"
|
||||
"typescript-eslint": "^8.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,16 +12,16 @@ importers:
|
|||
specifier: ^29.5.12
|
||||
version: 29.5.12
|
||||
'@types/node':
|
||||
specifier: ^22.0.2
|
||||
specifier: ^22.3.0
|
||||
version: 22.3.0
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.0.0
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0)(typescript@5.5.4))(eslint@9.9.0)(typescript@5.5.4)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.0.0
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
||||
eslint:
|
||||
specifier: ^9.8.0
|
||||
specifier: ^9.9.0
|
||||
version: 9.9.0
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^5.1.3
|
||||
|
@ -42,7 +42,7 @@ importers:
|
|||
specifier: ^5.5.4
|
||||
version: 5.5.4
|
||||
typescript-eslint:
|
||||
specifier: ^8.0.0
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0(eslint@9.9.0)(typescript@5.5.4)
|
||||
|
||||
packages:
|
||||
|
|
|
@ -628,7 +628,7 @@ test("Enforce community ban for federated user", async () => {
|
|||
// Alpha tries to make post on beta, but it fails because of ban
|
||||
await expect(
|
||||
createPost(alpha, betaCommunity.community.id),
|
||||
).rejects.toStrictEqual(Error("banned_from_community"));
|
||||
).rejects.toStrictEqual(Error("person_is_banned_from_community"));
|
||||
|
||||
// Unban alpha
|
||||
let unBanAlpha = await banPersonFromCommunity(
|
||||
|
|
|
@ -52,15 +52,12 @@ pub async fn add_mod_to_community(
|
|||
// moderator. This is necessary because otherwise the action would be rejected
|
||||
// by the community's home instance.
|
||||
if local_user_view.local_user.admin && !community.local {
|
||||
let is_mod = CommunityModeratorView::is_community_moderator(
|
||||
CommunityModeratorView::check_is_community_moderator(
|
||||
&mut context.pool(),
|
||||
community.id,
|
||||
local_user_view.person.id,
|
||||
)
|
||||
.await?;
|
||||
if !is_mod {
|
||||
Err(LemmyErrorType::NotAModerator)?
|
||||
}
|
||||
}
|
||||
|
||||
// Update in local database
|
||||
|
|
|
@ -63,9 +63,7 @@ pub async fn save_user_settings(
|
|||
let previous_email = local_user_view.local_user.email.clone().unwrap_or_default();
|
||||
// if email was changed, check that it is not taken and send verification mail
|
||||
if previous_email.deref() != email {
|
||||
if LocalUser::is_email_taken(&mut context.pool(), email).await? {
|
||||
return Err(LemmyErrorType::EmailAlreadyExists)?;
|
||||
}
|
||||
LocalUser::check_is_email_taken(&mut context.pool(), email).await?;
|
||||
send_verification_email(
|
||||
&local_user_view,
|
||||
email,
|
||||
|
|
|
@ -29,12 +29,8 @@ impl Claims {
|
|||
let claims =
|
||||
decode::<Claims>(jwt, &key, &validation).with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
||||
let user_id = LocalUserId(claims.claims.sub.parse()?);
|
||||
let is_valid = LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
||||
if !is_valid {
|
||||
Err(LemmyErrorType::NotLoggedIn)?
|
||||
} else {
|
||||
Ok(user_id)
|
||||
}
|
||||
LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
||||
Ok(user_id)
|
||||
}
|
||||
|
||||
pub async fn generate(
|
||||
|
|
|
@ -73,13 +73,7 @@ pub async fn is_mod_or_admin(
|
|||
community_id: CommunityId,
|
||||
) -> LemmyResult<()> {
|
||||
check_user_valid(person)?;
|
||||
|
||||
let is_mod_or_admin = CommunityView::is_mod_or_admin(pool, person.id, community_id).await?;
|
||||
if !is_mod_or_admin {
|
||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
CommunityView::check_is_mod_or_admin(pool, person.id, community_id).await
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
|
@ -110,13 +104,7 @@ pub async fn check_community_mod_of_any_or_admin_action(
|
|||
let person = &local_user_view.person;
|
||||
|
||||
check_user_valid(person)?;
|
||||
|
||||
let is_mod_of_any_or_admin = CommunityView::is_mod_of_any_or_admin(pool, person.id).await?;
|
||||
if !is_mod_of_any_or_admin {
|
||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
CommunityView::check_is_mod_of_any_or_admin(pool, person.id).await
|
||||
}
|
||||
|
||||
pub fn is_admin(local_user_view: &LocalUserView) -> LemmyResult<()> {
|
||||
|
@ -242,7 +230,7 @@ pub async fn check_community_user_action(
|
|||
) -> LemmyResult<()> {
|
||||
check_user_valid(person)?;
|
||||
check_community_deleted_removed(community_id, pool).await?;
|
||||
check_community_ban(person, community_id, pool).await?;
|
||||
CommunityPersonBanView::check(pool, person.id, community_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -257,19 +245,6 @@ async fn check_community_deleted_removed(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn check_community_ban(
|
||||
person: &Person,
|
||||
community_id: CommunityId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
// check if user was banned from site or community
|
||||
let is_banned = CommunityPersonBanView::get(pool, person.id, community_id).await?;
|
||||
if is_banned {
|
||||
Err(LemmyErrorType::BannedFromCommunity)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check that the given user can perform a mod action in the community.
|
||||
///
|
||||
/// In particular it checks that he is an admin or mod, wasn't banned and the community isn't
|
||||
|
@ -281,7 +256,7 @@ pub async fn check_community_mod_action(
|
|||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
is_mod_or_admin(pool, person, community_id).await?;
|
||||
check_community_ban(person, community_id, pool).await?;
|
||||
CommunityPersonBanView::check(pool, person.id, community_id).await?;
|
||||
|
||||
// it must be possible to restore deleted community
|
||||
if !allow_deleted {
|
||||
|
@ -307,51 +282,6 @@ pub fn check_comment_deleted_or_removed(comment: &Comment) -> LemmyResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Throws an error if a recipient has blocked a person.
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn check_person_block(
|
||||
my_id: PersonId,
|
||||
potential_blocker_id: PersonId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
let is_blocked = PersonBlock::read(pool, potential_blocker_id, my_id).await?;
|
||||
if is_blocked {
|
||||
Err(LemmyErrorType::PersonIsBlocked)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Throws an error if a recipient has blocked a community.
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn check_community_block(
|
||||
community_id: CommunityId,
|
||||
person_id: PersonId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
let is_blocked = CommunityBlock::read(pool, person_id, community_id).await?;
|
||||
if is_blocked {
|
||||
Err(LemmyErrorType::CommunityIsBlocked)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Throws an error if a recipient has blocked an instance.
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn check_instance_block(
|
||||
instance_id: InstanceId,
|
||||
person_id: PersonId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
let is_blocked = InstanceBlock::read(pool, person_id, instance_id).await?;
|
||||
if is_blocked {
|
||||
Err(LemmyErrorType::InstanceIsBlocked)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn check_person_instance_community_block(
|
||||
my_id: PersonId,
|
||||
|
@ -360,9 +290,9 @@ pub async fn check_person_instance_community_block(
|
|||
community_id: CommunityId,
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<()> {
|
||||
check_person_block(my_id, potential_blocker_id, pool).await?;
|
||||
check_instance_block(community_instance_id, potential_blocker_id, pool).await?;
|
||||
check_community_block(community_id, potential_blocker_id, pool).await?;
|
||||
PersonBlock::read(pool, potential_blocker_id, my_id).await?;
|
||||
InstanceBlock::read(pool, potential_blocker_id, community_instance_id).await?;
|
||||
CommunityBlock::read(pool, potential_blocker_id, community_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -95,15 +95,12 @@ pub async fn create_post(
|
|||
let community = Community::read(&mut context.pool(), community_id).await?;
|
||||
if community.posting_restricted_to_mods {
|
||||
let community_id = data.community_id;
|
||||
let is_mod = CommunityModeratorView::is_community_moderator(
|
||||
CommunityModeratorView::check_is_community_moderator(
|
||||
&mut context.pool(),
|
||||
community_id,
|
||||
local_user_view.local_user.person_id,
|
||||
)
|
||||
.await?;
|
||||
if !is_mod {
|
||||
Err(LemmyErrorType::OnlyModsCanPostInCommunity)?
|
||||
}
|
||||
}
|
||||
|
||||
// Only need to check if language is allowed in case user set it explicitly. When using default
|
||||
|
|
|
@ -5,7 +5,6 @@ use lemmy_api_common::{
|
|||
private_message::{CreatePrivateMessage, PrivateMessageResponse},
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{
|
||||
check_person_block,
|
||||
get_interface_language,
|
||||
get_url_blocklist,
|
||||
local_site_to_slur_regex,
|
||||
|
@ -16,6 +15,7 @@ use lemmy_api_common::{
|
|||
use lemmy_db_schema::{
|
||||
source::{
|
||||
local_site::LocalSite,
|
||||
person_block::PersonBlock,
|
||||
private_message::{PrivateMessage, PrivateMessageInsertForm},
|
||||
},
|
||||
traits::Crud,
|
||||
|
@ -39,10 +39,10 @@ pub async fn create_private_message(
|
|||
let content = process_markdown(&data.content, &slur_regex, &url_blocklist, &context).await?;
|
||||
is_valid_body_field(&content, false)?;
|
||||
|
||||
check_person_block(
|
||||
local_user_view.person.id,
|
||||
data.recipient_id,
|
||||
PersonBlock::read(
|
||||
&mut context.pool(),
|
||||
data.recipient_id,
|
||||
local_user_view.person.id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
|
@ -92,22 +92,15 @@ pub async fn register(
|
|||
}
|
||||
|
||||
if local_site.site_setup && local_site.captcha_enabled {
|
||||
if let Some(captcha_uuid) = &data.captcha_uuid {
|
||||
let uuid = uuid::Uuid::parse_str(captcha_uuid)?;
|
||||
let check = CaptchaAnswer::check_captcha(
|
||||
&mut context.pool(),
|
||||
CheckCaptchaAnswer {
|
||||
uuid,
|
||||
answer: data.captcha_answer.clone().unwrap_or_default(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
if !check {
|
||||
Err(LemmyErrorType::CaptchaIncorrect)?
|
||||
}
|
||||
} else {
|
||||
Err(LemmyErrorType::CaptchaIncorrect)?
|
||||
}
|
||||
let uuid = uuid::Uuid::parse_str(&data.captcha_uuid.clone().unwrap_or_default())?;
|
||||
CaptchaAnswer::check_captcha(
|
||||
&mut context.pool(),
|
||||
CheckCaptchaAnswer {
|
||||
uuid,
|
||||
answer: data.captcha_answer.clone().unwrap_or_default(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||
|
@ -119,9 +112,7 @@ pub async fn register(
|
|||
}
|
||||
|
||||
if let Some(email) = &data.email {
|
||||
if LocalUser::is_email_taken(&mut context.pool(), email).await? {
|
||||
Err(LemmyErrorType::EmailAlreadyExists)?
|
||||
}
|
||||
LocalUser::check_is_email_taken(&mut context.pool(), email).await?;
|
||||
}
|
||||
|
||||
// We have to create both a person, and local_user
|
||||
|
|
|
@ -213,15 +213,13 @@ async fn can_accept_activity_in_community(
|
|||
context: &Data<LemmyContext>,
|
||||
) -> LemmyResult<()> {
|
||||
if let Some(community) = community {
|
||||
if !community.local
|
||||
&& !CommunityFollower::has_local_followers(&mut context.pool(), community.id).await?
|
||||
{
|
||||
Err(LemmyErrorType::CommunityHasNoFollowers)?
|
||||
}
|
||||
// Local only community can't federate
|
||||
if community.visibility != CommunityVisibility::Public {
|
||||
return Err(LemmyErrorType::NotFound.into());
|
||||
}
|
||||
if !community.local {
|
||||
CommunityFollower::check_has_local_followers(&mut context.pool(), community.id).await?
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -87,12 +87,7 @@ pub(crate) async fn verify_person_in_community(
|
|||
}
|
||||
let person_id = person.id;
|
||||
let community_id = community.id;
|
||||
let is_banned = CommunityPersonBanView::get(&mut context.pool(), person_id, community_id).await?;
|
||||
if is_banned {
|
||||
Err(LemmyErrorType::PersonIsBannedFromCommunity)?
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
CommunityPersonBanView::check(&mut context.pool(), person_id, community_id).await
|
||||
}
|
||||
|
||||
/// Verify that mod action in community was performed by a moderator.
|
||||
|
@ -106,14 +101,6 @@ pub(crate) async fn verify_mod_action(
|
|||
community: &Community,
|
||||
context: &Data<LemmyContext>,
|
||||
) -> LemmyResult<()> {
|
||||
let mod_ = mod_id.dereference(context).await?;
|
||||
|
||||
let is_mod_or_admin =
|
||||
CommunityView::is_mod_or_admin(&mut context.pool(), mod_.id, community.id).await?;
|
||||
if is_mod_or_admin {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// mod action comes from the same instance as the community, so it was presumably done
|
||||
// by an instance admin.
|
||||
// TODO: federate instance admin status and check it here
|
||||
|
@ -121,7 +108,8 @@ pub(crate) async fn verify_mod_action(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
Err(LemmyErrorType::NotAModerator)?
|
||||
let mod_ = mod_id.dereference(context).await?;
|
||||
CommunityView::check_is_mod_or_admin(&mut context.pool(), mod_.id, community.id).await
|
||||
}
|
||||
|
||||
pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> {
|
||||
|
|
|
@ -39,7 +39,7 @@ use lemmy_db_schema::{
|
|||
};
|
||||
use lemmy_db_views_actor::structs::CommunityModeratorView;
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyErrorType, LemmyResult},
|
||||
error::{LemmyError, LemmyResult},
|
||||
spawn_try_task,
|
||||
utils::{
|
||||
markdown::markdown_to_html,
|
||||
|
@ -180,15 +180,12 @@ impl Object for ApubPost {
|
|||
let creator = page.creator()?.dereference(context).await?;
|
||||
let community = page.community(context).await?;
|
||||
if community.posting_restricted_to_mods {
|
||||
let is_mod = CommunityModeratorView::is_community_moderator(
|
||||
CommunityModeratorView::check_is_community_moderator(
|
||||
&mut context.pool(),
|
||||
community.id,
|
||||
creator.id,
|
||||
)
|
||||
.await?;
|
||||
if !is_mod {
|
||||
Err(LemmyErrorType::OnlyModsCanPostInCommunity)?
|
||||
}
|
||||
}
|
||||
let mut name = page
|
||||
.name
|
||||
|
|
|
@ -15,12 +15,13 @@ use activitypub_federation::{
|
|||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{check_person_block, get_url_blocklist, local_site_opt_to_slur_regex, process_markdown},
|
||||
utils::{get_url_blocklist, local_site_opt_to_slur_regex, process_markdown},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
local_site::LocalSite,
|
||||
person::Person,
|
||||
person_block::PersonBlock,
|
||||
private_message::{PrivateMessage, PrivateMessageInsertForm},
|
||||
},
|
||||
traits::Crud,
|
||||
|
@ -126,7 +127,7 @@ impl Object for ApubPrivateMessage {
|
|||
) -> LemmyResult<ApubPrivateMessage> {
|
||||
let creator = note.attributed_to.dereference(context).await?;
|
||||
let recipient = note.to[0].dereference(context).await?;
|
||||
check_person_block(creator.id, recipient.id, &mut context.pool()).await?;
|
||||
PersonBlock::read(&mut context.pool(), recipient.id, creator.id).await?;
|
||||
|
||||
let local_site = LocalSite::read(&mut context.pool()).await.ok();
|
||||
let slur_regex = &local_site_opt_to_slur_regex(&local_site);
|
||||
|
|
|
@ -13,6 +13,7 @@ use diesel::{
|
|||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl CaptchaAnswer {
|
||||
pub async fn insert(pool: &mut DbPool<'_>, captcha: &CaptchaAnswerForm) -> Result<Self, Error> {
|
||||
|
@ -27,7 +28,7 @@ impl CaptchaAnswer {
|
|||
pub async fn check_captcha(
|
||||
pool: &mut DbPool<'_>,
|
||||
to_check: CheckCaptchaAnswer,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
// fetch requested captcha
|
||||
|
@ -43,7 +44,9 @@ impl CaptchaAnswer {
|
|||
.execute(conn)
|
||||
.await?;
|
||||
|
||||
Ok(captcha_exists)
|
||||
captcha_exists
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::CaptchaIncorrect.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +86,6 @@ mod tests {
|
|||
.await;
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert!(result.unwrap());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -119,7 +121,6 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
assert!(result_repeat.is_ok());
|
||||
assert!(!result_repeat.unwrap());
|
||||
assert!(result_repeat.is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,7 @@ use crate::{
|
|||
use chrono::{DateTime, Utc};
|
||||
use diesel::{
|
||||
deserialize,
|
||||
dsl,
|
||||
dsl::{exists, insert_into},
|
||||
dsl::{self, exists, insert_into},
|
||||
pg::Pg,
|
||||
result::Error,
|
||||
select,
|
||||
|
@ -320,16 +319,18 @@ impl CommunityFollower {
|
|||
|
||||
/// Check if a remote instance has any followers on local instance. For this it is enough to check
|
||||
/// if any follow relation is stored. Dont use this for local community.
|
||||
pub async fn has_local_followers(
|
||||
pub async fn check_has_local_followers(
|
||||
pool: &mut DbPool<'_>,
|
||||
remote_community_id: CommunityId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(community_follower::table.filter(
|
||||
community_follower::community_id.eq(remote_community_id),
|
||||
)))
|
||||
.get_result(conn)
|
||||
.await
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::CommunityHasNoFollowers.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,26 +9,29 @@ use crate::{
|
|||
utils::{get_conn, DbPool},
|
||||
};
|
||||
use diesel::{
|
||||
dsl::{exists, insert_into},
|
||||
dsl::{exists, insert_into, not},
|
||||
result::Error,
|
||||
select,
|
||||
ExpressionMethods,
|
||||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl CommunityBlock {
|
||||
pub async fn read(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_person_id: PersonId,
|
||||
for_community_id: CommunityId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
select(not(exists(
|
||||
community_block::table.find((for_person_id, for_community_id)),
|
||||
))
|
||||
.get_result(conn)
|
||||
.await
|
||||
)))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::CommunityIsBlocked.into())
|
||||
}
|
||||
|
||||
pub async fn for_person(
|
||||
|
|
|
@ -9,26 +9,29 @@ use crate::{
|
|||
utils::{get_conn, DbPool},
|
||||
};
|
||||
use diesel::{
|
||||
dsl::{exists, insert_into},
|
||||
dsl::{exists, insert_into, not},
|
||||
result::Error,
|
||||
select,
|
||||
ExpressionMethods,
|
||||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl InstanceBlock {
|
||||
pub async fn read(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_person_id: PersonId,
|
||||
for_instance_id: InstanceId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
select(not(exists(
|
||||
instance_block::table.find((for_person_id, for_instance_id)),
|
||||
))
|
||||
.get_result(conn)
|
||||
.await
|
||||
)))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::InstanceIsBlocked.into())
|
||||
}
|
||||
|
||||
pub async fn for_person(
|
||||
|
|
|
@ -136,14 +136,16 @@ impl LocalUser {
|
|||
diesel::delete(persons).execute(conn).await
|
||||
}
|
||||
|
||||
pub async fn is_email_taken(pool: &mut DbPool<'_>, email: &str) -> Result<bool, Error> {
|
||||
pub async fn check_is_email_taken(pool: &mut DbPool<'_>, email: &str) -> LemmyResult<()> {
|
||||
use diesel::dsl::{exists, select};
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(local_user::table.filter(
|
||||
select(not(exists(local_user::table.filter(
|
||||
lower(coalesce(local_user::email, "")).eq(email.to_lowercase()),
|
||||
)))
|
||||
.get_result(conn)
|
||||
.await
|
||||
))))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::EmailAlreadyExists.into())
|
||||
}
|
||||
|
||||
// TODO: maybe move this and pass in LocalUserView
|
||||
|
@ -419,4 +421,32 @@ mod tests {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_email_taken() -> LemmyResult<()> {
|
||||
let pool = &build_db_pool_for_tests().await;
|
||||
let pool = &mut pool.into();
|
||||
|
||||
let darwin_email = "charles.darwin@gmail.com";
|
||||
|
||||
let inserted_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()).await?;
|
||||
|
||||
let darwin_person = PersonInsertForm::test_form(inserted_instance.id, "darwin");
|
||||
let inserted_darwin_person = Person::create(pool, &darwin_person).await?;
|
||||
|
||||
let mut darwin_local_user_form =
|
||||
LocalUserInsertForm::test_form_admin(inserted_darwin_person.id);
|
||||
darwin_local_user_form.email = Some(darwin_email.into());
|
||||
let _inserted_darwin_local_user =
|
||||
LocalUser::create(pool, &darwin_local_user_form, vec![]).await?;
|
||||
|
||||
let check = LocalUser::check_is_email_taken(pool, darwin_email).await;
|
||||
assert!(check.is_err());
|
||||
|
||||
let passed_check = LocalUser::check_is_email_taken(pool, "not_charles@gmail.com").await;
|
||||
assert!(passed_check.is_ok());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
|||
};
|
||||
use diesel::{delete, dsl::exists, insert_into, result::Error, select};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl LoginToken {
|
||||
pub async fn create(pool: &mut DbPool<'_>, form: LoginTokenCreateForm) -> Result<Self, Error> {
|
||||
|
@ -22,13 +23,15 @@ impl LoginToken {
|
|||
pool: &mut DbPool<'_>,
|
||||
user_id_: LocalUserId,
|
||||
token_: &str,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
login_token.find(token_).filter(user_id.eq(user_id_)),
|
||||
))
|
||||
.get_result(conn)
|
||||
.await
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::NotLoggedIn.into())
|
||||
}
|
||||
|
||||
pub async fn list(
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
utils::{get_conn, DbPool},
|
||||
};
|
||||
use diesel::{
|
||||
dsl::{exists, insert_into},
|
||||
dsl::{exists, insert_into, not},
|
||||
result::Error,
|
||||
select,
|
||||
ExpressionMethods,
|
||||
|
@ -17,19 +17,22 @@ use diesel::{
|
|||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl PersonBlock {
|
||||
pub async fn read(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_person_id: PersonId,
|
||||
for_recipient_id: PersonId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
select(not(exists(
|
||||
person_block::table.find((for_person_id, for_recipient_id)),
|
||||
))
|
||||
.get_result(conn)
|
||||
.await
|
||||
)))
|
||||
.get_result::<bool>(conn)
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::PersonIsBlocked.into())
|
||||
}
|
||||
|
||||
pub async fn for_person(
|
||||
|
|
|
@ -15,7 +15,13 @@ doctest = false
|
|||
workspace = true
|
||||
|
||||
[features]
|
||||
full = ["lemmy_db_schema/full", "diesel", "diesel-async", "ts-rs"]
|
||||
full = [
|
||||
"lemmy_db_schema/full",
|
||||
"lemmy_utils/full",
|
||||
"diesel",
|
||||
"diesel-async",
|
||||
"ts-rs",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
lemmy_db_schema = { workspace = true }
|
||||
|
@ -33,6 +39,7 @@ serde_with = { workspace = true }
|
|||
ts-rs = { workspace = true, optional = true }
|
||||
chrono.workspace = true
|
||||
strum = { workspace = true }
|
||||
lemmy_utils = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = { workspace = true }
|
||||
|
|
|
@ -8,13 +8,14 @@ use lemmy_db_schema::{
|
|||
source::local_user::LocalUser,
|
||||
utils::{get_conn, DbPool},
|
||||
};
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl CommunityModeratorView {
|
||||
pub async fn is_community_moderator(
|
||||
pub async fn check_is_community_moderator(
|
||||
pool: &mut DbPool<'_>,
|
||||
find_community_id: CommunityId,
|
||||
find_person_id: PersonId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
use lemmy_db_schema::schema::community_moderator::dsl::{
|
||||
community_id,
|
||||
community_moderator,
|
||||
|
@ -27,20 +28,24 @@ impl CommunityModeratorView {
|
|||
.filter(person_id.eq(find_person_id)),
|
||||
))
|
||||
.get_result::<bool>(conn)
|
||||
.await
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::NotAModerator.into())
|
||||
}
|
||||
|
||||
pub(crate) async fn is_community_moderator_of_any(
|
||||
pool: &mut DbPool<'_>,
|
||||
find_person_id: PersonId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
use lemmy_db_schema::schema::community_moderator::dsl::{community_moderator, person_id};
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
community_moderator.filter(person_id.eq(find_person_id)),
|
||||
))
|
||||
.get_result::<bool>(conn)
|
||||
.await
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::NotAModerator.into())
|
||||
}
|
||||
|
||||
pub async fn for_community(
|
||||
|
|
|
@ -1,25 +1,33 @@
|
|||
use crate::structs::CommunityPersonBanView;
|
||||
use diesel::{dsl::exists, result::Error, select, ExpressionMethods, QueryDsl};
|
||||
use diesel::{
|
||||
dsl::{exists, not},
|
||||
select,
|
||||
ExpressionMethods,
|
||||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommunityId, PersonId},
|
||||
schema::community_person_ban,
|
||||
utils::{get_conn, DbPool},
|
||||
};
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
impl CommunityPersonBanView {
|
||||
pub async fn get(
|
||||
pub async fn check(
|
||||
pool: &mut DbPool<'_>,
|
||||
from_person_id: PersonId,
|
||||
from_community_id: CommunityId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
select(exists(
|
||||
select(not(exists(
|
||||
community_person_ban::table
|
||||
.filter(community_person_ban::community_id.eq(from_community_id))
|
||||
.filter(community_person_ban::person_id.eq(from_person_id)),
|
||||
))
|
||||
)))
|
||||
.get_result::<bool>(conn)
|
||||
.await
|
||||
.await?
|
||||
.then_some(())
|
||||
.ok_or(LemmyErrorType::PersonIsBannedFromCommunity.into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use lemmy_db_schema::{
|
|||
ListingType,
|
||||
PostSortType,
|
||||
};
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
|
||||
fn queries<'a>() -> Queries<
|
||||
impl ReadFn<'a, CommunityView, (CommunityId, Option<&'a LocalUser>, bool)>,
|
||||
|
@ -185,35 +186,39 @@ impl CommunityView {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn is_mod_or_admin(
|
||||
pub async fn check_is_mod_or_admin(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
community_id: CommunityId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let is_mod =
|
||||
CommunityModeratorView::is_community_moderator(pool, community_id, person_id).await?;
|
||||
if is_mod {
|
||||
Ok(true)
|
||||
} else if let Ok(person_view) = PersonView::read(pool, person_id).await {
|
||||
Ok(person_view.is_admin)
|
||||
CommunityModeratorView::check_is_community_moderator(pool, community_id, person_id).await;
|
||||
if is_mod.is_ok()
|
||||
|| PersonView::read(pool, person_id)
|
||||
.await
|
||||
.is_ok_and(|t| t.is_admin)
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(false)
|
||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if a person is an admin, or moderator of any community.
|
||||
pub async fn is_mod_of_any_or_admin(
|
||||
pub async fn check_is_mod_of_any_or_admin(
|
||||
pool: &mut DbPool<'_>,
|
||||
person_id: PersonId,
|
||||
) -> Result<bool, Error> {
|
||||
) -> LemmyResult<()> {
|
||||
let is_mod_of_any =
|
||||
CommunityModeratorView::is_community_moderator_of_any(pool, person_id).await?;
|
||||
if is_mod_of_any {
|
||||
Ok(true)
|
||||
} else if let Ok(person_view) = PersonView::read(pool, person_id).await {
|
||||
Ok(person_view.is_admin)
|
||||
CommunityModeratorView::is_community_moderator_of_any(pool, person_id).await;
|
||||
if is_mod_of_any.is_ok()
|
||||
|| PersonView::read(pool, person_id)
|
||||
.await
|
||||
.is_ok_and(|t| t.is_admin)
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(false)
|
||||
Err(LemmyErrorType::NotAModOrAdmin)?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue