mirror of
https://github.com/n08i40k/schedule-parser-rusted.git
synced 2025-12-06 09:47:50 +03:00
81 lines
2.6 KiB
Rust
81 lines
2.6 KiB
Rust
use crate::extractors::base::FromRequestAsync;
|
|
use crate::state::AppState;
|
|
use crate::utility::req_auth;
|
|
use crate::utility::req_auth::get_claims_from_req;
|
|
use actix_macros::MiddlewareError;
|
|
use actix_web::body::BoxBody;
|
|
use actix_web::dev::Payload;
|
|
use actix_web::{web, HttpRequest};
|
|
use database::entity::{User, UserType};
|
|
use database::query::Query;
|
|
use derive_more::Display;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fmt::Debug;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Display, MiddlewareError)]
|
|
#[status_code = "actix_web::http::StatusCode::UNAUTHORIZED"]
|
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
|
pub enum Error {
|
|
/// There is no Authorization header or cookie in the request.
|
|
#[display("No Authorization header or cookie found")]
|
|
NoHeaderOrCookieFound,
|
|
|
|
/// Unknown authorization type other than Bearer.
|
|
#[display("Bearer token is required")]
|
|
UnknownAuthorizationType,
|
|
|
|
/// Invalid or expired access token.
|
|
#[display("Invalid or expired access token")]
|
|
InvalidAccessToken,
|
|
|
|
/// Default user is required.
|
|
#[display("Non-default user type is owning this access token")]
|
|
#[status_code = "actix_web::http::StatusCode::FORBIDDEN"]
|
|
NonDefaultUserType,
|
|
|
|
/// The user bound to the token is not found in the database.
|
|
#[display("No user associated with access token")]
|
|
NoUser,
|
|
|
|
/// User doesn't have required role.
|
|
#[display("You don't have sufficient rights")]
|
|
#[status_code = "actix_web::http::StatusCode::FORBIDDEN"]
|
|
InsufficientRights,
|
|
}
|
|
|
|
impl From<req_auth::Error> for Error {
|
|
fn from(value: req_auth::Error) -> Self {
|
|
match value {
|
|
req_auth::Error::NoHeaderOrCookieFound => Error::NoHeaderOrCookieFound,
|
|
req_auth::Error::UnknownAuthorizationType => Error::UnknownAuthorizationType,
|
|
req_auth::Error::InvalidAccessToken => Error::InvalidAccessToken,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// User extractor from request with Bearer access token.
|
|
impl FromRequestAsync for User {
|
|
type Error = Error;
|
|
|
|
async fn from_request_async(
|
|
req: &HttpRequest,
|
|
_payload: &mut Payload,
|
|
) -> Result<Self, Self::Error> {
|
|
let claims = get_claims_from_req(req).map_err(Error::from)?;
|
|
|
|
if claims.user_type.unwrap_or(UserType::Default) != UserType::Default {
|
|
return Err(Error::NonDefaultUserType);
|
|
}
|
|
|
|
let db = req
|
|
.app_data::<web::Data<AppState>>()
|
|
.unwrap()
|
|
.get_database();
|
|
|
|
match Query::find_user_by_id(db, &claims.id).await {
|
|
Ok(Some(user)) => Ok(user),
|
|
_ => Err(Error::NoUser),
|
|
}
|
|
}
|
|
}
|