From f85780ac25d35755c257b1339508aaf55aca90e2 Mon Sep 17 00:00:00 2001 From: Chris Pick Date: Tue, 26 Mar 2024 17:16:37 -0400 Subject: [PATCH 1/2] Add `SignedURLOptions.start_time` Allow the caller of `Client.signed_url()` to specify the time from which the URL will be valid. This allows signing URLs for future use. --- storage/src/sign.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/storage/src/sign.rs b/storage/src/sign.rs index 40a8a3c8..8e6bf5bc 100644 --- a/storage/src/sign.rs +++ b/storage/src/sign.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::fmt::{Debug, Formatter}; use std::ops::Deref; -use std::time::Duration; +use std::time::{Duration, SystemTime}; use base64::prelude::*; use once_cell::sync::Lazy; @@ -88,9 +88,14 @@ pub struct SignedURLOptions { /// Required. pub method: SignedURLMethod, - /// Expires is the expiration time on the signed URL. It must be - /// a datetime in the future. For SigningSchemeV4, the expiration may be no - /// more than seven days in the future. + /// StartTime is the time at which the signed URL starts being valid. + /// Defaults to the current time. + /// Optional. + pub start_time: Option, + + /// Expires is the duration of time, beginning at StartTime, within which + /// the signed URL is valid. For SigningSchemeV4, the duration may be no + /// more than 604800 seconds (7 days). /// Required. pub expires: std::time::Duration, @@ -136,6 +141,7 @@ impl Default for SignedURLOptions { fn default() -> Self { Self { method: SignedURLMethod::GET, + start_time: None, expires: std::time::Duration::from_secs(600), content_type: None, headers: vec![], @@ -165,8 +171,8 @@ pub(crate) fn create_signed_buffer( google_access_id: &str, opts: &SignedURLOptions, ) -> Result<(Vec, Url), SignedURLError> { - let now = OffsetDateTime::now_utc(); validate_options(opts)?; + let start_time: OffsetDateTime = opts.start_time.unwrap_or_else(|| SystemTime::now()).into(); let headers = v4_sanitize_headers(&opts.headers); // create base url @@ -199,10 +205,10 @@ pub(crate) fn create_signed_buffer( .set_time_precision(TimePrecision::Second { decimal_digits: None }) .encode(); - let timestamp = now.format(&Iso8601::).unwrap(); + let timestamp = start_time.format(&Iso8601::).unwrap(); let credential_scope = format!( "{}/auto/storage/goog4_request", - now.format(format_description!("[year][month][day]")).unwrap() + start_time.format(format_description!("[year][month][day]")).unwrap() ); // append query parameters From 9cf27dc71bcf9af4a3f33b31cf749303c80bc1b3 Mon Sep 17 00:00:00 2001 From: Chris Pick Date: Wed, 10 Apr 2024 17:05:12 -0400 Subject: [PATCH 2/2] Fix `SignedURLOptions.start_time` clippy warning Run `cargo clippy --fix`. https://github.com/yoshidan/google-cloud-rust/pull/246#issuecomment-2044304059 --- storage/src/sign.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/src/sign.rs b/storage/src/sign.rs index 8e6bf5bc..9dc21a72 100644 --- a/storage/src/sign.rs +++ b/storage/src/sign.rs @@ -172,7 +172,7 @@ pub(crate) fn create_signed_buffer( opts: &SignedURLOptions, ) -> Result<(Vec, Url), SignedURLError> { validate_options(opts)?; - let start_time: OffsetDateTime = opts.start_time.unwrap_or_else(|| SystemTime::now()).into(); + let start_time: OffsetDateTime = opts.start_time.unwrap_or_else(SystemTime::now).into(); let headers = v4_sanitize_headers(&opts.headers); // create base url