guards: new guard: get admin user that is not the logged-in admin

This commit is contained in:
Philippe Loctaux 2023-05-03 21:48:38 +02:00
parent f82c6368e3
commit 4a63bfa9a9
2 changed files with 58 additions and 2 deletions

View file

@ -3,7 +3,6 @@ use crate::guards::refresh_token::get_refresh_token_from_cookie;
use crate::tokens::{
JWT_COOKIE_NAME, JWT_DURATION_MINUTES, REFRESH_TOKEN_COOKIE_NAME, REFRESH_TOKEN_DURATION_DAYS,
};
pub use admin::JwtAdmin;
use id::KeyID;
use jwt::database::Key;
use jwt::{JwtClaims, PrivateKey};
@ -11,11 +10,15 @@ use rocket::http::Status;
use rocket::request::Outcome;
use rocket::tokio::task;
use rocket::Request;
pub use user::JwtUser;
mod admin;
mod admin_not_current;
mod user;
pub use admin::JwtAdmin;
pub use admin_not_current::JwtAdminNotCurrent;
pub use user::JwtUser;
#[derive(Debug)]
pub enum Error {
GetDatabase,

View file

@ -0,0 +1,53 @@
use super::Error;
use crate::guards::use_access_token_or_refresh_token;
use crate::id::RocketUserID;
use jwt::JwtClaims;
use rocket::request::{FromRequest, Outcome};
use rocket::Request;
#[derive(Debug)]
/// Use to allow access to an admin that is not the currently signed-in admin
pub struct JwtAdminNotCurrent(pub JwtClaims);
#[rocket::async_trait]
impl<'r> FromRequest<'r> for JwtAdminNotCurrent {
type Error = Error;
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let get_admin: Option<bool> = Some(true);
let user_id = match {
let mut ret = None;
// In all segments of uri, attempt to parse a valid user id
for (idx, _) in request.uri().path().segments().enumerate() {
if let Ok(user_id) = request.param::<RocketUserID>(idx).transpose() {
// Found user id, save it
ret = user_id;
}
}
ret
} {
Some(user_id) => user_id,
None => return Outcome::Forward(()),
};
match use_access_token_or_refresh_token(request, get_admin)
.await
.map(Self)
{
// Do we have a valid admin?
Outcome::Success(success) => {
// Is the requested user is not the current logged-in user?
if success.0.subject != user_id.0 .0 {
Outcome::Success(success)
} else {
Outcome::Forward(())
}
}
Outcome::Failure(failure) => Outcome::Failure(failure),
Outcome::Forward(forward) => Outcome::Forward(forward),
}
}
}