mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 16:48:58 +00:00
120 lines
3.2 KiB
Rust
120 lines
3.2 KiB
Rust
use crate::sys::{Args, Validator};
|
|
|
|
use super::{action::Action, ActionSet, Effect, Error as IamError, Functions, ResourceSet, ID};
|
|
use ecstore::error::{Error, Result};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
|
pub struct Statement {
|
|
#[serde(rename = "Sid", default)]
|
|
pub sid: ID,
|
|
#[serde(rename = "Effect")]
|
|
pub effect: Effect,
|
|
#[serde(rename = "Action")]
|
|
pub actions: ActionSet,
|
|
#[serde(rename = "NotAction", default)]
|
|
pub not_actions: ActionSet,
|
|
#[serde(rename = "Resource", default)]
|
|
pub resources: ResourceSet,
|
|
#[serde(rename = "NotResource", default)]
|
|
pub not_resources: ResourceSet,
|
|
#[serde(rename = "Condition", default)]
|
|
pub conditions: Functions,
|
|
}
|
|
|
|
impl Statement {
|
|
fn is_kms(&self) -> bool {
|
|
for act in self.actions.iter() {
|
|
if matches!(act, Action::KmsAction(_)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn is_admin(&self) -> bool {
|
|
for act in self.actions.iter() {
|
|
if matches!(act, Action::AdminAction(_)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn is_sts(&self) -> bool {
|
|
for act in self.actions.iter() {
|
|
if matches!(act, Action::StsAction(_)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
pub fn is_allowed(&self, args: &Args) -> bool {
|
|
let check = 'c: {
|
|
if (!self.actions.is_match(&args.action) && !self.actions.is_empty()) || self.not_actions.is_match(&args.action) {
|
|
break 'c false;
|
|
}
|
|
|
|
let mut resource = String::from(args.bucket);
|
|
if !args.object.is_empty() {
|
|
if !args.object.starts_with('/') {
|
|
resource.push('/');
|
|
}
|
|
|
|
resource.push_str(args.object);
|
|
} else {
|
|
resource.push('/');
|
|
}
|
|
|
|
if self.is_kms() && (resource == "/" || self.resources.is_empty()) {
|
|
break 'c self.conditions.evaluate(args.conditions);
|
|
}
|
|
|
|
if !self.resources.is_match(&resource, args.conditions) && !self.is_admin() && !self.is_sts() {
|
|
break 'c false;
|
|
}
|
|
|
|
self.conditions.evaluate(args.conditions)
|
|
};
|
|
|
|
self.effect.is_allowed(check)
|
|
}
|
|
}
|
|
|
|
impl Validator for Statement {
|
|
type Error = Error;
|
|
fn is_valid(&self) -> Result<()> {
|
|
self.effect.is_valid()?;
|
|
// check sid
|
|
self.sid.is_valid()?;
|
|
|
|
if self.actions.is_empty() && self.not_actions.is_empty() {
|
|
return Err(IamError::NonAction.into());
|
|
}
|
|
|
|
if self.resources.is_empty() {
|
|
return Err(IamError::NonResource.into());
|
|
}
|
|
|
|
self.actions.is_valid()?;
|
|
self.not_actions.is_valid()?;
|
|
self.resources.is_valid()?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl PartialEq for Statement {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.effect == other.effect
|
|
&& self.actions == other.actions
|
|
&& self.not_actions == other.not_actions
|
|
&& self.resources == other.resources
|
|
&& self.conditions == other.conditions
|
|
}
|
|
}
|