1package s3shared
2
3import (
4	"fmt"
5	"strings"
6
7	awsarn "github.com/aws/aws-sdk-go-v2/aws/arn"
8	"github.com/aws/aws-sdk-go-v2/service/internal/s3shared/arn"
9)
10
11// ResourceRequest represents an ARN resource and api request metadata
12type ResourceRequest struct {
13	Resource arn.Resource
14	// RequestRegion is the region configured on the request config
15	RequestRegion string
16
17	// SigningRegion is the signing region resolved for the request
18	SigningRegion string
19
20	// PartitionID is the resolved partition id for the provided request region
21	PartitionID string
22
23	// UseARNRegion indicates if client should use the region provided in an ARN resource
24	UseARNRegion bool
25}
26
27// ARN returns the resource ARN
28func (r ResourceRequest) ARN() awsarn.ARN {
29	return r.Resource.GetARN()
30}
31
32// UseFips returns true if request config region is FIPS region.
33func (r ResourceRequest) UseFips() bool {
34	return IsFIPS(r.RequestRegion)
35}
36
37// ResourceConfiguredForFIPS returns true if resource ARNs region is FIPS
38func (r ResourceRequest) ResourceConfiguredForFIPS() bool {
39	return IsFIPS(r.ARN().Region)
40}
41
42// AllowCrossRegion returns a bool value to denote if S3UseARNRegion flag is set
43func (r ResourceRequest) AllowCrossRegion() bool {
44	return r.UseARNRegion
45}
46
47// IsCrossPartition returns true if request is configured for region of another partition, than
48// the partition that resource ARN region resolves to. IsCrossPartition will not return an error,
49// if request is not configured with a specific partition id. This might happen if customer provides
50// custom endpoint url, but does not associate a partition id with it.
51func (r ResourceRequest) IsCrossPartition() (bool, error) {
52	rv := r.PartitionID
53	if len(rv) == 0 {
54		return false, nil
55	}
56
57	av := r.Resource.GetARN().Partition
58	if len(av) == 0 {
59		return false, fmt.Errorf("no partition id for provided ARN")
60	}
61
62	return !strings.EqualFold(rv, av), nil
63}
64
65// IsCrossRegion returns true if request signing region is not same as arn region
66func (r ResourceRequest) IsCrossRegion() bool {
67	v := r.SigningRegion
68	return !strings.EqualFold(v, r.Resource.GetARN().Region)
69}
70
71// IsFIPS returns true if region is a fips region
72func IsFIPS(clientRegion string) bool {
73	return (strings.HasPrefix(clientRegion, "fips-") ||
74		strings.HasSuffix(clientRegion, "-fips"))
75}
76