Skip to content

Commit e608df4

Browse files
fix(service): Reject resumable tokens without an expiration policy
Co-Authored-By: Lorenzo Cian <17258265+lcian@users.noreply.github.com>
1 parent 085c0db commit e608df4

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

‎objectstore-service/src/backend/tiered.rs‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ use base64::Engine as _;
124124
use bytes::Bytes;
125125
use futures_util::StreamExt;
126126
use objectstore_metrics::TimerGuard;
127-
use objectstore_types::metadata::Metadata;
127+
use objectstore_types::metadata::{ExpirationPolicy, Metadata};
128128
use objectstore_types::range::ByteRange;
129129
use objectstore_types::resumable::UploadProgress;
130130
use objectstore_types::time::Timestamp;
@@ -490,10 +490,11 @@ type LongTermBackendToken = BackendToken;
490490
struct TieredResumableToken {
491491
inner: LongTermBackendToken,
492492
revision: String,
493-
/// Duration of a time-based expiration policy, applied from the commit time.
493+
/// Expiration policy requested for the object, applied from the commit time.
494494
///
495-
/// `None` for manual expiration.
496-
expires_in: Option<Duration>,
495+
/// Required, so tokens issued before this field existed fail to decode instead of
496+
/// committing without an expiry.
497+
expiration_policy: ExpirationPolicy,
497498
}
498499

499500
impl TieredResumableToken {
@@ -582,7 +583,7 @@ impl Backend for TieredStorage {
582583
let token = TieredResumableToken {
583584
revision: revision.key,
584585
inner,
585-
expires_in: metadata.expiration_policy.expires_in(),
586+
expiration_policy: metadata.expiration_policy,
586587
};
587588
Ok(Some(serde_json::to_string(&token).context(
588589
ErrorKind::Internal,
@@ -605,7 +606,7 @@ impl Backend for TieredStorage {
605606
backend_type = self.backend_type(&BackendChoice::LongTerm),
606607
);
607608
let tiered = TieredResumableToken::decode(&session.backend_token)?;
608-
let expires_in = tiered.expires_in;
609+
let expires_in = tiered.expiration_policy.expires_in();
609610
let inner_session = tiered.into_inner_session(session);
610611
let id = &session.object_id;
611612
let revision = &inner_session.object_id;
@@ -1807,6 +1808,17 @@ mod tests {
18071808
Ok(())
18081809
}
18091810

1811+
#[test]
1812+
fn resumable_token_requires_expiration_policy() {
1813+
let legacy = r#"{"inner":"token","revision":"key/rev","time_expires":null}"#;
1814+
assert_eq!(
1815+
TieredResumableToken::decode(&legacy.to_owned())
1816+
.unwrap_err()
1817+
.kind(),
1818+
ErrorKind::UnknownUploadSession
1819+
);
1820+
}
1821+
18101822
#[tokio::test]
18111823
async fn resumable_commit_requires_confirmed_expiry() {
18121824
let (storage, hv, _, events) = tiered_with_expiry_hooks(false, true);

0 commit comments

Comments
 (0)