mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-22 20:31:19 +00:00
Combining mod or admin check with an SQL union.
This commit is contained in:
parent
dde444c1fa
commit
e3da031b61
2 changed files with 52 additions and 10 deletions
|
@ -186,15 +186,16 @@ pub async fn check_is_higher_mod_or_admin(
|
|||
community_id: CommunityId,
|
||||
target_person_ids: &[PersonId],
|
||||
) -> LemmyResult<()> {
|
||||
let higher_admin_check = check_is_higher_admin(pool, local_user_view, target_person_ids).await;
|
||||
let higher_mod_check =
|
||||
check_is_higher_mod(pool, local_user_view, community_id, target_person_ids).await;
|
||||
LocalUser::is_higher_mod_or_admin_check(
|
||||
pool,
|
||||
community_id,
|
||||
local_user_view.person.id,
|
||||
target_person_ids,
|
||||
)
|
||||
.await
|
||||
.with_lemmy_type(LemmyErrorType::NotHigherMod)?;
|
||||
|
||||
if higher_mod_check.is_ok() || higher_admin_check.is_ok() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(LemmyErrorType::NotHigherMod)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Marks a post as read for a given person.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
newtypes::{DbUrl, LanguageId, LocalUserId, PersonId},
|
||||
schema::{local_user, person, registration_application},
|
||||
newtypes::{CommunityId, DbUrl, LanguageId, LocalUserId, PersonId},
|
||||
schema::{community_moderator, local_user, person, registration_application},
|
||||
source::{
|
||||
actor_language::LocalUserLanguage,
|
||||
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
||||
|
@ -18,6 +18,7 @@ use bcrypt::{hash, DEFAULT_COST};
|
|||
use diesel::{
|
||||
dsl::{insert_into, not, IntervalDsl},
|
||||
result::Error,
|
||||
CombineDsl,
|
||||
ExpressionMethods,
|
||||
JoinOnDsl,
|
||||
QueryDsl,
|
||||
|
@ -244,6 +245,46 @@ impl LocalUser {
|
|||
Err(diesel::result::Error::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks to make sure the acting moderator is higher than the target moderator
|
||||
pub async fn is_higher_mod_or_admin_check(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_community_id: CommunityId,
|
||||
admin_person_id: PersonId,
|
||||
target_person_ids: &[PersonId],
|
||||
) -> Result<(), Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
// Build the list of persons
|
||||
let mut persons = target_person_ids.to_owned();
|
||||
persons.push(admin_person_id);
|
||||
persons.dedup();
|
||||
|
||||
let admins = local_user::table
|
||||
.filter(local_user::admin.eq(true))
|
||||
.filter(local_user::person_id.eq_any(&persons))
|
||||
.order_by(local_user::id)
|
||||
.select(local_user::person_id);
|
||||
|
||||
let mods = community_moderator::table
|
||||
.filter(community_moderator::community_id.eq(for_community_id))
|
||||
.filter(community_moderator::person_id.eq_any(&persons))
|
||||
.order_by(community_moderator::published)
|
||||
.select(community_moderator::person_id);
|
||||
|
||||
let res = admins.union_all(mods).get_results::<PersonId>(conn).await?;
|
||||
let first_person = res
|
||||
.as_slice()
|
||||
.first()
|
||||
.ok_or(diesel::result::Error::NotFound)?;
|
||||
|
||||
// If the first result sorted by published is the acting mod
|
||||
if *first_person == admin_person_id {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(diesel::result::Error::NotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds some helper functions for an optional LocalUser
|
||||
|
|
Loading…
Reference in a new issue