Skip to main content

rustfs_policy/policy/
action.rs

1// Copyright 2024 RustFS Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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)]
252// #[serde(try_from = "&str", into = "&str")]
253// pub enum AdminAction {
254//     #[strum(serialize = "admin:*")]
255//     AllActions,
256//     #[strum(serialize = "admin:Profiling")]
257//     ProfilingAdminAction,
258//     #[strum(serialize = "admin:ServerTrace")]
259//     TraceAdminAction,
260//     #[strum(serialize = "admin:ConsoleLog")]
261//     ConsoleLogAdminAction,
262//     #[strum(serialize = "admin:ServerInfo")]
263//     ServerInfoAdminAction,
264//     #[strum(serialize = "admin:OBDInfo")]
265//     HealthInfoAdminAction,
266//     #[strum(serialize = "admin:TopLocksInfo")]
267//     TopLocksAdminAction,
268//     #[strum(serialize = "admin:LicenseInfo")]
269//     LicenseInfoAdminAction,
270//     #[strum(serialize = "admin:BandwidthMonitor")]
271//     BandwidthMonitorAction,
272//     #[strum(serialize = "admin:InspectData")]
273//     InspectDataAction,
274//     #[strum(serialize = "admin:Prometheus")]
275//     PrometheusAdminAction,
276//     #[strum(serialize = "admin:ListServiceAccounts")]
277//     ListServiceAccountsAdminAction,
278//     #[strum(serialize = "admin:CreateServiceAccount")]
279//     CreateServiceAccountAdminAction,
280// }
281
282// AdminAction - admin policy action.
283#[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    // IsValid - checks if action is valid or not.
426    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}