mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-08 03:45:46 +00:00
start impl. access permissions
This commit is contained in:
parent
d967838214
commit
a73a7c33b2
@ -19,7 +19,7 @@ use url::form_urlencoded;
|
|||||||
|
|
||||||
use proxmox::http_err;
|
use proxmox::http_err;
|
||||||
use proxmox::api::{ApiHandler, ApiMethod, HttpError};
|
use proxmox::api::{ApiHandler, ApiMethod, HttpError};
|
||||||
use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
|
use proxmox::api::{RpcEnvironment, RpcEnvironmentType, check_api_permission};
|
||||||
use proxmox::api::schema::{ObjectSchema, parse_simple_value, verify_json_object, parse_parameter_strings};
|
use proxmox::api::schema::{ObjectSchema, parse_simple_value, verify_json_object, parse_parameter_strings};
|
||||||
|
|
||||||
use super::environment::RestEnvironment;
|
use super::environment::RestEnvironment;
|
||||||
@ -28,6 +28,7 @@ use super::ApiConfig;
|
|||||||
|
|
||||||
use crate::auth_helpers::*;
|
use crate::auth_helpers::*;
|
||||||
use crate::tools;
|
use crate::tools;
|
||||||
|
use crate::config::cached_user_info::CachedUserInfo;
|
||||||
|
|
||||||
extern "C" { fn tzset(); }
|
extern "C" { fn tzset(); }
|
||||||
|
|
||||||
@ -468,7 +469,12 @@ fn extract_auth_data(headers: &http::HeaderMap) -> (Option<String>, Option<Strin
|
|||||||
(ticket, token)
|
(ticket, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_auth(method: &hyper::Method, ticket: &Option<String>, token: &Option<String>) -> Result<String, Error> {
|
fn check_auth(
|
||||||
|
method: &hyper::Method,
|
||||||
|
ticket: &Option<String>,
|
||||||
|
token: &Option<String>,
|
||||||
|
user_info: &CachedUserInfo,
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
|
||||||
let ticket_lifetime = tools::ticket::TICKET_LIFETIME;
|
let ticket_lifetime = tools::ticket::TICKET_LIFETIME;
|
||||||
|
|
||||||
@ -481,6 +487,10 @@ fn check_auth(method: &hyper::Method, ticket: &Option<String>, token: &Option<St
|
|||||||
None => bail!("missing ticket"),
|
None => bail!("missing ticket"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !user_info.is_active_user(&username) {
|
||||||
|
bail!("user account disabled or expired.");
|
||||||
|
}
|
||||||
|
|
||||||
if method != hyper::Method::GET {
|
if method != hyper::Method::GET {
|
||||||
if let Some(token) = token {
|
if let Some(token) = token {
|
||||||
println!("CSRF prevention token: {:?}", token);
|
println!("CSRF prevention token: {:?}", token);
|
||||||
@ -508,6 +518,8 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
|||||||
let env_type = api.env_type();
|
let env_type = api.env_type();
|
||||||
let mut rpcenv = RestEnvironment::new(env_type);
|
let mut rpcenv = RestEnvironment::new(env_type);
|
||||||
|
|
||||||
|
let user_info = CachedUserInfo::new()?;
|
||||||
|
|
||||||
let delay_unauth_time = std::time::Instant::now() + std::time::Duration::from_millis(3000);
|
let delay_unauth_time = std::time::Instant::now() + std::time::Duration::from_millis(3000);
|
||||||
|
|
||||||
if comp_len >= 1 && components[0] == "api2" {
|
if comp_len >= 1 && components[0] == "api2" {
|
||||||
@ -531,16 +543,11 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
|||||||
// explicitly allow those calls without auth
|
// explicitly allow those calls without auth
|
||||||
} else {
|
} else {
|
||||||
let (ticket, token) = extract_auth_data(&parts.headers);
|
let (ticket, token) = extract_auth_data(&parts.headers);
|
||||||
match check_auth(&method, &ticket, &token) {
|
match check_auth(&method, &ticket, &token, &user_info) {
|
||||||
Ok(username) => {
|
Ok(username) => rpcenv.set_user(Some(username)),
|
||||||
|
|
||||||
// fixme: check permissions
|
|
||||||
|
|
||||||
rpcenv.set_user(Some(username));
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// always delay unauthorized calls by 3 seconds (from start of request)
|
// always delay unauthorized calls by 3 seconds (from start of request)
|
||||||
let err = http_err!(UNAUTHORIZED, format!("permission check failed - {}", err));
|
let err = http_err!(UNAUTHORIZED, format!("authentication failed - {}", err));
|
||||||
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;
|
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;
|
||||||
return Ok((formatter.format_error)(err));
|
return Ok((formatter.format_error)(err));
|
||||||
}
|
}
|
||||||
@ -553,6 +560,13 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
|||||||
return Ok((formatter.format_error)(err));
|
return Ok((formatter.format_error)(err));
|
||||||
}
|
}
|
||||||
Some(api_method) => {
|
Some(api_method) => {
|
||||||
|
let user = rpcenv.get_user();
|
||||||
|
if !check_api_permission(api_method.access.permission, user.as_deref(), &uri_param, &user_info) {
|
||||||
|
let err = http_err!(FORBIDDEN, format!("permission check failed"));
|
||||||
|
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;
|
||||||
|
return Ok((formatter.format_error)(err));
|
||||||
|
}
|
||||||
|
|
||||||
let result = if api_method.protected && env_type == RpcEnvironmentType::PUBLIC {
|
let result = if api_method.protected && env_type == RpcEnvironmentType::PUBLIC {
|
||||||
proxy_protected_request(api_method, parts, body).await
|
proxy_protected_request(api_method, parts, body).await
|
||||||
} else {
|
} else {
|
||||||
@ -577,7 +591,7 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
|||||||
if comp_len == 0 {
|
if comp_len == 0 {
|
||||||
let (ticket, token) = extract_auth_data(&parts.headers);
|
let (ticket, token) = extract_auth_data(&parts.headers);
|
||||||
if ticket != None {
|
if ticket != None {
|
||||||
match check_auth(&method, &ticket, &token) {
|
match check_auth(&method, &ticket, &token, &user_info) {
|
||||||
Ok(username) => {
|
Ok(username) => {
|
||||||
let new_token = assemble_csrf_prevention_token(csrf_secret(), &username);
|
let new_token = assemble_csrf_prevention_token(csrf_secret(), &username);
|
||||||
return Ok(get_index(Some(username), Some(new_token)));
|
return Ok(get_index(Some(username), Some(new_token)));
|
||||||
|
Loading…
Reference in New Issue
Block a user