mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-28 09:08:58 +00:00
@@ -0,0 +1,65 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use http::HeaderMap;
|
||||
use rustfs_iam::store::object::ObjectStore;
|
||||
use rustfs_iam::sys::IamSys;
|
||||
use rustfs_policy::auth;
|
||||
use rustfs_policy::policy::Args;
|
||||
use rustfs_policy::policy::action::Action;
|
||||
use s3s::S3Result;
|
||||
use s3s::s3_error;
|
||||
|
||||
use crate::auth::get_condition_values;
|
||||
|
||||
pub async fn validate_admin_request(
|
||||
headers: &HeaderMap,
|
||||
cred: &auth::Credentials,
|
||||
is_owner: bool,
|
||||
deny_only: bool,
|
||||
actions: Vec<Action>,
|
||||
) -> S3Result<()> {
|
||||
let Ok(iam_store) = rustfs_iam::get() else {
|
||||
return Err(s3_error!(InternalError, "iam not init"));
|
||||
};
|
||||
for action in actions {
|
||||
match check_admin_request_auth(iam_store.clone(), headers, cred, is_owner, deny_only, action).await {
|
||||
Ok(_) => return Ok(()),
|
||||
Err(_) => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(s3_error!(AccessDenied, "Access Denied"))
|
||||
}
|
||||
|
||||
async fn check_admin_request_auth(
|
||||
iam_store: Arc<IamSys<ObjectStore>>,
|
||||
headers: &HeaderMap,
|
||||
cred: &auth::Credentials,
|
||||
is_owner: bool,
|
||||
deny_only: bool,
|
||||
action: Action,
|
||||
) -> S3Result<()> {
|
||||
let conditions = get_condition_values(headers, cred);
|
||||
|
||||
if !iam_store
|
||||
.is_allowed(&Args {
|
||||
account: &cred.access_key,
|
||||
groups: &cred.groups,
|
||||
action,
|
||||
conditions: &conditions,
|
||||
is_owner,
|
||||
claims: cred.claims.as_ref().unwrap_or(&HashMap::new()),
|
||||
deny_only,
|
||||
bucket: "",
|
||||
object: "",
|
||||
})
|
||||
.await
|
||||
{
|
||||
return Err(s3_error!(AccessDenied, "Access Denied"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use super::router::Operation;
|
||||
use crate::admin::auth::validate_admin_request;
|
||||
use crate::auth::check_key_valid;
|
||||
use crate::auth::get_condition_values;
|
||||
use crate::auth::get_session_token;
|
||||
@@ -45,6 +46,7 @@ use rustfs_madmin::utils::parse_duration;
|
||||
use rustfs_policy::policy::Args;
|
||||
use rustfs_policy::policy::BucketPolicy;
|
||||
use rustfs_policy::policy::action::Action;
|
||||
use rustfs_policy::policy::action::AdminAction;
|
||||
use rustfs_policy::policy::action::S3Action;
|
||||
use rustfs_policy::policy::default::DEFAULT_POLICIES;
|
||||
use rustfs_utils::path::path_join;
|
||||
@@ -300,7 +302,23 @@ pub struct ServerInfoHandler {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for ServerInfoHandler {
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ServerInfoAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let info = get_server_info(true).await;
|
||||
|
||||
let data = serde_json::to_vec(&info)
|
||||
@@ -328,9 +346,25 @@ pub struct StorageInfoHandler {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for StorageInfoHandler {
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle StorageInfoHandler");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::StorageInfoAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
||||
};
|
||||
@@ -353,9 +387,25 @@ pub struct DataUsageInfoHandler {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for DataUsageInfoHandler {
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle DataUsageInfoHandler");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::DataUsageInfoAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
admin::router::Operation,
|
||||
admin::{auth::validate_admin_request, router::Operation},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
|
||||
@@ -44,7 +44,10 @@ use rustfs_ecstore::{
|
||||
bucket::utils::{deserialize, serialize},
|
||||
store_api::MakeBucketOptions,
|
||||
};
|
||||
use rustfs_policy::policy::BucketPolicy;
|
||||
use rustfs_policy::policy::{
|
||||
BucketPolicy,
|
||||
action::{Action, AdminAction},
|
||||
};
|
||||
use rustfs_utils::path::{SLASH_SEPARATOR, path_join_buf};
|
||||
use s3s::{
|
||||
Body, S3Request, S3Response, S3Result,
|
||||
@@ -85,9 +88,18 @@ impl Operation for ExportBucketMetadata {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (_cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ExportBucketMetadataAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(s3_error!(InvalidRequest, "object store not init"));
|
||||
};
|
||||
@@ -369,9 +381,18 @@ impl Operation for ImportBucketMetadata {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (_cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ImportBucketMetadataAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
Ok(b) => b,
|
||||
|
||||
@@ -17,6 +17,7 @@ use matchit::Params;
|
||||
use rustfs_ecstore::global::get_global_action_cred;
|
||||
use rustfs_iam::error::{is_err_no_such_group, is_err_no_such_user};
|
||||
use rustfs_madmin::GroupAddRemove;
|
||||
use rustfs_policy::policy::action::{Action, AdminAction};
|
||||
use s3s::{
|
||||
Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result,
|
||||
header::{CONTENT_LENGTH, CONTENT_TYPE},
|
||||
@@ -26,7 +27,10 @@ use serde::Deserialize;
|
||||
use serde_urlencoded::from_bytes;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::admin::{router::Operation, utils::has_space_be};
|
||||
use crate::{
|
||||
admin::{auth::validate_admin_request, router::Operation, utils::has_space_be},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, Default)]
|
||||
pub struct GroupQuery {
|
||||
@@ -37,9 +41,25 @@ pub struct GroupQuery {
|
||||
pub struct ListGroups {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for ListGroups {
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle ListGroups");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ListGroupsAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Ok(iam_store) = rustfs_iam::get() else { return Err(s3_error!(InternalError, "iam not init")) };
|
||||
|
||||
let groups = iam_store.list_groups().await.map_err(|e| {
|
||||
@@ -62,6 +82,22 @@ impl Operation for GetGroup {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle GetGroup");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::GetGroupAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: GroupQuery =
|
||||
@@ -93,6 +129,22 @@ impl Operation for SetGroupStatus {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle SetGroupStatus");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::EnableGroupAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: GroupQuery =
|
||||
@@ -144,6 +196,22 @@ impl Operation for UpdateGroupMembers {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle UpdateGroupMembers");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::AddUserToGroupAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
Ok(b) => b,
|
||||
|
||||
@@ -12,13 +12,19 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::admin::{router::Operation, utils::has_space_be};
|
||||
use crate::{
|
||||
admin::{auth::validate_admin_request, router::Operation, utils::has_space_be},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use matchit::Params;
|
||||
use rustfs_ecstore::global::get_global_action_cred;
|
||||
use rustfs_iam::error::is_err_no_such_user;
|
||||
use rustfs_iam::store::MappedPolicy;
|
||||
use rustfs_policy::policy::Policy;
|
||||
use rustfs_policy::policy::{
|
||||
Policy,
|
||||
action::{Action, AdminAction},
|
||||
};
|
||||
use s3s::{
|
||||
Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result,
|
||||
header::{CONTENT_LENGTH, CONTENT_TYPE},
|
||||
@@ -40,6 +46,22 @@ impl Operation for ListCannedPolicies {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle ListCannedPolicies");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ListUserPoliciesAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: BucketQuery =
|
||||
@@ -82,6 +104,22 @@ impl Operation for AddCannedPolicy {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle AddCannedPolicy");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::CreatePolicyAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: PolicyNameQuery =
|
||||
@@ -138,6 +176,22 @@ impl Operation for InfoCannedPolicy {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle InfoCannedPolicy");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::GetPolicyAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: PolicyNameQuery =
|
||||
@@ -179,6 +233,22 @@ impl Operation for RemoveCannedPolicy {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle RemoveCannedPolicy");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::DeletePolicyAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: PolicyNameQuery =
|
||||
@@ -223,6 +293,22 @@ impl Operation for SetPolicyForUserOrGroup {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle SetPolicyForUserOrGroup");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::AttachPolicyAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: SetPolicyForUserOrGroupQuery =
|
||||
@@ -233,10 +319,6 @@ impl Operation for SetPolicyForUserOrGroup {
|
||||
}
|
||||
};
|
||||
|
||||
if query.policy_name.is_empty() {
|
||||
return Err(s3_error!(InvalidArgument, "policy name is empty"));
|
||||
}
|
||||
|
||||
if query.user_or_group.is_empty() {
|
||||
return Err(s3_error!(InvalidArgument, "user or group is empty"));
|
||||
}
|
||||
|
||||
@@ -15,13 +15,18 @@
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use matchit::Params;
|
||||
use rustfs_ecstore::{GLOBAL_Endpoints, new_object_layer_fn};
|
||||
use rustfs_policy::policy::action::{Action, AdminAction};
|
||||
use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error};
|
||||
use serde::Deserialize;
|
||||
use serde_urlencoded::from_bytes;
|
||||
use tokio::sync::broadcast;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{admin::router::Operation, error::ApiError};
|
||||
use crate::{
|
||||
admin::{auth::validate_admin_request, router::Operation},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
error::ApiError,
|
||||
};
|
||||
|
||||
pub struct ListPools {}
|
||||
|
||||
@@ -29,9 +34,28 @@ pub struct ListPools {}
|
||||
impl Operation for ListPools {
|
||||
// GET <endpoint>/<admin-API>/pools/list
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle ListPools");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![
|
||||
Action::AdminAction(AdminAction::ServerInfoAdminAction),
|
||||
Action::AdminAction(AdminAction::DecommissionAdminAction),
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
||||
};
|
||||
@@ -79,6 +103,25 @@ impl Operation for StatusPool {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle StatusPool");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![
|
||||
Action::AdminAction(AdminAction::ServerInfoAdminAction),
|
||||
Action::AdminAction(AdminAction::DecommissionAdminAction),
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(endpoints) = GLOBAL_Endpoints.get() else {
|
||||
return Err(s3_error!(NotImplemented));
|
||||
};
|
||||
@@ -138,6 +181,22 @@ impl Operation for StartDecommission {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle StartDecommission");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::DecommissionAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(endpoints) = GLOBAL_Endpoints.get() else {
|
||||
return Err(s3_error!(NotImplemented));
|
||||
};
|
||||
@@ -221,6 +280,22 @@ impl Operation for CancelDecommission {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle CancelDecommission");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::DecommissionAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(endpoints) = GLOBAL_Endpoints.get() else {
|
||||
return Err(s3_error!(NotImplemented));
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ use rustfs_ecstore::{
|
||||
rebalance::{DiskStat, RebalSaveOpt},
|
||||
store_api::BucketOptions,
|
||||
};
|
||||
use rustfs_policy::policy::action::{Action, AdminAction};
|
||||
use s3s::{
|
||||
Body, S3Request, S3Response, S3Result,
|
||||
header::{CONTENT_LENGTH, CONTENT_TYPE},
|
||||
@@ -32,7 +33,10 @@ use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::admin::router::Operation;
|
||||
use crate::{
|
||||
admin::{auth::validate_admin_request, router::Operation},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
use rustfs_ecstore::rebalance::RebalanceMeta;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -84,9 +88,25 @@ pub struct RebalanceStart {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for RebalanceStart {
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle RebalanceStart");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::RebalanceAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(s3_error!(InternalError, "Not init"));
|
||||
};
|
||||
@@ -145,9 +165,25 @@ pub struct RebalanceStatus {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for RebalanceStatus {
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle RebalanceStatus");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::RebalanceAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(s3_error!(InternalError, "Not init"));
|
||||
};
|
||||
@@ -246,9 +282,25 @@ pub struct RebalanceStop {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for RebalanceStop {
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn call(&self, _req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
warn!("handle RebalanceStop");
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::RebalanceAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let Some(store) = new_object_layer_fn() else {
|
||||
return Err(s3_error!(InternalError, "Not init"));
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
use http::{HeaderMap, StatusCode};
|
||||
//use iam::get_global_action_cred;
|
||||
use matchit::Params;
|
||||
use rustfs_policy::policy::action::{Action, AdminAction};
|
||||
use s3s::{
|
||||
Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result,
|
||||
header::{CONTENT_LENGTH, CONTENT_TYPE},
|
||||
@@ -26,7 +27,7 @@ use time::OffsetDateTime;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::{
|
||||
admin::router::Operation,
|
||||
admin::{auth::validate_admin_request, router::Operation},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
|
||||
@@ -88,9 +89,11 @@ impl Operation for AddTier {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
Ok(b) => b,
|
||||
@@ -196,9 +199,11 @@ impl Operation for EditTier {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
Ok(b) => b,
|
||||
@@ -265,6 +270,15 @@ impl Operation for ListTiers {
|
||||
}
|
||||
};
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::ListTierAction)]).await?;
|
||||
|
||||
let mut tier_config_mgr = GLOBAL_TierConfigMgr.read().await;
|
||||
let tiers = tier_config_mgr.list_tiers();
|
||||
|
||||
@@ -296,11 +310,10 @@ impl Operation for RemoveTier {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
//let sys_cred = get_global_action_cred()
|
||||
// .ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
|
||||
|
||||
let mut force: bool = false;
|
||||
let force_str = query.force.clone().unwrap_or_default();
|
||||
@@ -360,11 +373,10 @@ impl Operation for VerifyTier {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
//let sys_cred = get_global_action_cred()
|
||||
// .ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::ListTierAction)]).await?;
|
||||
|
||||
let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await;
|
||||
tier_config_mgr.verify(&query.tier.unwrap()).await;
|
||||
@@ -380,6 +392,15 @@ pub struct GetTierInfo {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for GetTierInfo {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::ListTierAction)]).await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: AddTierQuery =
|
||||
@@ -423,12 +444,14 @@ impl Operation for ClearTier {
|
||||
}
|
||||
};
|
||||
|
||||
//let Some(input_cred) = req.credentials else {
|
||||
// return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
//};
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
//let (cred, _owner) =
|
||||
// check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
|
||||
|
||||
let mut force: bool = false;
|
||||
let force_str = query.force;
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::{
|
||||
admin::{router::Operation, utils::has_space_be},
|
||||
auth::{check_key_valid, get_condition_values, get_session_token},
|
||||
admin::{auth::validate_admin_request, router::Operation, utils::has_space_be},
|
||||
auth::{check_key_valid, get_session_token},
|
||||
};
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use matchit::Params;
|
||||
@@ -27,10 +27,7 @@ use rustfs_madmin::{
|
||||
AccountStatus, AddOrUpdateUserReq, IAMEntities, IAMErrEntities, IAMErrEntity, IAMErrPolicyEntity,
|
||||
user::{ImportIAMResult, SRSessionPolicy, SRSvcAccCreate},
|
||||
};
|
||||
use rustfs_policy::policy::{
|
||||
Args,
|
||||
action::{Action, AdminAction},
|
||||
};
|
||||
use rustfs_policy::policy::action::{Action, AdminAction};
|
||||
|
||||
use rustfs_utils::path::path_join_buf;
|
||||
use s3s::{
|
||||
@@ -121,23 +118,14 @@ impl Operation for AddUser {
|
||||
}
|
||||
|
||||
let deny_only = ak == cred.access_key;
|
||||
let conditions = get_condition_values(&req.headers, &cred);
|
||||
if !iam_store
|
||||
.is_allowed(&Args {
|
||||
account: &cred.access_key,
|
||||
groups: &cred.groups,
|
||||
action: Action::AdminAction(AdminAction::CreateUserAdminAction),
|
||||
bucket: "",
|
||||
conditions: &conditions,
|
||||
is_owner: owner,
|
||||
object: "",
|
||||
claims: cred.claims.as_ref().unwrap_or(&HashMap::new()),
|
||||
deny_only,
|
||||
})
|
||||
.await
|
||||
{
|
||||
return Err(s3_error!(AccessDenied, "access denied"));
|
||||
}
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
deny_only,
|
||||
vec![Action::AdminAction(AdminAction::CreateUserAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
iam_store
|
||||
.create_user(ak, &args)
|
||||
@@ -179,6 +167,18 @@ impl Operation for SetUserStatus {
|
||||
return Err(s3_error!(InvalidArgument, "can't change status of self"));
|
||||
}
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::EnableUserAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let status = AccountStatus::try_from(query.status.as_deref().unwrap_or_default())
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InvalidArgument, e))?;
|
||||
|
||||
@@ -207,6 +207,22 @@ pub struct ListUsers {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for ListUsers {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::ListUsersAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: BucketQuery =
|
||||
@@ -238,13 +254,6 @@ impl Operation for ListUsers {
|
||||
let data = serde_json::to_vec(&users)
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("marshal users err {e}")))?;
|
||||
|
||||
// let Some(input_cred) = req.credentials else {
|
||||
// return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
// };
|
||||
|
||||
// let body = encrypt_data(input_cred.secret_key.expose().as_bytes(), &data)
|
||||
// .map_err(|e| S3Error::with_message(S3ErrorCode::InvalidArgument, format!("encrypt_data err {}", e)))?;
|
||||
|
||||
let mut header = HeaderMap::new();
|
||||
header.insert(CONTENT_TYPE, "application/json".parse().unwrap());
|
||||
|
||||
@@ -256,6 +265,22 @@ pub struct RemoveUser {}
|
||||
#[async_trait::async_trait]
|
||||
impl Operation for RemoveUser {
|
||||
async fn call(&self, req: S3Request<Body>, _params: Params<'_, '_>) -> S3Result<S3Response<(StatusCode, Body)>> {
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
false,
|
||||
vec![Action::AdminAction(AdminAction::DeleteUserAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let query = {
|
||||
if let Some(query) = req.uri.query() {
|
||||
let input: AddUserQuery =
|
||||
@@ -272,6 +297,13 @@ impl Operation for RemoveUser {
|
||||
return Err(s3_error!(InvalidArgument, "access key is empty"));
|
||||
}
|
||||
|
||||
let sys_cred = get_global_action_cred()
|
||||
.ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||
|
||||
if ak == sys_cred.access_key || ak == cred.access_key || cred.parent_user == ak {
|
||||
return Err(s3_error!(InvalidArgument, "can't remove self"));
|
||||
}
|
||||
|
||||
let Ok(iam_store) = rustfs_iam::get() else {
|
||||
return Err(s3_error!(InvalidRequest, "iam not init"));
|
||||
};
|
||||
@@ -285,22 +317,12 @@ impl Operation for RemoveUser {
|
||||
return Err(s3_error!(InvalidArgument, "can't remove temp user"));
|
||||
}
|
||||
|
||||
let Some(input_cred) = req.credentials else {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (cred, _owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
let sys_cred = get_global_action_cred()
|
||||
.ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?;
|
||||
|
||||
if ak == sys_cred.access_key || ak == cred.access_key {
|
||||
warn!(
|
||||
"can't remove self or system access key {}, {}, {}",
|
||||
ak, sys_cred.access_key, cred.access_key
|
||||
);
|
||||
return Err(s3_error!(InvalidArgument, "can't remove self"));
|
||||
let (is_service_account, _) = iam_store
|
||||
.is_service_account(ak)
|
||||
.await
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("is_service_account err {e}")))?;
|
||||
if is_service_account {
|
||||
return Err(s3_error!(InvalidArgument, "can't remove service account"));
|
||||
}
|
||||
|
||||
iam_store
|
||||
@@ -308,6 +330,8 @@ impl Operation for RemoveUser {
|
||||
.await
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, format!("delete_user err {e}")))?;
|
||||
|
||||
// TODO: IAMChangeHook
|
||||
|
||||
let mut header = HeaderMap::new();
|
||||
header.insert(CONTENT_TYPE, "application/json".parse().unwrap());
|
||||
header.insert(CONTENT_LENGTH, "0".parse().unwrap());
|
||||
@@ -347,23 +371,14 @@ impl Operation for GetUserInfo {
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
let deny_only = ak == cred.access_key;
|
||||
let conditions = get_condition_values(&req.headers, &cred);
|
||||
if !iam_store
|
||||
.is_allowed(&Args {
|
||||
account: &cred.access_key,
|
||||
groups: &cred.groups,
|
||||
action: Action::AdminAction(AdminAction::GetUserAdminAction),
|
||||
bucket: "",
|
||||
conditions: &conditions,
|
||||
is_owner: owner,
|
||||
object: "",
|
||||
claims: cred.claims.as_ref().unwrap_or(&HashMap::new()),
|
||||
deny_only,
|
||||
})
|
||||
.await
|
||||
{
|
||||
return Err(s3_error!(AccessDenied, "access denied"));
|
||||
}
|
||||
validate_admin_request(
|
||||
&req.headers,
|
||||
&cred,
|
||||
owner,
|
||||
deny_only,
|
||||
vec![Action::AdminAction(AdminAction::GetUserAdminAction)],
|
||||
)
|
||||
.await?;
|
||||
|
||||
let info = iam_store
|
||||
.get_user_info(ak)
|
||||
@@ -408,9 +423,12 @@ impl Operation for ExportIam {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (_cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::ExportIAMAction)])
|
||||
.await?;
|
||||
|
||||
let Ok(iam_store) = rustfs_iam::get() else {
|
||||
return Err(s3_error!(InvalidRequest, "iam not init"));
|
||||
};
|
||||
@@ -612,9 +630,12 @@ impl Operation for ImportIam {
|
||||
return Err(s3_error!(InvalidRequest, "get cred failed"));
|
||||
};
|
||||
|
||||
let (_cred, _owner) =
|
||||
let (cred, owner) =
|
||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &input_cred.access_key).await?;
|
||||
|
||||
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::ExportIAMAction)])
|
||||
.await?;
|
||||
|
||||
let mut input = req.input;
|
||||
let body = match input.store_all_unlimited().await {
|
||||
Ok(b) => b,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
mod auth;
|
||||
pub mod console;
|
||||
pub mod handlers;
|
||||
pub mod router;
|
||||
|
||||
Reference in New Issue
Block a user