* Add validate_auth api endpoint (fixes #3702) * clippy --------- Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
cf1c32d2ab
commit
3f62135083
5 changed files with 50 additions and 25 deletions
|
@ -2,11 +2,15 @@ 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::utils::{local_site_to_slur_regex, AUTH_COOKIE_NAME};
|
use lemmy_api_common::{
|
||||||
|
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, LemmyErrorType, LemmyResult},
|
error::{LemmyError, LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
||||||
utils::slurs::check_slurs,
|
utils::slurs::check_slurs,
|
||||||
};
|
};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
@ -144,6 +148,20 @@ 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)]
|
||||||
|
|
|
@ -14,4 +14,5 @@ pub mod report_count;
|
||||||
pub mod reset_password;
|
pub mod reset_password;
|
||||||
pub mod save_settings;
|
pub mod save_settings;
|
||||||
pub mod update_totp;
|
pub mod update_totp;
|
||||||
|
pub mod validate_auth;
|
||||||
pub mod verify_email;
|
pub mod verify_email;
|
||||||
|
|
23
crates/api/src/local_user/validate_auth.rs
Normal file
23
crates/api/src/local_user/validate_auth.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use crate::{local_user_view_from_jwt, read_auth_token};
|
||||||
|
use actix_web::{
|
||||||
|
web::{Data, Json},
|
||||||
|
HttpRequest,
|
||||||
|
};
|
||||||
|
use lemmy_api_common::{context::LemmyContext, SuccessResponse};
|
||||||
|
use lemmy_utils::error::{LemmyError, LemmyErrorType};
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[tracing::instrument(skip(context))]
|
||||||
|
pub async fn validate_auth(
|
||||||
|
req: HttpRequest,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> Result<Json<SuccessResponse>, LemmyError> {
|
||||||
|
let jwt = read_auth_token(&req)?;
|
||||||
|
if let Some(jwt) = jwt {
|
||||||
|
local_user_view_from_jwt(&jwt, &context).await?;
|
||||||
|
} else {
|
||||||
|
Err(LemmyErrorType::NotLoggedIn)?;
|
||||||
|
}
|
||||||
|
Ok(Json(SuccessResponse::default()))
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ use lemmy_api::{
|
||||||
reset_password::reset_password,
|
reset_password::reset_password,
|
||||||
save_settings::save_user_settings,
|
save_settings::save_user_settings,
|
||||||
update_totp::update_totp,
|
update_totp::update_totp,
|
||||||
|
validate_auth::validate_auth,
|
||||||
verify_email::verify_email,
|
verify_email::verify_email,
|
||||||
},
|
},
|
||||||
post::{
|
post::{
|
||||||
|
@ -296,7 +297,8 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("/leave_admin", web::post().to(leave_admin))
|
.route("/leave_admin", web::post().to(leave_admin))
|
||||||
.route("/totp/generate", web::post().to(generate_totp_secret))
|
.route("/totp/generate", web::post().to(generate_totp_secret))
|
||||||
.route("/totp/update", web::post().to(update_totp))
|
.route("/totp/update", web::post().to(update_totp))
|
||||||
.route("/list_logins", web::get().to(list_logins)),
|
.route("/list_logins", web::get().to(list_logins))
|
||||||
|
.route("/validate_auth", web::get().to(validate_auth)),
|
||||||
)
|
)
|
||||||
.service(
|
.service(
|
||||||
web::scope("/user")
|
web::scope("/user")
|
||||||
|
|
|
@ -7,14 +7,8 @@ use actix_web::{
|
||||||
};
|
};
|
||||||
use core::future::Ready;
|
use core::future::Ready;
|
||||||
use futures_util::future::LocalBoxFuture;
|
use futures_util::future::LocalBoxFuture;
|
||||||
use lemmy_api::read_auth_token;
|
use lemmy_api::{local_user_view_from_jwt, read_auth_token};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::context::LemmyContext;
|
||||||
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};
|
||||||
|
|
||||||
|
@ -100,20 +94,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
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)]
|
||||||
|
@ -121,6 +101,7 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_web::test::TestRequest;
|
use actix_web::test::TestRequest;
|
||||||
|
use lemmy_api_common::claims::Claims;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
|
|
Loading…
Reference in a new issue