azure_storage_blobs/service/operations/
get_user_delegation_key.rs

1use 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}