Skip to content

Commit b2288ad

Browse files
CopilotovertrueCopilot
authored
fix: always include expiration field in service-account create request (#29)
* Initial plan * fix: always include expiration field in service-account create request The CreateServiceAccountRequest was using skip_serializing_if on the expiry field, which omitted the expiration key from the JSON body when not provided. RustFS server requires this field to be present. Remove the skip_serializing_if attribute so the field always serializes (as null when not set). Co-authored-by: overtrue <1472352+overtrue@users.noreply.github.com> * Update crates/core/src/admin/types.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: 安正超 <anzhengchao@gmail.com> * Update crates/core/src/admin/types.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: 安正超 <anzhengchao@gmail.com> --------- Signed-off-by: 安正超 <anzhengchao@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: overtrue <1472352+overtrue@users.noreply.github.com> Co-authored-by: 安正超 <anzhengchao@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent b92d261 commit b2288ad

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

crates/core/src/admin/types.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ pub struct CreateServiceAccountRequest {
315315
#[serde(skip_serializing_if = "Option::is_none")]
316316
pub policy: Option<String>,
317317

318-
/// Optional expiration time (ISO 8601 format)
319-
#[serde(rename = "expiration", skip_serializing_if = "Option::is_none")]
318+
/// Expiration time (ISO 8601). The `expiration` field must be present in the request body; use null when no expiration is set.
319+
#[serde(rename = "expiration")]
320320
pub expiry: Option<String>,
321321

322322
/// Optional name/description
@@ -481,6 +481,48 @@ mod tests {
481481
assert!("invalid".parse::<GroupStatus>().is_err());
482482
}
483483

484+
#[test]
485+
fn test_create_service_account_request_includes_expiration() {
486+
let request = CreateServiceAccountRequest {
487+
policy: None,
488+
expiry: None,
489+
name: None,
490+
description: None,
491+
access_key: "myaccesskey".to_string(),
492+
secret_key: "mysecretkey".to_string(),
493+
};
494+
495+
let json = serde_json::to_string(&request).unwrap();
496+
// expiration field must always be present even when None
497+
assert!(
498+
json.contains("\"expiration\""),
499+
"JSON must contain expiration field, got: {json}"
500+
);
501+
502+
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
503+
assert!(parsed.get("expiration").is_some());
504+
assert!(parsed["expiration"].is_null());
505+
}
506+
507+
#[test]
508+
fn test_create_service_account_request_with_expiry() {
509+
let request = CreateServiceAccountRequest {
510+
policy: None,
511+
expiry: Some("2025-12-31T23:59:59Z".to_string()),
512+
name: None,
513+
description: None,
514+
access_key: "myaccesskey".to_string(),
515+
secret_key: "mysecretkey".to_string(),
516+
};
517+
518+
let json = serde_json::to_string(&request).unwrap();
519+
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
520+
assert_eq!(
521+
parsed.get("expiration").and_then(|v| v.as_str()),
522+
Some("2025-12-31T23:59:59Z")
523+
);
524+
}
525+
484526
#[test]
485527
fn test_bucket_quota_serialization() {
486528
let quota = BucketQuota {

0 commit comments

Comments
 (0)