src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

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 }