github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/api/apc/access.go (about) 1 // Package apc: API control messages and constants 2 /* 3 * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package apc 6 7 import ( 8 "fmt" 9 "strconv" 10 "strings" 11 ) 12 13 type AccessAttrs uint64 14 15 // ACL aka access permissions 16 const ( 17 // object level 18 AceGET = AccessAttrs(1) << iota 19 AceObjHEAD // permission to get object props 20 AcePUT 21 AceAPPEND 22 AceObjDELETE 23 AceObjMOVE 24 AcePromote 25 // TODO: reserving the only perm that must be checked on the target side (NIY) 26 AceObjUpdate 27 // bucket metadata 28 AceBckHEAD // get bucket props and ACL 29 AceObjLIST // list objects in a bucket 30 AcePATCH // set bucket props 31 AceBckSetACL // set bucket permissions 32 // cluster level 33 AceListBuckets 34 AceShowCluster 35 AceCreateBucket 36 AceDestroyBucket 37 AceMoveBucket 38 AceAdmin 39 // note: must be the last one 40 AceMax 41 ) 42 43 // access => operation 44 var accessOp = map[AccessAttrs]string{ 45 // object 46 AceGET: "GET", 47 AceObjHEAD: "HEAD-OBJECT", 48 AcePUT: "PUT", 49 AceAPPEND: "APPEND", 50 AceObjDELETE: "DELETE-OBJECT", 51 AceObjMOVE: "MOVE-OBJECT", 52 AcePromote: "PROMOTE", 53 AceObjUpdate: "UPDATE-OBJECT", 54 // bucket 55 AceBckHEAD: "HEAD-BUCKET", 56 AceObjLIST: "LIST-OBJECTS", 57 AcePATCH: "PATCH", 58 AceBckSetACL: "SET-BUCKET-ACL", 59 // cluster 60 AceListBuckets: "LIST-BUCKETS", 61 AceShowCluster: "SHOW-CLUSTER", 62 AceCreateBucket: "CREATE-BUCKET", 63 AceDestroyBucket: "DESTROY-BUCKET", 64 AceMoveBucket: "MOVE-BUCKET", 65 AceAdmin: "ADMIN", 66 67 // NOTE: update Describe() when adding/deleting 68 } 69 70 // derived (convenience) constants 71 const ( 72 // encompasses all ACEs, current and future 73 AccessAll = AccessAttrs(^uint64(0)) 74 AllowAllAccess = "su" 75 76 // read-only and read-write access to bucket 77 AccessRO = AceGET | AceObjHEAD | AceListBuckets | AceBckHEAD | AceObjLIST 78 AllowReadOnlyAccess = "ro" 79 AccessRW = AccessRO | AcePUT | AceAPPEND | AceObjDELETE | AceObjMOVE 80 AllowReadWriteAccess = "rw" 81 82 AccessNone = AccessAttrs(0) 83 84 // permission to perform cluster-level ops 85 AccessCluster = AceListBuckets | AceCreateBucket | AceDestroyBucket | AceMoveBucket | AceAdmin 86 ) 87 88 // verbs 89 func SupportedPermissions() []string { 90 accList := []string{"ro", "rw", "su"} 91 for _, v := range accessOp { 92 accList = append(accList, v) 93 } 94 return accList 95 } 96 97 func (a AccessAttrs) Has(perms AccessAttrs) bool { return a&perms == perms } 98 func (a AccessAttrs) String() string { return strconv.FormatUint(uint64(a), 10) } 99 100 func (a AccessAttrs) Describe(all bool) string { 101 if a == 0 { 102 return "none" 103 } 104 accList := make([]string, 0, 24) 105 if a.Has(AceGET) { 106 accList = append(accList, accessOp[AceGET]) 107 } 108 if a.Has(AceObjHEAD) { 109 accList = append(accList, accessOp[AceObjHEAD]) 110 } 111 if a.Has(AcePUT) { 112 accList = append(accList, accessOp[AcePUT]) 113 } 114 if a.Has(AceAPPEND) { 115 accList = append(accList, accessOp[AceAPPEND]) 116 } 117 if a.Has(AceObjDELETE) { 118 accList = append(accList, accessOp[AceObjDELETE]) 119 } 120 if a.Has(AceObjMOVE) { 121 accList = append(accList, accessOp[AceObjMOVE]) 122 } 123 if a.Has(AcePromote) { 124 accList = append(accList, accessOp[AcePromote]) 125 } 126 if a.Has(AceObjUpdate) { 127 accList = append(accList, accessOp[AceObjUpdate]) 128 } 129 // 130 if a.Has(AceBckHEAD) { 131 accList = append(accList, accessOp[AceBckHEAD]) 132 } 133 if a.Has(AceObjLIST) { 134 accList = append(accList, accessOp[AceObjLIST]) 135 } 136 if a.Has(AcePATCH) { 137 accList = append(accList, accessOp[AcePATCH]) 138 } 139 if a.Has(AceBckSetACL) { 140 accList = append(accList, accessOp[AceBckSetACL]) 141 } 142 // 143 if a.Has(AceListBuckets) { 144 accList = append(accList, accessOp[AceListBuckets]) 145 } 146 if a.Has(AceShowCluster) { 147 accList = append(accList, accessOp[AceShowCluster]) 148 } 149 if a.Has(AceCreateBucket) { 150 accList = append(accList, accessOp[AceCreateBucket]) 151 } 152 if a.Has(AceDestroyBucket) { 153 accList = append(accList, accessOp[AceDestroyBucket]) 154 } 155 if a.Has(AceMoveBucket) { 156 accList = append(accList, accessOp[AceMoveBucket]) 157 } 158 if a.Has(AceAdmin) { 159 accList = append(accList, accessOp[AceAdmin]) 160 } 161 162 // return 163 if all || len(accList) <= 4 { 164 return strings.Join(accList, ",") 165 } 166 accList = accList[:4] 167 return strings.Join(accList, ",") + ", ..." 168 } 169 170 func AccessOp(access AccessAttrs) string { 171 if s, ok := accessOp[access]; ok { 172 return s 173 } 174 return "<unknown access>" 175 } 176 177 func StrToAccess(accessStr string) (access AccessAttrs, err error) { 178 switch accessStr { 179 case AllowReadOnlyAccess: 180 access |= AccessRO 181 case AllowReadWriteAccess: 182 access |= AccessRW 183 case AllowAllAccess: 184 access = AccessAll 185 case "": 186 access = AccessNone 187 default: 188 found := false 189 for k, v := range accessOp { 190 if v == accessStr { 191 access |= k 192 found = true 193 } 194 } 195 if !found { 196 err = fmt.Errorf("invalid access value: %q", accessStr) 197 } 198 } 199 return 200 }