bucketwarden_server/state/
storage.rs1use 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}