mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-25 21:48:28 -05:00
Bump github.com/tus/tusd from 1.12.1 to 1.13.0
Bumps [github.com/tus/tusd](https://github.com/tus/tusd) from 1.12.1 to 1.13.0. - [Release notes](https://github.com/tus/tusd/releases) - [Commits](https://github.com/tus/tusd/compare/v1.12.1...v1.13.0) --- updated-dependencies: - dependency-name: github.com/tus/tusd dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
963c492a73
commit
eca299789d
+50
@@ -0,0 +1,50 @@
|
||||
package bearer
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Token provides a type wrapping a bearer token and expiration metadata.
|
||||
type Token struct {
|
||||
Value string
|
||||
|
||||
CanExpire bool
|
||||
Expires time.Time
|
||||
}
|
||||
|
||||
// Expired returns if the token's Expires time is before or equal to the time
|
||||
// provided. If CanExpire is false, Expired will always return false.
|
||||
func (t Token) Expired(now time.Time) bool {
|
||||
if !t.CanExpire {
|
||||
return false
|
||||
}
|
||||
now = now.Round(0)
|
||||
return now.Equal(t.Expires) || now.After(t.Expires)
|
||||
}
|
||||
|
||||
// TokenProvider provides interface for retrieving bearer tokens.
|
||||
type TokenProvider interface {
|
||||
RetrieveBearerToken(aws.Context) (Token, error)
|
||||
}
|
||||
|
||||
// TokenProviderFunc provides a helper utility to wrap a function as a type
|
||||
// that implements the TokenProvider interface.
|
||||
type TokenProviderFunc func(aws.Context) (Token, error)
|
||||
|
||||
// RetrieveBearerToken calls the wrapped function, returning the Token or
|
||||
// error.
|
||||
func (fn TokenProviderFunc) RetrieveBearerToken(ctx aws.Context) (Token, error) {
|
||||
return fn(ctx)
|
||||
}
|
||||
|
||||
// StaticTokenProvider provides a utility for wrapping a static bearer token
|
||||
// value within an implementation of a token provider.
|
||||
type StaticTokenProvider struct {
|
||||
Token Token
|
||||
}
|
||||
|
||||
// RetrieveBearerToken returns the static token specified.
|
||||
func (s StaticTokenProvider) RetrieveBearerToken(aws.Context) (Token, error) {
|
||||
return s.Token, nil
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// DO NOT EDIT
|
||||
package corehandlers
|
||||
|
||||
const isAwsInternal = ""
|
||||
+10
@@ -35,3 +35,13 @@ var AddHostExecEnvUserAgentHander = request.NamedHandler{
|
||||
request.AddToUserAgent(r, execEnvUAKey+"/"+v)
|
||||
},
|
||||
}
|
||||
|
||||
var AddAwsInternal = request.NamedHandler{
|
||||
Name: "core.AddAwsInternal",
|
||||
Fn: func(r *request.Request) {
|
||||
if len(isAwsInternal) == 0 {
|
||||
return
|
||||
}
|
||||
request.AddToUserAgent(r, isAwsInternal)
|
||||
},
|
||||
}
|
||||
|
||||
+41
-34
@@ -4,13 +4,13 @@ import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/auth/bearer"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
@@ -55,6 +55,19 @@ type Provider struct {
|
||||
|
||||
// The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
|
||||
StartURL string
|
||||
|
||||
// The filepath the cached token will be retrieved from. If unset Provider will
|
||||
// use the startURL to determine the filepath at.
|
||||
//
|
||||
// ~/.aws/sso/cache/<sha1-hex-encoded-startURL>.json
|
||||
//
|
||||
// If custom cached token filepath is used, the Provider's startUrl
|
||||
// parameter will be ignored.
|
||||
CachedTokenFilepath string
|
||||
|
||||
// Used by the SSOCredentialProvider if a token configuration
|
||||
// profile is used in the shared config
|
||||
TokenProvider bearer.TokenProvider
|
||||
}
|
||||
|
||||
// NewCredentials returns a new AWS Single Sign-On (AWS SSO) credential provider. The ConfigProvider is expected to be configured
|
||||
@@ -89,13 +102,31 @@ func (p *Provider) Retrieve() (credentials.Value, error) {
|
||||
// RetrieveWithContext retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
||||
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
||||
tokenFile, err := loadTokenFile(p.StartURL)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
var accessToken *string
|
||||
if p.TokenProvider != nil {
|
||||
token, err := p.TokenProvider.RetrieveBearerToken(ctx)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
accessToken = &token.Value
|
||||
} else {
|
||||
if p.CachedTokenFilepath == "" {
|
||||
cachedTokenFilePath, err := getCachedFilePath(p.StartURL)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
p.CachedTokenFilepath = cachedTokenFilePath
|
||||
}
|
||||
|
||||
tokenFile, err := loadTokenFile(p.CachedTokenFilepath)
|
||||
if err != nil {
|
||||
return credentials.Value{}, err
|
||||
}
|
||||
accessToken = &tokenFile.AccessToken
|
||||
}
|
||||
|
||||
output, err := p.Client.GetRoleCredentialsWithContext(ctx, &sso.GetRoleCredentialsInput{
|
||||
AccessToken: &tokenFile.AccessToken,
|
||||
AccessToken: accessToken,
|
||||
AccountId: &p.AccountID,
|
||||
RoleName: &p.RoleName,
|
||||
})
|
||||
@@ -114,32 +145,13 @@ func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Val
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getCacheFileName(url string) (string, error) {
|
||||
func getCachedFilePath(startUrl string) (string, error) {
|
||||
hash := sha1.New()
|
||||
_, err := hash.Write([]byte(url))
|
||||
_, err := hash.Write([]byte(startUrl))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json", nil
|
||||
}
|
||||
|
||||
type rfc3339 time.Time
|
||||
|
||||
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
|
||||
var value string
|
||||
|
||||
if err := json.Unmarshal(bytes, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parse, err := time.Parse(time.RFC3339, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("expected RFC3339 timestamp: %v", err)
|
||||
}
|
||||
|
||||
*r = rfc3339(parse)
|
||||
|
||||
return nil
|
||||
return filepath.Join(defaultCacheLocation(), strings.ToLower(hex.EncodeToString(hash.Sum(nil)))+".json"), nil
|
||||
}
|
||||
|
||||
type token struct {
|
||||
@@ -153,13 +165,8 @@ func (t token) Expired() bool {
|
||||
return nowTime().Round(0).After(time.Time(t.ExpiresAt))
|
||||
}
|
||||
|
||||
func loadTokenFile(startURL string) (t token, err error) {
|
||||
key, err := getCacheFileName(startURL)
|
||||
if err != nil {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
||||
}
|
||||
|
||||
fileBytes, err := ioutil.ReadFile(filepath.Join(defaultCacheLocation(), key))
|
||||
func loadTokenFile(cachedTokenPath string) (t token, err error) {
|
||||
fileBytes, err := ioutil.ReadFile(cachedTokenPath)
|
||||
if err != nil {
|
||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
||||
}
|
||||
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
package ssocreds
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var resolvedOsUserHomeDir = shareddefaults.UserHomeDir
|
||||
|
||||
// StandardCachedTokenFilepath returns the filepath for the cached SSO token file, or
|
||||
// error if unable get derive the path. Key that will be used to compute a SHA1
|
||||
// value that is hex encoded.
|
||||
//
|
||||
// Derives the filepath using the Key as:
|
||||
//
|
||||
// ~/.aws/sso/cache/<sha1-hex-encoded-key>.json
|
||||
func StandardCachedTokenFilepath(key string) (string, error) {
|
||||
homeDir := resolvedOsUserHomeDir()
|
||||
if len(homeDir) == 0 {
|
||||
return "", fmt.Errorf("unable to get USER's home directory for cached token")
|
||||
}
|
||||
hash := sha1.New()
|
||||
if _, err := hash.Write([]byte(key)); err != nil {
|
||||
return "", fmt.Errorf("unable to compute cached token filepath key SHA1 hash, %v", err)
|
||||
}
|
||||
|
||||
cacheFilename := strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json"
|
||||
|
||||
return filepath.Join(homeDir, ".aws", "sso", "cache", cacheFilename), nil
|
||||
}
|
||||
|
||||
type tokenKnownFields struct {
|
||||
AccessToken string `json:"accessToken,omitempty"`
|
||||
ExpiresAt *rfc3339 `json:"expiresAt,omitempty"`
|
||||
|
||||
RefreshToken string `json:"refreshToken,omitempty"`
|
||||
ClientID string `json:"clientId,omitempty"`
|
||||
ClientSecret string `json:"clientSecret,omitempty"`
|
||||
}
|
||||
|
||||
type cachedToken struct {
|
||||
tokenKnownFields
|
||||
UnknownFields map[string]interface{} `json:"-"`
|
||||
}
|
||||
|
||||
// MarshalJSON provides custom marshalling because the standard library Go marshaller ignores unknown/unspecified fields
|
||||
// when marshalling from a struct: https://pkg.go.dev/encoding/json#Marshal
|
||||
// This function adds some extra validation to the known fields and captures unknown fields.
|
||||
func (t cachedToken) MarshalJSON() ([]byte, error) {
|
||||
fields := map[string]interface{}{}
|
||||
|
||||
setTokenFieldString(fields, "accessToken", t.AccessToken)
|
||||
setTokenFieldRFC3339(fields, "expiresAt", t.ExpiresAt)
|
||||
|
||||
setTokenFieldString(fields, "refreshToken", t.RefreshToken)
|
||||
setTokenFieldString(fields, "clientId", t.ClientID)
|
||||
setTokenFieldString(fields, "clientSecret", t.ClientSecret)
|
||||
|
||||
for k, v := range t.UnknownFields {
|
||||
if _, ok := fields[k]; ok {
|
||||
return nil, fmt.Errorf("unknown token field %v, duplicates known field", k)
|
||||
}
|
||||
fields[k] = v
|
||||
}
|
||||
|
||||
return json.Marshal(fields)
|
||||
}
|
||||
|
||||
func setTokenFieldString(fields map[string]interface{}, key, value string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
fields[key] = value
|
||||
}
|
||||
func setTokenFieldRFC3339(fields map[string]interface{}, key string, value *rfc3339) {
|
||||
if value == nil {
|
||||
return
|
||||
}
|
||||
fields[key] = value
|
||||
}
|
||||
|
||||
// UnmarshalJSON provides custom unmarshalling because the standard library Go unmarshaller ignores unknown/unspecified
|
||||
// fields when unmarshalling from a struct: https://pkg.go.dev/encoding/json#Unmarshal
|
||||
// This function adds some extra validation to the known fields and captures unknown fields.
|
||||
func (t *cachedToken) UnmarshalJSON(b []byte) error {
|
||||
var fields map[string]interface{}
|
||||
if err := json.Unmarshal(b, &fields); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.UnknownFields = map[string]interface{}{}
|
||||
|
||||
for k, v := range fields {
|
||||
var err error
|
||||
switch k {
|
||||
case "accessToken":
|
||||
err = getTokenFieldString(v, &t.AccessToken)
|
||||
case "expiresAt":
|
||||
err = getTokenFieldRFC3339(v, &t.ExpiresAt)
|
||||
case "refreshToken":
|
||||
err = getTokenFieldString(v, &t.RefreshToken)
|
||||
case "clientId":
|
||||
err = getTokenFieldString(v, &t.ClientID)
|
||||
case "clientSecret":
|
||||
err = getTokenFieldString(v, &t.ClientSecret)
|
||||
default:
|
||||
t.UnknownFields[k] = v
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("field %q, %v", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTokenFieldString(v interface{}, value *string) error {
|
||||
var ok bool
|
||||
*value, ok = v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expect value to be string, got %T", v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTokenFieldRFC3339(v interface{}, value **rfc3339) error {
|
||||
var stringValue string
|
||||
if err := getTokenFieldString(v, &stringValue); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
timeValue, err := parseRFC3339(stringValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*value = &timeValue
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCachedToken(filename string) (cachedToken, error) {
|
||||
fileBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return cachedToken{}, fmt.Errorf("failed to read cached SSO token file, %v", err)
|
||||
}
|
||||
|
||||
var t cachedToken
|
||||
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
||||
return cachedToken{}, fmt.Errorf("failed to parse cached SSO token file, %v", err)
|
||||
}
|
||||
|
||||
if len(t.AccessToken) == 0 || t.ExpiresAt == nil || time.Time(*t.ExpiresAt).IsZero() {
|
||||
return cachedToken{}, fmt.Errorf(
|
||||
"cached SSO token must contain accessToken and expiresAt fields")
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func storeCachedToken(filename string, t cachedToken, fileMode os.FileMode) (err error) {
|
||||
tmpFilename := filename + ".tmp-" + strconv.FormatInt(nowTime().UnixNano(), 10)
|
||||
if err := writeCacheFile(tmpFilename, fileMode, t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Rename(tmpFilename, filename); err != nil {
|
||||
return fmt.Errorf("failed to replace old cached SSO token file, %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeCacheFile(filename string, fileMode os.FileMode, t cachedToken) (err error) {
|
||||
var f *os.File
|
||||
f, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, fileMode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create cached SSO token file %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
closeErr := f.Close()
|
||||
if err == nil && closeErr != nil {
|
||||
err = fmt.Errorf("failed to close cached SSO token file, %v", closeErr)
|
||||
}
|
||||
}()
|
||||
|
||||
encoder := json.NewEncoder(f)
|
||||
|
||||
if err = encoder.Encode(t); err != nil {
|
||||
return fmt.Errorf("failed to serialize cached SSO token, %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type rfc3339 time.Time
|
||||
|
||||
// UnmarshalJSON decode rfc3339 from JSON format
|
||||
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
|
||||
var value string
|
||||
var err error
|
||||
|
||||
if err = json.Unmarshal(bytes, &value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*r, err = parseRFC3339(value)
|
||||
return err
|
||||
}
|
||||
|
||||
func parseRFC3339(v string) (rfc3339, error) {
|
||||
parsed, err := time.Parse(time.RFC3339, v)
|
||||
if err != nil {
|
||||
return rfc3339{}, fmt.Errorf("expected RFC3339 timestamp: %v", err)
|
||||
}
|
||||
|
||||
return rfc3339(parsed), nil
|
||||
}
|
||||
|
||||
// MarshalJSON encode rfc3339 to JSON format time
|
||||
func (r *rfc3339) MarshalJSON() ([]byte, error) {
|
||||
value := time.Time(*r).Format(time.RFC3339)
|
||||
|
||||
// Use JSON unmarshal to unescape the quoted value making use of JSON's
|
||||
// quoting rules.
|
||||
return json.Marshal(value)
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
package ssocreds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/auth/bearer"
|
||||
"github.com/aws/aws-sdk-go/service/ssooidc"
|
||||
)
|
||||
|
||||
// CreateTokenAPIClient provides the interface for the SSOTokenProvider's API
|
||||
// client for calling CreateToken operation to refresh the SSO token.
|
||||
type CreateTokenAPIClient interface {
|
||||
CreateToken(input *ssooidc.CreateTokenInput) (*ssooidc.CreateTokenOutput, error)
|
||||
}
|
||||
|
||||
// SSOTokenProviderOptions provides the options for configuring the
|
||||
// SSOTokenProvider.
|
||||
type SSOTokenProviderOptions struct {
|
||||
// Client that can be overridden
|
||||
Client CreateTokenAPIClient
|
||||
|
||||
// The path the file containing the cached SSO token will be read from.
|
||||
// Initialized the NewSSOTokenProvider's cachedTokenFilepath parameter.
|
||||
CachedTokenFilepath string
|
||||
}
|
||||
|
||||
// SSOTokenProvider provides a utility for refreshing SSO AccessTokens for
|
||||
// Bearer Authentication. The SSOTokenProvider can only be used to refresh
|
||||
// already cached SSO Tokens. This utility cannot perform the initial SSO
|
||||
// create token.
|
||||
//
|
||||
// The initial SSO create token should be preformed with the AWS CLI before the
|
||||
// Go application using the SSOTokenProvider will need to retrieve the SSO
|
||||
// token. If the AWS CLI has not created the token cache file, this provider
|
||||
// will return an error when attempting to retrieve the cached token.
|
||||
//
|
||||
// This provider will attempt to refresh the cached SSO token periodically if
|
||||
// needed when RetrieveBearerToken is called.
|
||||
//
|
||||
// A utility such as the AWS CLI must be used to initially create the SSO
|
||||
// session and cached token file.
|
||||
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
||||
type SSOTokenProvider struct {
|
||||
options SSOTokenProviderOptions
|
||||
}
|
||||
|
||||
// NewSSOTokenProvider returns an initialized SSOTokenProvider that will
|
||||
// periodically refresh the SSO token cached stored in the cachedTokenFilepath.
|
||||
// The cachedTokenFilepath file's content will be rewritten by the token
|
||||
// provider when the token is refreshed.
|
||||
//
|
||||
// The client must be configured for the AWS region the SSO token was created for.
|
||||
func NewSSOTokenProvider(client CreateTokenAPIClient, cachedTokenFilepath string, optFns ...func(o *SSOTokenProviderOptions)) *SSOTokenProvider {
|
||||
options := SSOTokenProviderOptions{
|
||||
Client: client,
|
||||
CachedTokenFilepath: cachedTokenFilepath,
|
||||
}
|
||||
for _, fn := range optFns {
|
||||
fn(&options)
|
||||
}
|
||||
|
||||
provider := &SSOTokenProvider{
|
||||
options: options,
|
||||
}
|
||||
|
||||
return provider
|
||||
}
|
||||
|
||||
// RetrieveBearerToken returns the SSO token stored in the cachedTokenFilepath
|
||||
// the SSOTokenProvider was created with. If the token has expired
|
||||
// RetrieveBearerToken will attempt to refresh it. If the token cannot be
|
||||
// refreshed or is not present an error will be returned.
|
||||
//
|
||||
// A utility such as the AWS CLI must be used to initially create the SSO
|
||||
// session and cached token file. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
||||
func (p *SSOTokenProvider) RetrieveBearerToken(ctx aws.Context) (bearer.Token, error) {
|
||||
cachedToken, err := loadCachedToken(p.options.CachedTokenFilepath)
|
||||
if err != nil {
|
||||
return bearer.Token{}, err
|
||||
}
|
||||
|
||||
if cachedToken.ExpiresAt != nil && nowTime().After(time.Time(*cachedToken.ExpiresAt)) {
|
||||
cachedToken, err = p.refreshToken(cachedToken)
|
||||
if err != nil {
|
||||
return bearer.Token{}, fmt.Errorf("refresh cached SSO token failed, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
expiresAt := toTime((*time.Time)(cachedToken.ExpiresAt))
|
||||
return bearer.Token{
|
||||
Value: cachedToken.AccessToken,
|
||||
CanExpire: !expiresAt.IsZero(),
|
||||
Expires: expiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *SSOTokenProvider) refreshToken(token cachedToken) (cachedToken, error) {
|
||||
if token.ClientSecret == "" || token.ClientID == "" || token.RefreshToken == "" {
|
||||
return cachedToken{}, fmt.Errorf("cached SSO token is expired, or not present, and cannot be refreshed")
|
||||
}
|
||||
|
||||
createResult, err := p.options.Client.CreateToken(&ssooidc.CreateTokenInput{
|
||||
ClientId: &token.ClientID,
|
||||
ClientSecret: &token.ClientSecret,
|
||||
RefreshToken: &token.RefreshToken,
|
||||
GrantType: aws.String("refresh_token"),
|
||||
})
|
||||
if err != nil {
|
||||
return cachedToken{}, fmt.Errorf("unable to refresh SSO token, %v", err)
|
||||
}
|
||||
if createResult.ExpiresIn == nil {
|
||||
return cachedToken{}, fmt.Errorf("missing required field ExpiresIn")
|
||||
}
|
||||
if createResult.AccessToken == nil {
|
||||
return cachedToken{}, fmt.Errorf("missing required field AccessToken")
|
||||
}
|
||||
if createResult.RefreshToken == nil {
|
||||
return cachedToken{}, fmt.Errorf("missing required field RefreshToken")
|
||||
}
|
||||
|
||||
expiresAt := nowTime().Add(time.Duration(*createResult.ExpiresIn) * time.Second)
|
||||
|
||||
token.AccessToken = *createResult.AccessToken
|
||||
token.ExpiresAt = (*rfc3339)(&expiresAt)
|
||||
token.RefreshToken = *createResult.RefreshToken
|
||||
|
||||
fileInfo, err := os.Stat(p.options.CachedTokenFilepath)
|
||||
if err != nil {
|
||||
return cachedToken{}, fmt.Errorf("failed to stat cached SSO token file %v", err)
|
||||
}
|
||||
|
||||
if err = storeCachedToken(p.options.CachedTokenFilepath, token, fileInfo.Mode()); err != nil {
|
||||
return cachedToken{}, fmt.Errorf("unable to cache refreshed SSO token, %v", err)
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func toTime(p *time.Time) (v time.Time) {
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return *p
|
||||
}
|
||||
+1
@@ -74,6 +74,7 @@ func Handlers() request.Handlers {
|
||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
handlers.Build.PushBackNamed(corehandlers.AddAwsInternal)
|
||||
handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
|
||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||
|
||||
+1427
-191
File diff suppressed because it is too large
Load Diff
+33
-3
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||
"github.com/aws/aws-sdk-go/service/ssooidc"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
@@ -23,6 +24,10 @@ type CredentialsProviderOptions struct {
|
||||
// WebIdentityRoleProviderOptions configures a WebIdentityRoleProvider,
|
||||
// such as setting its ExpiryWindow.
|
||||
WebIdentityRoleProviderOptions func(*stscreds.WebIdentityRoleProvider)
|
||||
|
||||
// ProcessProviderOptions configures a ProcessProvider,
|
||||
// such as setting its Timeout.
|
||||
ProcessProviderOptions func(*processcreds.ProcessProvider)
|
||||
}
|
||||
|
||||
func resolveCredentials(cfg *aws.Config,
|
||||
@@ -33,7 +38,7 @@ func resolveCredentials(cfg *aws.Config,
|
||||
|
||||
switch {
|
||||
case len(sessOpts.Profile) != 0:
|
||||
// User explicitly provided an Profile in the session's configuration
|
||||
// User explicitly provided a Profile in the session's configuration
|
||||
// so load that profile from shared config first.
|
||||
// Github(aws/aws-sdk-go#2727)
|
||||
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
|
||||
@@ -134,7 +139,11 @@ func resolveCredsFromProfile(cfg *aws.Config,
|
||||
|
||||
case len(sharedCfg.CredentialProcess) != 0:
|
||||
// Get credentials from CredentialProcess
|
||||
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess)
|
||||
var optFns []func(*processcreds.ProcessProvider)
|
||||
if sessOpts.CredentialsProviderOptions != nil && sessOpts.CredentialsProviderOptions.ProcessProviderOptions != nil {
|
||||
optFns = append(optFns, sessOpts.CredentialsProviderOptions.ProcessProviderOptions)
|
||||
}
|
||||
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess, optFns...)
|
||||
|
||||
default:
|
||||
// Fallback to default credentials provider, include mock errors for
|
||||
@@ -173,8 +182,28 @@ func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers req
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var optFns []func(provider *ssocreds.Provider)
|
||||
cfgCopy := cfg.Copy()
|
||||
cfgCopy.Region = &sharedCfg.SSORegion
|
||||
|
||||
if sharedCfg.SSOSession != nil {
|
||||
cfgCopy.Region = &sharedCfg.SSOSession.SSORegion
|
||||
cachedPath, err := ssocreds.StandardCachedTokenFilepath(sharedCfg.SSOSession.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// create oidcClient with AnonymousCredentials to avoid recursively resolving credentials
|
||||
mySession := Must(NewSession(&aws.Config{
|
||||
Credentials: credentials.AnonymousCredentials,
|
||||
}))
|
||||
oidcClient := ssooidc.New(mySession, cfgCopy)
|
||||
tokenProvider := ssocreds.NewSSOTokenProvider(oidcClient, cachedPath)
|
||||
optFns = append(optFns, func(p *ssocreds.Provider) {
|
||||
p.TokenProvider = tokenProvider
|
||||
p.CachedTokenFilepath = cachedPath
|
||||
})
|
||||
} else {
|
||||
cfgCopy.Region = &sharedCfg.SSORegion
|
||||
}
|
||||
|
||||
return ssocreds.NewCredentials(
|
||||
&Session{
|
||||
@@ -184,6 +213,7 @@ func resolveSSOCredentials(cfg *aws.Config, sharedCfg sharedConfig, handlers req
|
||||
sharedCfg.SSOAccountID,
|
||||
sharedCfg.SSORoleName,
|
||||
sharedCfg.SSOStartURL,
|
||||
optFns...,
|
||||
), nil
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ const (
|
||||
|
||||
// ErrSharedConfigSourceCollision will be returned if a section contains both
|
||||
// source_profile and credential_source
|
||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only one credential type may be specified per profile: source profile, credential source, credential process, web identity token, or sso", nil)
|
||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only one credential type may be specified per profile: source profile, credential source, credential process, web identity token", nil)
|
||||
|
||||
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
|
||||
// variables are empty and Environment was set as the credential source
|
||||
|
||||
+135
-33
@@ -26,6 +26,13 @@ const (
|
||||
roleSessionNameKey = `role_session_name` // optional
|
||||
roleDurationSecondsKey = "duration_seconds" // optional
|
||||
|
||||
// Prefix to be used for SSO sections. These are supposed to only exist in
|
||||
// the shared config file, not the credentials file.
|
||||
ssoSectionPrefix = `sso-session `
|
||||
|
||||
// AWS Single Sign-On (AWS SSO) group
|
||||
ssoSessionNameKey = "sso_session"
|
||||
|
||||
// AWS Single Sign-On (AWS SSO) group
|
||||
ssoAccountIDKey = "sso_account_id"
|
||||
ssoRegionKey = "sso_region"
|
||||
@@ -99,6 +106,10 @@ type sharedConfig struct {
|
||||
CredentialProcess string
|
||||
WebIdentityTokenFile string
|
||||
|
||||
// SSO session options
|
||||
SSOSessionName string
|
||||
SSOSession *ssoSession
|
||||
|
||||
SSOAccountID string
|
||||
SSORegion string
|
||||
SSORoleName string
|
||||
@@ -186,6 +197,20 @@ type sharedConfigFile struct {
|
||||
IniData ini.Sections
|
||||
}
|
||||
|
||||
// SSOSession provides the shared configuration parameters of the sso-session
|
||||
// section.
|
||||
type ssoSession struct {
|
||||
Name string
|
||||
SSORegion string
|
||||
SSOStartURL string
|
||||
}
|
||||
|
||||
func (s *ssoSession) setFromIniSection(section ini.Section) {
|
||||
updateString(&s.Name, section, ssoSessionNameKey)
|
||||
updateString(&s.SSORegion, section, ssoRegionKey)
|
||||
updateString(&s.SSOStartURL, section, ssoStartURL)
|
||||
}
|
||||
|
||||
// loadSharedConfig retrieves the configuration from the list of files using
|
||||
// the profile provided. The order the files are listed will determine
|
||||
// precedence. Values in subsequent files will overwrite values defined in
|
||||
@@ -266,13 +291,13 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
|
||||
// profile only have credential provider options.
|
||||
cfg.clearAssumeRoleOptions()
|
||||
} else {
|
||||
// First time a profile has been seen, It must either be a assume role
|
||||
// credentials, or SSO. Assert if the credential type requires a role ARN,
|
||||
// the ARN is also set, or validate that the SSO configuration is complete.
|
||||
// First time a profile has been seen. Assert if the credential type
|
||||
// requires a role ARN, the ARN is also set
|
||||
if err := cfg.validateCredentialsConfig(profile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
profiles[profile] = struct{}{}
|
||||
|
||||
if err := cfg.validateCredentialType(); err != nil {
|
||||
@@ -308,6 +333,30 @@ func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile s
|
||||
cfg.SourceProfile = srcCfg
|
||||
}
|
||||
|
||||
// If the profile contains an SSO session parameter, the session MUST exist
|
||||
// as a section in the config file. Load the SSO session using the name
|
||||
// provided. If the session section is not found or incomplete an error
|
||||
// will be returned.
|
||||
if cfg.hasSSOTokenProviderConfiguration() {
|
||||
skippedFiles = 0
|
||||
for _, f := range files {
|
||||
section, ok := f.IniData.GetSection(fmt.Sprintf(ssoSectionPrefix + strings.TrimSpace(cfg.SSOSessionName)))
|
||||
if ok {
|
||||
var ssoSession ssoSession
|
||||
ssoSession.setFromIniSection(section)
|
||||
ssoSession.Name = cfg.SSOSessionName
|
||||
cfg.SSOSession = &ssoSession
|
||||
break
|
||||
}
|
||||
skippedFiles++
|
||||
}
|
||||
if skippedFiles == len(files) {
|
||||
// If all files were skipped because the sso session section is not found, return
|
||||
// the sso section not found error.
|
||||
return fmt.Errorf("failed to find SSO session section, %v", cfg.SSOSessionName)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -363,6 +412,10 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
|
||||
cfg.S3UsEast1RegionalEndpoint = sre
|
||||
}
|
||||
|
||||
// AWS Single Sign-On (AWS SSO)
|
||||
// SSO session options
|
||||
updateString(&cfg.SSOSessionName, section, ssoSessionNameKey)
|
||||
|
||||
// AWS Single Sign-On (AWS SSO)
|
||||
updateString(&cfg.SSOAccountID, section, ssoAccountIDKey)
|
||||
updateString(&cfg.SSORegion, section, ssoRegionKey)
|
||||
@@ -461,32 +514,20 @@ func (cfg *sharedConfig) validateCredentialType() error {
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) validateSSOConfiguration() error {
|
||||
if !cfg.hasSSOConfiguration() {
|
||||
if cfg.hasSSOTokenProviderConfiguration() {
|
||||
err := cfg.validateSSOTokenProviderConfiguration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var missing []string
|
||||
if len(cfg.SSOAccountID) == 0 {
|
||||
missing = append(missing, ssoAccountIDKey)
|
||||
if cfg.hasLegacySSOConfiguration() {
|
||||
err := cfg.validateLegacySSOConfiguration()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(cfg.SSORegion) == 0 {
|
||||
missing = append(missing, ssoRegionKey)
|
||||
}
|
||||
|
||||
if len(cfg.SSORoleName) == 0 {
|
||||
missing = append(missing, ssoRoleNameKey)
|
||||
}
|
||||
|
||||
if len(cfg.SSOStartURL) == 0 {
|
||||
missing = append(missing, ssoStartURL)
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
|
||||
cfg.Profile, strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -525,15 +566,76 @@ func (cfg *sharedConfig) clearAssumeRoleOptions() {
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) hasSSOConfiguration() bool {
|
||||
switch {
|
||||
case len(cfg.SSOAccountID) != 0:
|
||||
case len(cfg.SSORegion) != 0:
|
||||
case len(cfg.SSORoleName) != 0:
|
||||
case len(cfg.SSOStartURL) != 0:
|
||||
default:
|
||||
return false
|
||||
return cfg.hasSSOTokenProviderConfiguration() || cfg.hasLegacySSOConfiguration()
|
||||
}
|
||||
|
||||
func (c *sharedConfig) hasSSOTokenProviderConfiguration() bool {
|
||||
return len(c.SSOSessionName) > 0
|
||||
}
|
||||
|
||||
func (c *sharedConfig) hasLegacySSOConfiguration() bool {
|
||||
return len(c.SSORegion) > 0 || len(c.SSOAccountID) > 0 || len(c.SSOStartURL) > 0 || len(c.SSORoleName) > 0
|
||||
}
|
||||
|
||||
func (c *sharedConfig) validateSSOTokenProviderConfiguration() error {
|
||||
var missing []string
|
||||
|
||||
if len(c.SSOSessionName) == 0 {
|
||||
missing = append(missing, ssoSessionNameKey)
|
||||
}
|
||||
return true
|
||||
|
||||
if c.SSOSession == nil {
|
||||
missing = append(missing, ssoSectionPrefix)
|
||||
} else {
|
||||
if len(c.SSOSession.SSORegion) == 0 {
|
||||
missing = append(missing, ssoRegionKey)
|
||||
}
|
||||
|
||||
if len(c.SSOSession.SSOStartURL) == 0 {
|
||||
missing = append(missing, ssoStartURL)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
|
||||
c.Profile, strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
if len(c.SSORegion) > 0 && c.SSORegion != c.SSOSession.SSORegion {
|
||||
return fmt.Errorf("%s in profile %q must match %s in %s", ssoRegionKey, c.Profile, ssoRegionKey, ssoSectionPrefix)
|
||||
}
|
||||
|
||||
if len(c.SSOStartURL) > 0 && c.SSOStartURL != c.SSOSession.SSOStartURL {
|
||||
return fmt.Errorf("%s in profile %q must match %s in %s", ssoStartURL, c.Profile, ssoStartURL, ssoSectionPrefix)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *sharedConfig) validateLegacySSOConfiguration() error {
|
||||
var missing []string
|
||||
|
||||
if len(c.SSORegion) == 0 {
|
||||
missing = append(missing, ssoRegionKey)
|
||||
}
|
||||
|
||||
if len(c.SSOStartURL) == 0 {
|
||||
missing = append(missing, ssoStartURL)
|
||||
}
|
||||
|
||||
if len(c.SSOAccountID) == 0 {
|
||||
missing = append(missing, ssoAccountIDKey)
|
||||
}
|
||||
|
||||
if len(c.SSORoleName) == 0 {
|
||||
missing = append(missing, ssoRoleNameKey)
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
|
||||
c.Profile, strings.Join(missing, ", "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func oneOrNone(bs ...bool) bool {
|
||||
|
||||
+2
-1
@@ -8,7 +8,7 @@
|
||||
// Generally using the signer outside of the SDK should not require any additional
|
||||
// logic when using Go v1.5 or higher. The signer does this by taking advantage
|
||||
// of the URL.EscapedPath method. If your request URI requires additional escaping
|
||||
// you many need to use the URL.Opaque to define what the raw URI should be sent
|
||||
// you may need to use the URL.Opaque to define what the raw URI should be sent
|
||||
// to the service as.
|
||||
//
|
||||
// The signer will first check the URL.Opaque field, and use its value if set.
|
||||
@@ -135,6 +135,7 @@ var requiredSignedHeaders = rules{
|
||||
"X-Amz-Request-Payer": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Context": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@ package aws
|
||||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.44.294"
|
||||
const SDKVersion = "1.45.1"
|
||||
|
||||
+20
-2
@@ -346,8 +346,9 @@ func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, ou
|
||||
// to read the entire body.
|
||||
//
|
||||
// The copy request charge is based on the storage class and Region that you
|
||||
// specify for the destination object. For pricing information, see Amazon S3
|
||||
// pricing (http://aws.amazon.com/s3/pricing/).
|
||||
// specify for the destination object. The request can also result in a data
|
||||
// retrieval charge for the source if the source storage class bills for data
|
||||
// retrieval. For pricing information, see Amazon S3 pricing (http://aws.amazon.com/s3/pricing/).
|
||||
//
|
||||
// Amazon S3 transfer acceleration does not support cross-Region copies. If
|
||||
// you request a cross-Region copy using a transfer acceleration endpoint, you
|
||||
@@ -10708,6 +10709,7 @@ func (c *S3) SelectObjectContentWithContext(ctx aws.Context, input *SelectObject
|
||||
}
|
||||
|
||||
var _ awserr.Error
|
||||
var _ time.Time
|
||||
|
||||
// SelectObjectContentEventStream provides the event stream handling for the SelectObjectContent.
|
||||
//
|
||||
@@ -41352,6 +41354,12 @@ const (
|
||||
|
||||
// BucketLocationConstraintUsWest2 is a BucketLocationConstraint enum value
|
||||
BucketLocationConstraintUsWest2 = "us-west-2"
|
||||
|
||||
// BucketLocationConstraintApSouth2 is a BucketLocationConstraint enum value
|
||||
BucketLocationConstraintApSouth2 = "ap-south-2"
|
||||
|
||||
// BucketLocationConstraintEuSouth2 is a BucketLocationConstraint enum value
|
||||
BucketLocationConstraintEuSouth2 = "eu-south-2"
|
||||
)
|
||||
|
||||
// BucketLocationConstraint_Values returns all elements of the BucketLocationConstraint enum
|
||||
@@ -41383,6 +41391,8 @@ func BucketLocationConstraint_Values() []string {
|
||||
BucketLocationConstraintUsGovWest1,
|
||||
BucketLocationConstraintUsWest1,
|
||||
BucketLocationConstraintUsWest2,
|
||||
BucketLocationConstraintApSouth2,
|
||||
BucketLocationConstraintEuSouth2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41832,6 +41842,12 @@ const (
|
||||
|
||||
// InventoryOptionalFieldChecksumAlgorithm is a InventoryOptionalField enum value
|
||||
InventoryOptionalFieldChecksumAlgorithm = "ChecksumAlgorithm"
|
||||
|
||||
// InventoryOptionalFieldObjectAccessControlList is a InventoryOptionalField enum value
|
||||
InventoryOptionalFieldObjectAccessControlList = "ObjectAccessControlList"
|
||||
|
||||
// InventoryOptionalFieldObjectOwner is a InventoryOptionalField enum value
|
||||
InventoryOptionalFieldObjectOwner = "ObjectOwner"
|
||||
)
|
||||
|
||||
// InventoryOptionalField_Values returns all elements of the InventoryOptionalField enum
|
||||
@@ -41850,6 +41866,8 @@ func InventoryOptionalField_Values() []string {
|
||||
InventoryOptionalFieldIntelligentTieringAccessTier,
|
||||
InventoryOptionalFieldBucketKeyStatus,
|
||||
InventoryOptionalFieldChecksumAlgorithm,
|
||||
InventoryOptionalFieldObjectAccessControlList,
|
||||
InventoryOptionalFieldObjectOwner,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1682
File diff suppressed because it is too large
Load Diff
+66
@@ -0,0 +1,66 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package ssooidc provides the client and types for making API
|
||||
// requests to AWS SSO OIDC.
|
||||
//
|
||||
// AWS IAM Identity Center (successor to AWS Single Sign-On) OpenID Connect
|
||||
// (OIDC) is a web service that enables a client (such as AWS CLI or a native
|
||||
// application) to register with IAM Identity Center. The service also enables
|
||||
// the client to fetch the user’s access token upon successful authentication
|
||||
// and authorization with IAM Identity Center.
|
||||
//
|
||||
// Although AWS Single Sign-On was renamed, the sso and identitystore API namespaces
|
||||
// will continue to retain their original name for backward compatibility purposes.
|
||||
// For more information, see IAM Identity Center rename (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed).
|
||||
//
|
||||
// # Considerations for Using This Guide
|
||||
//
|
||||
// Before you begin using this guide, we recommend that you first review the
|
||||
// following important information about how the IAM Identity Center OIDC service
|
||||
// works.
|
||||
//
|
||||
// - The IAM Identity Center OIDC service currently implements only the portions
|
||||
// of the OAuth 2.0 Device Authorization Grant standard (https://tools.ietf.org/html/rfc8628
|
||||
// (https://tools.ietf.org/html/rfc8628)) that are necessary to enable single
|
||||
// sign-on authentication with the AWS CLI. Support for other OIDC flows
|
||||
// frequently needed for native applications, such as Authorization Code
|
||||
// Flow (+ PKCE), will be addressed in future releases.
|
||||
//
|
||||
// - The service emits only OIDC access tokens, such that obtaining a new
|
||||
// token (For example, token refresh) requires explicit user re-authentication.
|
||||
//
|
||||
// - The access tokens provided by this service grant access to all AWS account
|
||||
// entitlements assigned to an IAM Identity Center user, not just a particular
|
||||
// application.
|
||||
//
|
||||
// - The documentation in this guide does not describe the mechanism to convert
|
||||
// the access token into AWS Auth (“sigv4”) credentials for use with
|
||||
// IAM-protected AWS service endpoints. For more information, see GetRoleCredentials
|
||||
// (https://docs.aws.amazon.com/singlesignon/latest/PortalAPIReference/API_GetRoleCredentials.html)
|
||||
// in the IAM Identity Center Portal API Reference Guide.
|
||||
//
|
||||
// For general information about IAM Identity Center, see What is IAM Identity
|
||||
// Center? (https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)
|
||||
// in the IAM Identity Center User Guide.
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/sso-oidc-2019-06-10 for more information on this service.
|
||||
//
|
||||
// See ssooidc package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssooidc/
|
||||
//
|
||||
// # Using the Client
|
||||
//
|
||||
// To contact AWS SSO OIDC with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the AWS SSO OIDC client SSOOIDC for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/ssooidc/#New
|
||||
package ssooidc
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package ssooidc
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeAccessDeniedException for service response error code
|
||||
// "AccessDeniedException".
|
||||
//
|
||||
// You do not have sufficient access to perform this action.
|
||||
ErrCodeAccessDeniedException = "AccessDeniedException"
|
||||
|
||||
// ErrCodeAuthorizationPendingException for service response error code
|
||||
// "AuthorizationPendingException".
|
||||
//
|
||||
// Indicates that a request to authorize a client with an access user session
|
||||
// token is pending.
|
||||
ErrCodeAuthorizationPendingException = "AuthorizationPendingException"
|
||||
|
||||
// ErrCodeExpiredTokenException for service response error code
|
||||
// "ExpiredTokenException".
|
||||
//
|
||||
// Indicates that the token issued by the service is expired and is no longer
|
||||
// valid.
|
||||
ErrCodeExpiredTokenException = "ExpiredTokenException"
|
||||
|
||||
// ErrCodeInternalServerException for service response error code
|
||||
// "InternalServerException".
|
||||
//
|
||||
// Indicates that an error from the service occurred while trying to process
|
||||
// a request.
|
||||
ErrCodeInternalServerException = "InternalServerException"
|
||||
|
||||
// ErrCodeInvalidClientException for service response error code
|
||||
// "InvalidClientException".
|
||||
//
|
||||
// Indicates that the clientId or clientSecret in the request is invalid. For
|
||||
// example, this can occur when a client sends an incorrect clientId or an expired
|
||||
// clientSecret.
|
||||
ErrCodeInvalidClientException = "InvalidClientException"
|
||||
|
||||
// ErrCodeInvalidClientMetadataException for service response error code
|
||||
// "InvalidClientMetadataException".
|
||||
//
|
||||
// Indicates that the client information sent in the request during registration
|
||||
// is invalid.
|
||||
ErrCodeInvalidClientMetadataException = "InvalidClientMetadataException"
|
||||
|
||||
// ErrCodeInvalidGrantException for service response error code
|
||||
// "InvalidGrantException".
|
||||
//
|
||||
// Indicates that a request contains an invalid grant. This can occur if a client
|
||||
// makes a CreateToken request with an invalid grant type.
|
||||
ErrCodeInvalidGrantException = "InvalidGrantException"
|
||||
|
||||
// ErrCodeInvalidRequestException for service response error code
|
||||
// "InvalidRequestException".
|
||||
//
|
||||
// Indicates that something is wrong with the input to the request. For example,
|
||||
// a required parameter might be missing or out of range.
|
||||
ErrCodeInvalidRequestException = "InvalidRequestException"
|
||||
|
||||
// ErrCodeInvalidScopeException for service response error code
|
||||
// "InvalidScopeException".
|
||||
//
|
||||
// Indicates that the scope provided in the request is invalid.
|
||||
ErrCodeInvalidScopeException = "InvalidScopeException"
|
||||
|
||||
// ErrCodeSlowDownException for service response error code
|
||||
// "SlowDownException".
|
||||
//
|
||||
// Indicates that the client is making the request too frequently and is more
|
||||
// than the service can handle.
|
||||
ErrCodeSlowDownException = "SlowDownException"
|
||||
|
||||
// ErrCodeUnauthorizedClientException for service response error code
|
||||
// "UnauthorizedClientException".
|
||||
//
|
||||
// Indicates that the client is not currently authorized to make the request.
|
||||
// This can happen when a clientId is not issued for a public client.
|
||||
ErrCodeUnauthorizedClientException = "UnauthorizedClientException"
|
||||
|
||||
// ErrCodeUnsupportedGrantTypeException for service response error code
|
||||
// "UnsupportedGrantTypeException".
|
||||
//
|
||||
// Indicates that the grant type in the request is not supported by the service.
|
||||
ErrCodeUnsupportedGrantTypeException = "UnsupportedGrantTypeException"
|
||||
)
|
||||
|
||||
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
|
||||
"AccessDeniedException": newErrorAccessDeniedException,
|
||||
"AuthorizationPendingException": newErrorAuthorizationPendingException,
|
||||
"ExpiredTokenException": newErrorExpiredTokenException,
|
||||
"InternalServerException": newErrorInternalServerException,
|
||||
"InvalidClientException": newErrorInvalidClientException,
|
||||
"InvalidClientMetadataException": newErrorInvalidClientMetadataException,
|
||||
"InvalidGrantException": newErrorInvalidGrantException,
|
||||
"InvalidRequestException": newErrorInvalidRequestException,
|
||||
"InvalidScopeException": newErrorInvalidScopeException,
|
||||
"SlowDownException": newErrorSlowDownException,
|
||||
"UnauthorizedClientException": newErrorUnauthorizedClientException,
|
||||
"UnsupportedGrantTypeException": newErrorUnsupportedGrantTypeException,
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package ssooidc
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
// SSOOIDC provides the API operation methods for making requests to
|
||||
// AWS SSO OIDC. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// SSOOIDC methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type SSOOIDC struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "SSO OIDC" // Name of service.
|
||||
EndpointsID = "oidc" // ID to lookup a service endpoint with.
|
||||
ServiceID = "SSO OIDC" // ServiceID is a unique identifier of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the SSOOIDC client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// mySession := session.Must(session.NewSession())
|
||||
//
|
||||
// // Create a SSOOIDC client from just a session.
|
||||
// svc := ssooidc.New(mySession)
|
||||
//
|
||||
// // Create a SSOOIDC client with additional configuration
|
||||
// svc := ssooidc.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SSOOIDC {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
if c.SigningNameDerived || len(c.SigningName) == 0 {
|
||||
c.SigningName = "awsssooidc"
|
||||
}
|
||||
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName, c.ResolvedRegion)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName, resolvedRegion string) *SSOOIDC {
|
||||
svc := &SSOOIDC{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
PartitionID: partitionID,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2019-06-10",
|
||||
ResolvedRegion: resolvedRegion,
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(restjson.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(
|
||||
protocol.NewUnmarshalErrorHandler(restjson.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(),
|
||||
)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a SSOOIDC operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *SSOOIDC) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
+78
-1
@@ -1460,6 +1460,9 @@ type AssumeRoleInput struct {
|
||||
// in the IAM User Guide.
|
||||
PolicyArns []*PolicyDescriptorType `type:"list"`
|
||||
|
||||
// Reserved for future use.
|
||||
ProvidedContexts []*ProvidedContext `type:"list"`
|
||||
|
||||
// The Amazon Resource Name (ARN) of the role to assume.
|
||||
//
|
||||
// RoleArn is a required field
|
||||
@@ -1633,6 +1636,16 @@ func (s *AssumeRoleInput) Validate() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.ProvidedContexts != nil {
|
||||
for i, v := range s.ProvidedContexts {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if err := v.Validate(); err != nil {
|
||||
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ProvidedContexts", i), err.(request.ErrInvalidParams))
|
||||
}
|
||||
}
|
||||
}
|
||||
if s.Tags != nil {
|
||||
for i, v := range s.Tags {
|
||||
if v == nil {
|
||||
@@ -1674,6 +1687,12 @@ func (s *AssumeRoleInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleIn
|
||||
return s
|
||||
}
|
||||
|
||||
// SetProvidedContexts sets the ProvidedContexts field's value.
|
||||
func (s *AssumeRoleInput) SetProvidedContexts(v []*ProvidedContext) *AssumeRoleInput {
|
||||
s.ProvidedContexts = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetRoleArn sets the RoleArn field's value.
|
||||
func (s *AssumeRoleInput) SetRoleArn(v string) *AssumeRoleInput {
|
||||
s.RoleArn = &v
|
||||
@@ -2266,7 +2285,8 @@ type AssumeRoleWithWebIdentityInput struct {
|
||||
// The OAuth 2.0 access token or OpenID Connect ID token that is provided by
|
||||
// the identity provider. Your application must get this token by authenticating
|
||||
// the user who is using your application with a web identity provider before
|
||||
// the application makes an AssumeRoleWithWebIdentity call.
|
||||
// the application makes an AssumeRoleWithWebIdentity call. Only tokens with
|
||||
// RSA algorithms (RS256) are supported.
|
||||
//
|
||||
// WebIdentityToken is a sensitive parameter and its value will be
|
||||
// replaced with "sensitive" in string returned by AssumeRoleWithWebIdentityInput's
|
||||
@@ -3385,6 +3405,63 @@ func (s *PolicyDescriptorType) SetArn(v string) *PolicyDescriptorType {
|
||||
return s
|
||||
}
|
||||
|
||||
// Reserved for future use.
|
||||
type ProvidedContext struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Reserved for future use.
|
||||
ContextAssertion *string `min:"4" type:"string"`
|
||||
|
||||
// Reserved for future use.
|
||||
ProviderArn *string `min:"20" type:"string"`
|
||||
}
|
||||
|
||||
// String returns the string representation.
|
||||
//
|
||||
// API parameter values that are decorated as "sensitive" in the API will not
|
||||
// be included in the string output. The member name will be present, but the
|
||||
// value will be replaced with "sensitive".
|
||||
func (s ProvidedContext) String() string {
|
||||
return awsutil.Prettify(s)
|
||||
}
|
||||
|
||||
// GoString returns the string representation.
|
||||
//
|
||||
// API parameter values that are decorated as "sensitive" in the API will not
|
||||
// be included in the string output. The member name will be present, but the
|
||||
// value will be replaced with "sensitive".
|
||||
func (s ProvidedContext) GoString() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// Validate inspects the fields of the type to determine if they are valid.
|
||||
func (s *ProvidedContext) Validate() error {
|
||||
invalidParams := request.ErrInvalidParams{Context: "ProvidedContext"}
|
||||
if s.ContextAssertion != nil && len(*s.ContextAssertion) < 4 {
|
||||
invalidParams.Add(request.NewErrParamMinLen("ContextAssertion", 4))
|
||||
}
|
||||
if s.ProviderArn != nil && len(*s.ProviderArn) < 20 {
|
||||
invalidParams.Add(request.NewErrParamMinLen("ProviderArn", 20))
|
||||
}
|
||||
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetContextAssertion sets the ContextAssertion field's value.
|
||||
func (s *ProvidedContext) SetContextAssertion(v string) *ProvidedContext {
|
||||
s.ContextAssertion = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetProviderArn sets the ProviderArn field's value.
|
||||
func (s *ProvidedContext) SetProviderArn(v string) *ProvidedContext {
|
||||
s.ProviderArn = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// You can pass custom key-value pair attributes when you assume a role or federate
|
||||
// a user. These are called session tags. You can then use the session tags
|
||||
// to control access to resources. For more information, see Tagging Amazon
|
||||
|
||||
Reference in New Issue
Block a user