Skip to main content

bucketwarden_server/state/
storage.rs

1use super::*;
2
3fn default_bucket_region() -> String {
4    DEFAULT_BUCKET_REGION.to_string()
5}
6
7fn default_tenant_id() -> String {
8    DEFAULT_TENANT_ID.to_string()
9}
10
11fn default_request_payment_payer() -> String {
12    "BucketOwner".to_string()
13}
14
15#[derive(Clone, Debug, Deserialize, Serialize)]
16pub struct BucketState {
17    #[serde(default)]
18    pub owner: String,
19    #[serde(default = "default_tenant_id")]
20    pub tenant_id: String,
21    #[serde(default = "default_bucket_region")]
22    pub region: String,
23    #[serde(default)]
24    pub created_epoch_seconds: u64,
25    pub versioning: BucketVersioningStatus,
26    pub cors_rules: Vec<CorsRule>,
27    #[serde(default)]
28    pub logging: Option<String>,
29    #[serde(default)]
30    pub website: Option<BucketWebsiteConfiguration>,
31    pub policy: Option<BucketPolicyState>,
32    pub tags: BTreeMap<String, String>,
33    #[serde(default)]
34    pub accelerate_enabled: bool,
35    #[serde(default)]
36    pub abac_enabled: bool,
37    #[serde(default = "default_request_payment_payer")]
38    pub request_payment_payer: String,
39    #[serde(default)]
40    pub public_access_block: Option<BucketPublicAccessBlockState>,
41    #[serde(default)]
42    pub metadata_configuration: Option<BucketMetadataConfiguration>,
43    #[serde(default)]
44    pub metadata_table_configuration: Option<BucketMetadataTableConfiguration>,
45    #[serde(default)]
46    pub metrics_configurations: BTreeMap<String, MetricsConfiguration>,
47    #[serde(default)]
48    pub analytics_configurations: BTreeMap<String, AnalyticsConfiguration>,
49    #[serde(default)]
50    pub inventory_configurations: BTreeMap<String, InventoryConfiguration>,
51    #[serde(default)]
52    pub intelligent_tiering_configurations: BTreeMap<String, IntelligentTieringConfiguration>,
53    pub object_lock: BucketObjectLockState,
54    pub encryption: Option<ServerSideEncryption>,
55    pub lifecycle_rules: Vec<LifecycleRule>,
56    pub notification_rules: Vec<NotificationRule>,
57    pub replication: BucketReplicationState,
58    #[serde(default)]
59    pub quota: BucketQuotaConfiguration,
60    #[serde(default)]
61    pub request_count: u64,
62    #[serde(default)]
63    pub ownership: BucketOwnershipState,
64    pub objects: BTreeMap<String, ObjectState>,
65}
66
67impl Default for BucketState {
68    fn default() -> Self {
69        Self {
70            owner: String::default(),
71            tenant_id: default_tenant_id(),
72            region: default_bucket_region(),
73            created_epoch_seconds: 0,
74            versioning: BucketVersioningStatus::default(),
75            cors_rules: Vec::default(),
76            logging: None,
77            website: None,
78            policy: None,
79            tags: BTreeMap::default(),
80            accelerate_enabled: false,
81            abac_enabled: false,
82            request_payment_payer: default_request_payment_payer(),
83            public_access_block: None,
84            metadata_configuration: None,
85            metadata_table_configuration: None,
86            metrics_configurations: BTreeMap::default(),
87            analytics_configurations: BTreeMap::default(),
88            inventory_configurations: BTreeMap::default(),
89            intelligent_tiering_configurations: BTreeMap::default(),
90            object_lock: BucketObjectLockState::default(),
91            encryption: None,
92            lifecycle_rules: Vec::default(),
93            notification_rules: Vec::default(),
94            replication: BucketReplicationState::default(),
95            quota: BucketQuotaConfiguration::default(),
96            request_count: 0,
97            ownership: BucketOwnershipState::default(),
98            objects: BTreeMap::default(),
99        }
100    }
101}
102
103#[derive(Clone, Debug, Deserialize, Serialize)]
104pub struct BucketPolicyState {
105    pub json: String,
106    pub policy: Policy,
107}
108
109#[derive(Clone, Debug, Default, Deserialize, Serialize)]
110pub struct BucketPublicAccessBlockState {
111    pub block_public_acls: bool,
112    pub ignore_public_acls: bool,
113    pub block_public_policy: bool,
114    pub restrict_public_buckets: bool,
115}
116
117#[derive(Clone, Debug, Default, Deserialize, Serialize)]
118pub struct BucketObjectLockState {
119    pub enabled: bool,
120    pub default_retention: Option<ObjectLockDefaultRetention>,
121}
122
123#[derive(Clone, Debug, Default, Deserialize, Serialize)]
124pub struct BucketReplicationState {
125    pub role: Option<String>,
126    pub rules: Vec<ReplicationRule>,
127    #[serde(default)]
128    pub configured_epoch_seconds: u64,
129}
130
131#[derive(Clone, Debug, Deserialize, Serialize)]
132pub struct BucketOwnershipState {
133    pub object_ownership: String,
134}
135
136impl Default for BucketOwnershipState {
137    fn default() -> Self {
138        Self {
139            object_ownership: "BucketOwnerEnforced".to_string(),
140        }
141    }
142}
143
144#[derive(Clone, Debug, Default, Deserialize, Serialize)]
145pub struct ObjectState {
146    pub versions: Vec<StoredVersion>,
147}
148
149impl ObjectState {
150    pub(crate) fn next_local_ordinal(&self) -> u64 {
151        self.versions
152            .iter()
153            .map(|version| version.local_ordinal)
154            .max()
155            .unwrap_or_default()
156            + 1
157    }
158
159    pub(crate) fn normalize_missing_local_ordinals(&mut self) {
160        let mut used_ordinals = self
161            .versions
162            .iter()
163            .filter_map(|version| (version.local_ordinal > 0).then_some(version.local_ordinal))
164            .collect::<Vec<_>>();
165        for index in 0..self.versions.len() {
166            let version = &mut self.versions[index];
167            if version.local_ordinal == 0 {
168                let mut candidate = index as u64 + 1;
169                while used_ordinals.contains(&candidate) {
170                    candidate += 1;
171                }
172                version.local_ordinal = candidate;
173                used_ordinals.push(candidate);
174            }
175        }
176    }
177
178    pub(crate) fn current_version(&self) -> Option<&StoredVersion> {
179        self.versions
180            .last()
181            .and_then(|version| (!version.delete_marker).then_some(version))
182    }
183
184    pub(crate) fn current_version_mut(&mut self) -> Option<&mut StoredVersion> {
185        self.versions
186            .last_mut()
187            .and_then(|version| (!version.delete_marker).then_some(version))
188    }
189
190    pub(crate) fn has_current_version(&self) -> bool {
191        self.current_version().is_some()
192    }
193}
194
195#[derive(Clone, Debug, Deserialize, Serialize)]
196pub struct StoredVersion {
197    pub version_id: String,
198    #[serde(default)]
199    pub local_ordinal: u64,
200    pub ciphertext: Ciphertext,
201    pub etag: String,
202    pub last_modified_epoch_seconds: u64,
203    pub metadata: ObjectMetadata,
204    #[serde(default)]
205    pub envelope: Option<EnvelopeMetadata>,
206    #[serde(default)]
207    pub integrity: IntegrityRecord,
208    pub tags: BTreeMap<String, String>,
209    pub lock: ObjectLock,
210    pub delete_marker: bool,
211    #[serde(default)]
212    pub owner: String,
213    #[serde(default)]
214    pub replication_status: Option<String>,
215}
216
217impl StoredVersion {
218    pub(crate) fn content_length(&self) -> usize {
219        self.ciphertext.bytes.len()
220    }
221}
222
223#[derive(Clone, Debug, Deserialize, Serialize)]
224pub struct MultipartUploadState {
225    pub bucket: String,
226    pub key: String,
227    pub metadata: ObjectMetadata,
228    pub lock: ObjectLock,
229    pub initiated_epoch_seconds: u64,
230    pub parts: BTreeMap<u16, MultipartPartState>,
231}
232
233#[derive(Clone, Debug, Deserialize, Serialize)]
234pub struct MultipartPartState {
235    pub etag: String,
236    pub body: Vec<u8>,
237    #[serde(default)]
238    pub checksum_sha256: String,
239}