mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 11:56:38 +00:00
feat: improve legacy metadata and admin compatibility (#2202)
This commit is contained in:
@@ -19,9 +19,27 @@ use super::Policy;
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
pub struct PolicyDoc {
|
||||
/// Version (omitempty), legacy: version.
|
||||
#[serde(rename = "Version", alias = "version", default)]
|
||||
pub version: i64,
|
||||
/// Policy, legacy: policy. Serialize as Policy.
|
||||
#[serde(rename = "Policy", alias = "policy")]
|
||||
pub policy: Policy,
|
||||
/// CreateDate (RFC3339), legacy: create_date. Serialize as CreateDate.
|
||||
#[serde(
|
||||
rename = "CreateDate",
|
||||
alias = "create_date",
|
||||
default,
|
||||
with = "crate::serde_datetime::option"
|
||||
)]
|
||||
pub create_date: Option<OffsetDateTime>,
|
||||
/// UpdateDate (RFC3339), legacy: update_date. Serialize as UpdateDate.
|
||||
#[serde(
|
||||
rename = "UpdateDate",
|
||||
alias = "update_date",
|
||||
default,
|
||||
with = "crate::serde_datetime::option"
|
||||
)]
|
||||
pub update_date: Option<OffsetDateTime>,
|
||||
}
|
||||
|
||||
@@ -73,3 +91,43 @@ impl TryFrom<Vec<u8>> for PolicyDoc {
|
||||
.map_err(|_| serde_json::Error::custom("Failed to parse as PolicyDoc or Policy".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::policy::Policy;
|
||||
|
||||
#[test]
|
||||
fn test_policy_doc_timestamps_serialize_as_rfc3339() {
|
||||
let policy = Policy::default();
|
||||
let doc = PolicyDoc::new(policy);
|
||||
let json = serde_json::to_string(&doc).expect("serialize");
|
||||
// RFC3339 uses 'T' between date and time and 'Z' or offset for UTC
|
||||
assert!(json.contains('T'), "PolicyDoc timestamps should be RFC3339 (contain 'T'); got: {}", json);
|
||||
assert!(
|
||||
json.contains('Z') || json.contains("+00:00"),
|
||||
"PolicyDoc timestamps should be RFC3339 (contain 'Z' or +00:00); got: {}",
|
||||
json
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_policy_doc_deserialize_minio_style_rfc3339_timestamps() {
|
||||
let minio_style = r#"{"Version":1,"Policy":{"Version":"2012-10-17","Statement":[]},"CreateDate":"2025-03-07T12:00:00Z","UpdateDate":"2025-03-07T12:00:00Z"}"#;
|
||||
let doc: PolicyDoc = serde_json::from_str(minio_style).expect("deserialize MinIO-style JSON");
|
||||
assert_eq!(doc.version, 1);
|
||||
assert!(doc.create_date.is_some());
|
||||
assert!(doc.update_date.is_some());
|
||||
}
|
||||
|
||||
/// Round-trip: serialize then deserialize PolicyDoc; timestamps must match.
|
||||
#[test]
|
||||
fn test_policy_doc_timestamp_roundtrip() {
|
||||
let policy = Policy::default();
|
||||
let doc = PolicyDoc::new(policy);
|
||||
let json = serde_json::to_string(&doc).expect("serialize");
|
||||
let restored: PolicyDoc = serde_json::from_str(&json).expect("deserialize");
|
||||
assert_eq!(doc.create_date, restored.create_date);
|
||||
assert_eq!(doc.update_date, restored.update_date);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ impl Args<'_> {
|
||||
pub struct Policy {
|
||||
#[serde(default, rename = "ID")]
|
||||
pub id: ID,
|
||||
#[serde(rename = "Version")]
|
||||
#[serde(default, rename = "Version")]
|
||||
pub version: String,
|
||||
#[serde(rename = "Statement")]
|
||||
#[serde(default, rename = "Statement")]
|
||||
pub statements: Vec<Statement>,
|
||||
}
|
||||
|
||||
@@ -1084,6 +1084,14 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_empty_policy_object_as_implied_policy() {
|
||||
let policy = Policy::parse_config(b"{}").expect("empty JSON object should parse");
|
||||
|
||||
assert!(policy.version.is_empty());
|
||||
assert!(policy.statements.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_statement_with_both_action_and_notaction_is_invalid() {
|
||||
// Test: A statement with both Action and NotAction returns BothActionAndNotAction error
|
||||
|
||||
Reference in New Issue
Block a user