From 038f38508905819e3a20345ef96e5ab1147a72b5 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 1 Oct 2021 07:29:11 +0200 Subject: [PATCH] proxmox-rest-server: make check_auth async --- .../examples/minimal-rest-server.rs | 22 +++++++----- proxmox-rest-server/src/lib.rs | 12 ++++--- proxmox-rest-server/src/rest.rs | 4 +-- .../src/proxmox_restore_daemon/auth.rs | 34 +++++++++++-------- src/server/auth.rs | 22 +++++++++--- 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/proxmox-rest-server/examples/minimal-rest-server.rs b/proxmox-rest-server/examples/minimal-rest-server.rs index 22477039..8954ce76 100644 --- a/proxmox-rest-server/examples/minimal-rest-server.rs +++ b/proxmox-rest-server/examples/minimal-rest-server.rs @@ -1,5 +1,7 @@ use std::sync::{Arc, Mutex}; use std::collections::HashMap; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; use lazy_static::lazy_static; @@ -26,15 +28,17 @@ impl UserInformation for DummyUserInfo { struct DummyAuth; impl ApiAuth for DummyAuth { - fn check_auth( - &self, - _headers: &http::HeaderMap, - _method: &hyper::Method, - ) -> Result<(String, Box), AuthError> { - // get some global/cached userinfo - let userinfo = DummyUserInfo; - // Do some user checks, e.g. cookie/csrf - Ok(("User".to_string(), Box::new(userinfo))) + fn check_auth<'a>( + &'a self, + _headers: &'a http::HeaderMap, + _method: &'a hyper::Method, + ) -> Pin), AuthError>> + Send + 'a>> { + Box::pin(async move { + // get some global/cached userinfo + let userinfo: Box = Box::new(DummyUserInfo); + // Do some user checks, e.g. cookie/csrf + Ok(("User".to_string(), userinfo)) + }) } } diff --git a/proxmox-rest-server/src/lib.rs b/proxmox-rest-server/src/lib.rs index fe392775..bb29295c 100644 --- a/proxmox-rest-server/src/lib.rs +++ b/proxmox-rest-server/src/lib.rs @@ -16,6 +16,8 @@ //! * generic interface to authenticate user use std::sync::atomic::{Ordering, AtomicBool}; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; use nix::unistd::Pid; @@ -74,11 +76,11 @@ pub trait ApiAuth { /// /// If credenthials are valid, returns the username and a /// [UserInformation] object to query additional user data. - fn check_auth( - &self, - headers: &http::HeaderMap, - method: &hyper::Method, - ) -> Result<(String, Box), AuthError>; + fn check_auth<'a>( + &'a self, + headers: &'a http::HeaderMap, + method: &'a hyper::Method, + ) -> Pin), AuthError>> + Send + 'a>>; } lazy_static::lazy_static!{ diff --git a/proxmox-rest-server/src/rest.rs b/proxmox-rest-server/src/rest.rs index e65e5d6b..80ab0461 100644 --- a/proxmox-rest-server/src/rest.rs +++ b/proxmox-rest-server/src/rest.rs @@ -654,7 +654,7 @@ async fn handle_request( let mut user_info: Box = Box::new(EmptyUserInformation {}); if auth_required { - match auth.check_auth(&parts.headers, &method) { + match auth.check_auth(&parts.headers, &method).await { Ok((authid, info)) => { rpcenv.set_auth_id(Some(authid)); user_info = info; @@ -726,7 +726,7 @@ async fn handle_request( if comp_len == 0 { let language = extract_lang_header(&parts.headers); - match auth.check_auth(&parts.headers, &method) { + match auth.check_auth(&parts.headers, &method).await { Ok((auth_id, _user_info)) => { return Ok(api.get_index(Some(auth_id), language, parts)); } diff --git a/proxmox-restore-daemon/src/proxmox_restore_daemon/auth.rs b/proxmox-restore-daemon/src/proxmox_restore_daemon/auth.rs index 6d6e9c58..faf57a3d 100644 --- a/proxmox-restore-daemon/src/proxmox_restore_daemon/auth.rs +++ b/proxmox-restore-daemon/src/proxmox_restore_daemon/auth.rs @@ -1,6 +1,8 @@ //! Authentication via a static ticket file use std::fs::File; use std::io::prelude::*; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; @@ -25,21 +27,25 @@ pub struct StaticAuth { } impl ApiAuth for StaticAuth { - fn check_auth( - &self, - headers: &http::HeaderMap, - _method: &hyper::Method, - ) -> Result<(String, Box), AuthError> { - match headers.get(hyper::header::AUTHORIZATION) { - Some(header) if header.to_str().unwrap_or("") == &self.ticket => { - Ok((String::from("root@pam"), Box::new(SimpleUserInformation {}))) + fn check_auth<'a>( + &'a self, + headers: &'a http::HeaderMap, + _method: &'a hyper::Method, + ) -> Pin), AuthError>> + Send + 'a>> { + Box::pin(async move { + + match headers.get(hyper::header::AUTHORIZATION) { + Some(header) if header.to_str().unwrap_or("") == &self.ticket => { + let user_info: Box = Box::new(SimpleUserInformation {}); + Ok((String::from("root@pam"), user_info)) + } + _ => { + return Err(AuthError::Generic(format_err!( + "invalid file restore ticket provided" + ))); + } } - _ => { - return Err(AuthError::Generic(format_err!( - "invalid file restore ticket provided" - ))); - } - } + }) } } diff --git a/src/server/auth.rs b/src/server/auth.rs index 90252435..d6c4a66f 100644 --- a/src/server/auth.rs +++ b/src/server/auth.rs @@ -1,7 +1,10 @@ //! Provides authentication primitives for the HTTP server -use anyhow::format_err; use std::sync::Arc; +use std::future::Future; +use std::pin::Pin; + +use anyhow::format_err; use proxmox::api::UserInformation; @@ -55,16 +58,15 @@ impl UserApiAuth { _ => None, } } -} -impl ApiAuth for UserApiAuth { - - fn check_auth( + async fn check_auth_async( &self, headers: &http::HeaderMap, method: &hyper::Method, ) -> Result<(String, Box), AuthError> { + // fixme: make all IO async + let user_info = CachedUserInfo::new()?; let auth_data = Self::extract_auth_data(headers); @@ -124,3 +126,13 @@ impl ApiAuth for UserApiAuth { } } } + +impl ApiAuth for UserApiAuth { + fn check_auth<'a>( + &'a self, + headers: &'a http::HeaderMap, + method: &'a hyper::Method, + ) -> Pin), AuthError>> + Send + 'a>> { + Box::pin(self.check_auth_async(headers, method)) + } +}