rusty_s3/credentials/
serde.rs1use std::fmt::{self, Debug, Formatter};
2use std::mem;
3
4use jiff::Timestamp;
5use serde::Deserialize;
6use zeroize::Zeroize as _;
7
8use super::{Credentials, RotatingCredentials};
9
10#[derive(Clone, Deserialize)]
12pub struct Ec2SecurityCredentialsMetadataResponse {
13 #[serde(rename = "AccessKeyId")]
14 key: String,
15 #[serde(rename = "SecretAccessKey")]
16 secret: String,
17 #[serde(rename = "Token")]
18 token: String,
19 #[serde(rename = "Expiration")]
20 expiration: Timestamp,
21}
22
23impl Ec2SecurityCredentialsMetadataResponse {
24 pub fn deserialize(s: &str) -> Result<Self, serde_json::Error> {
33 serde_json::from_str(s)
34 }
35
36 #[inline]
38 #[must_use]
39 pub fn key(&self) -> &str {
40 &self.key
41 }
42
43 #[inline]
45 #[must_use]
46 pub fn secret(&self) -> &str {
47 &self.secret
48 }
49
50 #[inline]
52 #[must_use]
53 pub fn token(&self) -> &str {
54 &self.token
55 }
56
57 #[inline]
59 #[must_use]
60 pub const fn expiration(&self) -> Timestamp {
61 self.expiration
62 }
63
64 #[inline]
66 #[must_use]
67 pub fn into_credentials(mut self) -> Credentials {
68 let key = mem::take(&mut self.key);
69 let secret = mem::take(&mut self.secret);
70 let token = mem::take(&mut self.token);
71 Credentials::new_with_token(key, secret, token)
72 }
73
74 #[inline]
76 pub fn rotate_credentials(mut self, rotating: &RotatingCredentials) {
77 let key = mem::take(&mut self.key);
78 let secret = mem::take(&mut self.secret);
79 let token = mem::take(&mut self.token);
80 rotating.update(key, secret, Some(token));
81 }
82}
83
84impl Debug for Ec2SecurityCredentialsMetadataResponse {
85 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
86 f.debug_struct("Ec2SecurityCredentialsMetadataResponse")
87 .field("key", &self.key)
88 .finish_non_exhaustive()
89 }
90}
91
92impl Drop for Ec2SecurityCredentialsMetadataResponse {
93 fn drop(&mut self) {
94 self.secret.zeroize();
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use pretty_assertions::assert_eq;
101
102 use super::*;
103
104 #[test]
105 fn deserialize() {
106 let json = r#"{
107 "Code" : "Success",
108 "LastUpdated" : "2020-12-28T16:47:50Z",
109 "Type" : "AWS-HMAC",
110 "AccessKeyId" : "some_access_key",
111 "SecretAccessKey" : "some_secret_key",
112 "Token" : "some_token",
113 "Expiration" : "2020-12-28T23:10:09Z"
114}"#;
115
116 let deserialized = Ec2SecurityCredentialsMetadataResponse::deserialize(json).unwrap();
117 assert_eq!(deserialized.key(), "some_access_key");
118 assert_eq!(deserialized.secret(), "some_secret_key");
119 assert_eq!(deserialized.token(), "some_token");
120 assert_eq!(
122 deserialized
123 .expiration()
124 .duration_since(Timestamp::UNIX_EPOCH)
125 .as_secs(),
126 1609197009
127 );
128
129 let debug_output = format!("{deserialized:?}");
130 assert_eq!(
131 debug_output,
132 "Ec2SecurityCredentialsMetadataResponse { key: \"some_access_key\", .. }"
133 );
134 }
135}