Skip to main content

greentic_deployer/bundle_upload/
types.rs

1use 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    /// S3 SigV4 hard limit on presigned URL expiry.
27    pub const S3_MAX_PRESIGN_EXPIRES_SECS: u64 = 604800;
28
29    /// Clamp expiry to S3 maximum.
30    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}