1use crate::error::{Error, Result};
16use serde::{Deserialize, Serialize};
17use std::{collections::HashSet, ops::Deref};
18use strum::{EnumString, IntoStaticStr};
19
20use super::{Error as IamError, Validator, utils::wildcard};
21
22#[derive(Serialize, Deserialize, Clone, Default, Debug)]
23pub struct ActionSet(pub HashSet<Action>);
24
25impl ActionSet {
26 pub fn is_match(&self, action: &Action) -> bool {
27 for act in self.0.iter() {
28 if act.is_match(action) {
29 return true;
30 }
31
32 if matches!(act, Action::S3Action(S3Action::GetObjectVersionAction))
33 && matches!(action, Action::S3Action(S3Action::GetObjectAction))
34 {
35 return true;
36 }
37 }
38
39 false
40 }
41}
42
43impl Deref for ActionSet {
44 type Target = HashSet<Action>;
45
46 fn deref(&self) -> &Self::Target {
47 &self.0
48 }
49}
50
51impl Validator for ActionSet {
52 type Error = Error;
53 fn is_valid(&self) -> Result<()> {
54 Ok(())
55 }
56}
57
58impl PartialEq for ActionSet {
59 fn eq(&self, other: &Self) -> bool {
60 self.len() == other.len() && self.0.iter().all(|x| other.0.contains(x))
61 }
62}
63
64#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Debug, Copy)]
65#[serde(try_from = "&str", untagged)]
66pub enum Action {
67 S3Action(S3Action),
68 AdminAction(AdminAction),
69 StsAction(StsAction),
70 KmsAction(KmsAction),
71 None,
72}
73
74impl Action {
75 pub fn is_match(&self, action: &Action) -> bool {
76 wildcard::is_match::<&str, &str>(self.into(), action.into())
77 }
78}
79
80impl From<&Action> for &str {
81 fn from(value: &Action) -> &'static str {
82 match value {
83 Action::S3Action(s) => s.into(),
84 Action::AdminAction(s) => s.into(),
85 Action::StsAction(s) => s.into(),
86 Action::KmsAction(s) => s.into(),
87 Action::None => "",
88 }
89 }
90}
91
92impl Action {
93 const S3_PREFIX: &'static str = "s3:";
94 const ADMIN_PREFIX: &'static str = "admin:";
95 const STS_PREFIX: &'static str = "sts:";
96 const KMS_PREFIX: &'static str = "kms:";
97}
98
99impl TryFrom<&str> for Action {
100 type Error = Error;
101 fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
102 if value.starts_with(Self::S3_PREFIX) {
103 Ok(Self::S3Action(
104 S3Action::try_from(value).map_err(|_| IamError::InvalidAction(value.into()))?,
105 ))
106 } else if value.starts_with(Self::ADMIN_PREFIX) {
107 Ok(Self::AdminAction(
108 AdminAction::try_from(value).map_err(|_| IamError::InvalidAction(value.into()))?,
109 ))
110 } else if value.starts_with(Self::STS_PREFIX) {
111 Ok(Self::StsAction(
112 StsAction::try_from(value).map_err(|_| IamError::InvalidAction(value.into()))?,
113 ))
114 } else if value.starts_with(Self::KMS_PREFIX) {
115 Ok(Self::KmsAction(
116 KmsAction::try_from(value).map_err(|_| IamError::InvalidAction(value.into()))?,
117 ))
118 } else {
119 Err(IamError::InvalidAction(value.into()).into())
120 }
121 }
122}
123
124#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug, Copy)]
125#[cfg_attr(test, derive(Default))]
126#[serde(try_from = "&str", into = "&str")]
127pub enum S3Action {
128 #[cfg_attr(test, default)]
129 #[strum(serialize = "s3:*")]
130 AllActions,
131 #[strum(serialize = "s3:AbortMultipartUpload")]
132 AbortMultipartUploadAction,
133 #[strum(serialize = "s3:CreateBucket")]
134 CreateBucketAction,
135 #[strum(serialize = "s3:DeleteBucket")]
136 DeleteBucketAction,
137 #[strum(serialize = "s3:ForceDeleteBucket")]
138 ForceDeleteBucketAction,
139 #[strum(serialize = "s3:DeleteBucketPolicy")]
140 DeleteBucketPolicyAction,
141 #[strum(serialize = "s3:DeleteBucketCors")]
142 DeleteBucketCorsAction,
143 #[strum(serialize = "s3:DeleteObject")]
144 DeleteObjectAction,
145 #[strum(serialize = "s3:GetBucketLocation")]
146 GetBucketLocationAction,
147 #[strum(serialize = "s3:GetBucketNotification")]
148 GetBucketNotificationAction,
149 #[strum(serialize = "s3:GetBucketPolicy")]
150 GetBucketPolicyAction,
151 #[strum(serialize = "s3:GetBucketCors")]
152 GetBucketCorsAction,
153 #[strum(serialize = "s3:GetObject")]
154 GetObjectAction,
155 #[strum(serialize = "s3:GetObjectAttributes")]
156 GetObjectAttributesAction,
157 #[strum(serialize = "s3:HeadBucket")]
158 HeadBucketAction,
159 #[strum(serialize = "s3:ListAllMyBuckets")]
160 ListAllMyBucketsAction,
161 #[strum(serialize = "s3:ListBucket")]
162 ListBucketAction,
163 #[strum(serialize = "s3:GetBucketPolicyStatus")]
164 GetBucketPolicyStatusAction,
165 #[strum(serialize = "s3:ListBucketVersions")]
166 ListBucketVersionsAction,
167 #[strum(serialize = "s3:ListBucketMultipartUploads")]
168 ListBucketMultipartUploadsAction,
169 #[strum(serialize = "s3:ListenNotification")]
170 ListenNotificationAction,
171 #[strum(serialize = "s3:ListenBucketNotification")]
172 ListenBucketNotificationAction,
173 #[strum(serialize = "s3:ListMultipartUploadParts")]
174 ListMultipartUploadPartsAction,
175 #[strum(serialize = "s3:PutBucketLifecycle")]
176 PutBucketLifecycleAction,
177 #[strum(serialize = "s3:GetBucketLifecycle")]
178 GetBucketLifecycleAction,
179 #[strum(serialize = "s3:PutBucketNotification")]
180 PutBucketNotificationAction,
181 #[strum(serialize = "s3:PutBucketPolicy")]
182 PutBucketPolicyAction,
183 #[strum(serialize = "s3:PutBucketCors")]
184 PutBucketCorsAction,
185 #[strum(serialize = "s3:PutObject")]
186 PutObjectAction,
187 #[strum(serialize = "s3:DeleteObjectVersion")]
188 DeleteObjectVersionAction,
189 #[strum(serialize = "s3:DeleteObjectVersionTagging")]
190 DeleteObjectVersionTaggingAction,
191 #[strum(serialize = "s3:GetObjectVersion")]
192 GetObjectVersionAction,
193 #[strum(serialize = "s3:GetObjectVersionAttributes")]
194 GetObjectVersionAttributesAction,
195 #[strum(serialize = "s3:GetObjectVersionTagging")]
196 GetObjectVersionTaggingAction,
197 #[strum(serialize = "s3:PutObjectVersionTagging")]
198 PutObjectVersionTaggingAction,
199 #[strum(serialize = "s3:BypassGovernanceRetention")]
200 BypassGovernanceRetentionAction,
201 #[strum(serialize = "s3:PutObjectRetention")]
202 PutObjectRetentionAction,
203 #[strum(serialize = "s3:GetObjectRetention")]
204 GetObjectRetentionAction,
205 #[strum(serialize = "s3:GetObjectLegalHold")]
206 GetObjectLegalHoldAction,
207 #[strum(serialize = "s3:PutObjectLegalHold")]
208 PutObjectLegalHoldAction,
209 #[strum(serialize = "s3:GetBucketObjectLockConfiguration")]
210 GetBucketObjectLockConfigurationAction,
211 #[strum(serialize = "s3:PutBucketObjectLockConfiguration")]
212 PutBucketObjectLockConfigurationAction,
213 #[strum(serialize = "s3:GetBucketTagging")]
214 GetBucketTaggingAction,
215 #[strum(serialize = "s3:PutBucketTagging")]
216 PutBucketTaggingAction,
217 #[strum(serialize = "s3:GetObjectTagging")]
218 GetObjectTaggingAction,
219 #[strum(serialize = "s3:PutObjectTagging")]
220 PutObjectTaggingAction,
221 #[strum(serialize = "s3:DeleteObjectTagging")]
222 DeleteObjectTaggingAction,
223 #[strum(serialize = "s3:PutBucketEncryption")]
224 PutBucketEncryptionAction,
225 #[strum(serialize = "s3:GetBucketEncryption")]
226 GetBucketEncryptionAction,
227 #[strum(serialize = "s3:PutBucketVersioning")]
228 PutBucketVersioningAction,
229 #[strum(serialize = "s3:GetBucketVersioning")]
230 GetBucketVersioningAction,
231 #[strum(serialize = "s3:GetReplicationConfiguration")]
232 GetReplicationConfigurationAction,
233 #[strum(serialize = "s3:PutReplicationConfiguration")]
234 PutReplicationConfigurationAction,
235 #[strum(serialize = "s3:ReplicateObject")]
236 ReplicateObjectAction,
237 #[strum(serialize = "s3:ReplicateDelete")]
238 ReplicateDeleteAction,
239 #[strum(serialize = "s3:ReplicateTags")]
240 ReplicateTagsAction,
241 #[strum(serialize = "s3:GetObjectVersionForReplication")]
242 GetObjectVersionForReplicationAction,
243 #[strum(serialize = "s3:RestoreObject")]
244 RestoreObjectAction,
245 #[strum(serialize = "s3:ResetBucketReplicationState")]
246 ResetBucketReplicationStateAction,
247 #[strum(serialize = "s3:PutObjectFanOut")]
248 PutObjectFanOutAction,
249}
250
251#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug, Copy)]
284#[serde(try_from = "&str", into = "&str")]
285pub enum AdminAction {
286 #[strum(serialize = "admin:Heal")]
287 HealAdminAction,
288 #[strum(serialize = "admin:Decommission")]
289 DecommissionAdminAction,
290 #[strum(serialize = "admin:Rebalance")]
291 RebalanceAdminAction,
292 #[strum(serialize = "admin:StorageInfo")]
293 StorageInfoAdminAction,
294 #[strum(serialize = "admin:Prometheus")]
295 PrometheusAdminAction,
296 #[strum(serialize = "admin:DataUsageInfo")]
297 DataUsageInfoAdminAction,
298 #[strum(serialize = "admin:ForceUnlock")]
299 ForceUnlockAdminAction,
300 #[strum(serialize = "admin:TopLocksInfo")]
301 TopLocksAdminAction,
302 #[strum(serialize = "admin:Profiling")]
303 ProfilingAdminAction,
304 #[strum(serialize = "admin:ServerTrace")]
305 TraceAdminAction,
306 #[strum(serialize = "admin:ConsoleLog")]
307 ConsoleLogAdminAction,
308 #[strum(serialize = "admin:KMSCreateKey")]
309 KMSCreateKeyAdminAction,
310 #[strum(serialize = "admin:KMSKeyStatus")]
311 KMSKeyStatusAdminAction,
312 #[strum(serialize = "admin:ServerInfo")]
313 ServerInfoAdminAction,
314 #[strum(serialize = "admin:OBDInfo")]
315 HealthInfoAdminAction,
316 #[strum(serialize = "admin:LicenseInfo")]
317 LicenseInfoAdminAction,
318 #[strum(serialize = "admin:BandwidthMonitor")]
319 BandwidthMonitorAction,
320 #[strum(serialize = "admin:InspectData")]
321 InspectDataAction,
322 #[strum(serialize = "admin:ServerUpdate")]
323 ServerUpdateAdminAction,
324 #[strum(serialize = "admin:ServiceRestart")]
325 ServiceRestartAdminAction,
326 #[strum(serialize = "admin:ServiceStop")]
327 ServiceStopAdminAction,
328 #[strum(serialize = "admin:ServiceFreeze")]
329 ServiceFreezeAdminAction,
330 #[strum(serialize = "admin:ConfigUpdate")]
331 ConfigUpdateAdminAction,
332 #[strum(serialize = "admin:CreateUser")]
333 CreateUserAdminAction,
334 #[strum(serialize = "admin:DeleteUser")]
335 DeleteUserAdminAction,
336 #[strum(serialize = "admin:ListUsers")]
337 ListUsersAdminAction,
338 #[strum(serialize = "admin:EnableUser")]
339 EnableUserAdminAction,
340 #[strum(serialize = "admin:DisableUser")]
341 DisableUserAdminAction,
342 #[strum(serialize = "admin:GetUser")]
343 GetUserAdminAction,
344 #[strum(serialize = "admin:SiteReplicationAdd")]
345 SiteReplicationAddAction,
346 #[strum(serialize = "admin:SiteReplicationDisable")]
347 SiteReplicationDisableAction,
348 #[strum(serialize = "admin:SiteReplicationRemove")]
349 SiteReplicationRemoveAction,
350 #[strum(serialize = "admin:SiteReplicationResync")]
351 SiteReplicationResyncAction,
352 #[strum(serialize = "admin:SiteReplicationInfo")]
353 SiteReplicationInfoAction,
354 #[strum(serialize = "admin:SiteReplicationOperation")]
355 SiteReplicationOperationAction,
356 #[strum(serialize = "admin:CreateServiceAccount")]
357 CreateServiceAccountAdminAction,
358 #[strum(serialize = "admin:UpdateServiceAccount")]
359 UpdateServiceAccountAdminAction,
360 #[strum(serialize = "admin:RemoveServiceAccount")]
361 RemoveServiceAccountAdminAction,
362 #[strum(serialize = "admin:ListServiceAccounts")]
363 ListServiceAccountsAdminAction,
364 #[strum(serialize = "admin:ListTemporaryAccounts")]
365 ListTemporaryAccountsAdminAction,
366 #[strum(serialize = "admin:AddUserToGroup")]
367 AddUserToGroupAdminAction,
368 #[strum(serialize = "admin:RemoveUserFromGroup")]
369 RemoveUserFromGroupAdminAction,
370 #[strum(serialize = "admin:GetGroup")]
371 GetGroupAdminAction,
372 #[strum(serialize = "admin:ListGroups")]
373 ListGroupsAdminAction,
374 #[strum(serialize = "admin:EnableGroup")]
375 EnableGroupAdminAction,
376 #[strum(serialize = "admin:DisableGroup")]
377 DisableGroupAdminAction,
378 #[strum(serialize = "admin:CreatePolicy")]
379 CreatePolicyAdminAction,
380 #[strum(serialize = "admin:DeletePolicy")]
381 DeletePolicyAdminAction,
382 #[strum(serialize = "admin:GetPolicy")]
383 GetPolicyAdminAction,
384 #[strum(serialize = "admin:AttachUserOrGroupPolicy")]
385 AttachPolicyAdminAction,
386 #[strum(serialize = "admin:UpdatePolicyAssociation")]
387 UpdatePolicyAssociationAction,
388 #[strum(serialize = "admin:ListUserPolicies")]
389 ListUserPoliciesAdminAction,
390 #[strum(serialize = "admin:SetBucketQuota")]
391 SetBucketQuotaAdminAction,
392 #[strum(serialize = "admin:GetBucketQuota")]
393 GetBucketQuotaAdminAction,
394 #[strum(serialize = "admin:SetBucketTarget")]
395 SetBucketTargetAction,
396 #[strum(serialize = "admin:GetBucketTarget")]
397 GetBucketTargetAction,
398 #[strum(serialize = "admin:ReplicationDiff")]
399 ReplicationDiff,
400 #[strum(serialize = "admin:ImportBucketMetadata")]
401 ImportBucketMetadataAction,
402 #[strum(serialize = "admin:ExportBucketMetadata")]
403 ExportBucketMetadataAction,
404 #[strum(serialize = "admin:SetTier")]
405 SetTierAction,
406 #[strum(serialize = "admin:ListTier")]
407 ListTierAction,
408 #[strum(serialize = "admin:ExportIAM")]
409 ExportIAMAction,
410 #[strum(serialize = "admin:ImportIAM")]
411 ImportIAMAction,
412 #[strum(serialize = "admin:ListBatchJobs")]
413 ListBatchJobsAction,
414 #[strum(serialize = "admin:DescribeBatchJob")]
415 DescribeBatchJobAction,
416 #[strum(serialize = "admin:StartBatchJob")]
417 StartBatchJobAction,
418 #[strum(serialize = "admin:CancelBatchJob")]
419 CancelBatchJobAction,
420 #[strum(serialize = "admin:*")]
421 AllAdminActions,
422}
423
424impl AdminAction {
425 pub fn is_valid(&self) -> bool {
427 matches!(
428 self,
429 AdminAction::HealAdminAction
430 | AdminAction::DecommissionAdminAction
431 | AdminAction::RebalanceAdminAction
432 | AdminAction::StorageInfoAdminAction
433 | AdminAction::PrometheusAdminAction
434 | AdminAction::DataUsageInfoAdminAction
435 | AdminAction::ForceUnlockAdminAction
436 | AdminAction::TopLocksAdminAction
437 | AdminAction::ProfilingAdminAction
438 | AdminAction::TraceAdminAction
439 | AdminAction::ConsoleLogAdminAction
440 | AdminAction::KMSCreateKeyAdminAction
441 | AdminAction::KMSKeyStatusAdminAction
442 | AdminAction::ServerInfoAdminAction
443 | AdminAction::HealthInfoAdminAction
444 | AdminAction::LicenseInfoAdminAction
445 | AdminAction::BandwidthMonitorAction
446 | AdminAction::InspectDataAction
447 | AdminAction::ServerUpdateAdminAction
448 | AdminAction::ServiceRestartAdminAction
449 | AdminAction::ServiceStopAdminAction
450 | AdminAction::ServiceFreezeAdminAction
451 | AdminAction::ConfigUpdateAdminAction
452 | AdminAction::CreateUserAdminAction
453 | AdminAction::DeleteUserAdminAction
454 | AdminAction::ListUsersAdminAction
455 | AdminAction::EnableUserAdminAction
456 | AdminAction::DisableUserAdminAction
457 | AdminAction::GetUserAdminAction
458 | AdminAction::SiteReplicationAddAction
459 | AdminAction::SiteReplicationDisableAction
460 | AdminAction::SiteReplicationRemoveAction
461 | AdminAction::SiteReplicationResyncAction
462 | AdminAction::SiteReplicationInfoAction
463 | AdminAction::SiteReplicationOperationAction
464 | AdminAction::CreateServiceAccountAdminAction
465 | AdminAction::UpdateServiceAccountAdminAction
466 | AdminAction::RemoveServiceAccountAdminAction
467 | AdminAction::ListServiceAccountsAdminAction
468 | AdminAction::ListTemporaryAccountsAdminAction
469 | AdminAction::AddUserToGroupAdminAction
470 | AdminAction::RemoveUserFromGroupAdminAction
471 | AdminAction::GetGroupAdminAction
472 | AdminAction::ListGroupsAdminAction
473 | AdminAction::EnableGroupAdminAction
474 | AdminAction::DisableGroupAdminAction
475 | AdminAction::CreatePolicyAdminAction
476 | AdminAction::DeletePolicyAdminAction
477 | AdminAction::GetPolicyAdminAction
478 | AdminAction::AttachPolicyAdminAction
479 | AdminAction::UpdatePolicyAssociationAction
480 | AdminAction::ListUserPoliciesAdminAction
481 | AdminAction::SetBucketQuotaAdminAction
482 | AdminAction::GetBucketQuotaAdminAction
483 | AdminAction::SetBucketTargetAction
484 | AdminAction::GetBucketTargetAction
485 | AdminAction::ReplicationDiff
486 | AdminAction::ImportBucketMetadataAction
487 | AdminAction::ExportBucketMetadataAction
488 | AdminAction::SetTierAction
489 | AdminAction::ListTierAction
490 | AdminAction::ExportIAMAction
491 | AdminAction::ImportIAMAction
492 | AdminAction::ListBatchJobsAction
493 | AdminAction::DescribeBatchJobAction
494 | AdminAction::StartBatchJobAction
495 | AdminAction::CancelBatchJobAction
496 | AdminAction::AllAdminActions
497 )
498 }
499}
500
501#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug, Copy)]
502#[serde(try_from = "&str", into = "&str")]
503pub enum StsAction {}
504
505#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, EnumString, IntoStaticStr, Debug, Copy)]
506#[serde(try_from = "&str", into = "&str")]
507pub enum KmsAction {
508 #[strum(serialize = "kms:*")]
509 AllActions,
510}