greentic_deployer/bundle_upload/
types.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct UploadedBundle {
6 pub url: String,
7 pub digest: String,
8 pub expires_at: Option<DateTime<Utc>>,
9 pub object_ref: String,
10}
11
12#[derive(Debug, Clone)]
13pub struct UploadOptions {
14 pub presign_expires_secs: u64,
15}
16
17impl Default for UploadOptions {
18 fn default() -> Self {
19 Self {
20 presign_expires_secs: 604800,
21 }
22 }
23}
24
25impl UploadOptions {
26 pub const S3_MAX_PRESIGN_EXPIRES_SECS: u64 = 604800;
28
29 pub fn clamped_for_s3(&self) -> u64 {
31 self.presign_expires_secs
32 .min(Self::S3_MAX_PRESIGN_EXPIRES_SECS)
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn default_expiry_is_seven_days() {
42 let opts = UploadOptions::default();
43 assert_eq!(opts.presign_expires_secs, 604800);
44 }
45
46 #[test]
47 fn s3_clamp_caps_at_seven_days() {
48 let opts = UploadOptions {
49 presign_expires_secs: 9_999_999,
50 };
51 assert_eq!(opts.clamped_for_s3(), 604800);
52 }
53
54 #[test]
55 fn s3_clamp_passes_smaller_values_through() {
56 let opts = UploadOptions {
57 presign_expires_secs: 3600,
58 };
59 assert_eq!(opts.clamped_for_s3(), 3600);
60 }
61
62 #[test]
63 fn uploaded_bundle_serializes_to_json() {
64 let bundle = UploadedBundle {
65 url: "https://example.com/bundle".to_string(),
66 digest: "sha256:abc".to_string(),
67 expires_at: None,
68 object_ref: "s3://bucket/key".to_string(),
69 };
70 let json = serde_json::to_string(&bundle).unwrap();
71 assert!(json.contains("\"url\":\"https://example.com/bundle\""));
72 assert!(json.contains("\"digest\":\"sha256:abc\""));
73 }
74}