Dont allow login if account is banned or deleted (fixes #2372) (#2374)

This commit is contained in:
Nutomic 2022-07-28 23:14:07 +02:00 committed by GitHub
parent c62671116c
commit b78826c2c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 50 deletions

View File

@ -3,7 +3,7 @@ use actix_web::web::Data;
use bcrypt::verify; use bcrypt::verify;
use lemmy_api_common::{ use lemmy_api_common::{
person::{Login, LoginResponse}, person::{Login, LoginResponse},
utils::{blocking, check_registration_application}, utils::{blocking, check_registration_application, check_user_valid},
}; };
use lemmy_db_schema::source::site::Site; use lemmy_db_schema::source::site::Site;
use lemmy_db_views::structs::LocalUserView; use lemmy_db_views::structs::LocalUserView;
@ -39,6 +39,11 @@ impl Perform for Login {
if !valid { if !valid {
return Err(LemmyError::from_message("password_incorrect")); return Err(LemmyError::from_message("password_incorrect"));
} }
check_user_valid(
local_user_view.person.banned,
local_user_view.person.ban_expires,
local_user_view.person.deleted,
)?;
let site = blocking(context.pool(), Site::read_local_site).await??; let site = blocking(context.pool(), Site::read_local_site).await??;
if site.require_email_verification && !local_user_view.local_user.email_verified { if site.require_email_verification && !local_user_view.local_user.email_verified {

View File

@ -1,5 +1,7 @@
use crate::{request::purge_image_from_pictrs, sensitive::Sensitive, site::FederatedInstances}; use crate::{request::purge_image_from_pictrs, sensitive::Sensitive, site::FederatedInstances};
use chrono::NaiveDateTime;
use lemmy_db_schema::{ use lemmy_db_schema::{
impls::person::is_banned,
newtypes::{CommunityId, LocalUserId, PersonId, PostId}, newtypes::{CommunityId, LocalUserId, PersonId, PostId},
source::{ source::{
comment::Comment, comment::Comment,
@ -129,15 +131,11 @@ pub async fn get_local_user_view_from_jwt(
let local_user_id = LocalUserId(claims.sub); let local_user_id = LocalUserId(claims.sub);
let local_user_view = let local_user_view =
blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??; blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??;
// Check for a site ban check_user_valid(
if local_user_view.person.is_banned() { local_user_view.person.banned,
return Err(LemmyError::from_message("site_ban")); local_user_view.person.ban_expires,
} local_user_view.person.deleted,
)?;
// Check for user deletion
if local_user_view.person.deleted {
return Err(LemmyError::from_message("deleted"));
}
check_validator_time(&local_user_view.local_user.validator_time, &claims)?; check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
@ -146,7 +144,7 @@ pub async fn get_local_user_view_from_jwt(
/// Checks if user's token was issued before user's password reset. /// Checks if user's token was issued before user's password reset.
pub fn check_validator_time( pub fn check_validator_time(
validator_time: &chrono::NaiveDateTime, validator_time: &NaiveDateTime,
claims: &Claims, claims: &Claims,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let user_validation_time = validator_time.timestamp(); let user_validation_time = validator_time.timestamp();
@ -169,30 +167,6 @@ pub async fn get_local_user_view_from_jwt_opt(
} }
} }
#[tracing::instrument(skip_all)]
pub async fn get_local_user_settings_view_from_jwt(
jwt: &Sensitive<String>,
pool: &DbPool,
secret: &Secret,
) -> Result<LocalUserSettingsView, LemmyError> {
let claims = Claims::decode(jwt.as_ref(), &secret.jwt_secret)
.map_err(|e| e.with_message("not_logged_in"))?
.claims;
let local_user_id = LocalUserId(claims.sub);
let local_user_view = blocking(pool, move |conn| {
LocalUserSettingsView::read(conn, local_user_id)
})
.await??;
// Check for a site ban
if local_user_view.person.is_banned() {
return Err(LemmyError::from_message("site_ban"));
}
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
Ok(local_user_view)
}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn get_local_user_settings_view_from_jwt_opt( pub async fn get_local_user_settings_view_from_jwt_opt(
jwt: Option<&Sensitive<String>>, jwt: Option<&Sensitive<String>>,
@ -200,12 +174,45 @@ pub async fn get_local_user_settings_view_from_jwt_opt(
secret: &Secret, secret: &Secret,
) -> Result<Option<LocalUserSettingsView>, LemmyError> { ) -> Result<Option<LocalUserSettingsView>, LemmyError> {
match jwt { match jwt {
Some(jwt) => Ok(Some( Some(jwt) => {
get_local_user_settings_view_from_jwt(jwt, pool, secret).await?, let claims = Claims::decode(jwt.as_ref(), &secret.jwt_secret)
)), .map_err(|e| e.with_message("not_logged_in"))?
.claims;
let local_user_id = LocalUserId(claims.sub);
let local_user_view = blocking(pool, move |conn| {
LocalUserSettingsView::read(conn, local_user_id)
})
.await??;
check_user_valid(
local_user_view.person.banned,
local_user_view.person.ban_expires,
local_user_view.person.deleted,
)?;
check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
Ok(Some(local_user_view))
}
None => Ok(None), None => Ok(None),
} }
} }
pub fn check_user_valid(
banned: bool,
ban_expires: Option<NaiveDateTime>,
deleted: bool,
) -> Result<(), LemmyError> {
// Check for a site ban
if is_banned(banned, ban_expires) {
return Err(LemmyError::from_message("site_ban"));
}
// check for account deletion
if deleted {
return Err(LemmyError::from_message("deleted"));
}
Ok(())
}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn check_community_ban( pub async fn check_community_ban(

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
newtypes::{DbUrl, PersonId}, newtypes::{DbUrl, PersonId},
schema::person::dsl::*, schema::person::dsl::*,
source::person::{Person, PersonForm, PersonSafe}, source::person::{Person, PersonForm},
traits::{ApubActor, Crud}, traits::{ApubActor, Crud},
utils::{functions::lower, naive_now}, utils::{functions::lower, naive_now},
}; };
@ -258,10 +258,6 @@ impl Person {
.get_result::<Self>(conn) .get_result::<Self>(conn)
} }
pub fn is_banned(&self) -> bool {
is_banned(self.banned, self.ban_expires)
}
pub fn leave_admin(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> { pub fn leave_admin(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
diesel::update(person.find(person_id)) diesel::update(person.find(person_id))
.set(admin.eq(false)) .set(admin.eq(false))
@ -278,13 +274,7 @@ impl Person {
} }
} }
impl PersonSafe { pub fn is_banned(banned_: bool, expires: Option<chrono::NaiveDateTime>) -> bool {
pub fn is_banned(&self) -> bool {
is_banned(self.banned, self.ban_expires)
}
}
fn is_banned(banned_: bool, expires: Option<chrono::NaiveDateTime>) -> bool {
if let Some(expires) = expires { if let Some(expires) = expires {
banned_ && expires.gt(&naive_now()) banned_ && expires.gt(&naive_now())
} else { } else {