verify current user role when creating new user

main
Hannaeko 2022-04-27 22:38:37 +02:00
parent dedb732b2f
commit 806d57379a
4 changed files with 20 additions and 7 deletions

View File

@ -17,7 +17,7 @@ pub enum UserError {
NotFound, NotFound,
UserConflict, UserConflict,
BadCreds, BadCreds,
BadToken, MissingToken,
ExpiredSession, ExpiredSession,
MalformedHeader, MalformedHeader,
PermissionDenied, PermissionDenied,
@ -90,7 +90,7 @@ impl From<UserError> for ErrorResponse {
UserError::BadCreds => ErrorResponse::new(Status::Unauthorized, "Provided credentials or token do not match any existing user".into()), 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::UserConflict => ErrorResponse::new(Status::Conflict, "This user already exists".into()),
UserError::NotFound => ErrorResponse::new(Status::NotFound, "User does not exist".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::ExpiredSession => ErrorResponse::new(Status::Unauthorized, "The provided session token has expired".into()),
UserError::MalformedHeader => ErrorResponse::new(Status::BadRequest, "Malformed authorization header".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()), UserError::PermissionDenied => ErrorResponse::new(Status::Forbidden, "Bearer is not authorized to access the resource".into()),
@ -172,5 +172,5 @@ impl From<ErrorResponse> for (Status, ErrorResponse) {
pub fn make_500<E: std::fmt::Debug>(e: E) -> ErrorResponse { pub fn make_500<E: std::fmt::Debug>(e: E) -> ErrorResponse {
error!("Making 500 for Error: {:?}", e); error!("Making 500 for Error: {:?}", e);
ErrorResponse::new(Status::InternalServerError, "An unexpected error occured.".into()) ErrorResponse::new(Status::InternalServerError, "An unexpected error occured".into())
} }

View File

@ -116,6 +116,7 @@ impl<'r> FromRequest<'r> for Session {
let token = try_outcome!( let token = try_outcome!(
Session::get_token_from_header(request) Session::get_token_from_header(request)
.forward_then(|_| Session::get_token_from_cookie(request)) .forward_then(|_| Session::get_token_from_cookie(request))
.forward_then(|_| ErrorResponse::from(UserError::MissingToken).into())
); );
let conn = try_outcome!(request.guard::<DbConn>().await.map_failure(make_500)); let conn = try_outcome!(request.guard::<DbConn>().await.map_failure(make_500));

View File

@ -115,7 +115,7 @@ impl<'r> FromRequest<'r> for UserInfo {
type Error = ErrorResponse; type Error = ErrorResponse;
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let session = try_outcome!(request.guard::<Session>().await.map_failure(make_500)); let session = try_outcome!(request.guard::<Session>().await);
let conn = try_outcome!(request.guard::<DbConn>().await.map_failure(make_500)); let conn = try_outcome!(request.guard::<DbConn>().await.map_failure(make_500));
conn.run(move |c| { conn.run(move |c| {

View File

@ -46,10 +46,22 @@ pub async fn create_auth_token(
} }
#[post("/users", data = "<user_request>")] #[post("/users", data = "<user_request>")]
pub async fn create_user<'r>(conn: DbConn, user_request: Json<models::CreateUserRequest>) -> Result<Status, models::ErrorResponse> { pub async fn create_user<'r>(
// TODO: Check current user if any to check if user has permission to create users (with or without role) conn: DbConn,
user_request: Json<models::CreateUserRequest>,
user_info: Result<models::UserInfo, models::ErrorResponse>,
) -> Result<Status, models::ErrorResponse> {
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| { conn.run(|c| {
models::LocalUser::create_user(&c, user_request.into_inner()) models::LocalUser::create_user(&c, user_request)
}).await?; }).await?;
Ok(Status::Created) Ok(Status::Created)