mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 11:56:38 +00:00
fix policy parse
This commit is contained in:
@@ -114,14 +114,124 @@ pub enum S3Action {
|
|||||||
#[cfg_attr(test, default)]
|
#[cfg_attr(test, default)]
|
||||||
#[strum(serialize = "s3:*")]
|
#[strum(serialize = "s3:*")]
|
||||||
AllActions,
|
AllActions,
|
||||||
|
#[strum(serialize = "s3:AbortMultipartUpload")]
|
||||||
|
AbortMultipartUploadAction,
|
||||||
|
#[strum(serialize = "s3:CreateBucket")]
|
||||||
|
CreateBucketAction,
|
||||||
|
#[strum(serialize = "s3:DeleteBucket")]
|
||||||
|
DeleteBucketAction,
|
||||||
|
#[strum(serialize = "s3:ForceDeleteBucket")]
|
||||||
|
ForceDeleteBucketAction,
|
||||||
|
#[strum(serialize = "s3:DeleteBucketPolicy")]
|
||||||
|
DeleteBucketPolicyAction,
|
||||||
|
#[strum(serialize = "s3:DeleteBucketCors")]
|
||||||
|
DeleteBucketCorsAction,
|
||||||
|
#[strum(serialize = "s3:DeleteObject")]
|
||||||
|
DeleteObjectAction,
|
||||||
#[strum(serialize = "s3:GetBucketLocation")]
|
#[strum(serialize = "s3:GetBucketLocation")]
|
||||||
GetBucketLocationAction,
|
GetBucketLocationAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketNotification")]
|
||||||
|
GetBucketNotificationAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketPolicy")]
|
||||||
|
GetBucketPolicyAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketCors")]
|
||||||
|
GetBucketCorsAction,
|
||||||
#[strum(serialize = "s3:GetObject")]
|
#[strum(serialize = "s3:GetObject")]
|
||||||
GetObjectAction,
|
GetObjectAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectAttributes")]
|
||||||
|
GetObjectAttributesAction,
|
||||||
|
#[strum(serialize = "s3:HeadBucket")]
|
||||||
|
HeadBucketAction,
|
||||||
|
#[strum(serialize = "s3:ListAllMyBuckets")]
|
||||||
|
ListAllMyBucketsAction,
|
||||||
|
#[strum(serialize = "s3:ListBucket")]
|
||||||
|
ListBucketAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketPolicyStatus")]
|
||||||
|
GetBucketPolicyStatusAction,
|
||||||
|
#[strum(serialize = "s3:ListBucketVersions")]
|
||||||
|
ListBucketVersionsAction,
|
||||||
|
#[strum(serialize = "s3:ListBucketMultipartUploads")]
|
||||||
|
ListBucketMultipartUploadsAction,
|
||||||
|
#[strum(serialize = "s3:ListenNotification")]
|
||||||
|
ListenNotificationAction,
|
||||||
|
#[strum(serialize = "s3:ListenBucketNotification")]
|
||||||
|
ListenBucketNotificationAction,
|
||||||
|
#[strum(serialize = "s3:ListMultipartUploadParts")]
|
||||||
|
ListMultipartUploadPartsAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketLifecycle")]
|
||||||
|
PutBucketLifecycleAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketLifecycle")]
|
||||||
|
GetBucketLifecycleAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketNotification")]
|
||||||
|
PutBucketNotificationAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketPolicy")]
|
||||||
|
PutBucketPolicyAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketCors")]
|
||||||
|
PutBucketCorsAction,
|
||||||
#[strum(serialize = "s3:PutObject")]
|
#[strum(serialize = "s3:PutObject")]
|
||||||
PutObjectAction,
|
PutObjectAction,
|
||||||
|
#[strum(serialize = "s3:DeleteObjectVersion")]
|
||||||
|
DeleteObjectVersionAction,
|
||||||
|
#[strum(serialize = "s3:DeleteObjectVersionTagging")]
|
||||||
|
DeleteObjectVersionTaggingAction,
|
||||||
#[strum(serialize = "s3:GetObjectVersion")]
|
#[strum(serialize = "s3:GetObjectVersion")]
|
||||||
GetObjectVersionAction,
|
GetObjectVersionAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectVersionAttributes")]
|
||||||
|
GetObjectVersionAttributesAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectVersionTagging")]
|
||||||
|
GetObjectVersionTaggingAction,
|
||||||
|
#[strum(serialize = "s3:PutObjectVersionTagging")]
|
||||||
|
PutObjectVersionTaggingAction,
|
||||||
|
#[strum(serialize = "s3:BypassGovernanceRetention")]
|
||||||
|
BypassGovernanceRetentionAction,
|
||||||
|
#[strum(serialize = "s3:PutObjectRetention")]
|
||||||
|
PutObjectRetentionAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectRetention")]
|
||||||
|
GetObjectRetentionAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectLegalHold")]
|
||||||
|
GetObjectLegalHoldAction,
|
||||||
|
#[strum(serialize = "s3:PutObjectLegalHold")]
|
||||||
|
PutObjectLegalHoldAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketObjectLockConfiguration")]
|
||||||
|
GetBucketObjectLockConfigurationAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketObjectLockConfiguration")]
|
||||||
|
PutBucketObjectLockConfigurationAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketTagging")]
|
||||||
|
GetBucketTaggingAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketTagging")]
|
||||||
|
PutBucketTaggingAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectTagging")]
|
||||||
|
GetObjectTaggingAction,
|
||||||
|
#[strum(serialize = "s3:PutObjectTagging")]
|
||||||
|
PutObjectTaggingAction,
|
||||||
|
#[strum(serialize = "s3:DeleteObjectTagging")]
|
||||||
|
DeleteObjectTaggingAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketEncryption")]
|
||||||
|
PutBucketEncryptionAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketEncryption")]
|
||||||
|
GetBucketEncryptionAction,
|
||||||
|
#[strum(serialize = "s3:PutBucketVersioning")]
|
||||||
|
PutBucketVersioningAction,
|
||||||
|
#[strum(serialize = "s3:GetBucketVersioning")]
|
||||||
|
GetBucketVersioningAction,
|
||||||
|
#[strum(serialize = "s3:GetReplicationConfiguration")]
|
||||||
|
GetReplicationConfigurationAction,
|
||||||
|
#[strum(serialize = "s3:PutReplicationConfiguration")]
|
||||||
|
PutReplicationConfigurationAction,
|
||||||
|
#[strum(serialize = "s3:ReplicateObject")]
|
||||||
|
ReplicateObjectAction,
|
||||||
|
#[strum(serialize = "s3:ReplicateDelete")]
|
||||||
|
ReplicateDeleteAction,
|
||||||
|
#[strum(serialize = "s3:ReplicateTags")]
|
||||||
|
ReplicateTagsAction,
|
||||||
|
#[strum(serialize = "s3:GetObjectVersionForReplication")]
|
||||||
|
GetObjectVersionForReplicationAction,
|
||||||
|
#[strum(serialize = "s3:RestoreObject")]
|
||||||
|
RestoreObjectAction,
|
||||||
|
#[strum(serialize = "s3:ResetBucketReplicationState")]
|
||||||
|
ResetBucketReplicationStateAction,
|
||||||
|
#[strum(serialize = "s3:PutObjectFanOut")]
|
||||||
|
PutObjectFanOutAction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug)]
|
#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug)]
|
||||||
|
|||||||
@@ -131,9 +131,9 @@ impl<'de> Deserialize<'de> for Functions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if inner_data.is_empty() {
|
// if inner_data.is_empty() {
|
||||||
return Err(Error::custom("has no condition element"));
|
// return Err(Error::custom("has no condition element"));
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(inner_data)
|
Ok(inner_data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ pub enum S3KeyName {
|
|||||||
|
|
||||||
#[strum(serialize = "s3:ExistingObjectTag")]
|
#[strum(serialize = "s3:ExistingObjectTag")]
|
||||||
S3ExistingObjectTag,
|
S3ExistingObjectTag,
|
||||||
|
#[strum(serialize = "s3:RequestObjectTagKeys")]
|
||||||
|
S3RequestObjectTagKeys,
|
||||||
|
#[strum(serialize = "s3:RequestObjectTag")]
|
||||||
|
S3RequestObjectTag,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, EnumString, Debug, IntoStaticStr, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, EnumString, Debug, IntoStaticStr, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
||||||
pub struct Policy {
|
pub struct Policy {
|
||||||
|
#[serde(default, rename = "ID")]
|
||||||
pub id: ID,
|
pub id: ID,
|
||||||
|
#[serde(rename = "Version")]
|
||||||
pub version: String,
|
pub version: String,
|
||||||
|
#[serde(rename = "Statement")]
|
||||||
pub statements: Vec<Statement>,
|
pub statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +156,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -177,6 +181,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -200,6 +205,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -223,6 +229,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -253,6 +260,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -273,6 +281,7 @@ pub mod default {
|
|||||||
not_actions: ActionSet(Default::default()),
|
not_actions: ActionSet(Default::default()),
|
||||||
resources: ResourceSet(HashSet::new()),
|
resources: ResourceSet(HashSet::new()),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
Statement {
|
Statement {
|
||||||
sid: "".into(),
|
sid: "".into(),
|
||||||
@@ -285,6 +294,7 @@ pub mod default {
|
|||||||
not_actions: ActionSet(Default::default()),
|
not_actions: ActionSet(Default::default()),
|
||||||
resources: ResourceSet(HashSet::new()),
|
resources: ResourceSet(HashSet::new()),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
Statement {
|
Statement {
|
||||||
sid: "".into(),
|
sid: "".into(),
|
||||||
@@ -301,6 +311,7 @@ pub mod default {
|
|||||||
hash_set
|
hash_set
|
||||||
}),
|
}),
|
||||||
conditions: Functions::default(),
|
conditions: Functions::default(),
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -308,3 +319,76 @@ pub mod default {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use ecstore::error::Result;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_parse_policy() -> Result<()> {
|
||||||
|
let data = r#"
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["s3:GetObject"],
|
||||||
|
"Resource": ["arn:aws:s3:::dada/*"],
|
||||||
|
"Condition": {
|
||||||
|
"StringEquals": {
|
||||||
|
"s3:ExistingObjectTag/security": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["s3:DeleteObjectTagging"],
|
||||||
|
"Resource": ["arn:aws:s3:::dada/*"],
|
||||||
|
"Condition": {
|
||||||
|
"StringEquals": {
|
||||||
|
"s3:ExistingObjectTag/security": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["s3:DeleteObject"],
|
||||||
|
"Resource": ["arn:aws:s3:::dada/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:PutObject"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::dada/*"
|
||||||
|
],
|
||||||
|
"Condition": {
|
||||||
|
"ForAllValues:StringLike": {
|
||||||
|
"s3:RequestObjectTagKeys": [
|
||||||
|
"security",
|
||||||
|
"virus"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let p = Policy::parse_config(data.as_bytes())?;
|
||||||
|
|
||||||
|
// println!("{:?}", p);
|
||||||
|
|
||||||
|
let str = serde_json::to_string(&p)?;
|
||||||
|
|
||||||
|
// println!("----- {}", str);
|
||||||
|
|
||||||
|
let _p2 = Policy::parse_config(str.as_bytes())?;
|
||||||
|
// println!("33{:?}", p2);
|
||||||
|
|
||||||
|
// assert_eq!(p, p2);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl PartialEq for ResourceSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq, Serialize, Deserialize, Clone, Debug)]
|
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
|
||||||
pub enum Resource {
|
pub enum Resource {
|
||||||
S3(String),
|
S3(String),
|
||||||
Kms(String),
|
Kms(String),
|
||||||
@@ -140,6 +140,28 @@ impl Validator for Resource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Resource {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Resource::S3(s) => serializer.serialize_str(&format!("{}{}", Self::S3_PREFIX, s)),
|
||||||
|
Resource::Kms(s) => serializer.serialize_str(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Resource {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let value = String::deserialize(deserializer)?;
|
||||||
|
Resource::try_from(value.as_str()).map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::policy::resource::Resource;
|
use crate::policy::resource::Resource;
|
||||||
|
|||||||
@@ -6,11 +6,19 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
||||||
pub struct Statement {
|
pub struct Statement {
|
||||||
|
#[serde(rename = "Sid", default)]
|
||||||
pub sid: ID,
|
pub sid: ID,
|
||||||
|
#[serde(rename = "Effect")]
|
||||||
pub effect: Effect,
|
pub effect: Effect,
|
||||||
|
#[serde(rename = "Action")]
|
||||||
pub actions: ActionSet,
|
pub actions: ActionSet,
|
||||||
|
#[serde(rename = "NotAction", default)]
|
||||||
pub not_actions: ActionSet,
|
pub not_actions: ActionSet,
|
||||||
|
#[serde(rename = "Resource", default)]
|
||||||
pub resources: ResourceSet,
|
pub resources: ResourceSet,
|
||||||
|
#[serde(rename = "NotResource", default)]
|
||||||
|
pub not_resources: ResourceSet,
|
||||||
|
#[serde(rename = "Condition", default)]
|
||||||
pub conditions: Functions,
|
pub conditions: Functions,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +92,7 @@ impl Validator for Statement {
|
|||||||
// check sid
|
// check sid
|
||||||
self.sid.is_valid()?;
|
self.sid.is_valid()?;
|
||||||
|
|
||||||
if self.actions.is_empty() || self.not_actions.is_empty() {
|
if self.actions.is_empty() && self.not_actions.is_empty() {
|
||||||
return Err(IamError::NonAction.into());
|
return Err(IamError::NonAction.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:GetObject"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::dada/*"
|
||||||
|
],
|
||||||
|
"Condition": {
|
||||||
|
"StringEquals": {
|
||||||
|
"s3:ExistingObjectTag/security": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:DeleteObjectTagging"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::dada/*"
|
||||||
|
],
|
||||||
|
"Condition": {
|
||||||
|
"StringEquals": {
|
||||||
|
"s3:ExistingObjectTag/security": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:DeleteObject"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::dada/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:PutObject"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::dada/*"
|
||||||
|
],
|
||||||
|
"Condition": {
|
||||||
|
"ForAllValues:StringLike": {
|
||||||
|
"s3:RequestObjectTagKeys": [
|
||||||
|
"security",
|
||||||
|
"virus"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user