proxmox-rest-server: make check_auth async
This commit is contained in:
parent
b914b94773
commit
038f385089
|
@ -1,5 +1,7 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -26,15 +28,17 @@ impl UserInformation for DummyUserInfo {
|
||||||
struct DummyAuth;
|
struct DummyAuth;
|
||||||
|
|
||||||
impl ApiAuth for DummyAuth {
|
impl ApiAuth for DummyAuth {
|
||||||
fn check_auth(
|
fn check_auth<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
_headers: &http::HeaderMap,
|
_headers: &'a http::HeaderMap,
|
||||||
_method: &hyper::Method,
|
_method: &'a hyper::Method,
|
||||||
) -> Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError> {
|
) -> Pin<Box<dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>> + Send + 'a>> {
|
||||||
// get some global/cached userinfo
|
Box::pin(async move {
|
||||||
let userinfo = DummyUserInfo;
|
// get some global/cached userinfo
|
||||||
// Do some user checks, e.g. cookie/csrf
|
let userinfo: Box<dyn UserInformation + Sync + Send> = Box::new(DummyUserInfo);
|
||||||
Ok(("User".to_string(), Box::new(userinfo)))
|
// Do some user checks, e.g. cookie/csrf
|
||||||
|
Ok(("User".to_string(), userinfo))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
//! * generic interface to authenticate user
|
//! * generic interface to authenticate user
|
||||||
|
|
||||||
use std::sync::atomic::{Ordering, AtomicBool};
|
use std::sync::atomic::{Ordering, AtomicBool};
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
use nix::unistd::Pid;
|
use nix::unistd::Pid;
|
||||||
|
@ -74,11 +76,11 @@ pub trait ApiAuth {
|
||||||
///
|
///
|
||||||
/// If credenthials are valid, returns the username and a
|
/// If credenthials are valid, returns the username and a
|
||||||
/// [UserInformation] object to query additional user data.
|
/// [UserInformation] object to query additional user data.
|
||||||
fn check_auth(
|
fn check_auth<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
headers: &http::HeaderMap,
|
headers: &'a http::HeaderMap,
|
||||||
method: &hyper::Method,
|
method: &'a hyper::Method,
|
||||||
) -> Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>;
|
) -> Pin<Box<dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>> + Send + 'a>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static!{
|
lazy_static::lazy_static!{
|
||||||
|
|
|
@ -654,7 +654,7 @@ async fn handle_request(
|
||||||
let mut user_info: Box<dyn UserInformation + Send + Sync> = Box::new(EmptyUserInformation {});
|
let mut user_info: Box<dyn UserInformation + Send + Sync> = Box::new(EmptyUserInformation {});
|
||||||
|
|
||||||
if auth_required {
|
if auth_required {
|
||||||
match auth.check_auth(&parts.headers, &method) {
|
match auth.check_auth(&parts.headers, &method).await {
|
||||||
Ok((authid, info)) => {
|
Ok((authid, info)) => {
|
||||||
rpcenv.set_auth_id(Some(authid));
|
rpcenv.set_auth_id(Some(authid));
|
||||||
user_info = info;
|
user_info = info;
|
||||||
|
@ -726,7 +726,7 @@ async fn handle_request(
|
||||||
|
|
||||||
if comp_len == 0 {
|
if comp_len == 0 {
|
||||||
let language = extract_lang_header(&parts.headers);
|
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)) => {
|
Ok((auth_id, _user_info)) => {
|
||||||
return Ok(api.get_index(Some(auth_id), language, parts));
|
return Ok(api.get_index(Some(auth_id), language, parts));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Authentication via a static ticket file
|
//! Authentication via a static ticket file
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
|
||||||
|
@ -25,21 +27,25 @@ pub struct StaticAuth {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiAuth for StaticAuth {
|
impl ApiAuth for StaticAuth {
|
||||||
fn check_auth(
|
fn check_auth<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
headers: &http::HeaderMap,
|
headers: &'a http::HeaderMap,
|
||||||
_method: &hyper::Method,
|
_method: &'a hyper::Method,
|
||||||
) -> Result<(String, Box<dyn UserInformation + Send + Sync>), AuthError> {
|
) -> Pin<Box<dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>> + Send + 'a>> {
|
||||||
match headers.get(hyper::header::AUTHORIZATION) {
|
Box::pin(async move {
|
||||||
Some(header) if header.to_str().unwrap_or("") == &self.ticket => {
|
|
||||||
Ok((String::from("root@pam"), Box::new(SimpleUserInformation {})))
|
match headers.get(hyper::header::AUTHORIZATION) {
|
||||||
|
Some(header) if header.to_str().unwrap_or("") == &self.ticket => {
|
||||||
|
let user_info: Box<dyn UserInformation + Send + Sync> = 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"
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
//! Provides authentication primitives for the HTTP server
|
//! Provides authentication primitives for the HTTP server
|
||||||
use anyhow::format_err;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use anyhow::format_err;
|
||||||
|
|
||||||
use proxmox::api::UserInformation;
|
use proxmox::api::UserInformation;
|
||||||
|
|
||||||
|
@ -55,16 +58,15 @@ impl UserApiAuth {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ApiAuth for UserApiAuth {
|
async fn check_auth_async(
|
||||||
|
|
||||||
fn check_auth(
|
|
||||||
&self,
|
&self,
|
||||||
headers: &http::HeaderMap,
|
headers: &http::HeaderMap,
|
||||||
method: &hyper::Method,
|
method: &hyper::Method,
|
||||||
) -> Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError> {
|
) -> Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError> {
|
||||||
|
|
||||||
|
// fixme: make all IO async
|
||||||
|
|
||||||
let user_info = CachedUserInfo::new()?;
|
let user_info = CachedUserInfo::new()?;
|
||||||
|
|
||||||
let auth_data = Self::extract_auth_data(headers);
|
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<Box<dyn Future<Output = Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError>> + Send + 'a>> {
|
||||||
|
Box::pin(self.check_auth_async(headers, method))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue