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