* Dont ignore errors during login (fixes #4319) * fix test * fmt
This commit is contained in:
parent
abe8b18ea8
commit
4163e0465e
6 changed files with 37 additions and 45 deletions
|
@ -112,18 +112,19 @@ test("Delete user", async () => {
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Requests with invalid auth should be treated as unauthenticated", async () => {
|
test("Requests with invalid auth should throw error", async () => {
|
||||||
let invalid_auth = new LemmyHttp(alphaUrl, {
|
let invalid_auth = new LemmyHttp(alphaUrl, {
|
||||||
headers: { Authorization: "Bearer foobar" },
|
headers: { Authorization: "Bearer foobar" },
|
||||||
fetchFunction,
|
fetchFunction,
|
||||||
});
|
});
|
||||||
let site = await getSite(invalid_auth);
|
await expect(getSite(invalid_auth)).rejects.toStrictEqual(
|
||||||
expect(site.my_user).toBeUndefined();
|
Error("incorrect_login"),
|
||||||
expect(site.site_view).toBeDefined();
|
);
|
||||||
|
|
||||||
let form: GetPosts = {};
|
let form: GetPosts = {};
|
||||||
let posts = invalid_auth.getPosts(form);
|
await expect(invalid_auth.getPosts(form)).rejects.toStrictEqual(
|
||||||
expect((await posts).posts).toBeDefined();
|
Error("incorrect_login"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Create user with Arabic name", async () => {
|
test("Create user with Arabic name", async () => {
|
||||||
|
|
|
@ -2,15 +2,11 @@ use actix_web::{http::header::Header, HttpRequest};
|
||||||
use actix_web_httpauth::headers::authorization::{Authorization, Bearer};
|
use actix_web_httpauth::headers::authorization::{Authorization, Bearer};
|
||||||
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::{
|
use lemmy_api_common::utils::{local_site_to_slur_regex, AUTH_COOKIE_NAME};
|
||||||
claims::Claims,
|
|
||||||
context::LemmyContext,
|
|
||||||
utils::{check_user_valid, local_site_to_slur_regex, AUTH_COOKIE_NAME},
|
|
||||||
};
|
|
||||||
use lemmy_db_schema::source::local_site::LocalSite;
|
use lemmy_db_schema::source::local_site::LocalSite;
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
error::{LemmyError, LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||||
utils::slurs::check_slurs,
|
utils::slurs::check_slurs,
|
||||||
};
|
};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
@ -141,20 +137,6 @@ pub(crate) fn build_totp_2fa(
|
||||||
.with_lemmy_type(LemmyErrorType::CouldntGenerateTotp)
|
.with_lemmy_type(LemmyErrorType::CouldntGenerateTotp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub async fn local_user_view_from_jwt(
|
|
||||||
jwt: &str,
|
|
||||||
context: &LemmyContext,
|
|
||||||
) -> Result<LocalUserView, LemmyError> {
|
|
||||||
let local_user_id = Claims::validate(jwt, context)
|
|
||||||
.await
|
|
||||||
.with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
|
||||||
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
|
||||||
check_user_valid(&local_user_view.person)?;
|
|
||||||
|
|
||||||
Ok(local_user_view)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{local_user_view_from_jwt, read_auth_token};
|
use crate::read_auth_token;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
web::{Data, Json},
|
web::{Data, Json},
|
||||||
HttpRequest,
|
HttpRequest,
|
||||||
};
|
};
|
||||||
use lemmy_api_common::{context::LemmyContext, SuccessResponse};
|
use lemmy_api_common::{claims::Claims, context::LemmyContext, SuccessResponse};
|
||||||
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType};
|
||||||
|
|
||||||
/// Returns an error message if the auth token is invalid for any reason. Necessary because other
|
/// Returns an error message if the auth token is invalid for any reason. Necessary because other
|
||||||
/// endpoints silently treat any call with invalid auth as unauthenticated.
|
/// endpoints silently treat any call with invalid auth as unauthenticated.
|
||||||
|
@ -15,7 +15,9 @@ pub async fn validate_auth(
|
||||||
) -> Result<Json<SuccessResponse>, LemmyError> {
|
) -> Result<Json<SuccessResponse>, LemmyError> {
|
||||||
let jwt = read_auth_token(&req)?;
|
let jwt = read_auth_token(&req)?;
|
||||||
if let Some(jwt) = jwt {
|
if let Some(jwt) = jwt {
|
||||||
local_user_view_from_jwt(&jwt, &context).await?;
|
Claims::validate(&jwt, &context)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
||||||
} else {
|
} else {
|
||||||
Err(LemmyErrorType::NotLoggedIn)?;
|
Err(LemmyErrorType::NotLoggedIn)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use lemmy_db_schema::{
|
||||||
newtypes::LocalUserId,
|
newtypes::LocalUserId,
|
||||||
source::login_token::{LoginToken, LoginTokenCreateForm},
|
source::login_token::{LoginToken, LoginTokenCreateForm},
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -25,8 +25,7 @@ impl Claims {
|
||||||
validation.required_spec_claims.remove("exp");
|
validation.required_spec_claims.remove("exp");
|
||||||
let jwt_secret = &context.secret().jwt_secret;
|
let jwt_secret = &context.secret().jwt_secret;
|
||||||
let key = DecodingKey::from_secret(jwt_secret.as_ref());
|
let key = DecodingKey::from_secret(jwt_secret.as_ref());
|
||||||
let claims =
|
let claims = decode::<Claims>(jwt, &key, &validation)?;
|
||||||
decode::<Claims>(jwt, &key, &validation).with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
|
||||||
let user_id = LocalUserId(claims.claims.sub.parse()?);
|
let user_id = LocalUserId(claims.claims.sub.parse()?);
|
||||||
let is_valid = LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
let is_valid = LoginToken::validate(&mut context.pool(), user_id, jwt).await?;
|
||||||
if !is_valid {
|
if !is_valid {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use lemmy_api_common::{claims::Claims, context::LemmyContext, utils::check_user_valid};
|
use lemmy_api_common::{claims::Claims, context::LemmyContext, utils::check_user_valid};
|
||||||
use lemmy_db_views::structs::LocalUserView;
|
use lemmy_db_views::structs::LocalUserView;
|
||||||
use lemmy_utils::error::LemmyError;
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType};
|
||||||
|
|
||||||
pub mod feeds;
|
pub mod feeds;
|
||||||
pub mod images;
|
pub mod images;
|
||||||
|
@ -12,7 +12,9 @@ async fn local_user_view_from_jwt(
|
||||||
jwt: &str,
|
jwt: &str,
|
||||||
context: &LemmyContext,
|
context: &LemmyContext,
|
||||||
) -> Result<LocalUserView, LemmyError> {
|
) -> Result<LocalUserView, LemmyError> {
|
||||||
let local_user_id = Claims::validate(jwt, context).await?;
|
let local_user_id = Claims::validate(jwt, context)
|
||||||
|
.await
|
||||||
|
.with_lemmy_type(LemmyErrorType::NotLoggedIn)?;
|
||||||
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id).await?;
|
||||||
check_user_valid(&local_user_view.person)?;
|
check_user_valid(&local_user_view.person)?;
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,14 @@ use actix_web::{
|
||||||
};
|
};
|
||||||
use core::future::Ready;
|
use core::future::Ready;
|
||||||
use futures_util::future::LocalBoxFuture;
|
use futures_util::future::LocalBoxFuture;
|
||||||
use lemmy_api::{local_user_view_from_jwt, read_auth_token};
|
use lemmy_api::read_auth_token;
|
||||||
use lemmy_api_common::context::LemmyContext;
|
use lemmy_api_common::{
|
||||||
|
claims::Claims,
|
||||||
|
context::LemmyContext,
|
||||||
|
lemmy_db_views::structs::LocalUserView,
|
||||||
|
utils::check_user_valid,
|
||||||
|
};
|
||||||
|
use lemmy_utils::error::{LemmyError, LemmyErrorExt2, LemmyErrorType};
|
||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
use std::{future::ready, rc::Rc};
|
use std::{future::ready, rc::Rc};
|
||||||
|
|
||||||
|
@ -67,15 +73,15 @@ where
|
||||||
let jwt = read_auth_token(req.request())?;
|
let jwt = read_auth_token(req.request())?;
|
||||||
|
|
||||||
if let Some(jwt) = &jwt {
|
if let Some(jwt) = &jwt {
|
||||||
// Ignore any invalid auth so the site can still be used
|
let local_user_id = Claims::validate(jwt, &context)
|
||||||
// TODO: this means it will be impossible to get any error message for invalid jwt. Need
|
.await
|
||||||
// to add a separate endpoint for that.
|
.with_lemmy_type(LemmyErrorType::IncorrectLogin)?;
|
||||||
// https://github.com/LemmyNet/lemmy/issues/3702
|
let local_user_view = LocalUserView::read(&mut context.pool(), local_user_id)
|
||||||
let local_user_view = local_user_view_from_jwt(jwt, &context).await.ok();
|
.await
|
||||||
if let Some(local_user_view) = local_user_view {
|
.map_err(LemmyError::from)?;
|
||||||
|
check_user_valid(&local_user_view.person)?;
|
||||||
req.extensions_mut().insert(local_user_view);
|
req.extensions_mut().insert(local_user_view);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = svc.call(req).await?;
|
let mut res = svc.call(req).await?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue