From 806d57379aa600cdff65a0646d2396260a1ac5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Wed, 27 Apr 2022 22:38:37 +0200 Subject: [PATCH] verify current user role when creating new user --- src/models/errors.rs | 6 +++--- src/models/session.rs | 1 + src/models/user.rs | 2 +- src/routes/users.rs | 18 +++++++++++++++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/models/errors.rs b/src/models/errors.rs index 576c98a..478ba99 100644 --- a/src/models/errors.rs +++ b/src/models/errors.rs @@ -17,7 +17,7 @@ pub enum UserError { NotFound, UserConflict, BadCreds, - BadToken, + MissingToken, ExpiredSession, MalformedHeader, PermissionDenied, @@ -90,7 +90,7 @@ impl From for ErrorResponse { UserError::BadCreds => ErrorResponse::new(Status::Unauthorized, "Provided credentials or token do not match any existing user".into()), UserError::UserConflict => ErrorResponse::new(Status::Conflict, "This user already exists".into()), UserError::NotFound => ErrorResponse::new(Status::NotFound, "User does not exist".into()), - UserError::BadToken => ErrorResponse::new(Status::BadRequest, "Malformed token".into()), + UserError::MissingToken => ErrorResponse::new(Status::Unauthorized, "Missing authorization token".into()), UserError::ExpiredSession => ErrorResponse::new(Status::Unauthorized, "The provided session token has expired".into()), UserError::MalformedHeader => ErrorResponse::new(Status::BadRequest, "Malformed authorization header".into()), UserError::PermissionDenied => ErrorResponse::new(Status::Forbidden, "Bearer is not authorized to access the resource".into()), @@ -172,5 +172,5 @@ impl From for (Status, ErrorResponse) { pub fn make_500(e: E) -> ErrorResponse { error!("Making 500 for Error: {:?}", e); - ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) + ErrorResponse::new(Status::InternalServerError, "An unexpected error occured".into()) } diff --git a/src/models/session.rs b/src/models/session.rs index 6e850da..09dc580 100644 --- a/src/models/session.rs +++ b/src/models/session.rs @@ -116,6 +116,7 @@ impl<'r> FromRequest<'r> for Session { let token = try_outcome!( Session::get_token_from_header(request) .forward_then(|_| Session::get_token_from_cookie(request)) + .forward_then(|_| ErrorResponse::from(UserError::MissingToken).into()) ); let conn = try_outcome!(request.guard::().await.map_failure(make_500)); diff --git a/src/models/user.rs b/src/models/user.rs index df4beba..54329e6 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -115,7 +115,7 @@ impl<'r> FromRequest<'r> for UserInfo { type Error = ErrorResponse; async fn from_request(request: &'r Request<'_>) -> Outcome { - let session = try_outcome!(request.guard::().await.map_failure(make_500)); + let session = try_outcome!(request.guard::().await); let conn = try_outcome!(request.guard::().await.map_failure(make_500)); conn.run(move |c| { diff --git a/src/routes/users.rs b/src/routes/users.rs index cfe6738..1f075a4 100644 --- a/src/routes/users.rs +++ b/src/routes/users.rs @@ -46,10 +46,22 @@ pub async fn create_auth_token( } #[post("/users", data = "")] -pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result { - // TODO: Check current user if any to check if user has permission to create users (with or without role) +pub async fn create_user<'r>( + conn: DbConn, + user_request: Json, + user_info: Result, +) -> Result { + let user_request = user_request.into_inner(); + + if user_request.role.is_some() && !user_info?.is_admin() { + return models::ErrorResponse::new( + Status::Forbidden, + "Only user with admin role can create a user with a specific role".into() + ).err() + } + conn.run(|c| { - models::LocalUser::create_user(&c, user_request.into_inner()) + models::LocalUser::create_user(&c, user_request) }).await?; Ok(Status::Created)