credentials.go (6027B)
1 package aws 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "time" 8 9 "github.com/aws/aws-sdk-go-v2/internal/sdk" 10 ) 11 12 // AnonymousCredentials provides a sentinel CredentialsProvider that should be 13 // used to instruct the SDK's signing middleware to not sign the request. 14 // 15 // Using `nil` credentials when configuring an API client will achieve the same 16 // result. The AnonymousCredentials type allows you to configure the SDK's 17 // external config loading to not attempt to source credentials from the shared 18 // config or environment. 19 // 20 // For example you can use this CredentialsProvider with an API client's 21 // Options to instruct the client not to sign a request for accessing public 22 // S3 bucket objects. 23 // 24 // The following example demonstrates using the AnonymousCredentials to prevent 25 // SDK's external config loading attempt to resolve credentials. 26 // 27 // cfg, err := config.LoadDefaultConfig(context.TODO(), 28 // config.WithCredentialsProvider(aws.AnonymousCredentials{}), 29 // ) 30 // if err != nil { 31 // log.Fatalf("failed to load config, %v", err) 32 // } 33 // 34 // client := s3.NewFromConfig(cfg) 35 // 36 // Alternatively you can leave the API client Option's `Credential` member to 37 // nil. If using the `NewFromConfig` constructor you'll need to explicitly set 38 // the `Credentials` member to nil, if the external config resolved a 39 // credential provider. 40 // 41 // client := s3.New(s3.Options{ 42 // // Credentials defaults to a nil value. 43 // }) 44 // 45 // This can also be configured for specific operations calls too. 46 // 47 // cfg, err := config.LoadDefaultConfig(context.TODO()) 48 // if err != nil { 49 // log.Fatalf("failed to load config, %v", err) 50 // } 51 // 52 // client := s3.NewFromConfig(config) 53 // 54 // result, err := client.GetObject(context.TODO(), s3.GetObject{ 55 // Bucket: aws.String("example-bucket"), 56 // Key: aws.String("example-key"), 57 // }, func(o *s3.Options) { 58 // o.Credentials = nil 59 // // Or 60 // o.Credentials = aws.AnonymousCredentials{} 61 // }) 62 type AnonymousCredentials struct{} 63 64 // Retrieve implements the CredentialsProvider interface, but will always 65 // return error, and cannot be used to sign a request. The AnonymousCredentials 66 // type is used as a sentinel type instructing the AWS request signing 67 // middleware to not sign a request. 68 func (AnonymousCredentials) Retrieve(context.Context) (Credentials, error) { 69 return Credentials{Source: "AnonymousCredentials"}, 70 fmt.Errorf("the AnonymousCredentials is not a valid credential provider, and cannot be used to sign AWS requests with") 71 } 72 73 // A Credentials is the AWS credentials value for individual credential fields. 74 type Credentials struct { 75 // AWS Access key ID 76 AccessKeyID string 77 78 // AWS Secret Access Key 79 SecretAccessKey string 80 81 // AWS Session Token 82 SessionToken string 83 84 // Source of the credentials 85 Source string 86 87 // States if the credentials can expire or not. 88 CanExpire bool 89 90 // The time the credentials will expire at. Should be ignored if CanExpire 91 // is false. 92 Expires time.Time 93 } 94 95 // Expired returns if the credentials have expired. 96 func (v Credentials) Expired() bool { 97 if v.CanExpire { 98 // Calling Round(0) on the current time will truncate the monotonic 99 // reading only. Ensures credential expiry time is always based on 100 // reported wall-clock time. 101 return !v.Expires.After(sdk.NowTime().Round(0)) 102 } 103 104 return false 105 } 106 107 // HasKeys returns if the credentials keys are set. 108 func (v Credentials) HasKeys() bool { 109 return len(v.AccessKeyID) > 0 && len(v.SecretAccessKey) > 0 110 } 111 112 // A CredentialsProvider is the interface for any component which will provide 113 // credentials Credentials. A CredentialsProvider is required to manage its own 114 // Expired state, and what to be expired means. 115 // 116 // A credentials provider implementation can be wrapped with a CredentialCache 117 // to cache the credential value retrieved. Without the cache the SDK will 118 // attempt to retrieve the credentials for every request. 119 type CredentialsProvider interface { 120 // Retrieve returns nil if it successfully retrieved the value. 121 // Error is returned if the value were not obtainable, or empty. 122 Retrieve(ctx context.Context) (Credentials, error) 123 } 124 125 // CredentialsProviderFunc provides a helper wrapping a function value to 126 // satisfy the CredentialsProvider interface. 127 type CredentialsProviderFunc func(context.Context) (Credentials, error) 128 129 // Retrieve delegates to the function value the CredentialsProviderFunc wraps. 130 func (fn CredentialsProviderFunc) Retrieve(ctx context.Context) (Credentials, error) { 131 return fn(ctx) 132 } 133 134 type isCredentialsProvider interface { 135 IsCredentialsProvider(CredentialsProvider) bool 136 } 137 138 // IsCredentialsProvider returns whether the target CredentialProvider is the same type as provider when comparing the 139 // implementation type. 140 // 141 // If provider has a method IsCredentialsProvider(CredentialsProvider) bool it will be responsible for validating 142 // whether target matches the credential provider type. 143 // 144 // When comparing the CredentialProvider implementations provider and target for equality, the following rules are used: 145 // 146 // If provider is of type T and target is of type V, true if type *T is the same as type *V, otherwise false 147 // If provider is of type *T and target is of type V, true if type *T is the same as type *V, otherwise false 148 // If provider is of type T and target is of type *V, true if type *T is the same as type *V, otherwise false 149 // If provider is of type *T and target is of type *V,true if type *T is the same as type *V, otherwise false 150 func IsCredentialsProvider(provider, target CredentialsProvider) bool { 151 if target == nil || provider == nil { 152 return provider == target 153 } 154 155 if x, ok := provider.(isCredentialsProvider); ok { 156 return x.IsCredentialsProvider(target) 157 } 158 159 targetType := reflect.TypeOf(target) 160 if targetType.Kind() != reflect.Ptr { 161 targetType = reflect.PtrTo(targetType) 162 } 163 164 providerType := reflect.TypeOf(provider) 165 if providerType.Kind() != reflect.Ptr { 166 providerType = reflect.PtrTo(providerType) 167 } 168 169 return targetType.AssignableTo(providerType) 170 }