Now checking that user_id from claims exists
This commit is contained in:
parent
9f36d8e663
commit
c4ff602ec7
29
src/auth.rs
29
src/auth.rs
@ -1,7 +1,7 @@
|
||||
use std::{array::TryFromSliceError, sync::LazyLock};
|
||||
|
||||
use axum::{
|
||||
extract::FromRequestParts,
|
||||
extract::{FromRef, FromRequestParts},
|
||||
http::{request::Parts, StatusCode},
|
||||
response::IntoResponse,
|
||||
RequestPartsExt,
|
||||
@ -15,7 +15,7 @@ use rand::{rngs::OsRng, RngCore};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use crate::{db, Pool};
|
||||
use crate::{db, errors::handle_error, Pool};
|
||||
|
||||
pub const HASH_LENGTH: usize = 64;
|
||||
pub const SALT_LENGTH: usize = 64;
|
||||
@ -141,6 +141,7 @@ impl Claims {
|
||||
pub enum Error {
|
||||
WrongCredentials,
|
||||
TokenCreation,
|
||||
Validation,
|
||||
InvalidToken,
|
||||
}
|
||||
|
||||
@ -149,6 +150,7 @@ impl IntoResponse for Error {
|
||||
let (status, error_message) = match self {
|
||||
Error::WrongCredentials => (StatusCode::UNAUTHORIZED, "Wrong credentials"),
|
||||
Error::TokenCreation => (StatusCode::INTERNAL_SERVER_ERROR, "Token creation error"),
|
||||
Error::Validation => (StatusCode::INTERNAL_SERVER_ERROR, "Token validation error"),
|
||||
Error::InvalidToken => (StatusCode::BAD_REQUEST, "Invalid token"),
|
||||
};
|
||||
(status, error_message).into_response()
|
||||
@ -156,17 +158,30 @@ impl IntoResponse for Error {
|
||||
}
|
||||
|
||||
#[axum::async_trait]
|
||||
impl<T> FromRequestParts<T> for Claims {
|
||||
impl<T> FromRequestParts<T> for Claims
|
||||
where
|
||||
Pool: FromRef<T>,
|
||||
T: Sync,
|
||||
{
|
||||
type Rejection = Error;
|
||||
|
||||
async fn from_request_parts(parts: &mut Parts, _state: &T) -> Result<Self, Self::Rejection> {
|
||||
async fn from_request_parts(parts: &mut Parts, state: &T) -> Result<Self, Self::Rejection> {
|
||||
let pool = Pool::from_ref(state);
|
||||
let TypedHeader(Authorization(bearer)) = parts
|
||||
.extract::<TypedHeader<Authorization<Bearer>>>()
|
||||
.await
|
||||
.map_err(|_| Error::InvalidToken)?;
|
||||
let token_data = decode(bearer.token(), &KEYS.decoding_key, &Validation::default())
|
||||
.map_err(|_| Error::InvalidToken)?;
|
||||
Ok(token_data.claims)
|
||||
let claims: Claims = decode(bearer.token(), &KEYS.decoding_key, &Validation::default())
|
||||
.map_err(|_| Error::InvalidToken)?
|
||||
.claims;
|
||||
match db::users::exists(claims.user_id, &pool).await {
|
||||
Ok(true) => Ok(claims),
|
||||
Ok(false) => Err(Error::WrongCredentials),
|
||||
Err(err) => {
|
||||
handle_error(err);
|
||||
Err(Error::Validation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,13 +61,23 @@ pub async fn update(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get(user_id: i32, pool: &Pool) -> sqlx::Result<UserInfo> {
|
||||
pub async fn exists(user_id: i32, pool: &Pool) -> sqlx::Result<bool> {
|
||||
sqlx::query!(
|
||||
"SELECT EXISTS(SELECT user_id FROM users WHERE user_id = $1)",
|
||||
user_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.map(|record| record.exists.unwrap_or(false))
|
||||
}
|
||||
|
||||
pub async fn get(user_id: i32, pool: &Pool) -> sqlx::Result<Option<UserInfo>> {
|
||||
sqlx::query_as!(
|
||||
UserInfo,
|
||||
"SELECT user_id, username, email FROM users WHERE user_id = $1",
|
||||
user_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.fetch_optional(pool)
|
||||
.await
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@ type Response = Result<Json<db::users::UserInfo>, StatusCode>;
|
||||
pub async fn get(State(pool): State<Pool>, Query(params): Query<Params>) -> Response {
|
||||
let info = db::users::get(params.user_id, &pool)
|
||||
.await
|
||||
.handle_internal()?;
|
||||
.handle_internal()?
|
||||
.ok_or(StatusCode::NOT_FOUND)?;
|
||||
Ok(Json(info))
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user