azure_storage/shared_access_signature/
mod.rs

1use std::fmt;
2use time::OffsetDateTime;
3
4pub mod account_sas;
5pub mod service_sas;
6
7pub trait SasToken {
8    fn token(&self) -> azure_core::Result<String>;
9}
10
11/// Converts an `OffsetDateTime` to an RFC3339 formatted string after truncating
12/// any partial seconds.
13pub(crate) fn format_date(d: OffsetDateTime) -> String {
14    // When validating signatures, Azure Storage server creates a canonicalized
15    // version of the request, then verifies the signature from the request with
16    // the canonicalized version.
17    //
18    // The canonicalization at the server truncates the timestamps without
19    // microseconds or nanoseconds.  As such, this needs to be truncated here
20    // too.
21    //
22    // replacing nanosecond with 0 is known to not panic
23    azure_core::date::to_rfc3339(&d.replace_nanosecond(0).unwrap())
24}
25
26/// Specifies the protocol permitted for a request made with the SAS ([Azure documentation](https://docs.microsoft.com/rest/api/storageservices/create-service-sas#specifying-the-http-protocol)).
27#[derive(Copy, Clone, PartialEq, Eq, Debug)]
28pub enum SasProtocol {
29    Https,
30    HttpHttps,
31}
32
33impl fmt::Display for SasProtocol {
34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35        match *self {
36            SasProtocol::Https => write!(f, "https"),
37            SasProtocol::HttpHttps => write!(f, "http,https"),
38        }
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use time::macros::datetime;
46
47    #[test]
48    // verify format_date truncates as expected.
49    fn test_format_date_truncation() {
50        let date = datetime!(2022-08-22 15:11:43.4185122 +00:00:00);
51        assert_eq!(format_date(date), "2022-08-22T15:11:43Z");
52    }
53}