github.com/aavshr/aws-sdk-go@v1.41.3/internal/s3shared/arn/arn.go (about) 1 package arn 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/aavshr/aws-sdk-go/aws/arn" 8 ) 9 10 var supportedServiceARN = []string{ 11 "s3", 12 "s3-outposts", 13 "s3-object-lambda", 14 } 15 16 func isSupportedServiceARN(service string) bool { 17 for _, name := range supportedServiceARN { 18 if name == service { 19 return true 20 } 21 } 22 return false 23 } 24 25 // Resource provides the interfaces abstracting ARNs of specific resource 26 // types. 27 type Resource interface { 28 GetARN() arn.ARN 29 String() string 30 } 31 32 // ResourceParser provides the function for parsing an ARN's resource 33 // component into a typed resource. 34 type ResourceParser func(arn.ARN) (Resource, error) 35 36 // ParseResource parses an AWS ARN into a typed resource for the S3 API. 37 func ParseResource(s string, resParser ResourceParser) (resARN Resource, err error) { 38 a, err := arn.Parse(s) 39 if err != nil { 40 return nil, err 41 } 42 43 if len(a.Partition) == 0 { 44 return nil, InvalidARNError{ARN: a, Reason: "partition not set"} 45 } 46 47 if !isSupportedServiceARN(a.Service) { 48 return nil, InvalidARNError{ARN: a, Reason: "service is not supported"} 49 } 50 51 if strings.HasPrefix(a.Region, "fips-") || strings.HasSuffix(a.Region, "-fips") { 52 return nil, InvalidARNError{ARN: a, Reason: "FIPS region not allowed in ARN"} 53 } 54 55 if len(a.Resource) == 0 { 56 return nil, InvalidARNError{ARN: a, Reason: "resource not set"} 57 } 58 59 return resParser(a) 60 } 61 62 // SplitResource splits the resource components by the ARN resource delimiters. 63 func SplitResource(v string) []string { 64 var parts []string 65 var offset int 66 67 for offset <= len(v) { 68 idx := strings.IndexAny(v[offset:], "/:") 69 if idx < 0 { 70 parts = append(parts, v[offset:]) 71 break 72 } 73 parts = append(parts, v[offset:idx+offset]) 74 offset += idx + 1 75 } 76 77 return parts 78 } 79 80 // IsARN returns whether the given string is an ARN 81 func IsARN(s string) bool { 82 return arn.IsARN(s) 83 } 84 85 // InvalidARNError provides the error for an invalid ARN error. 86 type InvalidARNError struct { 87 ARN arn.ARN 88 Reason string 89 } 90 91 // Error returns a string denoting the occurred InvalidARNError 92 func (e InvalidARNError) Error() string { 93 return fmt.Sprintf("invalid Amazon %s ARN, %s, %s", e.ARN.Service, e.Reason, e.ARN.String()) 94 }