From 6ce096178084f03b00c461674458e250eb8bb626 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Sun, 9 Aug 2026 14:10:25 +0800 Subject: [PATCH] fix(policy): accept object lock mode condition (#5874) --- crates/policy/src/policy/function/key_name.rs | 6 ++++++ crates/policy/src/policy/function/string.rs | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/policy/src/policy/function/key_name.rs b/crates/policy/src/policy/function/key_name.rs index 30158e3de..5b99ecaa5 100644 --- a/crates/policy/src/policy/function/key_name.rs +++ b/crates/policy/src/policy/function/key_name.rs @@ -198,6 +198,9 @@ pub enum S3KeyName { #[strum(serialize = "s3:object-lock-retain-until-date")] S3ObjectLockRetainUntilDate, + #[strum(serialize = "s3:object-lock-mode")] + S3ObjectLockMode, + #[strum(serialize = "s3:max-keys")] S3MaxKeys, @@ -385,6 +388,7 @@ mod tests { #[test_case("s3:x-amz-copy-source", KeyName::S3(S3KeyName::S3XAmzCopySource))] #[test_case("s3:VersionId", KeyName::S3(S3KeyName::S3VersionId) ; "aws_version_id")] #[test_case("s3:versionid", KeyName::S3(S3KeyName::S3VersionId) ; "minio_version_id")] + #[test_case("s3:object-lock-mode", KeyName::S3(S3KeyName::S3ObjectLockMode))] #[test_case("aws:SecureTransport", KeyName::Aws(AwsKeyName::AWSSecureTransport))] #[test_case("jwt:sub", KeyName::Jwt(JwtKeyName::JWTSub))] #[test_case("ldap:user", KeyName::Ldap(LdapKeyName::User))] @@ -407,6 +411,7 @@ mod tests { #[test_case("s3:x-amz-copy-source", KeyName::S3(S3KeyName::S3XAmzCopySource))] #[test_case("s3:VersionId", KeyName::S3(S3KeyName::S3VersionId) ; "aws_version_id")] #[test_case("s3:versionid", KeyName::S3(S3KeyName::S3VersionId) ; "minio_version_id")] + #[test_case("s3:object-lock-mode", KeyName::S3(S3KeyName::S3ObjectLockMode))] #[test_case("aws:SecureTransport", KeyName::Aws(AwsKeyName::AWSSecureTransport))] #[test_case("jwt:sub", KeyName::Jwt(JwtKeyName::JWTSub))] #[test_case("ldap:user", KeyName::Ldap(LdapKeyName::User))] @@ -425,6 +430,7 @@ mod tests { #[test_case("s3:x-amz-copy-source", KeyName::S3(S3KeyName::S3XAmzCopySource))] #[test_case("s3:versionid", KeyName::S3(S3KeyName::S3VersionId))] + #[test_case("s3:object-lock-mode", KeyName::S3(S3KeyName::S3ObjectLockMode))] #[test_case("aws:SecureTransport", KeyName::Aws(AwsKeyName::AWSSecureTransport))] #[test_case("jwt:sub", KeyName::Jwt(JwtKeyName::JWTSub))] #[test_case("ldap:user", KeyName::Ldap(LdapKeyName::User))] diff --git a/crates/policy/src/policy/function/string.rs b/crates/policy/src/policy/function/string.rs index 6368d21c5..cba2e6b3b 100644 --- a/crates/policy/src/policy/function/string.rs +++ b/crates/policy/src/policy/function/string.rs @@ -287,7 +287,7 @@ mod tests { }; use std::collections::HashMap; - use crate::policy::function::key_name::S3KeyName::S3LocationConstraint; + use crate::policy::function::key_name::S3KeyName::{S3LocationConstraint, S3ObjectLockMode}; use test_case::test_case; fn new_func(name: KeyName, variable: Option, values: Vec<&str>) -> StringFunc { @@ -308,6 +308,7 @@ mod tests { ))] #[test_case(r#"{"aws:username/value": ["johndoe", "aaa"]}"#, new_func(Aws(AWSUsername), Some("value".into()), vec!["johndoe", "aaa"] ))] + #[test_case(r#"{"s3:object-lock-mode": "COMPLIANCE"}"#, new_func(S3(S3ObjectLockMode), None, vec!["COMPLIANCE"]))] fn test_deser(input: &str, expect: StringFunc) -> Result<(), serde_json::Error> { let v: StringFunc = serde_json::from_str(input)?; assert_eq!(v, expect); @@ -410,6 +411,7 @@ mod tests { #[test_case(new_fkv("s3:ExistingObjectTag/security", vec!["public"]), false, vec![("ExistingObjectTag/project", vec!["webapp"])] => false ; "21")] #[test_case(new_fkv("s3:VersionId", vec!["version-1"]), false, vec![("versionid", vec!["version-1"])] => true ; "aws_version_id")] #[test_case(new_fkv("s3:versionid", vec!["version-1"]), false, vec![("versionid", vec!["version-1"])] => true ; "minio_version_id")] + #[test_case(new_fkv("s3:object-lock-mode", vec!["COMPLIANCE"]), false, vec![("object-lock-mode", vec!["COMPLIANCE"])] => true ; "object_lock_mode")] fn test_string_equals(s: FuncKeyValue, for_all: bool, values: Vec<(&str, Vec<&str>)>) -> bool { test_eval(s, for_all, false, false, values) }