azure_storage_blobs/service/operations/
get_user_delegation_key.rs1use crate::prelude::BlobServiceClient;
2use azure_core::{
3 date::iso8601,
4 headers::Headers,
5 xml::{read_xml_str, to_xml},
6 Method,
7};
8use azure_storage::{
9 headers::CommonStorageResponseHeaders, shared_access_signature::service_sas::UserDeligationKey,
10};
11use bytes::{Bytes, BytesMut};
12use time::OffsetDateTime;
13
14operation! {
15 GetUserDelegationKey,
16 client: BlobServiceClient,
17 start_time: OffsetDateTime,
18 expiry_time: OffsetDateTime,
19}
20
21impl GetUserDelegationKeyBuilder {
22 pub fn into_future(mut self) -> GetUserDelegationKey {
23 Box::pin(async move {
24 let mut url = self.client.url()?;
25
26 url.query_pairs_mut()
27 .extend_pairs([("restype", "service"), ("comp", "userdelegationkey")]);
28
29 let body = GetUserDelegationKeyRequest {
30 start: self.start_time,
31 expiry: self.expiry_time,
32 }
33 .encode()?;
34
35 let mut request = BlobServiceClient::finalize_request(
36 url,
37 Method::Post,
38 Headers::new(),
39 Some(body.into()),
40 )?;
41
42 let response = self.client.send(&mut self.context, &mut request).await?;
43
44 let (_, headers, body) = response.deconstruct();
45 let body = body.collect_string().await?;
46 GetUserDelegationKeyResponse::try_from(&headers, &body)
47 })
48 }
49}
50
51#[derive(Serialize)]
52#[serde(rename = "KeyInfo")]
53struct GetUserDelegationKeyRequest {
54 #[serde(rename = "Start", with = "iso8601")]
55 start: OffsetDateTime,
56 #[serde(rename = "Expiry", with = "iso8601")]
57 expiry: OffsetDateTime,
58}
59
60impl GetUserDelegationKeyRequest {
61 pub fn encode(&self) -> azure_core::Result<Bytes> {
62 let mut body = BytesMut::from("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
63 body.extend(to_xml(self)?);
64 Ok(body.freeze())
65 }
66}
67
68#[derive(Debug)]
69pub struct GetUserDelegationKeyResponse {
70 pub common: CommonStorageResponseHeaders,
71 pub user_deligation_key: UserDeligationKey,
72}
73
74impl GetUserDelegationKeyResponse {
75 pub(crate) fn try_from(headers: &Headers, body: &str) -> azure_core::Result<Self> {
76 let common = CommonStorageResponseHeaders::try_from(headers)?;
77 let user_deligation_key: UserDeligationKey = read_xml_str(body)?;
78
79 Ok(Self {
80 common,
81 user_deligation_key,
82 })
83 }
84}
85
86#[cfg(test)]
87mod test {
88 use super::*;
89 use azure_core::auth::Secret;
90 use uuid::Uuid;
91
92 const BASIC_REQUEST: &[u8] = b"<?xml version=\"1.0\" encoding=\"utf-8\"?><KeyInfo><Start>1970-01-01T00:00:00Z</Start><Expiry>1970-01-01T00:00:01Z</Expiry></KeyInfo>";
93 const BASIC_RESPONSE: &str = "
94 <UserDeligationKey>
95 <SignedOid>00000000-0000-0000-0000-000000000000</SignedOid>
96 <SignedTid>00000000-0000-0000-0000-000000000001</SignedTid>
97 <SignedStart>1970-01-01T00:00:00Z</SignedStart>
98 <SignedExpiry>1970-01-01T00:00:01Z</SignedExpiry>
99 <SignedService>b</SignedService>
100 <SignedVersion>c</SignedVersion>
101 <Value>d</Value>
102 </UserDeligationKey>
103 ";
104
105 #[test]
106 fn request_xml() -> azure_core::Result<()> {
107 let request = GetUserDelegationKeyRequest {
108 start: OffsetDateTime::from_unix_timestamp(0).unwrap(),
109 expiry: OffsetDateTime::from_unix_timestamp(1).unwrap(),
110 }
111 .encode()?;
112 assert_eq!(BASIC_REQUEST, request);
113 Ok(())
114 }
115
116 #[test]
117 fn parse_response() -> azure_core::Result<()> {
118 let expected = UserDeligationKey {
119 signed_oid: Uuid::from_u128(0),
120 signed_tid: Uuid::from_u128(1),
121 signed_start: OffsetDateTime::from_unix_timestamp(0).unwrap(),
122 signed_expiry: OffsetDateTime::from_unix_timestamp(1).unwrap(),
123 signed_service: "b".to_owned(),
124 signed_version: "c".to_owned(),
125 value: Secret::new("d"),
126 };
127
128 let deserialized: UserDeligationKey = read_xml_str(BASIC_RESPONSE)?;
129 assert_eq!(deserialized, expected);
130
131 Ok(())
132 }
133}