2023-09-20 14:49:54 +00:00
|
|
|
use crate::check_totp_2fa_valid;
|
2023-10-09 10:46:12 +00:00
|
|
|
use actix_web::{
|
|
|
|
http::StatusCode,
|
|
|
|
web::{Data, Json},
|
|
|
|
HttpRequest,
|
|
|
|
HttpResponse,
|
|
|
|
};
|
2022-04-13 18:12:25 +00:00
|
|
|
use bcrypt::verify;
|
|
|
|
use lemmy_api_common::{
|
2023-10-09 10:46:12 +00:00
|
|
|
claims::Claims,
|
2022-11-28 14:29:33 +00:00
|
|
|
context::LemmyContext,
|
2022-04-13 18:12:25 +00:00
|
|
|
person::{Login, LoginResponse},
|
2023-10-09 10:46:12 +00:00
|
|
|
utils::{check_user_valid, create_login_cookie},
|
2023-09-21 10:42:28 +00:00
|
|
|
};
|
|
|
|
use lemmy_db_schema::{
|
|
|
|
source::{local_site::LocalSite, registration_application::RegistrationApplication},
|
|
|
|
utils::DbPool,
|
|
|
|
RegistrationMode,
|
2022-04-13 18:12:25 +00:00
|
|
|
};
|
2023-03-02 20:37:41 +00:00
|
|
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
2023-10-09 10:46:12 +00:00
|
|
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-09-05 09:33:46 +00:00
|
|
|
#[tracing::instrument(skip(context))]
|
|
|
|
pub async fn login(
|
|
|
|
data: Json<Login>,
|
2023-10-09 10:46:12 +00:00
|
|
|
req: HttpRequest,
|
2023-09-05 09:33:46 +00:00
|
|
|
context: Data<LemmyContext>,
|
2023-10-09 10:46:12 +00:00
|
|
|
) -> Result<HttpResponse, LemmyError> {
|
2023-09-05 09:33:46 +00:00
|
|
|
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-09-05 09:33:46 +00:00
|
|
|
// Fetch that username / email
|
|
|
|
let username_or_email = data.username_or_email.clone();
|
|
|
|
let local_user_view =
|
|
|
|
LocalUserView::find_by_email_or_name(&mut context.pool(), &username_or_email)
|
|
|
|
.await
|
|
|
|
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-09-05 09:33:46 +00:00
|
|
|
// 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,
|
|
|
|
)?;
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-09-05 09:33:46 +00:00
|
|
|
// 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)?
|
|
|
|
}
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-09-05 09:33:46 +00:00
|
|
|
check_registration_application(&local_user_view, &site_view.local_site, &mut context.pool())
|
|
|
|
.await?;
|
2023-03-02 20:37:41 +00:00
|
|
|
|
2023-09-20 14:49:54 +00:00
|
|
|
// Check the totp if enabled
|
|
|
|
if local_user_view.local_user.totp_2fa_enabled {
|
|
|
|
check_totp_2fa_valid(&local_user_view, &data.totp_2fa_token, &site_view.site.name)?;
|
|
|
|
}
|
2022-04-13 18:12:25 +00:00
|
|
|
|
2023-10-09 10:46:12 +00:00
|
|
|
let jwt = Claims::generate(local_user_view.local_user.id, req, &context).await?;
|
|
|
|
|
|
|
|
let json = LoginResponse {
|
|
|
|
jwt: Some(jwt.clone()),
|
2023-09-05 09:33:46 +00:00
|
|
|
verify_email_sent: false,
|
|
|
|
registration_created: false,
|
2023-10-09 10:46:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut res = HttpResponse::build(StatusCode::OK).json(json);
|
|
|
|
res.add_cookie(&create_login_cookie(jwt))?;
|
|
|
|
Ok(res)
|
2022-04-13 18:12:25 +00:00
|
|
|
}
|
2023-09-21 10:42:28 +00:00
|
|
|
|
|
|
|
async fn check_registration_application(
|
|
|
|
local_user_view: &LocalUserView,
|
|
|
|
local_site: &LocalSite,
|
|
|
|
pool: &mut DbPool<'_>,
|
|
|
|
) -> Result<(), LemmyError> {
|
|
|
|
if (local_site.registration_mode == RegistrationMode::RequireApplication
|
|
|
|
|| local_site.registration_mode == RegistrationMode::Closed)
|
|
|
|
&& !local_user_view.local_user.accepted_application
|
|
|
|
&& !local_user_view.local_user.admin
|
|
|
|
{
|
2023-10-04 13:20:22 +00:00
|
|
|
// Fetch the registration application. If no admin id is present its still pending. Otherwise it
|
|
|
|
// was processed (either accepted or denied).
|
2023-09-21 10:42:28 +00:00
|
|
|
let local_user_id = local_user_view.local_user.id;
|
|
|
|
let registration = RegistrationApplication::find_by_local_user_id(pool, local_user_id).await?;
|
2023-10-04 13:20:22 +00:00
|
|
|
if registration.admin_id.is_some() {
|
|
|
|
Err(LemmyErrorType::RegistrationDenied(registration.deny_reason))?
|
2023-09-21 10:42:28 +00:00
|
|
|
} else {
|
|
|
|
Err(LemmyErrorType::RegistrationApplicationIsPending)?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|