vendor: update buildkit to v0.28.0-rc1
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
+4
@@ -118,6 +118,10 @@ const (
|
||||
CredentialSourceHTTP
|
||||
// CredentialSourceIMDS credentials resolved from the instance metadata service (IMDS)
|
||||
CredentialSourceIMDS
|
||||
// CredentialSourceProfileLogin credentials resolved from an `aws login` session sourced from a profile
|
||||
CredentialSourceProfileLogin
|
||||
// CredentialSourceLogin credentials resolved from an `aws login` session
|
||||
CredentialSourceLogin
|
||||
)
|
||||
|
||||
// A Credentials is the AWS credentials value for individual credential fields.
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package aws
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.39.6"
|
||||
const goModuleVersion = "1.41.1"
|
||||
|
||||
+5
@@ -137,6 +137,9 @@ const (
|
||||
UserAgentFeatureCredentialsIMDS = "0"
|
||||
|
||||
UserAgentFeatureBearerServiceEnvVars = "3"
|
||||
|
||||
UserAgentFeatureCredentialsProfileLogin = "AC"
|
||||
UserAgentFeatureCredentialsLogin = "AD"
|
||||
)
|
||||
|
||||
var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{
|
||||
@@ -160,6 +163,8 @@ var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{
|
||||
aws.CredentialSourceProcess: UserAgentFeatureCredentialsProcess,
|
||||
aws.CredentialSourceHTTP: UserAgentFeatureCredentialsHTTP,
|
||||
aws.CredentialSourceIMDS: UserAgentFeatureCredentialsIMDS,
|
||||
aws.CredentialSourceProfileLogin: UserAgentFeatureCredentialsProfileLogin,
|
||||
aws.CredentialSourceLogin: UserAgentFeatureCredentialsLogin,
|
||||
}
|
||||
|
||||
// RequestUserAgent is a build middleware that set the User-Agent for the request.
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ var (
|
||||
// Default connection pool options
|
||||
DefaultHTTPTransportMaxIdleConns = 100
|
||||
DefaultHTTPTransportMaxIdleConnsPerHost = 10
|
||||
DefaultHTTPTransportMaxConnsPerHost = 2048
|
||||
|
||||
// Default connection timeouts
|
||||
DefaultHTTPTransportIdleConnTimeout = 90 * time.Second
|
||||
@@ -186,6 +187,7 @@ func defaultHTTPTransport() *http.Transport {
|
||||
TLSHandshakeTimeout: DefaultHTTPTransportTLSHandleshakeTimeout,
|
||||
MaxIdleConns: DefaultHTTPTransportMaxIdleConns,
|
||||
MaxIdleConnsPerHost: DefaultHTTPTransportMaxIdleConnsPerHost,
|
||||
MaxConnsPerHost: DefaultHTTPTransportMaxConnsPerHost,
|
||||
IdleConnTimeout: DefaultHTTPTransportIdleConnTimeout,
|
||||
ExpectContinueTimeout: DefaultHTTPTransportExpectContinueTimeout,
|
||||
ForceAttemptHTTP2: true,
|
||||
|
||||
+38
@@ -1,3 +1,41 @@
|
||||
# v1.32.7 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.6 (2025-12-16)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.5 (2025-12-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.4 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.3 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.32.2 (2025-11-25)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.1 (2025-11-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.32.0 (2025-11-19.2)
|
||||
|
||||
* **Feature**: Add support for AWS Login credentials (package credentials/logincreds) to the default credential chain.
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.31.21 (2025-11-19)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.31.20 (2025-11-12)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package config
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.31.20"
|
||||
const goModuleVersion = "1.32.7"
|
||||
|
||||
+24
-1
@@ -13,10 +13,12 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/logincreds"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/processcreds"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sso"
|
||||
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sts"
|
||||
@@ -172,7 +174,10 @@ func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *En
|
||||
ctx = addCredentialSource(ctx, aws.CredentialSourceProfileSSO)
|
||||
}
|
||||
err = resolveSSOCredentials(ctx, cfg, sharedConfig, configs)
|
||||
|
||||
case len(sharedConfig.LoginSession) > 0:
|
||||
ctx = addCredentialSource(ctx, aws.CredentialSourceProfileLogin)
|
||||
ctx = addCredentialSource(ctx, aws.CredentialSourceLogin)
|
||||
err = resolveLoginCredentials(ctx, cfg, sharedConfig, configs)
|
||||
case len(sharedConfig.CredentialProcess) != 0:
|
||||
// Get credentials from CredentialProcess
|
||||
ctx = addCredentialSource(ctx, aws.CredentialSourceProfileProcess)
|
||||
@@ -625,3 +630,21 @@ func addCredentialSource(ctx context.Context, source aws.CredentialSource) conte
|
||||
func getCredentialSources(ctx context.Context) []aws.CredentialSource {
|
||||
return ctx.Value(credentialSource{}).([]aws.CredentialSource)
|
||||
}
|
||||
|
||||
func resolveLoginCredentials(ctx context.Context, cfg *aws.Config, sharedCfg *SharedConfig, configs configs) error {
|
||||
cacheDir := os.Getenv("AWS_LOGIN_CACHE_DIRECTORY")
|
||||
tokenPath, err := logincreds.StandardCachedTokenFilepath(sharedCfg.LoginSession, cacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc := signin.NewFromConfig(*cfg)
|
||||
provider := logincreds.New(svc, tokenPath, func(o *logincreds.Options) {
|
||||
o.CredentialSources = getCredentialSources(ctx)
|
||||
})
|
||||
cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+9
@@ -125,6 +125,8 @@ const (
|
||||
checksumWhenRequired = "when_required"
|
||||
|
||||
authSchemePreferenceKey = "auth_scheme_preference"
|
||||
|
||||
loginSessionKey = "login_session"
|
||||
)
|
||||
|
||||
// defaultSharedConfigProfile allows for swapping the default profile for testing
|
||||
@@ -362,6 +364,9 @@ type SharedConfig struct {
|
||||
|
||||
// Priority list of preferred auth scheme names (e.g. sigv4a).
|
||||
AuthSchemePreference []string
|
||||
|
||||
// Session ARN from an `aws login` session.
|
||||
LoginSession string
|
||||
}
|
||||
|
||||
func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) {
|
||||
@@ -897,6 +902,8 @@ func mergeSections(dst *ini.Sections, src ini.Sections) error {
|
||||
ssoStartURLKey,
|
||||
|
||||
authSchemePreferenceKey,
|
||||
|
||||
loginSessionKey,
|
||||
}
|
||||
for i := range stringKeys {
|
||||
if err := mergeStringKey(&srcSection, &dstSection, sectionName, stringKeys[i]); err != nil {
|
||||
@@ -1175,6 +1182,8 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er
|
||||
|
||||
c.AuthSchemePreference = toAuthSchemePreferenceList(section.String(authSchemePreferenceKey))
|
||||
|
||||
updateString(&c.LoginSession, section, loginSessionKey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+38
@@ -1,3 +1,41 @@
|
||||
# v1.19.7 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.6 (2025-12-16)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.5 (2025-12-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.4 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.3 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.19.2 (2025-11-25)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.1 (2025-11-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.19.0 (2025-11-19.2)
|
||||
|
||||
* **Feature**: Add support for AWS Login credentials (package credentials/logincreds) to the default credential chain.
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.18.25 (2025-11-19)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.18.24 (2025-11-12)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package credentials
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.18.24"
|
||||
const goModuleVersion = "1.19.7"
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package logincreds
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
smithyrand "github.com/aws/smithy-go/rand"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
)
|
||||
|
||||
// AWS signin DPOP always uses the P256 curve
|
||||
const curvelen = 256 / 8 // bytes
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc9449
|
||||
func mkdpop(token *loginToken, htu string) (string, error) {
|
||||
key, err := parseKey(token.DPOPKey)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("parse key: %w", err)
|
||||
}
|
||||
|
||||
header, err := jsonb64(&dpopHeader{
|
||||
Typ: "dpop+jwt",
|
||||
Alg: "ES256",
|
||||
Jwk: &dpopHeaderJwk{
|
||||
Kty: "EC",
|
||||
X: base64.RawURLEncoding.EncodeToString(key.X.Bytes()),
|
||||
Y: base64.RawURLEncoding.EncodeToString(key.Y.Bytes()),
|
||||
Crv: "P-256",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("marshal header: %w", err)
|
||||
}
|
||||
|
||||
uuid, err := smithyrand.NewUUID(cryptorand.Reader).GetUUID()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("uuid: %w", err)
|
||||
}
|
||||
|
||||
payload, err := jsonb64(&dpopPayload{
|
||||
Jti: uuid,
|
||||
Htm: "POST",
|
||||
Htu: htu,
|
||||
Iat: sdk.NowTime().Unix(),
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("marshal payload: %w", err)
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("%s.%s", header, payload)
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(msg))
|
||||
|
||||
r, s, err := ecdsa.Sign(cryptorand.Reader, key, h.Sum(nil))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sign: %w", err)
|
||||
}
|
||||
|
||||
// DPOP signatures are formatted in RAW r || s form (with each value padded
|
||||
// to fit in curve size which in our case is always the 256 bits) - rather
|
||||
// than encoded in something like asn.1
|
||||
sig := make([]byte, curvelen*2)
|
||||
r.FillBytes(sig[0:curvelen])
|
||||
s.FillBytes(sig[curvelen:])
|
||||
|
||||
dpop := fmt.Sprintf("%s.%s", msg, base64.RawURLEncoding.EncodeToString(sig))
|
||||
return dpop, nil
|
||||
}
|
||||
|
||||
func parseKey(pemBlock string) (*ecdsa.PrivateKey, error) {
|
||||
block, _ := pem.Decode([]byte(pemBlock))
|
||||
priv, err := x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse ec private key: %w", err)
|
||||
}
|
||||
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
func jsonb64(v any) (string, error) {
|
||||
j, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return base64.RawURLEncoding.EncodeToString(j), nil
|
||||
}
|
||||
|
||||
type dpopHeader struct {
|
||||
Typ string `json:"typ"`
|
||||
Alg string `json:"alg"`
|
||||
Jwk *dpopHeaderJwk `json:"jwk"`
|
||||
}
|
||||
|
||||
type dpopHeaderJwk struct {
|
||||
Kty string `json:"kty"`
|
||||
X string `json:"x"`
|
||||
Y string `json:"y"`
|
||||
Crv string `json:"crv"`
|
||||
}
|
||||
|
||||
type dpopPayload struct {
|
||||
Jti string `json:"jti"`
|
||||
Htm string `json:"htm"`
|
||||
Htu string `json:"htu"`
|
||||
Iat int64 `json:"iat"`
|
||||
}
|
||||
|
||||
type signDPOP struct {
|
||||
Token *loginToken
|
||||
}
|
||||
|
||||
func addSignDPOP(token *loginToken) func(o *signin.Options) {
|
||||
return signin.WithAPIOptions(func(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Add(&signDPOP{token}, middleware.After)
|
||||
})
|
||||
}
|
||||
|
||||
func (*signDPOP) ID() string {
|
||||
return "signDPOP"
|
||||
}
|
||||
|
||||
func (m *signDPOP) HandleFinalize(
|
||||
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, md middleware.Metadata, err error,
|
||||
) {
|
||||
req, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, md, fmt.Errorf("unexpected transport type %T", req)
|
||||
}
|
||||
|
||||
dpop, err := mkdpop(m.Token, req.URL.String())
|
||||
if err != nil {
|
||||
return out, md, fmt.Errorf("sign dpop: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("DPoP", dpop)
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package logincreds
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
var openFile func(string) (io.ReadCloser, error) = func(name string) (io.ReadCloser, error) {
|
||||
return os.Open(name)
|
||||
}
|
||||
|
||||
var createFile func(string) (io.WriteCloser, error) = func(name string) (io.WriteCloser, error) {
|
||||
return os.Create(name)
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
// Package logincreds implements AWS credential provision for sessions created
|
||||
// via an `aws login` command.
|
||||
package logincreds
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin/types"
|
||||
)
|
||||
|
||||
// ProviderName identifies the login provider.
|
||||
const ProviderName = "LoginProvider"
|
||||
|
||||
// TokenAPIClient provides the interface for the login session's token
|
||||
// retrieval operation.
|
||||
type TokenAPIClient interface {
|
||||
CreateOAuth2Token(context.Context, *signin.CreateOAuth2TokenInput, ...func(*signin.Options)) (*signin.CreateOAuth2TokenOutput, error)
|
||||
}
|
||||
|
||||
// Provider supplies credentials for an `aws login` session.
|
||||
type Provider struct {
|
||||
options Options
|
||||
}
|
||||
|
||||
var _ aws.CredentialsProvider = (*Provider)(nil)
|
||||
|
||||
// Options configures the Provider.
|
||||
type Options struct {
|
||||
Client TokenAPIClient
|
||||
|
||||
// APIOptions to pass to the underlying CreateOAuth2Token operation.
|
||||
ClientOptions []func(*signin.Options)
|
||||
|
||||
// The path to the cached login token.
|
||||
CachedTokenFilepath string
|
||||
|
||||
// The chain of providers that was used to create this provider.
|
||||
//
|
||||
// These values are for reporting purposes and are not meant to be set up
|
||||
// directly.
|
||||
CredentialSources []aws.CredentialSource
|
||||
}
|
||||
|
||||
// New returns a new login session credentials provider.
|
||||
func New(client TokenAPIClient, path string, opts ...func(*Options)) *Provider {
|
||||
options := Options{
|
||||
Client: client,
|
||||
CachedTokenFilepath: path,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
return &Provider{options}
|
||||
}
|
||||
|
||||
// Retrieve generates a new set of temporary credentials using an `aws login`
|
||||
// session.
|
||||
func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) {
|
||||
token, err := p.loadToken()
|
||||
if err != nil {
|
||||
return aws.Credentials{}, fmt.Errorf("load login token: %w", err)
|
||||
}
|
||||
if err := token.Validate(); err != nil {
|
||||
return aws.Credentials{}, fmt.Errorf("validate login token: %w", err)
|
||||
}
|
||||
|
||||
// the token may have been refreshed elsewhere or the login session might
|
||||
// have just been created
|
||||
if sdk.NowTime().Before(token.AccessToken.ExpiresAt) {
|
||||
return token.Credentials(), nil
|
||||
}
|
||||
|
||||
opts := make([]func(*signin.Options), len(p.options.ClientOptions)+1)
|
||||
opts[0] = addSignDPOP(token)
|
||||
copy(opts[1:], p.options.ClientOptions)
|
||||
|
||||
out, err := p.options.Client.CreateOAuth2Token(ctx, &signin.CreateOAuth2TokenInput{
|
||||
TokenInput: &types.CreateOAuth2TokenRequestBody{
|
||||
ClientId: aws.String(token.ClientID),
|
||||
GrantType: aws.String("refresh_token"),
|
||||
RefreshToken: aws.String(token.RefreshToken),
|
||||
},
|
||||
}, opts...)
|
||||
if err != nil {
|
||||
var terr *types.AccessDeniedException
|
||||
if errors.As(err, &terr) {
|
||||
err = toAccessDeniedError(terr)
|
||||
}
|
||||
return aws.Credentials{}, fmt.Errorf("create oauth2 token: %w", err)
|
||||
}
|
||||
|
||||
token.Update(out)
|
||||
if err := p.saveToken(token); err != nil {
|
||||
return aws.Credentials{}, fmt.Errorf("save token: %w", err)
|
||||
}
|
||||
|
||||
return token.Credentials(), nil
|
||||
}
|
||||
|
||||
// ProviderSources returns the credential chain that was used to construct this
|
||||
// provider.
|
||||
func (p *Provider) ProviderSources() []aws.CredentialSource {
|
||||
if p.options.CredentialSources == nil {
|
||||
return []aws.CredentialSource{aws.CredentialSourceLogin}
|
||||
}
|
||||
return p.options.CredentialSources
|
||||
}
|
||||
|
||||
func (p *Provider) loadToken() (*loginToken, error) {
|
||||
f, err := openFile(p.options.CachedTokenFilepath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("token file not found, please reauthenticate")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
j, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var t *loginToken
|
||||
if err := json.Unmarshal(j, &t); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (p *Provider) saveToken(token *loginToken) error {
|
||||
j, err := json.Marshal(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := createFile(p.options.CachedTokenFilepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := f.Write(j); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func toAccessDeniedError(err *types.AccessDeniedException) error {
|
||||
switch err.Error_ {
|
||||
case types.OAuth2ErrorCodeTokenExpired:
|
||||
return fmt.Errorf("login session has expired, please reauthenticate")
|
||||
case types.OAuth2ErrorCodeUserCredentialsChanged:
|
||||
return fmt.Errorf("login session password has changed, please reauthenticate")
|
||||
case types.OAuth2ErrorCodeInsufficientPermissions:
|
||||
return fmt.Errorf("insufficient permissions, you may be missing permissions for the CreateOAuth2Token action")
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package logincreds
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
||||
"github.com/aws/aws-sdk-go-v2/internal/shareddefaults"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin"
|
||||
)
|
||||
|
||||
var userHomeDir = shareddefaults.UserHomeDir
|
||||
|
||||
// StandardCachedTokenFilepath returns the filepath for the cached login token
|
||||
// file. Key that will be used to compute a SHA256 value that is hex encoded.
|
||||
//
|
||||
// An overriden root dir can be provided, if not set the path defaults to
|
||||
// ~/.aws/sso/cache.
|
||||
func StandardCachedTokenFilepath(session, dir string) (string, error) {
|
||||
session = strings.TrimSpace(session)
|
||||
|
||||
if len(dir) == 0 {
|
||||
dir = userHomeDir()
|
||||
if len(dir) == 0 {
|
||||
return "", errors.New("user home dir is blank")
|
||||
}
|
||||
dir = filepath.Join(dir, ".aws", "login", "cache")
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(session))
|
||||
|
||||
filename := strings.ToLower(hex.EncodeToString(h.Sum(nil))) + ".json"
|
||||
return filepath.Join(dir, filename), nil
|
||||
}
|
||||
|
||||
// contents of the token as they appear on disk
|
||||
type loginToken struct {
|
||||
AccessToken *loginTokenAccessToken `json:"accessToken"`
|
||||
TokenType string `json:"tokenType"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
IdentityToken string `json:"identityToken"`
|
||||
ClientID string `json:"clientId"`
|
||||
DPOPKey string `json:"dpopKey"`
|
||||
}
|
||||
|
||||
type loginTokenAccessToken struct {
|
||||
AccessKeyID string `json:"accessKeyId"`
|
||||
SecretAccessKey string `json:"secretAccessKey"`
|
||||
SessionToken string `json:"sessionToken"`
|
||||
AccountID string `json:"accountId"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
}
|
||||
|
||||
func (t *loginToken) Validate() error {
|
||||
if t.AccessToken == nil {
|
||||
return fmt.Errorf("missing accessToken")
|
||||
}
|
||||
if t.AccessToken.AccessKeyID == "" {
|
||||
return fmt.Errorf("missing accessToken.accessKeyId")
|
||||
}
|
||||
if t.AccessToken.SecretAccessKey == "" {
|
||||
return fmt.Errorf("missing accessToken.secretAccessKey")
|
||||
}
|
||||
if t.AccessToken.SessionToken == "" {
|
||||
return fmt.Errorf("missing accessToken.sessionToken")
|
||||
}
|
||||
if t.AccessToken.AccountID == "" {
|
||||
return fmt.Errorf("missing accessToken.accountId")
|
||||
}
|
||||
if t.AccessToken.ExpiresAt.IsZero() {
|
||||
return fmt.Errorf("missing accessToken.expiresAt")
|
||||
}
|
||||
if t.ClientID == "" {
|
||||
return fmt.Errorf("missing clientId")
|
||||
}
|
||||
if t.RefreshToken == "" {
|
||||
return fmt.Errorf("missing refreshToken")
|
||||
}
|
||||
if t.DPOPKey == "" {
|
||||
return fmt.Errorf("missing dpopKey")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *loginToken) Credentials() aws.Credentials {
|
||||
return aws.Credentials{
|
||||
AccessKeyID: t.AccessToken.AccessKeyID,
|
||||
SecretAccessKey: t.AccessToken.SecretAccessKey,
|
||||
SessionToken: t.AccessToken.SessionToken,
|
||||
Source: ProviderName,
|
||||
CanExpire: true,
|
||||
Expires: t.AccessToken.ExpiresAt,
|
||||
AccountID: t.AccessToken.AccountID,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *loginToken) Update(out *signin.CreateOAuth2TokenOutput) {
|
||||
t.AccessToken.AccessKeyID = *out.TokenOutput.AccessToken.AccessKeyId
|
||||
t.AccessToken.SecretAccessKey = *out.TokenOutput.AccessToken.SecretAccessKey
|
||||
t.AccessToken.SessionToken = *out.TokenOutput.AccessToken.SessionToken
|
||||
t.AccessToken.ExpiresAt = sdk.NowTime().Add(time.Duration(*out.TokenOutput.ExpiresIn) * time.Second)
|
||||
t.RefreshToken = *out.TokenOutput.RefreshToken
|
||||
}
|
||||
+17
@@ -1,3 +1,20 @@
|
||||
# v1.18.17 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.18.16 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.18.15 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.18.14 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.18.13 (2025-11-04)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package imds
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.18.13"
|
||||
const goModuleVersion = "1.18.17"
|
||||
|
||||
+17
@@ -1,3 +1,20 @@
|
||||
# v1.4.17 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.4.16 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.4.15 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.4.14 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.4.13 (2025-11-04)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package configsources
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.4.13"
|
||||
const goModuleVersion = "1.4.17"
|
||||
|
||||
+17
@@ -1,3 +1,20 @@
|
||||
# v2.7.17 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.7.16 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.7.15 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v2.7.14 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.7.13 (2025-11-04)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package endpoints
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "2.7.13"
|
||||
const goModuleVersion = "2.7.17"
|
||||
|
||||
Generated
Vendored
+4
@@ -1,3 +1,7 @@
|
||||
# v1.13.4 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.13.3 (2025-11-04)
|
||||
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system.
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -3,4 +3,4 @@
|
||||
package acceptencoding
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.13.3"
|
||||
const goModuleVersion = "1.13.4"
|
||||
|
||||
+17
@@ -1,3 +1,20 @@
|
||||
# v1.13.17 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.13.16 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.13.15 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.13.14 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.13.13 (2025-11-04)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -3,4 +3,4 @@
|
||||
package presignedurl
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.13.13"
|
||||
const goModuleVersion = "1.13.17"
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# v1.0.5 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.0.4 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.0.3 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.0.2 (2025-11-25)
|
||||
|
||||
* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234
|
||||
|
||||
# v1.0.1 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.0.0 (2025-11-19)
|
||||
|
||||
* **Release**: New AWS service client module
|
||||
* **Feature**: AWS Sign-In manages authentication for AWS services. This service provides secure authentication flows for accessing AWS resources from the console and developer tools. This release adds the CreateOAuth2Token API, which can be used to fetch OAuth2 access tokens and refresh tokens from Sign-In.
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+949
@@ -0,0 +1,949 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/aws/defaults"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
"github.com/aws/aws-sdk-go-v2/aws/retry"
|
||||
"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
||||
awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
|
||||
internalauth "github.com/aws/aws-sdk-go-v2/internal/auth"
|
||||
internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
|
||||
internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
|
||||
internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
smithydocument "github.com/aws/smithy-go/document"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
"github.com/aws/smithy-go/metrics"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const ServiceID = "Signin"
|
||||
const ServiceAPIVersion = "2023-01-01"
|
||||
|
||||
type operationMetrics struct {
|
||||
Duration metrics.Float64Histogram
|
||||
SerializeDuration metrics.Float64Histogram
|
||||
ResolveIdentityDuration metrics.Float64Histogram
|
||||
ResolveEndpointDuration metrics.Float64Histogram
|
||||
SignRequestDuration metrics.Float64Histogram
|
||||
DeserializeDuration metrics.Float64Histogram
|
||||
}
|
||||
|
||||
func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram {
|
||||
switch name {
|
||||
case "client.call.duration":
|
||||
return m.Duration
|
||||
case "client.call.serialization_duration":
|
||||
return m.SerializeDuration
|
||||
case "client.call.resolve_identity_duration":
|
||||
return m.ResolveIdentityDuration
|
||||
case "client.call.resolve_endpoint_duration":
|
||||
return m.ResolveEndpointDuration
|
||||
case "client.call.signing_duration":
|
||||
return m.SignRequestDuration
|
||||
case "client.call.deserialization_duration":
|
||||
return m.DeserializeDuration
|
||||
default:
|
||||
panic("unrecognized operation metric")
|
||||
}
|
||||
}
|
||||
|
||||
func timeOperationMetric[T any](
|
||||
ctx context.Context, metric string, fn func() (T, error),
|
||||
opts ...metrics.RecordMetricOption,
|
||||
) (T, error) {
|
||||
mm := getOperationMetrics(ctx)
|
||||
if mm == nil { // not using the metrics system
|
||||
return fn()
|
||||
}
|
||||
|
||||
instr := mm.histogramFor(metric)
|
||||
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
|
||||
|
||||
start := time.Now()
|
||||
v, err := fn()
|
||||
end := time.Now()
|
||||
|
||||
elapsed := end.Sub(start)
|
||||
instr.Record(ctx, float64(elapsed)/1e9, opts...)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() {
|
||||
mm := getOperationMetrics(ctx)
|
||||
if mm == nil { // not using the metrics system
|
||||
return func() {}
|
||||
}
|
||||
|
||||
instr := mm.histogramFor(metric)
|
||||
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
|
||||
|
||||
var ended bool
|
||||
start := time.Now()
|
||||
return func() {
|
||||
if ended {
|
||||
return
|
||||
}
|
||||
ended = true
|
||||
|
||||
end := time.Now()
|
||||
|
||||
elapsed := end.Sub(start)
|
||||
instr.Record(ctx, float64(elapsed)/1e9, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption {
|
||||
return func(o *metrics.RecordMetricOptions) {
|
||||
o.Properties.Set("rpc.service", middleware.GetServiceID(ctx))
|
||||
o.Properties.Set("rpc.method", middleware.GetOperationName(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
type operationMetricsKey struct{}
|
||||
|
||||
func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) {
|
||||
if _, ok := mp.(metrics.NopMeterProvider); ok {
|
||||
// not using the metrics system - setting up the metrics context is a memory-intensive operation
|
||||
// so we should skip it in this case
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/signin")
|
||||
om := &operationMetrics{}
|
||||
|
||||
var err error
|
||||
|
||||
om.Duration, err = operationMetricTimer(meter, "client.call.duration",
|
||||
"Overall call duration (including retries and time to send or receive request and response body)")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration",
|
||||
"The time it takes to serialize a message body")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration",
|
||||
"The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration",
|
||||
"The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration",
|
||||
"The time it takes to sign a request")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration",
|
||||
"The time it takes to deserialize a message body")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return context.WithValue(parent, operationMetricsKey{}, om), nil
|
||||
}
|
||||
|
||||
func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) {
|
||||
return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) {
|
||||
o.UnitLabel = "s"
|
||||
o.Description = desc
|
||||
})
|
||||
}
|
||||
|
||||
func getOperationMetrics(ctx context.Context) *operationMetrics {
|
||||
if v := ctx.Value(operationMetricsKey{}); v != nil {
|
||||
return v.(*operationMetrics)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func operationTracer(p tracing.TracerProvider) tracing.Tracer {
|
||||
return p.Tracer("github.com/aws/aws-sdk-go-v2/service/signin")
|
||||
}
|
||||
|
||||
// Client provides the API client to make operations call for AWS Sign-In Service.
|
||||
type Client struct {
|
||||
options Options
|
||||
|
||||
// Difference between the time reported by the server and the client
|
||||
timeOffset *atomic.Int64
|
||||
}
|
||||
|
||||
// New returns an initialized Client based on the functional options. Provide
|
||||
// additional functional options to further configure the behavior of the client,
|
||||
// such as changing the client's endpoint or adding custom middleware behavior.
|
||||
func New(options Options, optFns ...func(*Options)) *Client {
|
||||
options = options.Copy()
|
||||
|
||||
resolveDefaultLogger(&options)
|
||||
|
||||
setResolvedDefaultsMode(&options)
|
||||
|
||||
resolveRetryer(&options)
|
||||
|
||||
resolveHTTPClient(&options)
|
||||
|
||||
resolveHTTPSignerV4(&options)
|
||||
|
||||
resolveEndpointResolverV2(&options)
|
||||
|
||||
resolveTracerProvider(&options)
|
||||
|
||||
resolveMeterProvider(&options)
|
||||
|
||||
resolveAuthSchemeResolver(&options)
|
||||
|
||||
for _, fn := range optFns {
|
||||
fn(&options)
|
||||
}
|
||||
|
||||
finalizeRetryMaxAttempts(&options)
|
||||
|
||||
ignoreAnonymousAuth(&options)
|
||||
|
||||
wrapWithAnonymousAuth(&options)
|
||||
|
||||
resolveAuthSchemes(&options)
|
||||
|
||||
client := &Client{
|
||||
options: options,
|
||||
}
|
||||
|
||||
initializeTimeOffsetResolver(client)
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Options returns a copy of the client configuration.
|
||||
//
|
||||
// Callers SHOULD NOT perform mutations on any inner structures within client
|
||||
// config. Config overrides should instead be made on a per-operation basis through
|
||||
// functional options.
|
||||
func (c *Client) Options() Options {
|
||||
return c.options.Copy()
|
||||
}
|
||||
|
||||
func (c *Client) invokeOperation(
|
||||
ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error,
|
||||
) (
|
||||
result interface{}, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
ctx = middleware.ClearStackValues(ctx)
|
||||
ctx = middleware.WithServiceID(ctx, ServiceID)
|
||||
ctx = middleware.WithOperationName(ctx, opID)
|
||||
|
||||
stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
|
||||
options := c.options.Copy()
|
||||
|
||||
for _, fn := range optFns {
|
||||
fn(&options)
|
||||
}
|
||||
|
||||
finalizeOperationRetryMaxAttempts(&options, *c)
|
||||
|
||||
finalizeClientEndpointResolverOptions(&options)
|
||||
|
||||
for _, fn := range stackFns {
|
||||
if err := fn(stack, options); err != nil {
|
||||
return nil, metadata, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, fn := range options.APIOptions {
|
||||
if err := fn(stack); err != nil {
|
||||
return nil, metadata, err
|
||||
}
|
||||
}
|
||||
|
||||
ctx, err = withOperationMetrics(ctx, options.MeterProvider)
|
||||
if err != nil {
|
||||
return nil, metadata, err
|
||||
}
|
||||
|
||||
tracer := operationTracer(options.TracerProvider)
|
||||
spanName := fmt.Sprintf("%s.%s", ServiceID, opID)
|
||||
|
||||
ctx = tracing.WithOperationTracer(ctx, tracer)
|
||||
|
||||
ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) {
|
||||
o.Kind = tracing.SpanKindClient
|
||||
o.Properties.Set("rpc.system", "aws-api")
|
||||
o.Properties.Set("rpc.method", opID)
|
||||
o.Properties.Set("rpc.service", ServiceID)
|
||||
})
|
||||
endTimer := startMetricTimer(ctx, "client.call.duration")
|
||||
defer endTimer()
|
||||
defer span.End()
|
||||
|
||||
handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) {
|
||||
o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/signin")
|
||||
})
|
||||
decorated := middleware.DecorateHandler(handler, stack)
|
||||
result, metadata, err = decorated.Handle(ctx, params)
|
||||
if err != nil {
|
||||
span.SetProperty("exception.type", fmt.Sprintf("%T", err))
|
||||
span.SetProperty("exception.message", err.Error())
|
||||
|
||||
var aerr smithy.APIError
|
||||
if errors.As(err, &aerr) {
|
||||
span.SetProperty("api.error_code", aerr.ErrorCode())
|
||||
span.SetProperty("api.error_message", aerr.ErrorMessage())
|
||||
span.SetProperty("api.error_fault", aerr.ErrorFault().String())
|
||||
}
|
||||
|
||||
err = &smithy.OperationError{
|
||||
ServiceID: ServiceID,
|
||||
OperationName: opID,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
span.SetProperty("error", err != nil)
|
||||
if err == nil {
|
||||
span.SetStatus(tracing.SpanStatusOK)
|
||||
} else {
|
||||
span.SetStatus(tracing.SpanStatusError)
|
||||
}
|
||||
|
||||
return result, metadata, err
|
||||
}
|
||||
|
||||
type operationInputKey struct{}
|
||||
|
||||
func setOperationInput(ctx context.Context, input interface{}) context.Context {
|
||||
return middleware.WithStackValue(ctx, operationInputKey{}, input)
|
||||
}
|
||||
|
||||
func getOperationInput(ctx context.Context) interface{} {
|
||||
return middleware.GetStackValue(ctx, operationInputKey{})
|
||||
}
|
||||
|
||||
type setOperationInputMiddleware struct {
|
||||
}
|
||||
|
||||
func (*setOperationInputMiddleware) ID() string {
|
||||
return "setOperationInput"
|
||||
}
|
||||
|
||||
func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
|
||||
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
ctx = setOperationInput(ctx, in.Parameters)
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
|
||||
func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error {
|
||||
if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil {
|
||||
return fmt.Errorf("add ResolveAuthScheme: %w", err)
|
||||
}
|
||||
if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil {
|
||||
return fmt.Errorf("add GetIdentity: %v", err)
|
||||
}
|
||||
if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil {
|
||||
return fmt.Errorf("add ResolveEndpointV2: %v", err)
|
||||
}
|
||||
if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil {
|
||||
return fmt.Errorf("add Signing: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func resolveAuthSchemeResolver(options *Options) {
|
||||
if options.AuthSchemeResolver == nil {
|
||||
options.AuthSchemeResolver = &defaultAuthSchemeResolver{}
|
||||
}
|
||||
}
|
||||
|
||||
func resolveAuthSchemes(options *Options) {
|
||||
if options.AuthSchemes == nil {
|
||||
options.AuthSchemes = []smithyhttp.AuthScheme{
|
||||
internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{
|
||||
Signer: options.HTTPSignerV4,
|
||||
Logger: options.Logger,
|
||||
LogSigning: options.ClientLogMode.IsSigning(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type noSmithyDocumentSerde = smithydocument.NoSerde
|
||||
|
||||
type legacyEndpointContextSetter struct {
|
||||
LegacyResolver EndpointResolver
|
||||
}
|
||||
|
||||
func (*legacyEndpointContextSetter) ID() string {
|
||||
return "legacyEndpointContextSetter"
|
||||
}
|
||||
|
||||
func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
|
||||
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
if m.LegacyResolver != nil {
|
||||
ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true)
|
||||
}
|
||||
|
||||
return next.HandleInitialize(ctx, in)
|
||||
|
||||
}
|
||||
func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error {
|
||||
return stack.Initialize.Add(&legacyEndpointContextSetter{
|
||||
LegacyResolver: o.EndpointResolver,
|
||||
}, middleware.Before)
|
||||
}
|
||||
|
||||
func resolveDefaultLogger(o *Options) {
|
||||
if o.Logger != nil {
|
||||
return
|
||||
}
|
||||
o.Logger = logging.Nop{}
|
||||
}
|
||||
|
||||
func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error {
|
||||
return middleware.AddSetLoggerMiddleware(stack, o.Logger)
|
||||
}
|
||||
|
||||
func setResolvedDefaultsMode(o *Options) {
|
||||
if len(o.resolvedDefaultsMode) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var mode aws.DefaultsMode
|
||||
mode.SetFromString(string(o.DefaultsMode))
|
||||
|
||||
if mode == aws.DefaultsModeAuto {
|
||||
mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment)
|
||||
}
|
||||
|
||||
o.resolvedDefaultsMode = mode
|
||||
}
|
||||
|
||||
// NewFromConfig returns a new client from the provided config.
|
||||
func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
|
||||
opts := Options{
|
||||
Region: cfg.Region,
|
||||
DefaultsMode: cfg.DefaultsMode,
|
||||
RuntimeEnvironment: cfg.RuntimeEnvironment,
|
||||
HTTPClient: cfg.HTTPClient,
|
||||
Credentials: cfg.Credentials,
|
||||
APIOptions: cfg.APIOptions,
|
||||
Logger: cfg.Logger,
|
||||
ClientLogMode: cfg.ClientLogMode,
|
||||
AppID: cfg.AppID,
|
||||
AuthSchemePreference: cfg.AuthSchemePreference,
|
||||
}
|
||||
resolveAWSRetryerProvider(cfg, &opts)
|
||||
resolveAWSRetryMaxAttempts(cfg, &opts)
|
||||
resolveAWSRetryMode(cfg, &opts)
|
||||
resolveAWSEndpointResolver(cfg, &opts)
|
||||
resolveInterceptors(cfg, &opts)
|
||||
resolveUseDualStackEndpoint(cfg, &opts)
|
||||
resolveUseFIPSEndpoint(cfg, &opts)
|
||||
resolveBaseEndpoint(cfg, &opts)
|
||||
return New(opts, func(o *Options) {
|
||||
for _, opt := range cfg.ServiceOptions {
|
||||
opt(ServiceID, o)
|
||||
}
|
||||
for _, opt := range optFns {
|
||||
opt(o)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func resolveHTTPClient(o *Options) {
|
||||
var buildable *awshttp.BuildableClient
|
||||
|
||||
if o.HTTPClient != nil {
|
||||
var ok bool
|
||||
buildable, ok = o.HTTPClient.(*awshttp.BuildableClient)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
buildable = awshttp.NewBuildableClient()
|
||||
}
|
||||
|
||||
modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
|
||||
if err == nil {
|
||||
buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) {
|
||||
if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok {
|
||||
dialer.Timeout = dialerTimeout
|
||||
}
|
||||
})
|
||||
|
||||
buildable = buildable.WithTransportOptions(func(transport *http.Transport) {
|
||||
if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok {
|
||||
transport.TLSHandshakeTimeout = tlsHandshakeTimeout
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
o.HTTPClient = buildable
|
||||
}
|
||||
|
||||
func resolveRetryer(o *Options) {
|
||||
if o.Retryer != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(o.RetryMode) == 0 {
|
||||
modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode)
|
||||
if err == nil {
|
||||
o.RetryMode = modeConfig.RetryMode
|
||||
}
|
||||
}
|
||||
if len(o.RetryMode) == 0 {
|
||||
o.RetryMode = aws.RetryModeStandard
|
||||
}
|
||||
|
||||
var standardOptions []func(*retry.StandardOptions)
|
||||
if v := o.RetryMaxAttempts; v != 0 {
|
||||
standardOptions = append(standardOptions, func(so *retry.StandardOptions) {
|
||||
so.MaxAttempts = v
|
||||
})
|
||||
}
|
||||
|
||||
switch o.RetryMode {
|
||||
case aws.RetryModeAdaptive:
|
||||
var adaptiveOptions []func(*retry.AdaptiveModeOptions)
|
||||
if len(standardOptions) != 0 {
|
||||
adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) {
|
||||
ao.StandardOptions = append(ao.StandardOptions, standardOptions...)
|
||||
})
|
||||
}
|
||||
o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...)
|
||||
|
||||
default:
|
||||
o.Retryer = retry.NewStandard(standardOptions...)
|
||||
}
|
||||
}
|
||||
|
||||
func resolveAWSRetryerProvider(cfg aws.Config, o *Options) {
|
||||
if cfg.Retryer == nil {
|
||||
return
|
||||
}
|
||||
o.Retryer = cfg.Retryer()
|
||||
}
|
||||
|
||||
func resolveAWSRetryMode(cfg aws.Config, o *Options) {
|
||||
if len(cfg.RetryMode) == 0 {
|
||||
return
|
||||
}
|
||||
o.RetryMode = cfg.RetryMode
|
||||
}
|
||||
func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) {
|
||||
if cfg.RetryMaxAttempts == 0 {
|
||||
return
|
||||
}
|
||||
o.RetryMaxAttempts = cfg.RetryMaxAttempts
|
||||
}
|
||||
|
||||
func finalizeRetryMaxAttempts(o *Options) {
|
||||
if o.RetryMaxAttempts == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts)
|
||||
}
|
||||
|
||||
func finalizeOperationRetryMaxAttempts(o *Options, client Client) {
|
||||
if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts {
|
||||
return
|
||||
}
|
||||
|
||||
o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts)
|
||||
}
|
||||
|
||||
func resolveAWSEndpointResolver(cfg aws.Config, o *Options) {
|
||||
if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil {
|
||||
return
|
||||
}
|
||||
o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions)
|
||||
}
|
||||
|
||||
func resolveInterceptors(cfg aws.Config, o *Options) {
|
||||
o.Interceptors = cfg.Interceptors.Copy()
|
||||
}
|
||||
|
||||
func addClientUserAgent(stack *middleware.Stack, options Options) error {
|
||||
ua, err := getOrAddRequestUserAgent(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "signin", goModuleVersion)
|
||||
if len(options.AppID) > 0 {
|
||||
ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) {
|
||||
id := (*awsmiddleware.RequestUserAgent)(nil).ID()
|
||||
mw, ok := stack.Build.Get(id)
|
||||
if !ok {
|
||||
mw = awsmiddleware.NewRequestUserAgent()
|
||||
if err := stack.Build.Add(mw, middleware.After); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
ua, ok := mw.(*awsmiddleware.RequestUserAgent)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id)
|
||||
}
|
||||
|
||||
return ua, nil
|
||||
}
|
||||
|
||||
type HTTPSignerV4 interface {
|
||||
SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
|
||||
}
|
||||
|
||||
func resolveHTTPSignerV4(o *Options) {
|
||||
if o.HTTPSignerV4 != nil {
|
||||
return
|
||||
}
|
||||
o.HTTPSignerV4 = newDefaultV4Signer(*o)
|
||||
}
|
||||
|
||||
func newDefaultV4Signer(o Options) *v4.Signer {
|
||||
return v4.NewSigner(func(so *v4.SignerOptions) {
|
||||
so.Logger = o.Logger
|
||||
so.LogSigning = o.ClientLogMode.IsSigning()
|
||||
})
|
||||
}
|
||||
|
||||
func addClientRequestID(stack *middleware.Stack) error {
|
||||
return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After)
|
||||
}
|
||||
|
||||
func addComputeContentLength(stack *middleware.Stack) error {
|
||||
return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After)
|
||||
}
|
||||
|
||||
func addRawResponseToMetadata(stack *middleware.Stack) error {
|
||||
return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before)
|
||||
}
|
||||
|
||||
func addRecordResponseTiming(stack *middleware.Stack) error {
|
||||
return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After)
|
||||
}
|
||||
|
||||
func addSpanRetryLoop(stack *middleware.Stack, options Options) error {
|
||||
return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before)
|
||||
}
|
||||
|
||||
type spanRetryLoop struct {
|
||||
options Options
|
||||
}
|
||||
|
||||
func (*spanRetryLoop) ID() string {
|
||||
return "spanRetryLoop"
|
||||
}
|
||||
|
||||
func (m *spanRetryLoop) HandleFinalize(
|
||||
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
|
||||
) (
|
||||
middleware.FinalizeOutput, middleware.Metadata, error,
|
||||
) {
|
||||
tracer := operationTracer(m.options.TracerProvider)
|
||||
ctx, span := tracer.StartSpan(ctx, "RetryLoop")
|
||||
defer span.End()
|
||||
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
func addStreamingEventsPayload(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before)
|
||||
}
|
||||
|
||||
func addUnsignedPayload(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After)
|
||||
}
|
||||
|
||||
func addComputePayloadSHA256(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After)
|
||||
}
|
||||
|
||||
func addContentSHA256Header(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After)
|
||||
}
|
||||
|
||||
func addIsWaiterUserAgent(o *Options) {
|
||||
o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
|
||||
ua, err := getOrAddRequestUserAgent(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func addIsPaginatorUserAgent(o *Options) {
|
||||
o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error {
|
||||
ua, err := getOrAddRequestUserAgent(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func addRetry(stack *middleware.Stack, o Options) error {
|
||||
attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) {
|
||||
m.LogAttempts = o.ClientLogMode.IsRetries()
|
||||
m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/signin")
|
||||
})
|
||||
if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolves dual-stack endpoint configuration
|
||||
func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error {
|
||||
if len(cfg.ConfigSources) == 0 {
|
||||
return nil
|
||||
}
|
||||
value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if found {
|
||||
o.EndpointOptions.UseDualStackEndpoint = value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolves FIPS endpoint configuration
|
||||
func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error {
|
||||
if len(cfg.ConfigSources) == 0 {
|
||||
return nil
|
||||
}
|
||||
value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if found {
|
||||
o.EndpointOptions.UseFIPSEndpoint = value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string {
|
||||
if mode == aws.AccountIDEndpointModeDisabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" {
|
||||
return aws.String(ca.Credentials.AccountID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error {
|
||||
mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset}
|
||||
if err := stack.Build.Add(&mw, middleware.After); err != nil {
|
||||
return err
|
||||
}
|
||||
return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before)
|
||||
}
|
||||
func initializeTimeOffsetResolver(c *Client) {
|
||||
c.timeOffset = new(atomic.Int64)
|
||||
}
|
||||
|
||||
func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
|
||||
ua, err := getOrAddRequestUserAgent(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch options.Retryer.(type) {
|
||||
case *retry.Standard:
|
||||
ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard)
|
||||
case *retry.AdaptiveMode:
|
||||
ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type setCredentialSourceMiddleware struct {
|
||||
ua *awsmiddleware.RequestUserAgent
|
||||
options Options
|
||||
}
|
||||
|
||||
func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" }
|
||||
|
||||
func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (
|
||||
out middleware.BuildOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource)
|
||||
if !ok {
|
||||
return next.HandleBuild(ctx, in)
|
||||
}
|
||||
providerSources := asProviderSource.ProviderSources()
|
||||
for _, source := range providerSources {
|
||||
m.ua.AddCredentialsSource(source)
|
||||
}
|
||||
return next.HandleBuild(ctx, in)
|
||||
}
|
||||
|
||||
func addCredentialSource(stack *middleware.Stack, options Options) error {
|
||||
ua, err := getOrAddRequestUserAgent(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mw := setCredentialSourceMiddleware{ua: ua, options: options}
|
||||
return stack.Build.Insert(&mw, "UserAgent", middleware.Before)
|
||||
}
|
||||
|
||||
func resolveTracerProvider(options *Options) {
|
||||
if options.TracerProvider == nil {
|
||||
options.TracerProvider = &tracing.NopTracerProvider{}
|
||||
}
|
||||
}
|
||||
|
||||
func resolveMeterProvider(options *Options) {
|
||||
if options.MeterProvider == nil {
|
||||
options.MeterProvider = metrics.NopMeterProvider{}
|
||||
}
|
||||
}
|
||||
|
||||
func addRecursionDetection(stack *middleware.Stack) error {
|
||||
return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After)
|
||||
}
|
||||
|
||||
func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before)
|
||||
|
||||
}
|
||||
|
||||
func addResponseErrorMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before)
|
||||
|
||||
}
|
||||
|
||||
func addRequestResponseLogging(stack *middleware.Stack, o Options) error {
|
||||
return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{
|
||||
LogRequest: o.ClientLogMode.IsRequest(),
|
||||
LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(),
|
||||
LogResponse: o.ClientLogMode.IsResponse(),
|
||||
LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(),
|
||||
}, middleware.After)
|
||||
}
|
||||
|
||||
type disableHTTPSMiddleware struct {
|
||||
DisableHTTPS bool
|
||||
}
|
||||
|
||||
func (*disableHTTPSMiddleware) ID() string {
|
||||
return "disableHTTPS"
|
||||
}
|
||||
|
||||
func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
req, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
|
||||
}
|
||||
|
||||
if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) {
|
||||
req.URL.Scheme = "http"
|
||||
}
|
||||
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
|
||||
func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error {
|
||||
return stack.Finalize.Insert(&disableHTTPSMiddleware{
|
||||
DisableHTTPS: o.EndpointOptions.DisableHTTPS,
|
||||
}, "ResolveEndpointV2", middleware.After)
|
||||
}
|
||||
|
||||
func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error {
|
||||
return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{
|
||||
Interceptors: opts.Interceptors.BeforeRetryLoop,
|
||||
}, "Retry", middleware.Before)
|
||||
}
|
||||
|
||||
func addInterceptAttempt(stack *middleware.Stack, opts Options) error {
|
||||
return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{
|
||||
BeforeAttempt: opts.Interceptors.BeforeAttempt,
|
||||
AfterAttempt: opts.Interceptors.AfterAttempt,
|
||||
}, "Retry", middleware.After)
|
||||
}
|
||||
|
||||
func addInterceptors(stack *middleware.Stack, opts Options) error {
|
||||
// middlewares are expensive, don't add all of these interceptor ones unless the caller
|
||||
// actually has at least one interceptor configured
|
||||
//
|
||||
// at the moment it's all-or-nothing because some of the middlewares here are responsible for
|
||||
// setting fields in the interceptor context for future ones
|
||||
if len(opts.Interceptors.BeforeExecution) == 0 &&
|
||||
len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 &&
|
||||
len(opts.Interceptors.BeforeRetryLoop) == 0 &&
|
||||
len(opts.Interceptors.BeforeAttempt) == 0 &&
|
||||
len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 &&
|
||||
len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 &&
|
||||
len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 &&
|
||||
len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.Join(
|
||||
stack.Initialize.Add(&smithyhttp.InterceptExecution{
|
||||
BeforeExecution: opts.Interceptors.BeforeExecution,
|
||||
AfterExecution: opts.Interceptors.AfterExecution,
|
||||
}, middleware.Before),
|
||||
stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{
|
||||
Interceptors: opts.Interceptors.BeforeSerialization,
|
||||
}, "OperationSerializer", middleware.Before),
|
||||
stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{
|
||||
Interceptors: opts.Interceptors.AfterSerialization,
|
||||
}, "OperationSerializer", middleware.After),
|
||||
stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{
|
||||
Interceptors: opts.Interceptors.BeforeSigning,
|
||||
}, "Signing", middleware.Before),
|
||||
stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{
|
||||
Interceptors: opts.Interceptors.AfterSigning,
|
||||
}, "Signing", middleware.After),
|
||||
stack.Deserialize.Add(&smithyhttp.InterceptTransmit{
|
||||
BeforeTransmit: opts.Interceptors.BeforeTransmit,
|
||||
AfterTransmit: opts.Interceptors.AfterTransmit,
|
||||
}, middleware.After),
|
||||
stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{
|
||||
Interceptors: opts.Interceptors.BeforeDeserialization,
|
||||
}, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse)
|
||||
stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{
|
||||
Interceptors: opts.Interceptors.AfterDeserialization,
|
||||
}, "OperationDeserializer", middleware.Before),
|
||||
)
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin/types"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
)
|
||||
|
||||
// CreateOAuth2Token API
|
||||
//
|
||||
// Path: /v1/token Request Method: POST Content-Type: application/json or
|
||||
// application/x-www-form-urlencoded
|
||||
//
|
||||
// This API implements OAuth 2.0 flows for AWS Sign-In CLI clients, supporting
|
||||
// both:
|
||||
//
|
||||
// - Authorization code redemption (grant_type=authorization_code) - NOT
|
||||
// idempotent
|
||||
// - Token refresh (grant_type=refresh_token) - Idempotent within token validity
|
||||
// window
|
||||
//
|
||||
// The operation behavior is determined by the grant_type parameter in the request
|
||||
// body:
|
||||
//
|
||||
// Authorization Code Flow (NOT Idempotent):
|
||||
//
|
||||
// - JSON or form-encoded body with client_id, grant_type=authorization_code,
|
||||
// code, redirect_uri, code_verifier
|
||||
// - Returns access_token, token_type, expires_in, refresh_token, and id_token
|
||||
// - Each authorization code can only be used ONCE for security (prevents replay
|
||||
// attacks)
|
||||
//
|
||||
// Token Refresh Flow (Idempotent):
|
||||
//
|
||||
// - JSON or form-encoded body with client_id, grant_type=refresh_token,
|
||||
// refresh_token
|
||||
// - Returns access_token, token_type, expires_in, and refresh_token (no
|
||||
// id_token)
|
||||
// - Multiple calls with same refresh_token return consistent results within
|
||||
// validity window
|
||||
//
|
||||
// Authentication and authorization:
|
||||
//
|
||||
// - Confidential clients: sigv4 signing required with signin:ExchangeToken
|
||||
// permissions
|
||||
// - CLI clients (public): authn/authz skipped based on client_id & grant_type
|
||||
//
|
||||
// Note: This operation cannot be marked as @idempotent because it handles both
|
||||
// idempotent (token refresh) and non-idempotent (auth code redemption) flows in a
|
||||
// single endpoint.
|
||||
func (c *Client) CreateOAuth2Token(ctx context.Context, params *CreateOAuth2TokenInput, optFns ...func(*Options)) (*CreateOAuth2TokenOutput, error) {
|
||||
if params == nil {
|
||||
params = &CreateOAuth2TokenInput{}
|
||||
}
|
||||
|
||||
result, metadata, err := c.invokeOperation(ctx, "CreateOAuth2Token", params, optFns, c.addOperationCreateOAuth2TokenMiddlewares)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := result.(*CreateOAuth2TokenOutput)
|
||||
out.ResultMetadata = metadata
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Input structure for CreateOAuth2Token operation
|
||||
//
|
||||
// Contains flattened token operation inputs for both authorization code and
|
||||
// refresh token flows. The operation type is determined by the grant_type
|
||||
// parameter in the request body.
|
||||
type CreateOAuth2TokenInput struct {
|
||||
|
||||
// Flattened token operation inputs The specific operation is determined by
|
||||
// grant_type in the request body
|
||||
//
|
||||
// This member is required.
|
||||
TokenInput *types.CreateOAuth2TokenRequestBody
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
// Output structure for CreateOAuth2Token operation
|
||||
//
|
||||
// Contains flattened token operation outputs for both authorization code and
|
||||
// refresh token flows. The response content depends on the grant_type from the
|
||||
// original request.
|
||||
type CreateOAuth2TokenOutput struct {
|
||||
|
||||
// Flattened token operation outputs The specific response fields depend on the
|
||||
// grant_type used in the request
|
||||
//
|
||||
// This member is required.
|
||||
TokenOutput *types.CreateOAuth2TokenResponseBody
|
||||
|
||||
// Metadata pertaining to the operation's result.
|
||||
ResultMetadata middleware.Metadata
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (c *Client) addOperationCreateOAuth2TokenMiddlewares(stack *middleware.Stack, options Options) (err error) {
|
||||
if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
|
||||
return err
|
||||
}
|
||||
err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateOAuth2Token{}, middleware.After)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateOAuth2Token{}, middleware.After)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addProtocolFinalizerMiddlewares(stack, options, "CreateOAuth2Token"); err != nil {
|
||||
return fmt.Errorf("add protocol finalizers: %v", err)
|
||||
}
|
||||
|
||||
if err = addlegacyEndpointContextSetter(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSetLoggerMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addClientRequestID(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addComputeContentLength(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addResolveEndpointMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRetry(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRawResponseToMetadata(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRecordResponseTiming(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSpanRetryLoop(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addClientUserAgent(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addTimeOffsetBuild(stack, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addUserAgentRetryMode(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addCredentialSource(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addOpCreateOAuth2TokenValidationMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateOAuth2Token(options.Region), middleware.Before); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRecursionDetection(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addResponseErrorMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRequestResponseLogging(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptBeforeRetryLoop(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptAttempt(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptors(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newServiceMetadataMiddleware_opCreateOAuth2Token(region string) *awsmiddleware.RegisterServiceMetadata {
|
||||
return &awsmiddleware.RegisterServiceMetadata{
|
||||
Region: region,
|
||||
ServiceID: ServiceID,
|
||||
OperationName: "CreateOAuth2Token",
|
||||
}
|
||||
}
|
||||
+351
@@ -0,0 +1,351 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
"github.com/aws/smithy-go/metrics"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error {
|
||||
params.Region = options.Region
|
||||
return nil
|
||||
}
|
||||
|
||||
type setLegacyContextSigningOptionsMiddleware struct {
|
||||
}
|
||||
|
||||
func (*setLegacyContextSigningOptionsMiddleware) ID() string {
|
||||
return "setLegacyContextSigningOptions"
|
||||
}
|
||||
|
||||
func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
rscheme := getResolvedAuthScheme(ctx)
|
||||
schemeID := rscheme.Scheme.SchemeID()
|
||||
|
||||
if sn := awsmiddleware.GetSigningName(ctx); sn != "" {
|
||||
if schemeID == "aws.auth#sigv4" {
|
||||
smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn)
|
||||
} else if schemeID == "aws.auth#sigv4a" {
|
||||
smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn)
|
||||
}
|
||||
}
|
||||
|
||||
if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" {
|
||||
if schemeID == "aws.auth#sigv4" {
|
||||
smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr)
|
||||
} else if schemeID == "aws.auth#sigv4a" {
|
||||
smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr})
|
||||
}
|
||||
}
|
||||
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
|
||||
func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before)
|
||||
}
|
||||
|
||||
type withAnonymous struct {
|
||||
resolver AuthSchemeResolver
|
||||
}
|
||||
|
||||
var _ AuthSchemeResolver = (*withAnonymous)(nil)
|
||||
|
||||
func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) {
|
||||
opts, err := v.resolver.ResolveAuthSchemes(ctx, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts = append(opts, &smithyauth.Option{
|
||||
SchemeID: smithyauth.SchemeIDAnonymous,
|
||||
})
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func wrapWithAnonymousAuth(options *Options) {
|
||||
if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
options.AuthSchemeResolver = &withAnonymous{
|
||||
resolver: options.AuthSchemeResolver,
|
||||
}
|
||||
}
|
||||
|
||||
// AuthResolverParameters contains the set of inputs necessary for auth scheme
|
||||
// resolution.
|
||||
type AuthResolverParameters struct {
|
||||
// The name of the operation being invoked.
|
||||
Operation string
|
||||
|
||||
// The region in which the operation is being invoked.
|
||||
Region string
|
||||
}
|
||||
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) {
|
||||
params := &AuthResolverParameters{
|
||||
Operation: operation,
|
||||
}
|
||||
|
||||
if err := bindAuthParamsRegion(ctx, params, input, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// AuthSchemeResolver returns a set of possible authentication options for an
|
||||
// operation.
|
||||
type AuthSchemeResolver interface {
|
||||
ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error)
|
||||
}
|
||||
|
||||
type defaultAuthSchemeResolver struct{}
|
||||
|
||||
var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil)
|
||||
|
||||
func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) {
|
||||
if overrides, ok := operationAuthOptions[params.Operation]; ok {
|
||||
return overrides(params), nil
|
||||
}
|
||||
return serviceAuthOptions(params), nil
|
||||
}
|
||||
|
||||
var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{
|
||||
"CreateOAuth2Token": func(params *AuthResolverParameters) []*smithyauth.Option {
|
||||
return []*smithyauth.Option{
|
||||
{SchemeID: smithyauth.SchemeIDAnonymous},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option {
|
||||
return []*smithyauth.Option{
|
||||
{
|
||||
SchemeID: smithyauth.SchemeIDSigV4,
|
||||
SignerProperties: func() smithy.Properties {
|
||||
var props smithy.Properties
|
||||
smithyhttp.SetSigV4SigningName(&props, "signin")
|
||||
smithyhttp.SetSigV4SigningRegion(&props, params.Region)
|
||||
return props
|
||||
}(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type resolveAuthSchemeMiddleware struct {
|
||||
operation string
|
||||
options Options
|
||||
}
|
||||
|
||||
func (*resolveAuthSchemeMiddleware) ID() string {
|
||||
return "ResolveAuthScheme"
|
||||
}
|
||||
|
||||
func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
|
||||
defer span.End()
|
||||
|
||||
params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("bind auth scheme params: %w", err)
|
||||
}
|
||||
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
|
||||
}
|
||||
|
||||
scheme, ok := m.selectScheme(options)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("could not select an auth scheme")
|
||||
}
|
||||
|
||||
ctx = setResolvedAuthScheme(ctx, scheme)
|
||||
|
||||
span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
|
||||
span.End()
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
|
||||
func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) {
|
||||
sorted := sortAuthOptions(options, m.options.AuthSchemePreference)
|
||||
for _, option := range sorted {
|
||||
if option.SchemeID == smithyauth.SchemeIDAnonymous {
|
||||
return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true
|
||||
}
|
||||
|
||||
for _, scheme := range m.options.AuthSchemes {
|
||||
if scheme.SchemeID() != option.SchemeID {
|
||||
continue
|
||||
}
|
||||
|
||||
if scheme.IdentityResolver(m.options) != nil {
|
||||
return newResolvedAuthScheme(scheme, option), true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option {
|
||||
byPriority := make([]*smithyauth.Option, 0, len(options))
|
||||
for _, prefName := range preferred {
|
||||
for _, option := range options {
|
||||
optName := option.SchemeID
|
||||
if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 {
|
||||
optName = parts[1]
|
||||
}
|
||||
if prefName == optName {
|
||||
byPriority = append(byPriority, option)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, option := range options {
|
||||
if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool {
|
||||
return o.SchemeID == option.SchemeID
|
||||
}) {
|
||||
byPriority = append(byPriority, option)
|
||||
}
|
||||
}
|
||||
return byPriority
|
||||
}
|
||||
|
||||
type resolvedAuthSchemeKey struct{}
|
||||
|
||||
type resolvedAuthScheme struct {
|
||||
Scheme smithyhttp.AuthScheme
|
||||
IdentityProperties smithy.Properties
|
||||
SignerProperties smithy.Properties
|
||||
}
|
||||
|
||||
func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme {
|
||||
return &resolvedAuthScheme{
|
||||
Scheme: scheme,
|
||||
IdentityProperties: option.IdentityProperties,
|
||||
SignerProperties: option.SignerProperties,
|
||||
}
|
||||
}
|
||||
|
||||
func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context {
|
||||
return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme)
|
||||
}
|
||||
|
||||
func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme {
|
||||
v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme)
|
||||
return v
|
||||
}
|
||||
|
||||
type getIdentityMiddleware struct {
|
||||
options Options
|
||||
}
|
||||
|
||||
func (*getIdentityMiddleware) ID() string {
|
||||
return "GetIdentity"
|
||||
}
|
||||
|
||||
func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
|
||||
defer span.End()
|
||||
|
||||
rscheme := getResolvedAuthScheme(innerCtx)
|
||||
if rscheme == nil {
|
||||
return out, metadata, fmt.Errorf("no resolved auth scheme")
|
||||
}
|
||||
|
||||
resolver := rscheme.Scheme.IdentityResolver(m.options)
|
||||
if resolver == nil {
|
||||
return out, metadata, fmt.Errorf("no identity resolver")
|
||||
}
|
||||
|
||||
identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
|
||||
func() (smithyauth.Identity, error) {
|
||||
return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
|
||||
},
|
||||
func(o *metrics.RecordMetricOptions) {
|
||||
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
|
||||
})
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("get identity: %w", err)
|
||||
}
|
||||
|
||||
ctx = setIdentity(ctx, identity)
|
||||
|
||||
span.End()
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
|
||||
type identityKey struct{}
|
||||
|
||||
func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context {
|
||||
return middleware.WithStackValue(ctx, identityKey{}, identity)
|
||||
}
|
||||
|
||||
func getIdentity(ctx context.Context) smithyauth.Identity {
|
||||
v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity)
|
||||
return v
|
||||
}
|
||||
|
||||
type signRequestMiddleware struct {
|
||||
options Options
|
||||
}
|
||||
|
||||
func (*signRequestMiddleware) ID() string {
|
||||
return "Signing"
|
||||
}
|
||||
|
||||
func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
_, span := tracing.StartSpan(ctx, "SignRequest")
|
||||
defer span.End()
|
||||
|
||||
req, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
|
||||
}
|
||||
|
||||
rscheme := getResolvedAuthScheme(ctx)
|
||||
if rscheme == nil {
|
||||
return out, metadata, fmt.Errorf("no resolved auth scheme")
|
||||
}
|
||||
|
||||
identity := getIdentity(ctx)
|
||||
if identity == nil {
|
||||
return out, metadata, fmt.Errorf("no identity")
|
||||
}
|
||||
|
||||
signer := rscheme.Scheme.Signer()
|
||||
if signer == nil {
|
||||
return out, metadata, fmt.Errorf("no signer")
|
||||
}
|
||||
|
||||
_, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
|
||||
return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
|
||||
}, func(o *metrics.RecordMetricOptions) {
|
||||
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
|
||||
})
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
span.End()
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
+655
@@ -0,0 +1,655 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/aws/protocol/restjson"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin/types"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
smithyio "github.com/aws/smithy-go/io"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/ptr"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type awsRestjson1_deserializeOpCreateOAuth2Token struct {
|
||||
}
|
||||
|
||||
func (*awsRestjson1_deserializeOpCreateOAuth2Token) ID() string {
|
||||
return "OperationDeserializer"
|
||||
}
|
||||
|
||||
func (m *awsRestjson1_deserializeOpCreateOAuth2Token) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
|
||||
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
out, metadata, err = next.HandleDeserialize(ctx, in)
|
||||
if err != nil {
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
|
||||
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
|
||||
defer endTimer()
|
||||
defer span.End()
|
||||
response, ok := out.RawResponse.(*smithyhttp.Response)
|
||||
if !ok {
|
||||
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
|
||||
}
|
||||
|
||||
if response.StatusCode < 200 || response.StatusCode >= 300 {
|
||||
return out, metadata, awsRestjson1_deserializeOpErrorCreateOAuth2Token(response, &metadata)
|
||||
}
|
||||
output := &CreateOAuth2TokenOutput{}
|
||||
out.Result = output
|
||||
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(response.Body, ringBuffer)
|
||||
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
var shape interface{}
|
||||
if err := decoder.Decode(&shape); err != nil && err != io.EOF {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
err = awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(&output.TokenOutput, shape)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return out, metadata, &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
span.End()
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeOpErrorCreateOAuth2Token(response *smithyhttp.Response, metadata *middleware.Metadata) error {
|
||||
var errorBuffer bytes.Buffer
|
||||
if _, err := io.Copy(&errorBuffer, response.Body); err != nil {
|
||||
return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)}
|
||||
}
|
||||
errorBody := bytes.NewReader(errorBuffer.Bytes())
|
||||
|
||||
errorCode := "UnknownError"
|
||||
errorMessage := errorCode
|
||||
|
||||
headerCode := response.Header.Get("X-Amzn-ErrorType")
|
||||
if len(headerCode) != 0 {
|
||||
errorCode = restjson.SanitizeErrorCode(headerCode)
|
||||
}
|
||||
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
jsonCode, message, err := restjson.GetErrorInfo(decoder)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
if len(headerCode) == 0 && len(jsonCode) != 0 {
|
||||
errorCode = restjson.SanitizeErrorCode(jsonCode)
|
||||
}
|
||||
if len(message) != 0 {
|
||||
errorMessage = message
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.EqualFold("AccessDeniedException", errorCode):
|
||||
return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("InternalServerException", errorCode):
|
||||
return awsRestjson1_deserializeErrorInternalServerException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("TooManyRequestsError", errorCode):
|
||||
return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody)
|
||||
|
||||
case strings.EqualFold("ValidationException", errorCode):
|
||||
return awsRestjson1_deserializeErrorValidationException(response, errorBody)
|
||||
|
||||
default:
|
||||
genericError := &smithy.GenericAPIError{
|
||||
Code: errorCode,
|
||||
Message: errorMessage,
|
||||
}
|
||||
return genericError
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeOpDocumentCreateOAuth2TokenOutput(v **CreateOAuth2TokenOutput, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *CreateOAuth2TokenOutput
|
||||
if *v == nil {
|
||||
sv = &CreateOAuth2TokenOutput{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "tokenOutput":
|
||||
if err := awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(&sv.TokenOutput, value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeErrorAccessDeniedException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.AccessDeniedException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
var shape interface{}
|
||||
if err := decoder.Decode(&shape); err != nil && err != io.EOF {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err := awsRestjson1_deserializeDocumentAccessDeniedException(&output, shape)
|
||||
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeErrorInternalServerException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.InternalServerException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
var shape interface{}
|
||||
if err := decoder.Decode(&shape); err != nil && err != io.EOF {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err := awsRestjson1_deserializeDocumentInternalServerException(&output, shape)
|
||||
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeErrorTooManyRequestsError(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.TooManyRequestsError{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
var shape interface{}
|
||||
if err := decoder.Decode(&shape); err != nil && err != io.EOF {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err := awsRestjson1_deserializeDocumentTooManyRequestsError(&output, shape)
|
||||
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeErrorValidationException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.ValidationException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
decoder := json.NewDecoder(body)
|
||||
decoder.UseNumber()
|
||||
var shape interface{}
|
||||
if err := decoder.Decode(&shape); err != nil && err != io.EOF {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err := awsRestjson1_deserializeDocumentValidationException(&output, shape)
|
||||
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentAccessDeniedException(v **types.AccessDeniedException, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.AccessDeniedException
|
||||
if *v == nil {
|
||||
sv = &types.AccessDeniedException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "error":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Error_ = types.OAuth2ErrorCode(jtv)
|
||||
}
|
||||
|
||||
case "message", "Message":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Message = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentAccessToken(v **types.AccessToken, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.AccessToken
|
||||
if *v == nil {
|
||||
sv = &types.AccessToken{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "accessKeyId":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.AccessKeyId = ptr.String(jtv)
|
||||
}
|
||||
|
||||
case "secretAccessKey":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.SecretAccessKey = ptr.String(jtv)
|
||||
}
|
||||
|
||||
case "sessionToken":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.SessionToken = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(v **types.CreateOAuth2TokenResponseBody, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.CreateOAuth2TokenResponseBody
|
||||
if *v == nil {
|
||||
sv = &types.CreateOAuth2TokenResponseBody{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "accessToken":
|
||||
if err := awsRestjson1_deserializeDocumentAccessToken(&sv.AccessToken, value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case "expiresIn":
|
||||
if value != nil {
|
||||
jtv, ok := value.(json.Number)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected ExpiresIn to be json.Number, got %T instead", value)
|
||||
}
|
||||
i64, err := jtv.Int64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sv.ExpiresIn = ptr.Int32(int32(i64))
|
||||
}
|
||||
|
||||
case "idToken":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected IdToken to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.IdToken = ptr.String(jtv)
|
||||
}
|
||||
|
||||
case "refreshToken":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected RefreshToken to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.RefreshToken = ptr.String(jtv)
|
||||
}
|
||||
|
||||
case "tokenType":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected TokenType to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.TokenType = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentInternalServerException(v **types.InternalServerException, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.InternalServerException
|
||||
if *v == nil {
|
||||
sv = &types.InternalServerException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "error":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Error_ = types.OAuth2ErrorCode(jtv)
|
||||
}
|
||||
|
||||
case "message", "Message":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Message = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentTooManyRequestsError(v **types.TooManyRequestsError, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.TooManyRequestsError
|
||||
if *v == nil {
|
||||
sv = &types.TooManyRequestsError{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "error":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Error_ = types.OAuth2ErrorCode(jtv)
|
||||
}
|
||||
|
||||
case "message", "Message":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Message = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_deserializeDocumentValidationException(v **types.ValidationException, value interface{}) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
shape, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected JSON type %v", value)
|
||||
}
|
||||
|
||||
var sv *types.ValidationException
|
||||
if *v == nil {
|
||||
sv = &types.ValidationException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for key, value := range shape {
|
||||
switch key {
|
||||
case "error":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Error_ = types.OAuth2ErrorCode(jtv)
|
||||
}
|
||||
|
||||
case "message", "Message":
|
||||
if value != nil {
|
||||
jtv, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected String to be of type string, got %T instead", value)
|
||||
}
|
||||
sv.Message = ptr.String(jtv)
|
||||
}
|
||||
|
||||
default:
|
||||
_, _ = key, value
|
||||
|
||||
}
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
// Package signin provides the API client, operations, and parameter types for AWS
|
||||
// Sign-In Service.
|
||||
//
|
||||
// AWS Sign-In manages authentication for AWS services. This service provides
|
||||
// secure authentication flows for accessing AWS resources from the console and
|
||||
// developer tools.
|
||||
package signin
|
||||
+624
@@ -0,0 +1,624 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
|
||||
"github.com/aws/aws-sdk-go-v2/internal/endpoints"
|
||||
"github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn"
|
||||
internalendpoints "github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
smithyendpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/aws/smithy-go/endpoints/private/rulesfn"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/ptr"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EndpointResolverOptions is the service endpoint resolver options
|
||||
type EndpointResolverOptions = internalendpoints.Options
|
||||
|
||||
// EndpointResolver interface for resolving service endpoints.
|
||||
type EndpointResolver interface {
|
||||
ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
|
||||
}
|
||||
|
||||
var _ EndpointResolver = &internalendpoints.Resolver{}
|
||||
|
||||
// NewDefaultEndpointResolver constructs a new service endpoint resolver
|
||||
func NewDefaultEndpointResolver() *internalendpoints.Resolver {
|
||||
return internalendpoints.New()
|
||||
}
|
||||
|
||||
// EndpointResolverFunc is a helper utility that wraps a function so it satisfies
|
||||
// the EndpointResolver interface. This is useful when you want to add additional
|
||||
// endpoint resolving logic, or stub out specific endpoints with custom values.
|
||||
type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error)
|
||||
|
||||
func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
|
||||
return fn(region, options)
|
||||
}
|
||||
|
||||
// EndpointResolverFromURL returns an EndpointResolver configured using the
|
||||
// provided endpoint url. By default, the resolved endpoint resolver uses the
|
||||
// client region as signing region, and the endpoint source is set to
|
||||
// EndpointSourceCustom.You can provide functional options to configure endpoint
|
||||
// values for the resolved endpoint.
|
||||
func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver {
|
||||
e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom}
|
||||
for _, fn := range optFns {
|
||||
fn(&e)
|
||||
}
|
||||
|
||||
return EndpointResolverFunc(
|
||||
func(region string, options EndpointResolverOptions) (aws.Endpoint, error) {
|
||||
if len(e.SigningRegion) == 0 {
|
||||
e.SigningRegion = region
|
||||
}
|
||||
return e, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type ResolveEndpoint struct {
|
||||
Resolver EndpointResolver
|
||||
Options EndpointResolverOptions
|
||||
}
|
||||
|
||||
func (*ResolveEndpoint) ID() string {
|
||||
return "ResolveEndpoint"
|
||||
}
|
||||
|
||||
func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
|
||||
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
|
||||
req, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
|
||||
}
|
||||
|
||||
if m.Resolver == nil {
|
||||
return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
|
||||
}
|
||||
|
||||
eo := m.Options
|
||||
eo.Logger = middleware.GetLogger(ctx)
|
||||
|
||||
var endpoint aws.Endpoint
|
||||
endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo)
|
||||
if err != nil {
|
||||
nf := (&aws.EndpointNotFoundError{})
|
||||
if errors.As(err, &nf) {
|
||||
ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false)
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
|
||||
}
|
||||
|
||||
req.URL, err = url.Parse(endpoint.URL)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err)
|
||||
}
|
||||
|
||||
if len(awsmiddleware.GetSigningName(ctx)) == 0 {
|
||||
signingName := endpoint.SigningName
|
||||
if len(signingName) == 0 {
|
||||
signingName = "signin"
|
||||
}
|
||||
ctx = awsmiddleware.SetSigningName(ctx, signingName)
|
||||
}
|
||||
ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source)
|
||||
ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable)
|
||||
ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion)
|
||||
ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID)
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error {
|
||||
return stack.Serialize.Insert(&ResolveEndpoint{
|
||||
Resolver: o.EndpointResolver,
|
||||
Options: o.EndpointOptions,
|
||||
}, "OperationSerializer", middleware.Before)
|
||||
}
|
||||
|
||||
func removeResolveEndpointMiddleware(stack *middleware.Stack) error {
|
||||
_, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID())
|
||||
return err
|
||||
}
|
||||
|
||||
type wrappedEndpointResolver struct {
|
||||
awsResolver aws.EndpointResolverWithOptions
|
||||
}
|
||||
|
||||
func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
|
||||
return w.awsResolver.ResolveEndpoint(ServiceID, region, options)
|
||||
}
|
||||
|
||||
type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error)
|
||||
|
||||
func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
||||
return a(service, region)
|
||||
}
|
||||
|
||||
var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)
|
||||
|
||||
// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver.
|
||||
// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error,
|
||||
// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked
|
||||
// via its middleware.
|
||||
//
|
||||
// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated.
|
||||
func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver {
|
||||
var resolver aws.EndpointResolverWithOptions
|
||||
|
||||
if awsResolverWithOptions != nil {
|
||||
resolver = awsResolverWithOptions
|
||||
} else if awsResolver != nil {
|
||||
resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint)
|
||||
}
|
||||
|
||||
return &wrappedEndpointResolver{
|
||||
awsResolver: resolver,
|
||||
}
|
||||
}
|
||||
|
||||
func finalizeClientEndpointResolverOptions(options *Options) {
|
||||
options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage()
|
||||
|
||||
if len(options.EndpointOptions.ResolvedRegion) == 0 {
|
||||
const fipsInfix = "-fips-"
|
||||
const fipsPrefix = "fips-"
|
||||
const fipsSuffix = "-fips"
|
||||
|
||||
if strings.Contains(options.Region, fipsInfix) ||
|
||||
strings.Contains(options.Region, fipsPrefix) ||
|
||||
strings.Contains(options.Region, fipsSuffix) {
|
||||
options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
|
||||
options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "")
|
||||
options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func resolveEndpointResolverV2(options *Options) {
|
||||
if options.EndpointResolverV2 == nil {
|
||||
options.EndpointResolverV2 = NewDefaultEndpointResolverV2()
|
||||
}
|
||||
}
|
||||
|
||||
func resolveBaseEndpoint(cfg aws.Config, o *Options) {
|
||||
if cfg.BaseEndpoint != nil {
|
||||
o.BaseEndpoint = cfg.BaseEndpoint
|
||||
}
|
||||
|
||||
_, g := os.LookupEnv("AWS_ENDPOINT_URL")
|
||||
_, s := os.LookupEnv("AWS_ENDPOINT_URL_SIGNIN")
|
||||
|
||||
if g && !s {
|
||||
return
|
||||
}
|
||||
|
||||
value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "Signin", cfg.ConfigSources)
|
||||
if found && err == nil {
|
||||
o.BaseEndpoint = &value
|
||||
}
|
||||
}
|
||||
|
||||
func bindRegion(region string) (*string, error) {
|
||||
if region == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !rulesfn.IsValidHostLabel(region, true) {
|
||||
return nil, fmt.Errorf("invalid input region %s", region)
|
||||
}
|
||||
|
||||
return aws.String(endpoints.MapFIPSRegion(region)), nil
|
||||
}
|
||||
|
||||
// EndpointParameters provides the parameters that influence how endpoints are
|
||||
// resolved.
|
||||
type EndpointParameters struct {
|
||||
// When true, use the dual-stack endpoint. If the configured endpoint does not
|
||||
// support dual-stack, dispatching the request MAY return an error.
|
||||
//
|
||||
// Defaults to
|
||||
// false if no value is provided.
|
||||
//
|
||||
// AWS::UseDualStack
|
||||
UseDualStack *bool
|
||||
|
||||
// When true, send this request to the FIPS-compliant regional endpoint. If the
|
||||
// configured endpoint does not have a FIPS compliant endpoint, dispatching the
|
||||
// request will return an error.
|
||||
//
|
||||
// Defaults to false if no value is
|
||||
// provided.
|
||||
//
|
||||
// AWS::UseFIPS
|
||||
UseFIPS *bool
|
||||
|
||||
// Override the endpoint used to send this request
|
||||
//
|
||||
// Parameter is
|
||||
// required.
|
||||
//
|
||||
// SDK::Endpoint
|
||||
Endpoint *string
|
||||
|
||||
// The AWS region used to dispatch the request.
|
||||
//
|
||||
// Parameter is
|
||||
// required.
|
||||
//
|
||||
// AWS::Region
|
||||
Region *string
|
||||
}
|
||||
|
||||
// ValidateRequired validates required parameters are set.
|
||||
func (p EndpointParameters) ValidateRequired() error {
|
||||
if p.UseDualStack == nil {
|
||||
return fmt.Errorf("parameter UseDualStack is required")
|
||||
}
|
||||
|
||||
if p.UseFIPS == nil {
|
||||
return fmt.Errorf("parameter UseFIPS is required")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithDefaults returns a shallow copy of EndpointParameterswith default values
|
||||
// applied to members where applicable.
|
||||
func (p EndpointParameters) WithDefaults() EndpointParameters {
|
||||
if p.UseDualStack == nil {
|
||||
p.UseDualStack = ptr.Bool(false)
|
||||
}
|
||||
|
||||
if p.UseFIPS == nil {
|
||||
p.UseFIPS = ptr.Bool(false)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
type stringSlice []string
|
||||
|
||||
func (s stringSlice) Get(i int) *string {
|
||||
if i < 0 || i >= len(s) {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := s[i]
|
||||
return &v
|
||||
}
|
||||
|
||||
// EndpointResolverV2 provides the interface for resolving service endpoints.
|
||||
type EndpointResolverV2 interface {
|
||||
// ResolveEndpoint attempts to resolve the endpoint with the provided options,
|
||||
// returning the endpoint if found. Otherwise an error is returned.
|
||||
ResolveEndpoint(ctx context.Context, params EndpointParameters) (
|
||||
smithyendpoints.Endpoint, error,
|
||||
)
|
||||
}
|
||||
|
||||
// resolver provides the implementation for resolving endpoints.
|
||||
type resolver struct{}
|
||||
|
||||
func NewDefaultEndpointResolverV2() EndpointResolverV2 {
|
||||
return &resolver{}
|
||||
}
|
||||
|
||||
// ResolveEndpoint attempts to resolve the endpoint with the provided options,
|
||||
// returning the endpoint if found. Otherwise an error is returned.
|
||||
func (r *resolver) ResolveEndpoint(
|
||||
ctx context.Context, params EndpointParameters,
|
||||
) (
|
||||
endpoint smithyendpoints.Endpoint, err error,
|
||||
) {
|
||||
params = params.WithDefaults()
|
||||
if err = params.ValidateRequired(); err != nil {
|
||||
return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err)
|
||||
}
|
||||
_UseDualStack := *params.UseDualStack
|
||||
_ = _UseDualStack
|
||||
_UseFIPS := *params.UseFIPS
|
||||
_ = _UseFIPS
|
||||
|
||||
if exprVal := params.Endpoint; exprVal != nil {
|
||||
_Endpoint := *exprVal
|
||||
_ = _Endpoint
|
||||
if _UseFIPS == true {
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported")
|
||||
}
|
||||
if _UseDualStack == true {
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported")
|
||||
}
|
||||
uriString := _Endpoint
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
if exprVal := params.Region; exprVal != nil {
|
||||
_Region := *exprVal
|
||||
_ = _Region
|
||||
if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil {
|
||||
_PartitionResult := *exprVal
|
||||
_ = _PartitionResult
|
||||
if _PartitionResult.Name == "aws" {
|
||||
if _UseFIPS == false {
|
||||
if _UseDualStack == false {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".signin.aws.amazon.com")
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if _PartitionResult.Name == "aws-cn" {
|
||||
if _UseFIPS == false {
|
||||
if _UseDualStack == false {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".signin.amazonaws.cn")
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if _PartitionResult.Name == "aws-us-gov" {
|
||||
if _UseFIPS == false {
|
||||
if _UseDualStack == false {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".signin.amazonaws-us-gov.com")
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if _UseFIPS == true {
|
||||
if _UseDualStack == true {
|
||||
if true == _PartitionResult.SupportsFIPS {
|
||||
if true == _PartitionResult.SupportsDualStack {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://signin-fips.")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".")
|
||||
out.WriteString(_PartitionResult.DualStackDnsSuffix)
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both")
|
||||
}
|
||||
}
|
||||
if _UseFIPS == true {
|
||||
if _UseDualStack == false {
|
||||
if _PartitionResult.SupportsFIPS == true {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://signin-fips.")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".")
|
||||
out.WriteString(_PartitionResult.DnsSuffix)
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS")
|
||||
}
|
||||
}
|
||||
if _UseFIPS == false {
|
||||
if _UseDualStack == true {
|
||||
if true == _PartitionResult.SupportsDualStack {
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://signin.")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".")
|
||||
out.WriteString(_PartitionResult.DualStackDnsSuffix)
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack")
|
||||
}
|
||||
}
|
||||
uriString := func() string {
|
||||
var out strings.Builder
|
||||
out.WriteString("https://signin.")
|
||||
out.WriteString(_Region)
|
||||
out.WriteString(".")
|
||||
out.WriteString(_PartitionResult.DnsSuffix)
|
||||
return out.String()
|
||||
}()
|
||||
|
||||
uri, err := url.Parse(uriString)
|
||||
if err != nil {
|
||||
return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
|
||||
}
|
||||
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *uri,
|
||||
Headers: http.Header{},
|
||||
}, nil
|
||||
}
|
||||
return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.")
|
||||
}
|
||||
return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region")
|
||||
}
|
||||
|
||||
type endpointParamsBinder interface {
|
||||
bindEndpointParams(*EndpointParameters)
|
||||
}
|
||||
|
||||
func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) {
|
||||
params := &EndpointParameters{}
|
||||
|
||||
params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled)
|
||||
params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled)
|
||||
params.Endpoint = options.BaseEndpoint
|
||||
region, err := bindRegion(options.Region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
params.Region = region
|
||||
|
||||
if b, ok := input.(endpointParamsBinder); ok {
|
||||
b.bindEndpointParams(params)
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
type resolveEndpointV2Middleware struct {
|
||||
options Options
|
||||
}
|
||||
|
||||
func (*resolveEndpointV2Middleware) ID() string {
|
||||
return "ResolveEndpointV2"
|
||||
}
|
||||
|
||||
func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
|
||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
_, span := tracing.StartSpan(ctx, "ResolveEndpoint")
|
||||
defer span.End()
|
||||
|
||||
if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
|
||||
req, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
|
||||
}
|
||||
|
||||
if m.options.EndpointResolverV2 == nil {
|
||||
return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
|
||||
}
|
||||
|
||||
params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err)
|
||||
}
|
||||
endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
|
||||
func() (smithyendpoints.Endpoint, error) {
|
||||
return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
|
||||
})
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
|
||||
}
|
||||
|
||||
span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())
|
||||
|
||||
if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
|
||||
endpt.URI.RawPath = endpt.URI.Path
|
||||
}
|
||||
req.URL.Scheme = endpt.URI.Scheme
|
||||
req.URL.Host = endpt.URI.Host
|
||||
req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path)
|
||||
req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath)
|
||||
for k := range endpt.Headers {
|
||||
req.Header.Set(k, endpt.Headers.Get(k))
|
||||
}
|
||||
|
||||
rscheme := getResolvedAuthScheme(ctx)
|
||||
if rscheme == nil {
|
||||
return out, metadata, fmt.Errorf("no resolved auth scheme")
|
||||
}
|
||||
|
||||
opts, _ := smithyauth.GetAuthOptions(&endpt.Properties)
|
||||
for _, o := range opts {
|
||||
rscheme.SignerProperties.SetAll(&o.SignerProperties)
|
||||
}
|
||||
|
||||
span.End()
|
||||
return next.HandleFinalize(ctx, in)
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"github.com/aws/aws-sdk-go-v2": "v1.4.0",
|
||||
"github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000",
|
||||
"github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000",
|
||||
"github.com/aws/smithy-go": "v1.4.0"
|
||||
},
|
||||
"files": [
|
||||
"api_client.go",
|
||||
"api_client_test.go",
|
||||
"api_op_CreateOAuth2Token.go",
|
||||
"auth.go",
|
||||
"deserializers.go",
|
||||
"doc.go",
|
||||
"endpoints.go",
|
||||
"endpoints_config_test.go",
|
||||
"endpoints_test.go",
|
||||
"generated.json",
|
||||
"internal/endpoints/endpoints.go",
|
||||
"internal/endpoints/endpoints_test.go",
|
||||
"options.go",
|
||||
"protocol_test.go",
|
||||
"serializers.go",
|
||||
"snapshot_test.go",
|
||||
"sra_operation_order_test.go",
|
||||
"types/enums.go",
|
||||
"types/errors.go",
|
||||
"types/types.go",
|
||||
"validators.go"
|
||||
],
|
||||
"go": "1.23",
|
||||
"module": "github.com/aws/aws-sdk-go-v2/service/signin",
|
||||
"unstable": false
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.0.5"
|
||||
Generated
Vendored
+333
@@ -0,0 +1,333 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Options is the endpoint resolver configuration options
|
||||
type Options struct {
|
||||
// Logger is a logging implementation that log events should be sent to.
|
||||
Logger logging.Logger
|
||||
|
||||
// LogDeprecated indicates that deprecated endpoints should be logged to the
|
||||
// provided logger.
|
||||
LogDeprecated bool
|
||||
|
||||
// ResolvedRegion is used to override the region to be resolved, rather then the
|
||||
// using the value passed to the ResolveEndpoint method. This value is used by the
|
||||
// SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative
|
||||
// name. You must not set this value directly in your application.
|
||||
ResolvedRegion string
|
||||
|
||||
// DisableHTTPS informs the resolver to return an endpoint that does not use the
|
||||
// HTTPS scheme.
|
||||
DisableHTTPS bool
|
||||
|
||||
// UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint.
|
||||
UseDualStackEndpoint aws.DualStackEndpointState
|
||||
|
||||
// UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint.
|
||||
UseFIPSEndpoint aws.FIPSEndpointState
|
||||
}
|
||||
|
||||
func (o Options) GetResolvedRegion() string {
|
||||
return o.ResolvedRegion
|
||||
}
|
||||
|
||||
func (o Options) GetDisableHTTPS() bool {
|
||||
return o.DisableHTTPS
|
||||
}
|
||||
|
||||
func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState {
|
||||
return o.UseDualStackEndpoint
|
||||
}
|
||||
|
||||
func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState {
|
||||
return o.UseFIPSEndpoint
|
||||
}
|
||||
|
||||
func transformToSharedOptions(options Options) endpoints.Options {
|
||||
return endpoints.Options{
|
||||
Logger: options.Logger,
|
||||
LogDeprecated: options.LogDeprecated,
|
||||
ResolvedRegion: options.ResolvedRegion,
|
||||
DisableHTTPS: options.DisableHTTPS,
|
||||
UseDualStackEndpoint: options.UseDualStackEndpoint,
|
||||
UseFIPSEndpoint: options.UseFIPSEndpoint,
|
||||
}
|
||||
}
|
||||
|
||||
// Resolver Signin endpoint resolver
|
||||
type Resolver struct {
|
||||
partitions endpoints.Partitions
|
||||
}
|
||||
|
||||
// ResolveEndpoint resolves the service endpoint for the given region and options
|
||||
func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) {
|
||||
if len(region) == 0 {
|
||||
return endpoint, &aws.MissingRegionError{}
|
||||
}
|
||||
|
||||
opt := transformToSharedOptions(options)
|
||||
return r.partitions.ResolveEndpoint(region, opt)
|
||||
}
|
||||
|
||||
// New returns a new Resolver
|
||||
func New() *Resolver {
|
||||
return &Resolver{
|
||||
partitions: defaultPartitions,
|
||||
}
|
||||
}
|
||||
|
||||
var partitionRegexp = struct {
|
||||
Aws *regexp.Regexp
|
||||
AwsCn *regexp.Regexp
|
||||
AwsEusc *regexp.Regexp
|
||||
AwsIso *regexp.Regexp
|
||||
AwsIsoB *regexp.Regexp
|
||||
AwsIsoE *regexp.Regexp
|
||||
AwsIsoF *regexp.Regexp
|
||||
AwsUsGov *regexp.Regexp
|
||||
}{
|
||||
|
||||
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"),
|
||||
AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"),
|
||||
AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"),
|
||||
AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"),
|
||||
AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"),
|
||||
AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"),
|
||||
AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"),
|
||||
AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"),
|
||||
}
|
||||
|
||||
var defaultPartitions = endpoints.Partitions{
|
||||
{
|
||||
ID: "aws",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin.{region}.api.aws",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.amazonaws.com",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.api.aws",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.amazonaws.com",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.Aws,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-cn",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin.{region}.api.amazonwebservices.com.cn",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.amazonaws.com.cn",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.api.amazonwebservices.com.cn",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.amazonaws.com.cn",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsCn,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-eusc",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.amazonaws.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.amazonaws.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsEusc,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-iso",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.c2s.ic.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.c2s.ic.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsIso,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-iso-b",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.sc2s.sgov.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.sc2s.sgov.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsIsoB,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-iso-e",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.cloud.adc-e.uk",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.cloud.adc-e.uk",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsIsoE,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-iso-f",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.csp.hci.ic.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.csp.hci.ic.gov",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsIsoF,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
{
|
||||
ID: "aws-us-gov",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin.{region}.api.aws",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.amazonaws.com",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "signin-fips.{region}.api.aws",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
Hostname: "signin.{region}.amazonaws.com",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsUsGov,
|
||||
IsRegionalized: true,
|
||||
},
|
||||
}
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
"github.com/aws/smithy-go/metrics"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type HTTPClient interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
// Set of options to modify how an operation is invoked. These apply to all
|
||||
// operations invoked for this client. Use functional options on operation call to
|
||||
// modify this list for per operation behavior.
|
||||
APIOptions []func(*middleware.Stack) error
|
||||
|
||||
// The optional application specific identifier appended to the User-Agent header.
|
||||
AppID string
|
||||
|
||||
// This endpoint will be given as input to an EndpointResolverV2. It is used for
|
||||
// providing a custom base endpoint that is subject to modifications by the
|
||||
// processing EndpointResolverV2.
|
||||
BaseEndpoint *string
|
||||
|
||||
// Configures the events that will be sent to the configured logger.
|
||||
ClientLogMode aws.ClientLogMode
|
||||
|
||||
// The credentials object to use when signing requests.
|
||||
Credentials aws.CredentialsProvider
|
||||
|
||||
// The configuration DefaultsMode that the SDK should use when constructing the
|
||||
// clients initial default settings.
|
||||
DefaultsMode aws.DefaultsMode
|
||||
|
||||
// The endpoint options to be used when attempting to resolve an endpoint.
|
||||
EndpointOptions EndpointResolverOptions
|
||||
|
||||
// The service endpoint resolver.
|
||||
//
|
||||
// Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a
|
||||
// value for this field will likely prevent you from using any endpoint-related
|
||||
// service features released after the introduction of EndpointResolverV2 and
|
||||
// BaseEndpoint.
|
||||
//
|
||||
// To migrate an EndpointResolver implementation that uses a custom endpoint, set
|
||||
// the client option BaseEndpoint instead.
|
||||
EndpointResolver EndpointResolver
|
||||
|
||||
// Resolves the endpoint used for a particular service operation. This should be
|
||||
// used over the deprecated EndpointResolver.
|
||||
EndpointResolverV2 EndpointResolverV2
|
||||
|
||||
// Signature Version 4 (SigV4) Signer
|
||||
HTTPSignerV4 HTTPSignerV4
|
||||
|
||||
// The logger writer interface to write logging messages to.
|
||||
Logger logging.Logger
|
||||
|
||||
// The client meter provider.
|
||||
MeterProvider metrics.MeterProvider
|
||||
|
||||
// The region to send requests to. (Required)
|
||||
Region string
|
||||
|
||||
// RetryMaxAttempts specifies the maximum number attempts an API client will call
|
||||
// an operation that fails with a retryable error. A value of 0 is ignored, and
|
||||
// will not be used to configure the API client created default retryer, or modify
|
||||
// per operation call's retry max attempts.
|
||||
//
|
||||
// If specified in an operation call's functional options with a value that is
|
||||
// different than the constructed client's Options, the Client's Retryer will be
|
||||
// wrapped to use the operation's specific RetryMaxAttempts value.
|
||||
RetryMaxAttempts int
|
||||
|
||||
// RetryMode specifies the retry mode the API client will be created with, if
|
||||
// Retryer option is not also specified.
|
||||
//
|
||||
// When creating a new API Clients this member will only be used if the Retryer
|
||||
// Options member is nil. This value will be ignored if Retryer is not nil.
|
||||
//
|
||||
// Currently does not support per operation call overrides, may in the future.
|
||||
RetryMode aws.RetryMode
|
||||
|
||||
// Retryer guides how HTTP requests should be retried in case of recoverable
|
||||
// failures. When nil the API client will use a default retryer. The kind of
|
||||
// default retry created by the API client can be changed with the RetryMode
|
||||
// option.
|
||||
Retryer aws.Retryer
|
||||
|
||||
// The RuntimeEnvironment configuration, only populated if the DefaultsMode is set
|
||||
// to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You
|
||||
// should not populate this structure programmatically, or rely on the values here
|
||||
// within your applications.
|
||||
RuntimeEnvironment aws.RuntimeEnvironment
|
||||
|
||||
// The client tracer provider.
|
||||
TracerProvider tracing.TracerProvider
|
||||
|
||||
// The initial DefaultsMode used when the client options were constructed. If the
|
||||
// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
|
||||
// value was at that point in time.
|
||||
//
|
||||
// Currently does not support per operation call overrides, may in the future.
|
||||
resolvedDefaultsMode aws.DefaultsMode
|
||||
|
||||
// The HTTP client to invoke API calls with. Defaults to client's default HTTP
|
||||
// implementation if nil.
|
||||
HTTPClient HTTPClient
|
||||
|
||||
// Client registry of operation interceptors.
|
||||
Interceptors smithyhttp.InterceptorRegistry
|
||||
|
||||
// The auth scheme resolver which determines how to authenticate for each
|
||||
// operation.
|
||||
AuthSchemeResolver AuthSchemeResolver
|
||||
|
||||
// The list of auth schemes supported by the client.
|
||||
AuthSchemes []smithyhttp.AuthScheme
|
||||
|
||||
// Priority list of preferred auth scheme names (e.g. sigv4a).
|
||||
AuthSchemePreference []string
|
||||
}
|
||||
|
||||
// Copy creates a clone where the APIOptions list is deep copied.
|
||||
func (o Options) Copy() Options {
|
||||
to := o
|
||||
to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions))
|
||||
copy(to.APIOptions, o.APIOptions)
|
||||
to.Interceptors = o.Interceptors.Copy()
|
||||
|
||||
return to
|
||||
}
|
||||
|
||||
func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver {
|
||||
if schemeID == "aws.auth#sigv4" {
|
||||
return getSigV4IdentityResolver(o)
|
||||
}
|
||||
if schemeID == "smithy.api#noAuth" {
|
||||
return &smithyauth.AnonymousIdentityResolver{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithAPIOptions returns a functional option for setting the Client's APIOptions
|
||||
// option.
|
||||
func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.APIOptions = append(o.APIOptions, optFns...)
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for
|
||||
// this field will likely prevent you from using any endpoint-related service
|
||||
// features released after the introduction of EndpointResolverV2 and BaseEndpoint.
|
||||
//
|
||||
// To migrate an EndpointResolver implementation that uses a custom endpoint, set
|
||||
// the client option BaseEndpoint instead.
|
||||
func WithEndpointResolver(v EndpointResolver) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.EndpointResolver = v
|
||||
}
|
||||
}
|
||||
|
||||
// WithEndpointResolverV2 returns a functional option for setting the Client's
|
||||
// EndpointResolverV2 option.
|
||||
func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.EndpointResolverV2 = v
|
||||
}
|
||||
}
|
||||
|
||||
func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver {
|
||||
if o.Credentials != nil {
|
||||
return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithSigV4SigningName applies an override to the authentication workflow to
|
||||
// use the given signing name for SigV4-authenticated operations.
|
||||
//
|
||||
// This is an advanced setting. The value here is FINAL, taking precedence over
|
||||
// the resolved signing name from both auth scheme resolution and endpoint
|
||||
// resolution.
|
||||
func WithSigV4SigningName(name string) func(*Options) {
|
||||
fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
|
||||
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in)
|
||||
}
|
||||
return func(o *Options) {
|
||||
o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error {
|
||||
return s.Initialize.Add(
|
||||
middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn),
|
||||
middleware.Before,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithSigV4SigningRegion applies an override to the authentication workflow to
|
||||
// use the given signing region for SigV4-authenticated operations.
|
||||
//
|
||||
// This is an advanced setting. The value here is FINAL, taking precedence over
|
||||
// the resolved signing region from both auth scheme resolution and endpoint
|
||||
// resolution.
|
||||
func WithSigV4SigningRegion(region string) func(*Options) {
|
||||
fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
|
||||
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in)
|
||||
}
|
||||
return func(o *Options) {
|
||||
o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error {
|
||||
return s.Initialize.Add(
|
||||
middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn),
|
||||
middleware.Before,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func ignoreAnonymousAuth(options *Options) {
|
||||
if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) {
|
||||
options.Credentials = nil
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin/types"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
"github.com/aws/smithy-go/encoding/httpbinding"
|
||||
smithyjson "github.com/aws/smithy-go/encoding/json"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
)
|
||||
|
||||
type awsRestjson1_serializeOpCreateOAuth2Token struct {
|
||||
}
|
||||
|
||||
func (*awsRestjson1_serializeOpCreateOAuth2Token) ID() string {
|
||||
return "OperationSerializer"
|
||||
}
|
||||
|
||||
func (m *awsRestjson1_serializeOpCreateOAuth2Token) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
|
||||
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
_, span := tracing.StartSpan(ctx, "OperationSerializer")
|
||||
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
|
||||
defer endTimer()
|
||||
defer span.End()
|
||||
request, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
|
||||
}
|
||||
|
||||
input, ok := in.Parameters.(*CreateOAuth2TokenInput)
|
||||
_ = input
|
||||
if !ok {
|
||||
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)}
|
||||
}
|
||||
|
||||
opPath, opQuery := httpbinding.SplitURI("/v1/token")
|
||||
request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath)
|
||||
request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery)
|
||||
request.Method = "POST"
|
||||
var restEncoder *httpbinding.Encoder
|
||||
if request.URL.RawPath == "" {
|
||||
restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header)
|
||||
} else {
|
||||
request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath)
|
||||
restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
|
||||
if !restEncoder.HasHeader("Content-Type") {
|
||||
ctx = smithyhttp.SetIsContentTypeDefaultValue(ctx, true)
|
||||
restEncoder.SetHeader("Content-Type").String("application/json")
|
||||
}
|
||||
|
||||
if input.TokenInput != nil {
|
||||
jsonEncoder := smithyjson.NewEncoder()
|
||||
if err := awsRestjson1_serializeDocumentCreateOAuth2TokenRequestBody(input.TokenInput, jsonEncoder.Value); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
payload := bytes.NewReader(jsonEncoder.Bytes())
|
||||
if request, err = request.SetStream(payload); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
} else {
|
||||
jsonEncoder := smithyjson.NewEncoder()
|
||||
jsonEncoder.Value.Object().Close()
|
||||
payload := bytes.NewReader(jsonEncoder.Bytes())
|
||||
if request, err = request.SetStream(payload); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if request.Request, err = restEncoder.Encode(request.Request); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
in.Request = request
|
||||
|
||||
endTimer()
|
||||
span.End()
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
func awsRestjson1_serializeOpHttpBindingsCreateOAuth2TokenInput(v *CreateOAuth2TokenInput, encoder *httpbinding.Encoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unsupported serialization of nil %T", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsRestjson1_serializeDocumentCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody, value smithyjson.Value) error {
|
||||
object := value.Object()
|
||||
defer object.Close()
|
||||
|
||||
if v.ClientId != nil {
|
||||
ok := object.Key("clientId")
|
||||
ok.String(*v.ClientId)
|
||||
}
|
||||
|
||||
if v.Code != nil {
|
||||
ok := object.Key("code")
|
||||
ok.String(*v.Code)
|
||||
}
|
||||
|
||||
if v.CodeVerifier != nil {
|
||||
ok := object.Key("codeVerifier")
|
||||
ok.String(*v.CodeVerifier)
|
||||
}
|
||||
|
||||
if v.GrantType != nil {
|
||||
ok := object.Key("grantType")
|
||||
ok.String(*v.GrantType)
|
||||
}
|
||||
|
||||
if v.RedirectUri != nil {
|
||||
ok := object.Key("redirectUri")
|
||||
ok.String(*v.RedirectUri)
|
||||
}
|
||||
|
||||
if v.RefreshToken != nil {
|
||||
ok := object.Key("refreshToken")
|
||||
ok.String(*v.RefreshToken)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
type OAuth2ErrorCode string
|
||||
|
||||
// Enum values for OAuth2ErrorCode
|
||||
const (
|
||||
// Token has expired and needs to be refreshed
|
||||
OAuth2ErrorCodeTokenExpired OAuth2ErrorCode = "TOKEN_EXPIRED"
|
||||
// User credentials have been changed
|
||||
OAuth2ErrorCodeUserCredentialsChanged OAuth2ErrorCode = "USER_CREDENTIALS_CHANGED"
|
||||
// Insufficient permissions to perform this operation
|
||||
OAuth2ErrorCodeInsufficientPermissions OAuth2ErrorCode = "INSUFFICIENT_PERMISSIONS"
|
||||
// Authorization code has expired
|
||||
OAuth2ErrorCodeAuthcodeExpired OAuth2ErrorCode = "AUTHCODE_EXPIRED"
|
||||
// Internal server error occurred
|
||||
OAuth2ErrorCodeServerError OAuth2ErrorCode = "server_error"
|
||||
// The request is missing a required parameter, includes an invalid parameter
|
||||
// value, or is otherwise malformed
|
||||
OAuth2ErrorCodeInvalidRequest OAuth2ErrorCode = "INVALID_REQUEST"
|
||||
)
|
||||
|
||||
// Values returns all known values for OAuth2ErrorCode. Note that this can be
|
||||
// expanded in the future, and so it is only as up to date as the client.
|
||||
//
|
||||
// The ordering of this slice is not guaranteed to be stable across updates.
|
||||
func (OAuth2ErrorCode) Values() []OAuth2ErrorCode {
|
||||
return []OAuth2ErrorCode{
|
||||
"TOKEN_EXPIRED",
|
||||
"USER_CREDENTIALS_CHANGED",
|
||||
"INSUFFICIENT_PERMISSIONS",
|
||||
"AUTHCODE_EXPIRED",
|
||||
"server_error",
|
||||
"INVALID_REQUEST",
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
)
|
||||
|
||||
// Error thrown for access denied scenarios with flexible HTTP status mapping
|
||||
//
|
||||
// Runtime HTTP Status Code Mapping:
|
||||
//
|
||||
// - HTTP 401 (Unauthorized): TOKEN_EXPIRED, AUTHCODE_EXPIRED
|
||||
// - HTTP 403 (Forbidden): USER_CREDENTIALS_CHANGED, INSUFFICIENT_PERMISSIONS
|
||||
//
|
||||
// The specific HTTP status code is determined at runtime based on the error enum
|
||||
// value. Consumers should use the error field to determine the specific access
|
||||
// denial reason.
|
||||
type AccessDeniedException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
Error_ OAuth2ErrorCode
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *AccessDeniedException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *AccessDeniedException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *AccessDeniedException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "AccessDeniedException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *AccessDeniedException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// Error thrown when an internal server error occurs
|
||||
//
|
||||
// HTTP Status Code: 500 Internal Server Error
|
||||
//
|
||||
// Used for unexpected server-side errors that prevent request processing.
|
||||
type InternalServerException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
Error_ OAuth2ErrorCode
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *InternalServerException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *InternalServerException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *InternalServerException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "InternalServerException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *InternalServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer }
|
||||
|
||||
// Error thrown when rate limit is exceeded
|
||||
//
|
||||
// HTTP Status Code: 429 Too Many Requests
|
||||
//
|
||||
// Possible OAuth2ErrorCode values:
|
||||
//
|
||||
// - INVALID_REQUEST: Rate limiting, too many requests, abuse prevention
|
||||
//
|
||||
// Possible causes:
|
||||
//
|
||||
// - Too many token requests from the same client
|
||||
// - Rate limiting based on client_id or IP address
|
||||
// - Abuse prevention mechanisms triggered
|
||||
// - Service protection against excessive token generation
|
||||
type TooManyRequestsError struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
Error_ OAuth2ErrorCode
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *TooManyRequestsError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *TooManyRequestsError) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *TooManyRequestsError) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "TooManyRequestsError"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *TooManyRequestsError) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// Error thrown when request validation fails
|
||||
//
|
||||
// HTTP Status Code: 400 Bad Request
|
||||
//
|
||||
// Used for request validation errors such as malformed parameters, missing
|
||||
// required fields, or invalid parameter values.
|
||||
type ValidationException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
Error_ OAuth2ErrorCode
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *ValidationException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *ValidationException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *ValidationException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "ValidationException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *ValidationException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
smithydocument "github.com/aws/smithy-go/document"
|
||||
)
|
||||
|
||||
// AWS credentials structure containing temporary access credentials
|
||||
//
|
||||
// The scoped-down, 15 minute duration AWS credentials. Scoping down will be based
|
||||
// on CLI policy (CLI team needs to create it). Similar to cloud shell
|
||||
// implementation.
|
||||
type AccessToken struct {
|
||||
|
||||
// AWS access key ID for temporary credentials
|
||||
//
|
||||
// This member is required.
|
||||
AccessKeyId *string
|
||||
|
||||
// AWS secret access key for temporary credentials
|
||||
//
|
||||
// This member is required.
|
||||
SecretAccessKey *string
|
||||
|
||||
// AWS session token for temporary credentials
|
||||
//
|
||||
// This member is required.
|
||||
SessionToken *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
// Request body payload for CreateOAuth2Token operation
|
||||
//
|
||||
// The operation type is determined by the grant_type parameter:
|
||||
//
|
||||
// - grant_type=authorization_code: Requires code, redirect_uri, code_verifier
|
||||
// - grant_type=refresh_token: Requires refresh_token
|
||||
type CreateOAuth2TokenRequestBody struct {
|
||||
|
||||
// The client identifier (ARN) used during Sign-In onboarding Required for both
|
||||
// authorization code and refresh token flows
|
||||
//
|
||||
// This member is required.
|
||||
ClientId *string
|
||||
|
||||
// OAuth 2.0 grant type - determines which flow is used Must be
|
||||
// "authorization_code" or "refresh_token"
|
||||
//
|
||||
// This member is required.
|
||||
GrantType *string
|
||||
|
||||
// The authorization code received from /v1/authorize Required only when
|
||||
// grant_type=authorization_code
|
||||
Code *string
|
||||
|
||||
// PKCE code verifier to prove possession of the original code challenge Required
|
||||
// only when grant_type=authorization_code
|
||||
CodeVerifier *string
|
||||
|
||||
// The redirect URI that must match the original authorization request Required
|
||||
// only when grant_type=authorization_code
|
||||
RedirectUri *string
|
||||
|
||||
// The refresh token returned from auth_code redemption Required only when
|
||||
// grant_type=refresh_token
|
||||
RefreshToken *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
// Response body payload for CreateOAuth2Token operation
|
||||
//
|
||||
// The response content depends on the grant_type from the request:
|
||||
//
|
||||
// - grant_type=authorization_code: Returns all fields including refresh_token
|
||||
// and id_token
|
||||
// - grant_type=refresh_token: Returns access_token, token_type, expires_in,
|
||||
// refresh_token (no id_token)
|
||||
type CreateOAuth2TokenResponseBody struct {
|
||||
|
||||
// Scoped-down AWS credentials (15 minute duration) Present for both authorization
|
||||
// code redemption and token refresh
|
||||
//
|
||||
// This member is required.
|
||||
AccessToken *AccessToken
|
||||
|
||||
// Time to expiry in seconds (maximum 900) Present for both authorization code
|
||||
// redemption and token refresh
|
||||
//
|
||||
// This member is required.
|
||||
ExpiresIn *int32
|
||||
|
||||
// Encrypted refresh token with cnf.jkt (SHA-256 thumbprint of presented jwk)
|
||||
// Always present in responses (required for both flows)
|
||||
//
|
||||
// This member is required.
|
||||
RefreshToken *string
|
||||
|
||||
// Token type indicating this is AWS SigV4 credentials Value is "aws_sigv4" for
|
||||
// both flows
|
||||
//
|
||||
// This member is required.
|
||||
TokenType *string
|
||||
|
||||
// ID token containing user identity information Present only in authorization
|
||||
// code redemption response (grant_type=authorization_code) Not included in token
|
||||
// refresh responses
|
||||
IdToken *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
type noSmithyDocumentSerde = smithydocument.NoSerde
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package signin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/service/signin/types"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
)
|
||||
|
||||
type validateOpCreateOAuth2Token struct {
|
||||
}
|
||||
|
||||
func (*validateOpCreateOAuth2Token) ID() string {
|
||||
return "OperationInputValidation"
|
||||
}
|
||||
|
||||
func (m *validateOpCreateOAuth2Token) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
|
||||
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
input, ok := in.Parameters.(*CreateOAuth2TokenInput)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters)
|
||||
}
|
||||
if err := validateOpCreateOAuth2TokenInput(input); err != nil {
|
||||
return out, metadata, err
|
||||
}
|
||||
return next.HandleInitialize(ctx, in)
|
||||
}
|
||||
|
||||
func addOpCreateOAuth2TokenValidationMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Initialize.Add(&validateOpCreateOAuth2Token{}, middleware.After)
|
||||
}
|
||||
|
||||
func validateCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
invalidParams := smithy.InvalidParamsError{Context: "CreateOAuth2TokenRequestBody"}
|
||||
if v.ClientId == nil {
|
||||
invalidParams.Add(smithy.NewErrParamRequired("ClientId"))
|
||||
}
|
||||
if v.GrantType == nil {
|
||||
invalidParams.Add(smithy.NewErrParamRequired("GrantType"))
|
||||
}
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func validateOpCreateOAuth2TokenInput(v *CreateOAuth2TokenInput) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
invalidParams := smithy.InvalidParamsError{Context: "CreateOAuth2TokenInput"}
|
||||
if v.TokenInput == nil {
|
||||
invalidParams.Add(smithy.NewErrParamRequired("TokenInput"))
|
||||
} else if v.TokenInput != nil {
|
||||
if err := validateCreateOAuth2TokenRequestBody(v.TokenInput); err != nil {
|
||||
invalidParams.AddNested("TokenInput", err.(smithy.InvalidParamsError))
|
||||
}
|
||||
}
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
+25
@@ -1,3 +1,28 @@
|
||||
# v1.30.9 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.30.8 (2025-12-16)
|
||||
|
||||
* No change notes available for this release.
|
||||
|
||||
# v1.30.7 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.30.6 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.30.5 (2025-11-25)
|
||||
|
||||
* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234
|
||||
|
||||
# v1.30.4 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.30.3 (2025-11-12)
|
||||
|
||||
* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use.
|
||||
|
||||
+11
-5
@@ -16,8 +16,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) {
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error {
|
||||
params.Region = options.Region
|
||||
return nil
|
||||
}
|
||||
|
||||
type setLegacyContextSigningOptionsMiddleware struct {
|
||||
@@ -94,14 +95,16 @@ type AuthResolverParameters struct {
|
||||
Region string
|
||||
}
|
||||
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters {
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) {
|
||||
params := &AuthResolverParameters{
|
||||
Operation: operation,
|
||||
}
|
||||
|
||||
bindAuthParamsRegion(ctx, params, input, options)
|
||||
if err := bindAuthParamsRegion(ctx, params, input, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// AuthSchemeResolver returns a set of possible authentication options for an
|
||||
@@ -176,7 +179,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
|
||||
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
|
||||
defer span.End()
|
||||
|
||||
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("bind auth scheme params: %w", err)
|
||||
}
|
||||
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import (
|
||||
internalendpoints "github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
smithyendpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/aws/smithy-go/endpoints/private/rulesfn"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/ptr"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
@@ -221,7 +222,7 @@ func bindRegion(region string) (*string, error) {
|
||||
if region == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !smithyhttp.ValidHostLabel(region) {
|
||||
if !rulesfn.IsValidHostLabel(region, true) {
|
||||
return nil, fmt.Errorf("invalid input region %s", region)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package sso
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.30.3"
|
||||
const goModuleVersion = "1.30.9"
|
||||
|
||||
+17
@@ -157,6 +157,9 @@ var defaultPartitions = endpoints.Partitions{
|
||||
Region: "ap-east-1",
|
||||
},
|
||||
},
|
||||
endpoints.EndpointKey{
|
||||
Region: "ap-east-2",
|
||||
}: endpoints.Endpoint{},
|
||||
endpoints.EndpointKey{
|
||||
Region: "ap-northeast-1",
|
||||
}: endpoints.Endpoint{
|
||||
@@ -445,6 +448,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
{
|
||||
ID: "aws-eusc",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "portal.sso.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
@@ -452,6 +462,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "portal.sso-fips.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
|
||||
+25
@@ -1,3 +1,28 @@
|
||||
# v1.35.13 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.35.12 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.35.11 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.35.10 (2025-11-25)
|
||||
|
||||
* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234
|
||||
|
||||
# v1.35.9 (2025-11-21)
|
||||
|
||||
* No change notes available for this release.
|
||||
|
||||
# v1.35.8 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.35.7 (2025-11-12)
|
||||
|
||||
* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use.
|
||||
|
||||
+11
-5
@@ -16,8 +16,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) {
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error {
|
||||
params.Region = options.Region
|
||||
return nil
|
||||
}
|
||||
|
||||
type setLegacyContextSigningOptionsMiddleware struct {
|
||||
@@ -94,14 +95,16 @@ type AuthResolverParameters struct {
|
||||
Region string
|
||||
}
|
||||
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters {
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) {
|
||||
params := &AuthResolverParameters{
|
||||
Operation: operation,
|
||||
}
|
||||
|
||||
bindAuthParamsRegion(ctx, params, input, options)
|
||||
if err := bindAuthParamsRegion(ctx, params, input, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// AuthSchemeResolver returns a set of possible authentication options for an
|
||||
@@ -170,7 +173,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
|
||||
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
|
||||
defer span.End()
|
||||
|
||||
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("bind auth scheme params: %w", err)
|
||||
}
|
||||
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import (
|
||||
internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
smithyendpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/aws/smithy-go/endpoints/private/rulesfn"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/ptr"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
@@ -221,7 +222,7 @@ func bindRegion(region string) (*string, error) {
|
||||
if region == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !smithyhttp.ValidHostLabel(region) {
|
||||
if !rulesfn.IsValidHostLabel(region, true) {
|
||||
return nil, fmt.Errorf("invalid input region %s", region)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package ssooidc
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.35.7"
|
||||
const goModuleVersion = "1.35.13"
|
||||
|
||||
Generated
Vendored
+17
@@ -157,6 +157,9 @@ var defaultPartitions = endpoints.Partitions{
|
||||
Region: "ap-east-1",
|
||||
},
|
||||
},
|
||||
endpoints.EndpointKey{
|
||||
Region: "ap-east-2",
|
||||
}: endpoints.Endpoint{},
|
||||
endpoints.EndpointKey{
|
||||
Region: "ap-northeast-1",
|
||||
}: endpoints.Endpoint{
|
||||
@@ -445,6 +448,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
{
|
||||
ID: "aws-eusc",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "oidc.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
@@ -452,6 +462,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "oidc-fips.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
|
||||
+29
@@ -1,3 +1,32 @@
|
||||
# v1.41.6 (2026-01-09)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.41.5 (2025-12-09)
|
||||
|
||||
* No change notes available for this release.
|
||||
|
||||
# v1.41.4 (2025-12-08)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.41.3 (2025-12-02)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change.
|
||||
|
||||
# v1.41.2 (2025-11-25)
|
||||
|
||||
* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234
|
||||
|
||||
# v1.41.1 (2025-11-19.2)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.41.0 (2025-11-19)
|
||||
|
||||
* **Feature**: IAM now supports outbound identity federation via the STS GetWebIdentityToken API, enabling AWS workloads to securely authenticate with external services using short-lived JSON Web Tokens.
|
||||
|
||||
# v1.40.2 (2025-11-12)
|
||||
|
||||
* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use.
|
||||
|
||||
Generated
Vendored
+13
-4
@@ -11,7 +11,10 @@ import (
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
)
|
||||
|
||||
// This API is currently unavailable for general use.
|
||||
// Exchanges a trade-in token for temporary Amazon Web Services credentials with
|
||||
// the permissions associated with the assumed principal. This operation allows you
|
||||
// to obtain credentials for a specific principal based on a trade-in token,
|
||||
// enabling delegation of access to Amazon Web Services resources.
|
||||
func (c *Client) GetDelegatedAccessToken(ctx context.Context, params *GetDelegatedAccessTokenInput, optFns ...func(*Options)) (*GetDelegatedAccessTokenOutput, error) {
|
||||
if params == nil {
|
||||
params = &GetDelegatedAccessTokenInput{}
|
||||
@@ -29,7 +32,8 @@ func (c *Client) GetDelegatedAccessToken(ctx context.Context, params *GetDelegat
|
||||
|
||||
type GetDelegatedAccessTokenInput struct {
|
||||
|
||||
//
|
||||
// The token to exchange for temporary Amazon Web Services credentials. This token
|
||||
// must be valid and unexpired at the time of the request.
|
||||
//
|
||||
// This member is required.
|
||||
TradeInToken *string
|
||||
@@ -39,13 +43,18 @@ type GetDelegatedAccessTokenInput struct {
|
||||
|
||||
type GetDelegatedAccessTokenOutput struct {
|
||||
|
||||
//
|
||||
// The Amazon Resource Name (ARN) of the principal that was assumed when obtaining
|
||||
// the delegated access token. This ARN identifies the IAM entity whose permissions
|
||||
// are granted by the temporary credentials.
|
||||
AssumedPrincipal *string
|
||||
|
||||
// Amazon Web Services credentials for API authentication.
|
||||
Credentials *types.Credentials
|
||||
|
||||
//
|
||||
// The percentage of the maximum policy size that is used by the session policy.
|
||||
// The policy size is calculated as the sum of all the session policies and
|
||||
// permission boundaries attached to the session. If the packed size exceeds 100%,
|
||||
// the request fails.
|
||||
PackedPolicySize *int32
|
||||
|
||||
// Metadata pertaining to the operation's result.
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
// Code generated by smithy-go-codegen DO NOT EDIT.
|
||||
|
||||
package sts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sts/types"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Returns a signed JSON Web Token (JWT) that represents the calling Amazon Web
|
||||
// Services identity. The returned JWT can be used to authenticate with external
|
||||
// services that support OIDC discovery. The token is signed by Amazon Web Services
|
||||
// STS and can be publicly verified using the verification keys published at the
|
||||
// issuer's JWKS endpoint.
|
||||
func (c *Client) GetWebIdentityToken(ctx context.Context, params *GetWebIdentityTokenInput, optFns ...func(*Options)) (*GetWebIdentityTokenOutput, error) {
|
||||
if params == nil {
|
||||
params = &GetWebIdentityTokenInput{}
|
||||
}
|
||||
|
||||
result, metadata, err := c.invokeOperation(ctx, "GetWebIdentityToken", params, optFns, c.addOperationGetWebIdentityTokenMiddlewares)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := result.(*GetWebIdentityTokenOutput)
|
||||
out.ResultMetadata = metadata
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type GetWebIdentityTokenInput struct {
|
||||
|
||||
// The intended recipient of the web identity token. This value populates the aud
|
||||
// claim in the JWT and should identify the service or application that will
|
||||
// validate and use the token. The external service should verify this claim to
|
||||
// ensure the token was intended for their use.
|
||||
//
|
||||
// This member is required.
|
||||
Audience []string
|
||||
|
||||
// The cryptographic algorithm to use for signing the JSON Web Token (JWT). Valid
|
||||
// values are RS256 (RSA with SHA-256) and ES384 (ECDSA using P-384 curve with
|
||||
// SHA-384).
|
||||
//
|
||||
// This member is required.
|
||||
SigningAlgorithm *string
|
||||
|
||||
// The duration, in seconds, for which the JSON Web Token (JWT) will remain valid.
|
||||
// The value can range from 60 seconds (1 minute) to 3600 seconds (1 hour). If not
|
||||
// specified, the default duration is 300 seconds (5 minutes). The token is
|
||||
// designed to be short-lived and should be used for proof of identity, then
|
||||
// exchanged for credentials or short-lived tokens in the external service.
|
||||
DurationSeconds *int32
|
||||
|
||||
// An optional list of tags to include in the JSON Web Token (JWT). These tags are
|
||||
// added as custom claims to the JWT and can be used by the downstream service for
|
||||
// authorization decisions.
|
||||
Tags []types.Tag
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
type GetWebIdentityTokenOutput struct {
|
||||
|
||||
// The date and time when the web identity token expires, in UTC. The expiration
|
||||
// is determined by adding the DurationSeconds value to the time the token was
|
||||
// issued. After this time, the token should no longer be considered valid.
|
||||
Expiration *time.Time
|
||||
|
||||
// A signed JSON Web Token (JWT) that represents the caller's Amazon Web Services
|
||||
// identity. The token contains standard JWT claims such as subject, audience,
|
||||
// expiration time, and additional identity attributes added by STS as custom
|
||||
// claims. You can also add your own custom claims to the token by passing tags as
|
||||
// request parameters to the GetWebIdentityToken API. The token is signed using
|
||||
// the specified signing algorithm and can be verified using the verification keys
|
||||
// available at the issuer's JWKS endpoint.
|
||||
WebIdentityToken *string
|
||||
|
||||
// Metadata pertaining to the operation's result.
|
||||
ResultMetadata middleware.Metadata
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.Stack, options Options) (err error) {
|
||||
if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
|
||||
return err
|
||||
}
|
||||
err = stack.Serialize.Add(&awsAwsquery_serializeOpGetWebIdentityToken{}, middleware.After)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetWebIdentityToken{}, middleware.After)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addProtocolFinalizerMiddlewares(stack, options, "GetWebIdentityToken"); err != nil {
|
||||
return fmt.Errorf("add protocol finalizers: %v", err)
|
||||
}
|
||||
|
||||
if err = addlegacyEndpointContextSetter(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSetLoggerMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addClientRequestID(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addComputeContentLength(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addResolveEndpointMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addComputePayloadSHA256(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRetry(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRawResponseToMetadata(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRecordResponseTiming(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSpanRetryLoop(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addClientUserAgent(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addTimeOffsetBuild(stack, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addUserAgentRetryMode(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addCredentialSource(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addOpGetWebIdentityTokenValidationMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetWebIdentityToken(options.Region), middleware.Before); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRecursionDetection(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addResponseErrorMiddleware(stack); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addRequestResponseLogging(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptBeforeRetryLoop(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptAttempt(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = addInterceptors(stack, options); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newServiceMetadataMiddleware_opGetWebIdentityToken(region string) *awsmiddleware.RegisterServiceMetadata {
|
||||
return &awsmiddleware.RegisterServiceMetadata{
|
||||
Region: region,
|
||||
ServiceID: ServiceID,
|
||||
OperationName: "GetWebIdentityToken",
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -16,8 +16,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) {
|
||||
func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error {
|
||||
params.Region = options.Region
|
||||
return nil
|
||||
}
|
||||
|
||||
type setLegacyContextSigningOptionsMiddleware struct {
|
||||
@@ -94,14 +95,16 @@ type AuthResolverParameters struct {
|
||||
Region string
|
||||
}
|
||||
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters {
|
||||
func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) {
|
||||
params := &AuthResolverParameters{
|
||||
Operation: operation,
|
||||
}
|
||||
|
||||
bindAuthParamsRegion(ctx, params, input, options)
|
||||
if err := bindAuthParamsRegion(ctx, params, input, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params
|
||||
return params, nil
|
||||
}
|
||||
|
||||
// AuthSchemeResolver returns a set of possible authentication options for an
|
||||
@@ -164,7 +167,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
|
||||
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
|
||||
defer span.End()
|
||||
|
||||
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("bind auth scheme params: %w", err)
|
||||
}
|
||||
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
|
||||
if err != nil {
|
||||
return out, metadata, fmt.Errorf("resolve auth scheme: %w", err)
|
||||
|
||||
+466
@@ -948,6 +948,9 @@ func awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response *smithyhttp.
|
||||
case strings.EqualFold("ExpiredTradeInTokenException", errorCode):
|
||||
return awsAwsquery_deserializeErrorExpiredTradeInTokenException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("PackedPolicyTooLarge", errorCode):
|
||||
return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("RegionDisabledException", errorCode):
|
||||
return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody)
|
||||
|
||||
@@ -1191,6 +1194,124 @@ func awsAwsquery_deserializeOpErrorGetSessionToken(response *smithyhttp.Response
|
||||
}
|
||||
}
|
||||
|
||||
type awsAwsquery_deserializeOpGetWebIdentityToken struct {
|
||||
}
|
||||
|
||||
func (*awsAwsquery_deserializeOpGetWebIdentityToken) ID() string {
|
||||
return "OperationDeserializer"
|
||||
}
|
||||
|
||||
func (m *awsAwsquery_deserializeOpGetWebIdentityToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
|
||||
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
out, metadata, err = next.HandleDeserialize(ctx, in)
|
||||
if err != nil {
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
|
||||
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
|
||||
defer endTimer()
|
||||
defer span.End()
|
||||
response, ok := out.RawResponse.(*smithyhttp.Response)
|
||||
if !ok {
|
||||
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
|
||||
}
|
||||
|
||||
if response.StatusCode < 200 || response.StatusCode >= 300 {
|
||||
return out, metadata, awsAwsquery_deserializeOpErrorGetWebIdentityToken(response, &metadata)
|
||||
}
|
||||
output := &GetWebIdentityTokenOutput{}
|
||||
out.Result = output
|
||||
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
body := io.TeeReader(response.Body, ringBuffer)
|
||||
rootDecoder := xml.NewDecoder(body)
|
||||
t, err := smithyxml.FetchRootElement(rootDecoder)
|
||||
if err == io.EOF {
|
||||
return out, metadata, nil
|
||||
}
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return out, metadata, &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder := smithyxml.WrapNodeDecoder(rootDecoder, t)
|
||||
t, err = decoder.GetElement("GetWebIdentityTokenResult")
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t)
|
||||
err = awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(&output, decoder)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
err = &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
return out, metadata, err
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeOpErrorGetWebIdentityToken(response *smithyhttp.Response, metadata *middleware.Metadata) error {
|
||||
var errorBuffer bytes.Buffer
|
||||
if _, err := io.Copy(&errorBuffer, response.Body); err != nil {
|
||||
return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)}
|
||||
}
|
||||
errorBody := bytes.NewReader(errorBuffer.Bytes())
|
||||
|
||||
errorCode := "UnknownError"
|
||||
errorMessage := errorCode
|
||||
|
||||
errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if reqID := errorComponents.RequestID; len(reqID) != 0 {
|
||||
awsmiddleware.SetRequestIDMetadata(metadata, reqID)
|
||||
}
|
||||
if len(errorComponents.Code) != 0 {
|
||||
errorCode = errorComponents.Code
|
||||
}
|
||||
if len(errorComponents.Message) != 0 {
|
||||
errorMessage = errorComponents.Message
|
||||
}
|
||||
errorBody.Seek(0, io.SeekStart)
|
||||
switch {
|
||||
case strings.EqualFold("JWTPayloadSizeExceededException", errorCode):
|
||||
return awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("OutboundWebIdentityFederationDisabledException", errorCode):
|
||||
return awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response, errorBody)
|
||||
|
||||
case strings.EqualFold("SessionDurationEscalationException", errorCode):
|
||||
return awsAwsquery_deserializeErrorSessionDurationEscalationException(response, errorBody)
|
||||
|
||||
default:
|
||||
genericError := &smithy.GenericAPIError{
|
||||
Code: errorCode,
|
||||
Message: errorMessage,
|
||||
}
|
||||
return genericError
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.ExpiredTokenException{}
|
||||
var buff [1024]byte
|
||||
@@ -1455,6 +1576,50 @@ func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyh
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.JWTPayloadSizeExceededException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
rootDecoder := xml.NewDecoder(body)
|
||||
t, err := smithyxml.FetchRootElement(rootDecoder)
|
||||
if err == io.EOF {
|
||||
return output
|
||||
}
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder := smithyxml.WrapNodeDecoder(rootDecoder, t)
|
||||
t, err = decoder.GetElement("Error")
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t)
|
||||
err = awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(&output, decoder)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.MalformedPolicyDocumentException{}
|
||||
var buff [1024]byte
|
||||
@@ -1499,6 +1664,50 @@ func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smit
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.OutboundWebIdentityFederationDisabledException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
rootDecoder := xml.NewDecoder(body)
|
||||
t, err := smithyxml.FetchRootElement(rootDecoder)
|
||||
if err == io.EOF {
|
||||
return output
|
||||
}
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder := smithyxml.WrapNodeDecoder(rootDecoder, t)
|
||||
t, err = decoder.GetElement("Error")
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t)
|
||||
err = awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(&output, decoder)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.PackedPolicyTooLargeException{}
|
||||
var buff [1024]byte
|
||||
@@ -1587,6 +1796,50 @@ func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Re
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeErrorSessionDurationEscalationException(response *smithyhttp.Response, errorBody *bytes.Reader) error {
|
||||
output := &types.SessionDurationEscalationException{}
|
||||
var buff [1024]byte
|
||||
ringBuffer := smithyio.NewRingBuffer(buff[:])
|
||||
body := io.TeeReader(errorBody, ringBuffer)
|
||||
rootDecoder := xml.NewDecoder(body)
|
||||
t, err := smithyxml.FetchRootElement(rootDecoder)
|
||||
if err == io.EOF {
|
||||
return output
|
||||
}
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder := smithyxml.WrapNodeDecoder(rootDecoder, t)
|
||||
t, err = decoder.GetElement("Error")
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t)
|
||||
err = awsAwsquery_deserializeDocumentSessionDurationEscalationException(&output, decoder)
|
||||
if err != nil {
|
||||
var snapshot bytes.Buffer
|
||||
io.Copy(&snapshot, ringBuffer)
|
||||
return &smithy.DeserializationError{
|
||||
Err: fmt.Errorf("failed to decode response body, %w", err),
|
||||
Snapshot: snapshot.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentAssumedRoleUser(v **types.AssumedRoleUser, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
@@ -2097,6 +2350,55 @@ func awsAwsquery_deserializeDocumentInvalidIdentityTokenException(v **types.Inva
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(v **types.JWTPayloadSizeExceededException, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
var sv *types.JWTPayloadSizeExceededException
|
||||
if *v == nil {
|
||||
sv = &types.JWTPayloadSizeExceededException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for {
|
||||
t, done, err := decoder.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
originalDecoder := decoder
|
||||
decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t)
|
||||
switch {
|
||||
case strings.EqualFold("message", t.Name.Local):
|
||||
val, err := decoder.Value()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == nil {
|
||||
break
|
||||
}
|
||||
{
|
||||
xtv := string(val)
|
||||
sv.Message = ptr.String(xtv)
|
||||
}
|
||||
|
||||
default:
|
||||
// Do nothing and ignore the unexpected tag element
|
||||
err = decoder.Decoder.Skip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
decoder = originalDecoder
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.MalformedPolicyDocumentException, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
@@ -2146,6 +2448,55 @@ func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.M
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(v **types.OutboundWebIdentityFederationDisabledException, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
var sv *types.OutboundWebIdentityFederationDisabledException
|
||||
if *v == nil {
|
||||
sv = &types.OutboundWebIdentityFederationDisabledException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for {
|
||||
t, done, err := decoder.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
originalDecoder := decoder
|
||||
decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t)
|
||||
switch {
|
||||
case strings.EqualFold("message", t.Name.Local):
|
||||
val, err := decoder.Value()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == nil {
|
||||
break
|
||||
}
|
||||
{
|
||||
xtv := string(val)
|
||||
sv.Message = ptr.String(xtv)
|
||||
}
|
||||
|
||||
default:
|
||||
// Do nothing and ignore the unexpected tag element
|
||||
err = decoder.Decoder.Skip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
decoder = originalDecoder
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(v **types.PackedPolicyTooLargeException, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
@@ -2244,6 +2595,55 @@ func awsAwsquery_deserializeDocumentRegionDisabledException(v **types.RegionDisa
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeDocumentSessionDurationEscalationException(v **types.SessionDurationEscalationException, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
var sv *types.SessionDurationEscalationException
|
||||
if *v == nil {
|
||||
sv = &types.SessionDurationEscalationException{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for {
|
||||
t, done, err := decoder.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
originalDecoder := decoder
|
||||
decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t)
|
||||
switch {
|
||||
case strings.EqualFold("message", t.Name.Local):
|
||||
val, err := decoder.Value()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == nil {
|
||||
break
|
||||
}
|
||||
{
|
||||
xtv := string(val)
|
||||
sv.Message = ptr.String(xtv)
|
||||
}
|
||||
|
||||
default:
|
||||
// Do nothing and ignore the unexpected tag element
|
||||
err = decoder.Decoder.Skip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
decoder = originalDecoder
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeOpDocumentAssumeRoleOutput(v **AssumeRoleOutput, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
@@ -2988,3 +3388,69 @@ func awsAwsquery_deserializeOpDocumentGetSessionTokenOutput(v **GetSessionTokenO
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(v **GetWebIdentityTokenOutput, decoder smithyxml.NodeDecoder) error {
|
||||
if v == nil {
|
||||
return fmt.Errorf("unexpected nil of type %T", v)
|
||||
}
|
||||
var sv *GetWebIdentityTokenOutput
|
||||
if *v == nil {
|
||||
sv = &GetWebIdentityTokenOutput{}
|
||||
} else {
|
||||
sv = *v
|
||||
}
|
||||
|
||||
for {
|
||||
t, done, err := decoder.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
originalDecoder := decoder
|
||||
decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t)
|
||||
switch {
|
||||
case strings.EqualFold("Expiration", t.Name.Local):
|
||||
val, err := decoder.Value()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == nil {
|
||||
break
|
||||
}
|
||||
{
|
||||
xtv := string(val)
|
||||
t, err := smithytime.ParseDateTime(xtv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sv.Expiration = ptr.Time(t)
|
||||
}
|
||||
|
||||
case strings.EqualFold("WebIdentityToken", t.Name.Local):
|
||||
val, err := decoder.Value()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val == nil {
|
||||
break
|
||||
}
|
||||
{
|
||||
xtv := string(val)
|
||||
sv.WebIdentityToken = ptr.String(xtv)
|
||||
}
|
||||
|
||||
default:
|
||||
// Do nothing and ignore the unexpected tag element
|
||||
err = decoder.Decoder.Skip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
decoder = originalDecoder
|
||||
}
|
||||
*v = sv
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@ import (
|
||||
smithy "github.com/aws/smithy-go"
|
||||
smithyauth "github.com/aws/smithy-go/auth"
|
||||
smithyendpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/aws/smithy-go/endpoints/private/rulesfn"
|
||||
"github.com/aws/smithy-go/middleware"
|
||||
"github.com/aws/smithy-go/ptr"
|
||||
"github.com/aws/smithy-go/tracing"
|
||||
@@ -222,7 +223,7 @@ func bindRegion(region string) (*string, error) {
|
||||
if region == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if !smithyhttp.ValidHostLabel(region) {
|
||||
if !rulesfn.IsValidHostLabel(region, true) {
|
||||
return nil, fmt.Errorf("invalid input region %s", region)
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -20,6 +20,7 @@
|
||||
"api_op_GetDelegatedAccessToken.go",
|
||||
"api_op_GetFederationToken.go",
|
||||
"api_op_GetSessionToken.go",
|
||||
"api_op_GetWebIdentityToken.go",
|
||||
"auth.go",
|
||||
"deserializers.go",
|
||||
"doc.go",
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package sts
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.40.2"
|
||||
const goModuleVersion = "1.41.6"
|
||||
|
||||
+19
@@ -359,6 +359,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
{
|
||||
ID: "aws-eusc",
|
||||
Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{
|
||||
{
|
||||
Variant: endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "sts.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant,
|
||||
}: {
|
||||
@@ -366,6 +373,13 @@ var defaultPartitions = endpoints.Partitions{
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: endpoints.FIPSVariant | endpoints.DualStackVariant,
|
||||
}: {
|
||||
Hostname: "sts-fips.{region}.api.amazonwebservices.eu",
|
||||
Protocols: []string{"https"},
|
||||
SignatureVersions: []string{"v4"},
|
||||
},
|
||||
{
|
||||
Variant: 0,
|
||||
}: {
|
||||
@@ -376,6 +390,11 @@ var defaultPartitions = endpoints.Partitions{
|
||||
},
|
||||
RegionRegex: partitionRegexp.AwsEusc,
|
||||
IsRegionalized: true,
|
||||
Endpoints: endpoints.Endpoints{
|
||||
endpoints.EndpointKey{
|
||||
Region: "eusc-de-east-1",
|
||||
}: endpoints.Endpoint{},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "aws-iso",
|
||||
|
||||
+111
@@ -711,6 +711,76 @@ func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Con
|
||||
span.End()
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
|
||||
type awsAwsquery_serializeOpGetWebIdentityToken struct {
|
||||
}
|
||||
|
||||
func (*awsAwsquery_serializeOpGetWebIdentityToken) ID() string {
|
||||
return "OperationSerializer"
|
||||
}
|
||||
|
||||
func (m *awsAwsquery_serializeOpGetWebIdentityToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
|
||||
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
_, span := tracing.StartSpan(ctx, "OperationSerializer")
|
||||
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
|
||||
defer endTimer()
|
||||
defer span.End()
|
||||
request, ok := in.Request.(*smithyhttp.Request)
|
||||
if !ok {
|
||||
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
|
||||
}
|
||||
|
||||
input, ok := in.Parameters.(*GetWebIdentityTokenInput)
|
||||
_ = input
|
||||
if !ok {
|
||||
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)}
|
||||
}
|
||||
|
||||
operationPath := "/"
|
||||
if len(request.Request.URL.Path) == 0 {
|
||||
request.Request.URL.Path = operationPath
|
||||
} else {
|
||||
request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath)
|
||||
if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' {
|
||||
request.Request.URL.Path += "/"
|
||||
}
|
||||
}
|
||||
request.Request.Method = "POST"
|
||||
httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header)
|
||||
if err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded")
|
||||
|
||||
bodyWriter := bytes.NewBuffer(nil)
|
||||
bodyEncoder := query.NewEncoder(bodyWriter)
|
||||
body := bodyEncoder.Object()
|
||||
body.Key("Action").String("GetWebIdentityToken")
|
||||
body.Key("Version").String("2011-06-15")
|
||||
|
||||
if err := awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(input, bodyEncoder.Value); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
|
||||
err = bodyEncoder.Encode()
|
||||
if err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
|
||||
if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
|
||||
if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil {
|
||||
return out, metadata, &smithy.SerializationError{Err: err}
|
||||
}
|
||||
in.Request = request
|
||||
|
||||
endTimer()
|
||||
span.End()
|
||||
return next.HandleSerialize(ctx, in)
|
||||
}
|
||||
func awsAwsquery_serializeDocumentPolicyDescriptorListType(v []types.PolicyDescriptorType, value query.Value) error {
|
||||
array := value.Array("member")
|
||||
|
||||
@@ -803,6 +873,16 @@ func awsAwsquery_serializeDocumentTagListType(v []types.Tag, value query.Value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v []string, value query.Value) error {
|
||||
array := value.Array("member")
|
||||
|
||||
for i := range v {
|
||||
av := array.Value()
|
||||
av.String(v[i])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_serializeOpDocumentAssumeRoleInput(v *AssumeRoleInput, value query.Value) error {
|
||||
object := value.Object()
|
||||
_ = object
|
||||
@@ -1085,3 +1165,34 @@ func awsAwsquery_serializeOpDocumentGetSessionTokenInput(v *GetSessionTokenInput
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(v *GetWebIdentityTokenInput, value query.Value) error {
|
||||
object := value.Object()
|
||||
_ = object
|
||||
|
||||
if v.Audience != nil {
|
||||
objectKey := object.Key("Audience")
|
||||
if err := awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v.Audience, objectKey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v.DurationSeconds != nil {
|
||||
objectKey := object.Key("DurationSeconds")
|
||||
objectKey.Integer(*v.DurationSeconds)
|
||||
}
|
||||
|
||||
if v.SigningAlgorithm != nil {
|
||||
objectKey := object.Key("SigningAlgorithm")
|
||||
objectKey.String(*v.SigningAlgorithm)
|
||||
}
|
||||
|
||||
if v.Tags != nil {
|
||||
objectKey := object.Key("Tags")
|
||||
if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+90
@@ -34,6 +34,8 @@ func (e *ExpiredTokenException) ErrorCode() string {
|
||||
}
|
||||
func (e *ExpiredTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// The trade-in token provided in the request has expired and can no longer be
|
||||
// exchanged for credentials. Request a new token and retry the operation.
|
||||
type ExpiredTradeInTokenException struct {
|
||||
Message *string
|
||||
|
||||
@@ -177,6 +179,34 @@ func (e *InvalidIdentityTokenException) ErrorCode() string {
|
||||
}
|
||||
func (e *InvalidIdentityTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// The requested token payload size exceeds the maximum allowed size. Reduce the
|
||||
// number of request tags included in the GetWebIdentityToken API call to reduce
|
||||
// the token payload size.
|
||||
type JWTPayloadSizeExceededException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *JWTPayloadSizeExceededException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *JWTPayloadSizeExceededException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *JWTPayloadSizeExceededException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "JWTPayloadSizeExceededException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *JWTPayloadSizeExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// The request was rejected because the policy document was malformed. The error
|
||||
// message describes the specific error.
|
||||
type MalformedPolicyDocumentException struct {
|
||||
@@ -204,6 +234,36 @@ func (e *MalformedPolicyDocumentException) ErrorCode() string {
|
||||
}
|
||||
func (e *MalformedPolicyDocumentException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// The outbound web identity federation feature is not enabled for this account.
|
||||
// To use this feature, you must first enable it through the Amazon Web Services
|
||||
// Management Console or API.
|
||||
type OutboundWebIdentityFederationDisabledException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *OutboundWebIdentityFederationDisabledException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *OutboundWebIdentityFederationDisabledException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *OutboundWebIdentityFederationDisabledException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "OutboundWebIdentityFederationDisabledException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *OutboundWebIdentityFederationDisabledException) ErrorFault() smithy.ErrorFault {
|
||||
return smithy.FaultClient
|
||||
}
|
||||
|
||||
// The request was rejected because the total packed size of the session policies
|
||||
// and session tags combined was too large. An Amazon Web Services conversion
|
||||
// compresses the session policy document, session policy ARNs, and session tags
|
||||
@@ -271,3 +331,33 @@ func (e *RegionDisabledException) ErrorCode() string {
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *RegionDisabledException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
|
||||
|
||||
// The requested token duration would extend the session beyond its original
|
||||
// expiration time. You cannot use this operation to extend the lifetime of a
|
||||
// session beyond what was granted when the session was originally created.
|
||||
type SessionDurationEscalationException struct {
|
||||
Message *string
|
||||
|
||||
ErrorCodeOverride *string
|
||||
|
||||
noSmithyDocumentSerde
|
||||
}
|
||||
|
||||
func (e *SessionDurationEscalationException) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage())
|
||||
}
|
||||
func (e *SessionDurationEscalationException) ErrorMessage() string {
|
||||
if e.Message == nil {
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
||||
func (e *SessionDurationEscalationException) ErrorCode() string {
|
||||
if e == nil || e.ErrorCodeOverride == nil {
|
||||
return "SessionDurationEscalationException"
|
||||
}
|
||||
return *e.ErrorCodeOverride
|
||||
}
|
||||
func (e *SessionDurationEscalationException) ErrorFault() smithy.ErrorFault {
|
||||
return smithy.FaultClient
|
||||
}
|
||||
|
||||
+47
@@ -170,6 +170,26 @@ func (m *validateOpGetFederationToken) HandleInitialize(ctx context.Context, in
|
||||
return next.HandleInitialize(ctx, in)
|
||||
}
|
||||
|
||||
type validateOpGetWebIdentityToken struct {
|
||||
}
|
||||
|
||||
func (*validateOpGetWebIdentityToken) ID() string {
|
||||
return "OperationInputValidation"
|
||||
}
|
||||
|
||||
func (m *validateOpGetWebIdentityToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
|
||||
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
|
||||
) {
|
||||
input, ok := in.Parameters.(*GetWebIdentityTokenInput)
|
||||
if !ok {
|
||||
return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters)
|
||||
}
|
||||
if err := validateOpGetWebIdentityTokenInput(input); err != nil {
|
||||
return out, metadata, err
|
||||
}
|
||||
return next.HandleInitialize(ctx, in)
|
||||
}
|
||||
|
||||
func addOpAssumeRoleValidationMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Initialize.Add(&validateOpAssumeRole{}, middleware.After)
|
||||
}
|
||||
@@ -202,6 +222,10 @@ func addOpGetFederationTokenValidationMiddleware(stack *middleware.Stack) error
|
||||
return stack.Initialize.Add(&validateOpGetFederationToken{}, middleware.After)
|
||||
}
|
||||
|
||||
func addOpGetWebIdentityTokenValidationMiddleware(stack *middleware.Stack) error {
|
||||
return stack.Initialize.Add(&validateOpGetWebIdentityToken{}, middleware.After)
|
||||
}
|
||||
|
||||
func validateTag(v *types.Tag) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
@@ -384,3 +408,26 @@ func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func validateOpGetWebIdentityTokenInput(v *GetWebIdentityTokenInput) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
invalidParams := smithy.InvalidParamsError{Context: "GetWebIdentityTokenInput"}
|
||||
if v.Audience == nil {
|
||||
invalidParams.Add(smithy.NewErrParamRequired("Audience"))
|
||||
}
|
||||
if v.SigningAlgorithm == nil {
|
||||
invalidParams.Add(smithy.NewErrParamRequired("SigningAlgorithm"))
|
||||
}
|
||||
if v.Tags != nil {
|
||||
if err := validateTagListType(v.Tags); err != nil {
|
||||
invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError))
|
||||
}
|
||||
}
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -1,3 +1,12 @@
|
||||
# Release (2025-12-01)
|
||||
|
||||
## General Highlights
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
## Module Highlights
|
||||
* `github.com/aws/smithy-go`: v1.24.0
|
||||
* **Feature**: Improve allocation footprint of the middleware stack. This should convey a ~10% reduction in allocations per SDK request.
|
||||
|
||||
# Release (2025-11-03)
|
||||
|
||||
## General Highlights
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// Package rulesfn provides endpoint rule functions for evaluating endpoint
|
||||
// resolution rules.
|
||||
|
||||
package rulesfn
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package rulesfn
|
||||
|
||||
// Substring returns the substring of the input provided. If the start or stop
|
||||
// indexes are not valid for the input nil will be returned. If errors occur
|
||||
// they will be added to the provided [ErrorCollector].
|
||||
func SubString(input string, start, stop int, reverse bool) *string {
|
||||
if start < 0 || stop < 1 || start >= stop || len(input) < stop {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, r := range input {
|
||||
if r > 127 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if !reverse {
|
||||
v := input[start:stop]
|
||||
return &v
|
||||
}
|
||||
|
||||
rStart := len(input) - stop
|
||||
rStop := len(input) - start
|
||||
return SubString(input, rStart, rStop, false)
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package rulesfn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
)
|
||||
|
||||
// IsValidHostLabel returns if the input is a single valid [RFC 1123] host
|
||||
// label. If allowSubDomains is true, will allow validation to include nested
|
||||
// host labels. Returns false if the input is not a valid host label. If errors
|
||||
// occur they will be added to the provided [ErrorCollector].
|
||||
//
|
||||
// [RFC 1123]: https://www.ietf.org/rfc/rfc1123.txt
|
||||
func IsValidHostLabel(input string, allowSubDomains bool) bool {
|
||||
var labels []string
|
||||
if allowSubDomains {
|
||||
labels = strings.Split(input, ".")
|
||||
} else {
|
||||
labels = []string{input}
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
if !smithyhttp.ValidHostLabel(label) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ParseURL returns a [URL] if the provided string could be parsed. Returns nil
|
||||
// if the string could not be parsed. Any parsing error will be added to the
|
||||
// [ErrorCollector].
|
||||
//
|
||||
// If the input URL string contains an IP6 address with a zone index. The
|
||||
// returned [builtin.URL.Authority] value will contain the percent escaped (%)
|
||||
// zone index separator.
|
||||
func ParseURL(input string) *URL {
|
||||
u, err := url.Parse(input)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if u.RawQuery != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if u.Scheme != "http" && u.Scheme != "https" {
|
||||
return nil
|
||||
}
|
||||
|
||||
normalizedPath := u.Path
|
||||
if !strings.HasPrefix(normalizedPath, "/") {
|
||||
normalizedPath = "/" + normalizedPath
|
||||
}
|
||||
if !strings.HasSuffix(normalizedPath, "/") {
|
||||
normalizedPath = normalizedPath + "/"
|
||||
}
|
||||
|
||||
// IP6 hosts may have zone indexes that need to be escaped to be valid in a
|
||||
// URI. The Go URL parser will unescape the `%25` into `%`. This needs to
|
||||
// be reverted since the returned URL will be used in string builders.
|
||||
authority := strings.ReplaceAll(u.Host, "%", "%25")
|
||||
|
||||
return &URL{
|
||||
Scheme: u.Scheme,
|
||||
Authority: authority,
|
||||
Path: u.Path,
|
||||
NormalizedPath: normalizedPath,
|
||||
IsIp: net.ParseIP(hostnameWithoutZone(u)) != nil,
|
||||
}
|
||||
}
|
||||
|
||||
// URL provides the structure describing the parts of a parsed URL returned by
|
||||
// [ParseURL].
|
||||
type URL struct {
|
||||
Scheme string // https://www.rfc-editor.org/rfc/rfc3986#section-3.1
|
||||
Authority string // https://www.rfc-editor.org/rfc/rfc3986#section-3.2
|
||||
Path string // https://www.rfc-editor.org/rfc/rfc3986#section-3.3
|
||||
NormalizedPath string // https://www.rfc-editor.org/rfc/rfc3986#section-6.2.3
|
||||
IsIp bool
|
||||
}
|
||||
|
||||
// URIEncode returns an percent-encoded [RFC3986 section 2.1] version of the
|
||||
// input string.
|
||||
//
|
||||
// [RFC3986 section 2.1]: https://www.rfc-editor.org/rfc/rfc3986#section-2.1
|
||||
func URIEncode(input string) string {
|
||||
var output strings.Builder
|
||||
for _, c := range []byte(input) {
|
||||
if validPercentEncodedChar(c) {
|
||||
output.WriteByte(c)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Fprintf(&output, "%%%X", c)
|
||||
}
|
||||
|
||||
return output.String()
|
||||
}
|
||||
|
||||
func validPercentEncodedChar(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '-' || c == '_' || c == '.' || c == '~'
|
||||
}
|
||||
|
||||
// hostname implements u.Hostname() but strips the ipv6 zone ID (if present)
|
||||
// such that net.ParseIP can still recognize IPv6 addresses with zone IDs.
|
||||
//
|
||||
// FUTURE(10/2023): netip.ParseAddr handles this natively but we can't take
|
||||
// that package as a dependency yet due to our min go version (1.15, netip
|
||||
// starts in 1.18). When we align with go runtime deprecation policy in
|
||||
// 10/2023, we can remove this.
|
||||
func hostnameWithoutZone(u *url.URL) string {
|
||||
full := u.Hostname()
|
||||
|
||||
// this more or less mimics the internals of net/ (see unexported
|
||||
// splitHostZone in that source) but throws the zone away because we don't
|
||||
// need it
|
||||
if i := strings.LastIndex(full, "%"); i > -1 {
|
||||
return full[:i]
|
||||
}
|
||||
return full
|
||||
}
|
||||
+1
-1
@@ -3,4 +3,4 @@
|
||||
package smithy
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.23.2"
|
||||
const goModuleVersion = "1.24.0"
|
||||
|
||||
+136
-49
@@ -1,7 +1,9 @@
|
||||
// Code generated by smithy-go/middleware/generate.go DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// BuildInput provides the input parameters for the BuildMiddleware to consume.
|
||||
@@ -25,14 +27,14 @@ type BuildHandler interface {
|
||||
}
|
||||
|
||||
// BuildMiddleware provides the interface for middleware specific to the
|
||||
// serialize step. Delegates to the next BuildHandler for further
|
||||
// build step. Delegates to the next BuildHandler for further
|
||||
// processing.
|
||||
type BuildMiddleware interface {
|
||||
// Unique ID for the middleware in theBuildStep. The step does not allow
|
||||
// duplicate IDs.
|
||||
// ID returns a unique ID for the middleware in the BuildStep. The step does not
|
||||
// allow duplicate IDs.
|
||||
ID() string
|
||||
|
||||
// Invokes the middleware behavior which must delegate to the next handler
|
||||
// HandleBuild invokes the middleware behavior which must delegate to the next handler
|
||||
// for the middleware chain to continue. The method must return a result or
|
||||
// error to its caller.
|
||||
HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) (
|
||||
@@ -54,7 +56,9 @@ type buildMiddlewareFunc struct {
|
||||
id string
|
||||
|
||||
// Middleware function to be called.
|
||||
fn func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error)
|
||||
fn func(context.Context, BuildInput, BuildHandler) (
|
||||
BuildOutput, Metadata, error,
|
||||
)
|
||||
}
|
||||
|
||||
// ID returns the unique ID for the middleware.
|
||||
@@ -69,23 +73,22 @@ func (s buildMiddlewareFunc) HandleBuild(ctx context.Context, in BuildInput, nex
|
||||
|
||||
var _ BuildMiddleware = (buildMiddlewareFunc{})
|
||||
|
||||
// BuildStep provides the ordered grouping of BuildMiddleware to be invoked on
|
||||
// a handler.
|
||||
// BuildStep provides the ordered grouping of BuildMiddleware to be
|
||||
// invoked on a handler.
|
||||
type BuildStep struct {
|
||||
ids *orderedIDs
|
||||
head *decoratedBuildHandler
|
||||
tail *decoratedBuildHandler
|
||||
}
|
||||
|
||||
// NewBuildStep returns a BuildStep ready to have middleware for
|
||||
// initialization added to it.
|
||||
// NewBuildStep returns an BuildStep ready to have middleware for
|
||||
// build added to it.
|
||||
func NewBuildStep() *BuildStep {
|
||||
return &BuildStep{
|
||||
ids: newOrderedIDs(baseOrderedItems),
|
||||
}
|
||||
return &BuildStep{}
|
||||
}
|
||||
|
||||
var _ Middleware = (*BuildStep)(nil)
|
||||
|
||||
// ID returns the unique name of the step as a middleware.
|
||||
// ID returns the unique ID of the step as a middleware.
|
||||
func (s *BuildStep) ID() string {
|
||||
return "Build stack step"
|
||||
}
|
||||
@@ -97,77 +100,161 @@ func (s *BuildStep) ID() string {
|
||||
func (s *BuildStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
|
||||
out interface{}, metadata Metadata, err error,
|
||||
) {
|
||||
order := s.ids.GetOrder()
|
||||
|
||||
var h BuildHandler = buildWrapHandler{Next: next}
|
||||
for i := len(order) - 1; i >= 0; i-- {
|
||||
h = decoratedBuildHandler{
|
||||
Next: h,
|
||||
With: order[i].(BuildMiddleware),
|
||||
}
|
||||
}
|
||||
|
||||
sIn := BuildInput{
|
||||
Request: in,
|
||||
}
|
||||
|
||||
res, metadata, err := h.HandleBuild(ctx, sIn)
|
||||
wh := &buildWrapHandler{next}
|
||||
if s.head == nil {
|
||||
res, metadata, err := wh.HandleBuild(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
s.tail.Next = wh
|
||||
res, metadata, err := s.head.HandleBuild(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
|
||||
func (s *BuildStep) Get(id string) (BuildMiddleware, bool) {
|
||||
get, ok := s.ids.Get(id)
|
||||
if !ok {
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, false
|
||||
}
|
||||
return get.(BuildMiddleware), ok
|
||||
|
||||
return found.With, true
|
||||
}
|
||||
|
||||
// Add injects the middleware to the relative position of the middleware group.
|
||||
// Returns an error if the middleware already exists.
|
||||
//
|
||||
// Add never returns an error. It used to for duplicate phases but this
|
||||
// behavior has since been removed as part of a performance optimization. The
|
||||
// return value from Add can be ignored.
|
||||
func (s *BuildStep) Add(m BuildMiddleware, pos RelativePosition) error {
|
||||
return s.ids.Add(m, pos)
|
||||
if s.head == nil {
|
||||
s.head = &decoratedBuildHandler{nil, m}
|
||||
s.tail = s.head
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
s.head = &decoratedBuildHandler{s.head, m}
|
||||
} else {
|
||||
tail := &decoratedBuildHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert injects the middleware relative to an existing middleware id.
|
||||
// Returns an error if the original middleware does not exist, or the middleware
|
||||
// Insert injects the middleware relative to an existing middleware ID.
|
||||
// Returns error if the original middleware does not exist, or the middleware
|
||||
// being added already exists.
|
||||
func (s *BuildStep) Insert(m BuildMiddleware, relativeTo string, pos RelativePosition) error {
|
||||
return s.ids.Insert(m, relativeTo, pos)
|
||||
found, prev := s.get(relativeTo)
|
||||
if found == nil {
|
||||
return fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
if prev == nil { // at the front
|
||||
s.head = &decoratedBuildHandler{s.head, m}
|
||||
} else { // somewhere in the middle
|
||||
prev.Next = &decoratedBuildHandler{found, m}
|
||||
}
|
||||
} else {
|
||||
if found.Next == nil { // at the end
|
||||
tail := &decoratedBuildHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
} else { // somewhere in the middle
|
||||
found.Next = &decoratedBuildHandler{found.Next, m}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Swap removes the middleware by id, replacing it with the new middleware.
|
||||
// Returns the middleware removed, or an error if the middleware to be removed
|
||||
// Returns the middleware removed, or error if the middleware to be removed
|
||||
// doesn't exist.
|
||||
func (s *BuildStep) Swap(id string, m BuildMiddleware) (BuildMiddleware, error) {
|
||||
removed, err := s.ids.Swap(id, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
return removed.(BuildMiddleware), nil
|
||||
swapped := found.With
|
||||
found.With = m
|
||||
return swapped, nil
|
||||
}
|
||||
|
||||
// Remove removes the middleware by id. Returns error if the middleware
|
||||
// doesn't exist.
|
||||
func (s *BuildStep) Remove(id string) (BuildMiddleware, error) {
|
||||
removed, err := s.ids.Remove(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, prev := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
|
||||
return removed.(BuildMiddleware), nil
|
||||
if s.head == s.tail { // it's the only one
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
} else if found == s.head { // at the front
|
||||
s.head = s.head.Next.(*decoratedBuildHandler)
|
||||
} else if found == s.tail { // at the end
|
||||
prev.Next = nil
|
||||
s.tail = prev
|
||||
} else {
|
||||
prev.Next = found.Next // somewhere in the middle
|
||||
}
|
||||
|
||||
return found.With, nil
|
||||
}
|
||||
|
||||
// List returns a list of the middleware in the step.
|
||||
func (s *BuildStep) List() []string {
|
||||
return s.ids.List()
|
||||
var ids []string
|
||||
for h := s.head; h != nil; {
|
||||
ids = append(ids, h.With.ID())
|
||||
if h.Next == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *buildWrapHandler, make sure to check for that
|
||||
if hnext, ok := h.Next.(*decoratedBuildHandler); ok {
|
||||
h = hnext
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Clear removes all middleware in the step.
|
||||
func (s *BuildStep) Clear() {
|
||||
s.ids.Clear()
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
}
|
||||
|
||||
func (s *BuildStep) get(id string) (found, prev *decoratedBuildHandler) {
|
||||
for h := s.head; h != nil; {
|
||||
if h.With.ID() == id {
|
||||
found = h
|
||||
return
|
||||
}
|
||||
prev = h
|
||||
if h.Next == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *buildWrapHandler
|
||||
h, _ = h.Next.(*decoratedBuildHandler)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type buildWrapHandler struct {
|
||||
@@ -176,7 +263,7 @@ type buildWrapHandler struct {
|
||||
|
||||
var _ BuildHandler = (*buildWrapHandler)(nil)
|
||||
|
||||
// Implements BuildHandler, converts types and delegates to underlying
|
||||
// HandleBuild implements BuildHandler, converts types and delegates to underlying
|
||||
// generic handler.
|
||||
func (w buildWrapHandler) HandleBuild(ctx context.Context, in BuildInput) (
|
||||
out BuildOutput, metadata Metadata, err error,
|
||||
@@ -200,12 +287,12 @@ func (h decoratedBuildHandler) HandleBuild(ctx context.Context, in BuildInput) (
|
||||
return h.With.HandleBuild(ctx, in, h.Next)
|
||||
}
|
||||
|
||||
// BuildHandlerFunc provides a wrapper around a function to be used as a build middleware handler.
|
||||
// BuildHandlerFunc provides a wrapper around a function to be used as buildMiddleware.
|
||||
type BuildHandlerFunc func(context.Context, BuildInput) (BuildOutput, Metadata, error)
|
||||
|
||||
// HandleBuild invokes the wrapped function with the provided arguments.
|
||||
func (b BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) {
|
||||
return b(ctx, in)
|
||||
// HandleBuild calls the wrapped function with the provided arguments.
|
||||
func (f BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) {
|
||||
return f(ctx, in)
|
||||
}
|
||||
|
||||
var _ BuildHandler = BuildHandlerFunc(nil)
|
||||
|
||||
+129
-47
@@ -1,7 +1,9 @@
|
||||
// Code generated by smithy-go/middleware/generate.go DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// DeserializeInput provides the input parameters for the DeserializeInput to
|
||||
@@ -11,10 +13,7 @@ type DeserializeInput struct {
|
||||
Request interface{}
|
||||
}
|
||||
|
||||
// DeserializeOutput provides the result returned by the next
|
||||
// DeserializeHandler. The DeserializeMiddleware should deserialize the
|
||||
// RawResponse into a Result that can be consumed by middleware higher up in
|
||||
// the stack.
|
||||
// DeserializeOutput provides the result returned by the next DeserializeHandler.
|
||||
type DeserializeOutput struct {
|
||||
RawResponse interface{}
|
||||
Result interface{}
|
||||
@@ -29,7 +28,7 @@ type DeserializeHandler interface {
|
||||
}
|
||||
|
||||
// DeserializeMiddleware provides the interface for middleware specific to the
|
||||
// serialize step. Delegates to the next DeserializeHandler for further
|
||||
// deserialize step. Delegates to the next DeserializeHandler for further
|
||||
// processing.
|
||||
type DeserializeMiddleware interface {
|
||||
// ID returns a unique ID for the middleware in the DeserializeStep. The step does not
|
||||
@@ -44,8 +43,8 @@ type DeserializeMiddleware interface {
|
||||
)
|
||||
}
|
||||
|
||||
// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID
|
||||
// provided, and the func to be invoked.
|
||||
// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID provided,
|
||||
// and the func to be invoked.
|
||||
func DeserializeMiddlewareFunc(id string, fn func(context.Context, DeserializeInput, DeserializeHandler) (DeserializeOutput, Metadata, error)) DeserializeMiddleware {
|
||||
return deserializeMiddlewareFunc{
|
||||
id: id,
|
||||
@@ -78,16 +77,14 @@ var _ DeserializeMiddleware = (deserializeMiddlewareFunc{})
|
||||
// DeserializeStep provides the ordered grouping of DeserializeMiddleware to be
|
||||
// invoked on a handler.
|
||||
type DeserializeStep struct {
|
||||
ids *orderedIDs
|
||||
head *decoratedDeserializeHandler
|
||||
tail *decoratedDeserializeHandler
|
||||
}
|
||||
|
||||
// NewDeserializeStep returns a DeserializeStep ready to have middleware for
|
||||
// initialization added to it.
|
||||
// NewDeserializeStep returns an DeserializeStep ready to have middleware for
|
||||
// deserialize added to it.
|
||||
func NewDeserializeStep() *DeserializeStep {
|
||||
return &DeserializeStep{
|
||||
// downstream SDK typically has larger Deserialize step
|
||||
ids: newOrderedIDs(baseOrderedItems * 2),
|
||||
}
|
||||
return &DeserializeStep{}
|
||||
}
|
||||
|
||||
var _ Middleware = (*DeserializeStep)(nil)
|
||||
@@ -104,77 +101,161 @@ func (s *DeserializeStep) ID() string {
|
||||
func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
|
||||
out interface{}, metadata Metadata, err error,
|
||||
) {
|
||||
order := s.ids.GetOrder()
|
||||
|
||||
var h DeserializeHandler = deserializeWrapHandler{Next: next}
|
||||
for i := len(order) - 1; i >= 0; i-- {
|
||||
h = decoratedDeserializeHandler{
|
||||
Next: h,
|
||||
With: order[i].(DeserializeMiddleware),
|
||||
}
|
||||
}
|
||||
|
||||
sIn := DeserializeInput{
|
||||
Request: in,
|
||||
}
|
||||
|
||||
res, metadata, err := h.HandleDeserialize(ctx, sIn)
|
||||
wh := &deserializeWrapHandler{next}
|
||||
if s.head == nil {
|
||||
res, metadata, err := wh.HandleDeserialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
s.tail.Next = wh
|
||||
res, metadata, err := s.head.HandleDeserialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
|
||||
func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) {
|
||||
get, ok := s.ids.Get(id)
|
||||
if !ok {
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, false
|
||||
}
|
||||
return get.(DeserializeMiddleware), ok
|
||||
|
||||
return found.With, true
|
||||
}
|
||||
|
||||
// Add injects the middleware to the relative position of the middleware group.
|
||||
// Returns an error if the middleware already exists.
|
||||
//
|
||||
// Add never returns an error. It used to for duplicate phases but this
|
||||
// behavior has since been removed as part of a performance optimization. The
|
||||
// return value from Add can be ignored.
|
||||
func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error {
|
||||
return s.ids.Add(m, pos)
|
||||
if s.head == nil {
|
||||
s.head = &decoratedDeserializeHandler{nil, m}
|
||||
s.tail = s.head
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
s.head = &decoratedDeserializeHandler{s.head, m}
|
||||
} else {
|
||||
tail := &decoratedDeserializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert injects the middleware relative to an existing middleware ID.
|
||||
// Returns error if the original middleware does not exist, or the middleware
|
||||
// being added already exists.
|
||||
func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error {
|
||||
return s.ids.Insert(m, relativeTo, pos)
|
||||
found, prev := s.get(relativeTo)
|
||||
if found == nil {
|
||||
return fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
if prev == nil { // at the front
|
||||
s.head = &decoratedDeserializeHandler{s.head, m}
|
||||
} else { // somewhere in the middle
|
||||
prev.Next = &decoratedDeserializeHandler{found, m}
|
||||
}
|
||||
} else {
|
||||
if found.Next == nil { // at the end
|
||||
tail := &decoratedDeserializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
} else { // somewhere in the middle
|
||||
found.Next = &decoratedDeserializeHandler{found.Next, m}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Swap removes the middleware by id, replacing it with the new middleware.
|
||||
// Returns the middleware removed, or error if the middleware to be removed
|
||||
// doesn't exist.
|
||||
func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) {
|
||||
removed, err := s.ids.Swap(id, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
return removed.(DeserializeMiddleware), nil
|
||||
swapped := found.With
|
||||
found.With = m
|
||||
return swapped, nil
|
||||
}
|
||||
|
||||
// Remove removes the middleware by id. Returns error if the middleware
|
||||
// doesn't exist.
|
||||
func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) {
|
||||
removed, err := s.ids.Remove(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, prev := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
|
||||
return removed.(DeserializeMiddleware), nil
|
||||
if s.head == s.tail { // it's the only one
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
} else if found == s.head { // at the front
|
||||
s.head = s.head.Next.(*decoratedDeserializeHandler)
|
||||
} else if found == s.tail { // at the end
|
||||
prev.Next = nil
|
||||
s.tail = prev
|
||||
} else {
|
||||
prev.Next = found.Next // somewhere in the middle
|
||||
}
|
||||
|
||||
return found.With, nil
|
||||
}
|
||||
|
||||
// List returns a list of the middleware in the step.
|
||||
func (s *DeserializeStep) List() []string {
|
||||
return s.ids.List()
|
||||
var ids []string
|
||||
for h := s.head; h != nil; {
|
||||
ids = append(ids, h.With.ID())
|
||||
if h.Next == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *deserializeWrapHandler, make sure to check for that
|
||||
if hnext, ok := h.Next.(*decoratedDeserializeHandler); ok {
|
||||
h = hnext
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Clear removes all middleware in the step.
|
||||
func (s *DeserializeStep) Clear() {
|
||||
s.ids.Clear()
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
}
|
||||
|
||||
func (s *DeserializeStep) get(id string) (found, prev *decoratedDeserializeHandler) {
|
||||
for h := s.head; h != nil; {
|
||||
if h.With.ID() == id {
|
||||
found = h
|
||||
return
|
||||
}
|
||||
prev = h
|
||||
if h.Next == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *deserializeWrapHandler
|
||||
h, _ = h.Next.(*decoratedDeserializeHandler)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type deserializeWrapHandler struct {
|
||||
@@ -188,9 +269,10 @@ var _ DeserializeHandler = (*deserializeWrapHandler)(nil)
|
||||
func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) (
|
||||
out DeserializeOutput, metadata Metadata, err error,
|
||||
) {
|
||||
resp, metadata, err := w.Next.Handle(ctx, in.Request)
|
||||
res, metadata, err := w.Next.Handle(ctx, in.Request)
|
||||
return DeserializeOutput{
|
||||
RawResponse: resp,
|
||||
RawResponse: res,
|
||||
Result: nil,
|
||||
}, metadata, err
|
||||
}
|
||||
|
||||
@@ -207,12 +289,12 @@ func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in D
|
||||
return h.With.HandleDeserialize(ctx, in, h.Next)
|
||||
}
|
||||
|
||||
// DeserializeHandlerFunc provides a wrapper around a function to be used as a deserialize middleware handler.
|
||||
// DeserializeHandlerFunc provides a wrapper around a function to be used as deserializeMiddleware.
|
||||
type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error)
|
||||
|
||||
// HandleDeserialize invokes the wrapped function with the given arguments.
|
||||
func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) {
|
||||
return d(ctx, in)
|
||||
// HandleDeserialize calls the wrapped function with the provided arguments.
|
||||
func (f DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) {
|
||||
return f(ctx, in)
|
||||
}
|
||||
|
||||
var _ DeserializeHandler = DeserializeHandlerFunc(nil)
|
||||
|
||||
+127
-41
@@ -1,6 +1,10 @@
|
||||
// Code generated by smithy-go/middleware/generate.go DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FinalizeInput provides the input parameters for the FinalizeMiddleware to
|
||||
// consume. FinalizeMiddleware may modify the Request value before forwarding
|
||||
@@ -23,7 +27,7 @@ type FinalizeHandler interface {
|
||||
}
|
||||
|
||||
// FinalizeMiddleware provides the interface for middleware specific to the
|
||||
// serialize step. Delegates to the next FinalizeHandler for further
|
||||
// finalize step. Delegates to the next FinalizeHandler for further
|
||||
// processing.
|
||||
type FinalizeMiddleware interface {
|
||||
// ID returns a unique ID for the middleware in the FinalizeStep. The step does not
|
||||
@@ -38,8 +42,8 @@ type FinalizeMiddleware interface {
|
||||
)
|
||||
}
|
||||
|
||||
// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID
|
||||
// provided, and the func to be invoked.
|
||||
// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID provided,
|
||||
// and the func to be invoked.
|
||||
func FinalizeMiddlewareFunc(id string, fn func(context.Context, FinalizeInput, FinalizeHandler) (FinalizeOutput, Metadata, error)) FinalizeMiddleware {
|
||||
return finalizeMiddlewareFunc{
|
||||
id: id,
|
||||
@@ -72,21 +76,19 @@ var _ FinalizeMiddleware = (finalizeMiddlewareFunc{})
|
||||
// FinalizeStep provides the ordered grouping of FinalizeMiddleware to be
|
||||
// invoked on a handler.
|
||||
type FinalizeStep struct {
|
||||
ids *orderedIDs
|
||||
head *decoratedFinalizeHandler
|
||||
tail *decoratedFinalizeHandler
|
||||
}
|
||||
|
||||
// NewFinalizeStep returns a FinalizeStep ready to have middleware for
|
||||
// initialization added to it.
|
||||
// NewFinalizeStep returns an FinalizeStep ready to have middleware for
|
||||
// finalize added to it.
|
||||
func NewFinalizeStep() *FinalizeStep {
|
||||
return &FinalizeStep{
|
||||
// downstream SDK typically has larger Finalize step
|
||||
ids: newOrderedIDs(baseOrderedItems * 2),
|
||||
}
|
||||
return &FinalizeStep{}
|
||||
}
|
||||
|
||||
var _ Middleware = (*FinalizeStep)(nil)
|
||||
|
||||
// ID returns the unique id of the step as a middleware.
|
||||
// ID returns the unique ID of the step as a middleware.
|
||||
func (s *FinalizeStep) ID() string {
|
||||
return "Finalize stack step"
|
||||
}
|
||||
@@ -98,77 +100,161 @@ func (s *FinalizeStep) ID() string {
|
||||
func (s *FinalizeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
|
||||
out interface{}, metadata Metadata, err error,
|
||||
) {
|
||||
order := s.ids.GetOrder()
|
||||
|
||||
var h FinalizeHandler = finalizeWrapHandler{Next: next}
|
||||
for i := len(order) - 1; i >= 0; i-- {
|
||||
h = decoratedFinalizeHandler{
|
||||
Next: h,
|
||||
With: order[i].(FinalizeMiddleware),
|
||||
}
|
||||
}
|
||||
|
||||
sIn := FinalizeInput{
|
||||
Request: in,
|
||||
}
|
||||
|
||||
res, metadata, err := h.HandleFinalize(ctx, sIn)
|
||||
wh := &finalizeWrapHandler{next}
|
||||
if s.head == nil {
|
||||
res, metadata, err := wh.HandleFinalize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
s.tail.Next = wh
|
||||
res, metadata, err := s.head.HandleFinalize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
|
||||
func (s *FinalizeStep) Get(id string) (FinalizeMiddleware, bool) {
|
||||
get, ok := s.ids.Get(id)
|
||||
if !ok {
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, false
|
||||
}
|
||||
return get.(FinalizeMiddleware), ok
|
||||
|
||||
return found.With, true
|
||||
}
|
||||
|
||||
// Add injects the middleware to the relative position of the middleware group.
|
||||
// Returns an error if the middleware already exists.
|
||||
//
|
||||
// Add never returns an error. It used to for duplicate phases but this
|
||||
// behavior has since been removed as part of a performance optimization. The
|
||||
// return value from Add can be ignored.
|
||||
func (s *FinalizeStep) Add(m FinalizeMiddleware, pos RelativePosition) error {
|
||||
return s.ids.Add(m, pos)
|
||||
if s.head == nil {
|
||||
s.head = &decoratedFinalizeHandler{nil, m}
|
||||
s.tail = s.head
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
s.head = &decoratedFinalizeHandler{s.head, m}
|
||||
} else {
|
||||
tail := &decoratedFinalizeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert injects the middleware relative to an existing middleware ID.
|
||||
// Returns error if the original middleware does not exist, or the middleware
|
||||
// being added already exists.
|
||||
func (s *FinalizeStep) Insert(m FinalizeMiddleware, relativeTo string, pos RelativePosition) error {
|
||||
return s.ids.Insert(m, relativeTo, pos)
|
||||
found, prev := s.get(relativeTo)
|
||||
if found == nil {
|
||||
return fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
if prev == nil { // at the front
|
||||
s.head = &decoratedFinalizeHandler{s.head, m}
|
||||
} else { // somewhere in the middle
|
||||
prev.Next = &decoratedFinalizeHandler{found, m}
|
||||
}
|
||||
} else {
|
||||
if found.Next == nil { // at the end
|
||||
tail := &decoratedFinalizeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
} else { // somewhere in the middle
|
||||
found.Next = &decoratedFinalizeHandler{found.Next, m}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Swap removes the middleware by id, replacing it with the new middleware.
|
||||
// Returns the middleware removed, or error if the middleware to be removed
|
||||
// doesn't exist.
|
||||
func (s *FinalizeStep) Swap(id string, m FinalizeMiddleware) (FinalizeMiddleware, error) {
|
||||
removed, err := s.ids.Swap(id, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
return removed.(FinalizeMiddleware), nil
|
||||
swapped := found.With
|
||||
found.With = m
|
||||
return swapped, nil
|
||||
}
|
||||
|
||||
// Remove removes the middleware by id. Returns error if the middleware
|
||||
// doesn't exist.
|
||||
func (s *FinalizeStep) Remove(id string) (FinalizeMiddleware, error) {
|
||||
removed, err := s.ids.Remove(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, prev := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
|
||||
return removed.(FinalizeMiddleware), nil
|
||||
if s.head == s.tail { // it's the only one
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
} else if found == s.head { // at the front
|
||||
s.head = s.head.Next.(*decoratedFinalizeHandler)
|
||||
} else if found == s.tail { // at the end
|
||||
prev.Next = nil
|
||||
s.tail = prev
|
||||
} else {
|
||||
prev.Next = found.Next // somewhere in the middle
|
||||
}
|
||||
|
||||
return found.With, nil
|
||||
}
|
||||
|
||||
// List returns a list of the middleware in the step.
|
||||
func (s *FinalizeStep) List() []string {
|
||||
return s.ids.List()
|
||||
var ids []string
|
||||
for h := s.head; h != nil; {
|
||||
ids = append(ids, h.With.ID())
|
||||
if h.Next == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *finalizeWrapHandler, make sure to check for that
|
||||
if hnext, ok := h.Next.(*decoratedFinalizeHandler); ok {
|
||||
h = hnext
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Clear removes all middleware in the step.
|
||||
func (s *FinalizeStep) Clear() {
|
||||
s.ids.Clear()
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
}
|
||||
|
||||
func (s *FinalizeStep) get(id string) (found, prev *decoratedFinalizeHandler) {
|
||||
for h := s.head; h != nil; {
|
||||
if h.With.ID() == id {
|
||||
found = h
|
||||
return
|
||||
}
|
||||
prev = h
|
||||
if h.Next == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *finalizeWrapHandler
|
||||
h, _ = h.Next.(*decoratedFinalizeHandler)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type finalizeWrapHandler struct {
|
||||
@@ -201,10 +287,10 @@ func (h decoratedFinalizeHandler) HandleFinalize(ctx context.Context, in Finaliz
|
||||
return h.With.HandleFinalize(ctx, in, h.Next)
|
||||
}
|
||||
|
||||
// FinalizeHandlerFunc provides a wrapper around a function to be used as a finalize middleware handler.
|
||||
// FinalizeHandlerFunc provides a wrapper around a function to be used as finalizeMiddleware.
|
||||
type FinalizeHandlerFunc func(context.Context, FinalizeInput) (FinalizeOutput, Metadata, error)
|
||||
|
||||
// HandleFinalize invokes the wrapped function with the given arguments.
|
||||
// HandleFinalize calls the wrapped function with the provided arguments.
|
||||
func (f FinalizeHandlerFunc) HandleFinalize(ctx context.Context, in FinalizeInput) (FinalizeOutput, Metadata, error) {
|
||||
return f(ctx, in)
|
||||
}
|
||||
|
||||
+124
-36
@@ -1,10 +1,15 @@
|
||||
// Code generated by smithy-go/middleware/generate.go DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// InitializeInput wraps the input parameters for the InitializeMiddlewares to
|
||||
// consume. InitializeMiddleware may modify the parameter value before
|
||||
// forwarding it along to the next InitializeHandler.
|
||||
|
||||
type InitializeInput struct {
|
||||
Parameters interface{}
|
||||
}
|
||||
@@ -72,15 +77,14 @@ var _ InitializeMiddleware = (initializeMiddlewareFunc{})
|
||||
// InitializeStep provides the ordered grouping of InitializeMiddleware to be
|
||||
// invoked on a handler.
|
||||
type InitializeStep struct {
|
||||
ids *orderedIDs
|
||||
head *decoratedInitializeHandler
|
||||
tail *decoratedInitializeHandler
|
||||
}
|
||||
|
||||
// NewInitializeStep returns an InitializeStep ready to have middleware for
|
||||
// initialization added to it.
|
||||
// initialize added to it.
|
||||
func NewInitializeStep() *InitializeStep {
|
||||
return &InitializeStep{
|
||||
ids: newOrderedIDs(baseOrderedItems),
|
||||
}
|
||||
return &InitializeStep{}
|
||||
}
|
||||
|
||||
var _ Middleware = (*InitializeStep)(nil)
|
||||
@@ -97,77 +101,161 @@ func (s *InitializeStep) ID() string {
|
||||
func (s *InitializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
|
||||
out interface{}, metadata Metadata, err error,
|
||||
) {
|
||||
order := s.ids.GetOrder()
|
||||
|
||||
var h InitializeHandler = initializeWrapHandler{Next: next}
|
||||
for i := len(order) - 1; i >= 0; i-- {
|
||||
h = decoratedInitializeHandler{
|
||||
Next: h,
|
||||
With: order[i].(InitializeMiddleware),
|
||||
}
|
||||
}
|
||||
|
||||
sIn := InitializeInput{
|
||||
Parameters: in,
|
||||
}
|
||||
|
||||
res, metadata, err := h.HandleInitialize(ctx, sIn)
|
||||
wh := &initializeWrapHandler{next}
|
||||
if s.head == nil {
|
||||
res, metadata, err := wh.HandleInitialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
s.tail.Next = wh
|
||||
res, metadata, err := s.head.HandleInitialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
|
||||
func (s *InitializeStep) Get(id string) (InitializeMiddleware, bool) {
|
||||
get, ok := s.ids.Get(id)
|
||||
if !ok {
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, false
|
||||
}
|
||||
return get.(InitializeMiddleware), ok
|
||||
|
||||
return found.With, true
|
||||
}
|
||||
|
||||
// Add injects the middleware to the relative position of the middleware group.
|
||||
// Returns an error if the middleware already exists.
|
||||
//
|
||||
// Add never returns an error. It used to for duplicate phases but this
|
||||
// behavior has since been removed as part of a performance optimization. The
|
||||
// return value from Add can be ignored.
|
||||
func (s *InitializeStep) Add(m InitializeMiddleware, pos RelativePosition) error {
|
||||
return s.ids.Add(m, pos)
|
||||
if s.head == nil {
|
||||
s.head = &decoratedInitializeHandler{nil, m}
|
||||
s.tail = s.head
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
s.head = &decoratedInitializeHandler{s.head, m}
|
||||
} else {
|
||||
tail := &decoratedInitializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert injects the middleware relative to an existing middleware ID.
|
||||
// Returns error if the original middleware does not exist, or the middleware
|
||||
// being added already exists.
|
||||
func (s *InitializeStep) Insert(m InitializeMiddleware, relativeTo string, pos RelativePosition) error {
|
||||
return s.ids.Insert(m, relativeTo, pos)
|
||||
found, prev := s.get(relativeTo)
|
||||
if found == nil {
|
||||
return fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
if prev == nil { // at the front
|
||||
s.head = &decoratedInitializeHandler{s.head, m}
|
||||
} else { // somewhere in the middle
|
||||
prev.Next = &decoratedInitializeHandler{found, m}
|
||||
}
|
||||
} else {
|
||||
if found.Next == nil { // at the end
|
||||
tail := &decoratedInitializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
} else { // somewhere in the middle
|
||||
found.Next = &decoratedInitializeHandler{found.Next, m}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Swap removes the middleware by id, replacing it with the new middleware.
|
||||
// Returns the middleware removed, or error if the middleware to be removed
|
||||
// doesn't exist.
|
||||
func (s *InitializeStep) Swap(id string, m InitializeMiddleware) (InitializeMiddleware, error) {
|
||||
removed, err := s.ids.Swap(id, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
return removed.(InitializeMiddleware), nil
|
||||
swapped := found.With
|
||||
found.With = m
|
||||
return swapped, nil
|
||||
}
|
||||
|
||||
// Remove removes the middleware by id. Returns error if the middleware
|
||||
// doesn't exist.
|
||||
func (s *InitializeStep) Remove(id string) (InitializeMiddleware, error) {
|
||||
removed, err := s.ids.Remove(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, prev := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
|
||||
return removed.(InitializeMiddleware), nil
|
||||
if s.head == s.tail { // it's the only one
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
} else if found == s.head { // at the front
|
||||
s.head = s.head.Next.(*decoratedInitializeHandler)
|
||||
} else if found == s.tail { // at the end
|
||||
prev.Next = nil
|
||||
s.tail = prev
|
||||
} else {
|
||||
prev.Next = found.Next // somewhere in the middle
|
||||
}
|
||||
|
||||
return found.With, nil
|
||||
}
|
||||
|
||||
// List returns a list of the middleware in the step.
|
||||
func (s *InitializeStep) List() []string {
|
||||
return s.ids.List()
|
||||
var ids []string
|
||||
for h := s.head; h != nil; {
|
||||
ids = append(ids, h.With.ID())
|
||||
if h.Next == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *initializeWrapHandler, make sure to check for that
|
||||
if hnext, ok := h.Next.(*decoratedInitializeHandler); ok {
|
||||
h = hnext
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Clear removes all middleware in the step.
|
||||
func (s *InitializeStep) Clear() {
|
||||
s.ids.Clear()
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
}
|
||||
|
||||
func (s *InitializeStep) get(id string) (found, prev *decoratedInitializeHandler) {
|
||||
for h := s.head; h != nil; {
|
||||
if h.With.ID() == id {
|
||||
found = h
|
||||
return
|
||||
}
|
||||
prev = h
|
||||
if h.Next == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *initializeWrapHandler
|
||||
h, _ = h.Next.(*decoratedInitializeHandler)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type initializeWrapHandler struct {
|
||||
@@ -200,12 +288,12 @@ func (h decoratedInitializeHandler) HandleInitialize(ctx context.Context, in Ini
|
||||
return h.With.HandleInitialize(ctx, in, h.Next)
|
||||
}
|
||||
|
||||
// InitializeHandlerFunc provides a wrapper around a function to be used as an initialize middleware handler.
|
||||
// InitializeHandlerFunc provides a wrapper around a function to be used as initializeMiddleware.
|
||||
type InitializeHandlerFunc func(context.Context, InitializeInput) (InitializeOutput, Metadata, error)
|
||||
|
||||
// HandleInitialize calls the wrapped function with the provided arguments.
|
||||
func (i InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) {
|
||||
return i(ctx, in)
|
||||
func (f InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) {
|
||||
return f(ctx, in)
|
||||
}
|
||||
|
||||
var _ InitializeHandler = InitializeHandlerFunc(nil)
|
||||
|
||||
+126
-40
@@ -1,6 +1,10 @@
|
||||
// Code generated by smithy-go/middleware/generate.go DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SerializeInput provides the input parameters for the SerializeMiddleware to
|
||||
// consume. SerializeMiddleware may modify the Request value before forwarding
|
||||
@@ -41,8 +45,8 @@ type SerializeMiddleware interface {
|
||||
)
|
||||
}
|
||||
|
||||
// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID
|
||||
// provided, and the func to be invoked.
|
||||
// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID provided,
|
||||
// and the func to be invoked.
|
||||
func SerializeMiddlewareFunc(id string, fn func(context.Context, SerializeInput, SerializeHandler) (SerializeOutput, Metadata, error)) SerializeMiddleware {
|
||||
return serializeMiddlewareFunc{
|
||||
id: id,
|
||||
@@ -75,17 +79,15 @@ var _ SerializeMiddleware = (serializeMiddlewareFunc{})
|
||||
// SerializeStep provides the ordered grouping of SerializeMiddleware to be
|
||||
// invoked on a handler.
|
||||
type SerializeStep struct {
|
||||
head *decoratedSerializeHandler
|
||||
tail *decoratedSerializeHandler
|
||||
newRequest func() interface{}
|
||||
ids *orderedIDs
|
||||
}
|
||||
|
||||
// NewSerializeStep returns a SerializeStep ready to have middleware for
|
||||
// initialization added to it. The newRequest func parameter is used to
|
||||
// initialize the transport specific request for the stack SerializeStep to
|
||||
// serialize the input parameters into.
|
||||
// NewSerializeStep returns an SerializeStep ready to have middleware for
|
||||
// serialize added to it.
|
||||
func NewSerializeStep(newRequest func() interface{}) *SerializeStep {
|
||||
return &SerializeStep{
|
||||
ids: newOrderedIDs(baseOrderedItems),
|
||||
newRequest: newRequest,
|
||||
}
|
||||
}
|
||||
@@ -104,78 +106,162 @@ func (s *SerializeStep) ID() string {
|
||||
func (s *SerializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
|
||||
out interface{}, metadata Metadata, err error,
|
||||
) {
|
||||
order := s.ids.GetOrder()
|
||||
|
||||
var h SerializeHandler = serializeWrapHandler{Next: next}
|
||||
for i := len(order) - 1; i >= 0; i-- {
|
||||
h = decoratedSerializeHandler{
|
||||
Next: h,
|
||||
With: order[i].(SerializeMiddleware),
|
||||
}
|
||||
}
|
||||
|
||||
sIn := SerializeInput{
|
||||
Parameters: in,
|
||||
Request: s.newRequest(),
|
||||
}
|
||||
|
||||
res, metadata, err := h.HandleSerialize(ctx, sIn)
|
||||
wh := &serializeWrapHandler{next}
|
||||
if s.head == nil {
|
||||
res, metadata, err := wh.HandleSerialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
s.tail.Next = wh
|
||||
res, metadata, err := s.head.HandleSerialize(ctx, sIn)
|
||||
return res.Result, metadata, err
|
||||
}
|
||||
|
||||
// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
|
||||
func (s *SerializeStep) Get(id string) (SerializeMiddleware, bool) {
|
||||
get, ok := s.ids.Get(id)
|
||||
if !ok {
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, false
|
||||
}
|
||||
return get.(SerializeMiddleware), ok
|
||||
|
||||
return found.With, true
|
||||
}
|
||||
|
||||
// Add injects the middleware to the relative position of the middleware group.
|
||||
// Returns an error if the middleware already exists.
|
||||
//
|
||||
// Add never returns an error. It used to for duplicate phases but this
|
||||
// behavior has since been removed as part of a performance optimization. The
|
||||
// return value from Add can be ignored.
|
||||
func (s *SerializeStep) Add(m SerializeMiddleware, pos RelativePosition) error {
|
||||
return s.ids.Add(m, pos)
|
||||
if s.head == nil {
|
||||
s.head = &decoratedSerializeHandler{nil, m}
|
||||
s.tail = s.head
|
||||
return nil
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
s.head = &decoratedSerializeHandler{s.head, m}
|
||||
} else {
|
||||
tail := &decoratedSerializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Insert injects the middleware relative to an existing middleware ID.
|
||||
// Returns error if the original middleware does not exist, or the middleware
|
||||
// being added already exists.
|
||||
func (s *SerializeStep) Insert(m SerializeMiddleware, relativeTo string, pos RelativePosition) error {
|
||||
return s.ids.Insert(m, relativeTo, pos)
|
||||
found, prev := s.get(relativeTo)
|
||||
if found == nil {
|
||||
return fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
if pos == Before {
|
||||
if prev == nil { // at the front
|
||||
s.head = &decoratedSerializeHandler{s.head, m}
|
||||
} else { // somewhere in the middle
|
||||
prev.Next = &decoratedSerializeHandler{found, m}
|
||||
}
|
||||
} else {
|
||||
if found.Next == nil { // at the end
|
||||
tail := &decoratedSerializeHandler{nil, m}
|
||||
s.tail.Next = tail
|
||||
s.tail = tail
|
||||
} else { // somewhere in the middle
|
||||
found.Next = &decoratedSerializeHandler{found.Next, m}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Swap removes the middleware by id, replacing it with the new middleware.
|
||||
// Returns the middleware removed, or error if the middleware to be removed
|
||||
// doesn't exist.
|
||||
func (s *SerializeStep) Swap(id string, m SerializeMiddleware) (SerializeMiddleware, error) {
|
||||
removed, err := s.ids.Swap(id, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, _ := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", m.ID())
|
||||
}
|
||||
|
||||
return removed.(SerializeMiddleware), nil
|
||||
swapped := found.With
|
||||
found.With = m
|
||||
return swapped, nil
|
||||
}
|
||||
|
||||
// Remove removes the middleware by id. Returns error if the middleware
|
||||
// doesn't exist.
|
||||
func (s *SerializeStep) Remove(id string) (SerializeMiddleware, error) {
|
||||
removed, err := s.ids.Remove(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
found, prev := s.get(id)
|
||||
if found == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
|
||||
return removed.(SerializeMiddleware), nil
|
||||
if s.head == s.tail { // it's the only one
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
} else if found == s.head { // at the front
|
||||
s.head = s.head.Next.(*decoratedSerializeHandler)
|
||||
} else if found == s.tail { // at the end
|
||||
prev.Next = nil
|
||||
s.tail = prev
|
||||
} else {
|
||||
prev.Next = found.Next // somewhere in the middle
|
||||
}
|
||||
|
||||
return found.With, nil
|
||||
}
|
||||
|
||||
// List returns a list of the middleware in the step.
|
||||
func (s *SerializeStep) List() []string {
|
||||
return s.ids.List()
|
||||
var ids []string
|
||||
for h := s.head; h != nil; {
|
||||
ids = append(ids, h.With.ID())
|
||||
if h.Next == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *serializeWrapHandler, make sure to check for that
|
||||
if hnext, ok := h.Next.(*decoratedSerializeHandler); ok {
|
||||
h = hnext
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Clear removes all middleware in the step.
|
||||
func (s *SerializeStep) Clear() {
|
||||
s.ids.Clear()
|
||||
s.head = nil
|
||||
s.tail = nil
|
||||
}
|
||||
|
||||
func (s *SerializeStep) get(id string) (found, prev *decoratedSerializeHandler) {
|
||||
for h := s.head; h != nil; {
|
||||
if h.With.ID() == id {
|
||||
found = h
|
||||
return
|
||||
}
|
||||
prev = h
|
||||
if h.Next == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// once executed, tail.Next of the list will be set to an
|
||||
// *serializeWrapHandler
|
||||
h, _ = h.Next.(*decoratedSerializeHandler)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type serializeWrapHandler struct {
|
||||
@@ -184,7 +270,7 @@ type serializeWrapHandler struct {
|
||||
|
||||
var _ SerializeHandler = (*serializeWrapHandler)(nil)
|
||||
|
||||
// Implements SerializeHandler, converts types and delegates to underlying
|
||||
// HandleSerialize implements SerializeHandler, converts types and delegates to underlying
|
||||
// generic handler.
|
||||
func (w serializeWrapHandler) HandleSerialize(ctx context.Context, in SerializeInput) (
|
||||
out SerializeOutput, metadata Metadata, err error,
|
||||
@@ -208,12 +294,12 @@ func (h decoratedSerializeHandler) HandleSerialize(ctx context.Context, in Seria
|
||||
return h.With.HandleSerialize(ctx, in, h.Next)
|
||||
}
|
||||
|
||||
// SerializeHandlerFunc provides a wrapper around a function to be used as a serialize middleware handler.
|
||||
// SerializeHandlerFunc provides a wrapper around a function to be used as serializeMiddleware.
|
||||
type SerializeHandlerFunc func(context.Context, SerializeInput) (SerializeOutput, Metadata, error)
|
||||
|
||||
// HandleSerialize calls the wrapped function with the provided arguments.
|
||||
func (s SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) {
|
||||
return s(ctx, in)
|
||||
func (f SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) {
|
||||
return f(ctx, in)
|
||||
}
|
||||
|
||||
var _ SerializeHandler = SerializeHandlerFunc(nil)
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
# git-cliff ~ configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
|
||||
[changelog]
|
||||
header = """
|
||||
"""
|
||||
|
||||
footer = """
|
||||
|
||||
-----
|
||||
|
||||
**[{{ remote.github.repo }}]({{ self::remote_url() }}) license terms**
|
||||
|
||||
[![License][license-badge]][license-url]
|
||||
|
||||
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
|
||||
[license-url]: {{ self::remote_url() }}/?tab=Apache-2.0-1-ov-file#readme
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
|
||||
body = """
|
||||
{%- if version %}
|
||||
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{%- else %}
|
||||
## [unreleased]
|
||||
{%- endif %}
|
||||
{%- if message %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ message }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
{%- if version %}
|
||||
{%- if previous.version %}
|
||||
|
||||
**Full Changelog**: <{{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}>
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if statistics %}{% if statistics.commit_count %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ statistics.commit_count }} commits in this release.
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}{% endif %}
|
||||
-----
|
||||
|
||||
{%- for group, commits in commits | group_by(attribute="group") %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
### {{ group | upper_first }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- for commit in commits %}
|
||||
{%- if commit.remote.pr_title %}
|
||||
{%- set commit_message = commit.remote.pr_title %}
|
||||
{%- else %}
|
||||
{%- set commit_message = commit.message %}
|
||||
{%- endif %}
|
||||
* {{ commit_message | split(pat="\n") | first | trim }}
|
||||
{%- if commit.remote.username %}
|
||||
{%- raw %} {% endraw %}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }})
|
||||
{%- endif %}
|
||||
{%- if commit.remote.pr_number %}
|
||||
{%- raw %} {% endraw %}in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})
|
||||
{%- endif %}
|
||||
{%- raw %} {% endraw %}[...]({{ self::remote_url() }}/commit/{{ commit.id }})
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if github %}
|
||||
{%- raw %}\n{% endraw -%}
|
||||
{%- set all_contributors = github.contributors | length %}
|
||||
{%- if github.contributors | filter(attribute="username", value="dependabot[bot]") | length < all_contributors %}
|
||||
-----
|
||||
|
||||
### People who contributed to this release
|
||||
{% endif %}
|
||||
{%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* [@{{ contributor.username }}](https://github.com/{{ contributor.username }})
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||
-----
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
### New Contributors
|
||||
{%- endif %}
|
||||
|
||||
{%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* @{{ contributor.username }} made their first contribution
|
||||
{%- if contributor.pr_number %}
|
||||
in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
# Remove leading and trailing whitespaces from the changelog's body.
|
||||
trim = true
|
||||
# Render body even when there are no releases to process.
|
||||
render_always = true
|
||||
# An array of regex based postprocessors to modify the changelog.
|
||||
postprocessors = [
|
||||
# Replace the placeholder <REPO> with a URL.
|
||||
#{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" },
|
||||
]
|
||||
# output file path
|
||||
# output = "test.md"
|
||||
|
||||
[git]
|
||||
# Parse commits according to the conventional commits specification.
|
||||
# See https://www.conventionalcommits.org
|
||||
conventional_commits = false
|
||||
# Exclude commits that do not match the conventional commits specification.
|
||||
filter_unconventional = false
|
||||
# Require all commits to be conventional.
|
||||
# Takes precedence over filter_unconventional.
|
||||
require_conventional = false
|
||||
# Split commits on newlines, treating each line as an individual commit.
|
||||
split_commits = false
|
||||
# An array of regex based parsers to modify commit messages prior to further processing.
|
||||
commit_preprocessors = [
|
||||
# Replace issue numbers with link templates to be updated in `changelog.postprocessors`.
|
||||
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||
# Check spelling of the commit message using https://github.com/crate-ci/typos.
|
||||
# If the spelling is incorrect, it will be fixed automatically.
|
||||
#{ pattern = '.*', replace_command = 'typos --write-changes -' }
|
||||
]
|
||||
# Prevent commits that are breaking from being excluded by commit parsers.
|
||||
protect_breaking_commits = false
|
||||
# An array of regex based parsers for extracting data from the commit message.
|
||||
# Assigns commits to groups.
|
||||
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
|
||||
commit_parsers = [
|
||||
{ message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true },
|
||||
{ message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true },
|
||||
{ field = "author.name", pattern = "dependabot*", group = "<!-- 0A -->Updates" },
|
||||
{ message = "([Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ body = "(.*[Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "<!-- 05 -->Code quality" },
|
||||
{ message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "<!-- 03 -->Documentation" },
|
||||
{ message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "<!-- 00 -->Implemented enhancements" },
|
||||
{ message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^test", group = "<!-- 06 -->Testing" },
|
||||
{ message = "(^fix)|(panic)", group = "<!-- 01 -->Fixed bugs" },
|
||||
{ message = "(^refact)|(rework)", group = "<!-- 02 -->Refactor" },
|
||||
{ message = "(^[Pp]erf)|(performance)", group = "<!-- 04 -->Performance" },
|
||||
{ message = "(^[Cc]hore)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^[Rr]evert", group = "<!-- 09 -->Reverted changes" },
|
||||
{ message = "(upgrade.*?go)|(go\\s+version)", group = "<!-- 0A -->Updates" },
|
||||
{ message = ".*", group = "<!-- 0B -->Other" },
|
||||
]
|
||||
# Exclude commits that are not matched by any commit parser.
|
||||
filter_commits = false
|
||||
# An array of link parsers for extracting external references, and turning them into URLs, using regex.
|
||||
link_parsers = []
|
||||
# Include only the tags that belong to the current branch.
|
||||
use_branch_tags = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order_commits = true
|
||||
# Order of commits in each group/release within the changelog.
|
||||
# Allowed values: newest, oldest
|
||||
sort_commits = "newest"
|
||||
# Process submodules commits
|
||||
recurse_submodules = false
|
||||
|
||||
#[remote.github]
|
||||
#owner = "go-openapi"
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Set default charset
|
||||
[*.{js,py,go,scala,rb,java,html,css,less,sass,md}]
|
||||
charset = utf-8
|
||||
|
||||
# Tab indentation (no size specified)
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
# Matches the exact files either package.json or .travis.yml
|
||||
[{package.json,.travis.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
+2
-1
@@ -1,2 +1,3 @@
|
||||
secrets.yml
|
||||
coverage.out
|
||||
*.out
|
||||
settings.local.json
|
||||
|
||||
+11
-20
@@ -2,34 +2,17 @@ version: "2"
|
||||
linters:
|
||||
default: all
|
||||
disable:
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- exhaustruct
|
||||
- nlreturn
|
||||
- noinlineerr
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
@@ -41,8 +24,15 @@ linters:
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
cyclop:
|
||||
max-complexity: 20
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
min-complexity: 20
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: true
|
||||
default-case-required: true
|
||||
lll:
|
||||
line-length: 180
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
@@ -58,6 +48,7 @@ formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- gofumpt
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
# Contributors
|
||||
|
||||
- Repository: ['go-openapi/errors']
|
||||
|
||||
| Total Contributors | Total Contributions |
|
||||
| --- | --- |
|
||||
| 12 | 105 |
|
||||
|
||||
| Username | All Time Contribution Count | All Commits |
|
||||
| --- | --- | --- |
|
||||
| @casualjim | 58 | https://github.com/go-openapi/errors/commits?author=casualjim |
|
||||
| @fredbi | 32 | https://github.com/go-openapi/errors/commits?author=fredbi |
|
||||
| @youyuanwu | 5 | https://github.com/go-openapi/errors/commits?author=youyuanwu |
|
||||
| @alexandear | 2 | https://github.com/go-openapi/errors/commits?author=alexandear |
|
||||
| @fiorix | 1 | https://github.com/go-openapi/errors/commits?author=fiorix |
|
||||
| @ligustah | 1 | https://github.com/go-openapi/errors/commits?author=ligustah |
|
||||
| @artemseleznev | 1 | https://github.com/go-openapi/errors/commits?author=artemseleznev |
|
||||
| @gautierdelorme | 1 | https://github.com/go-openapi/errors/commits?author=gautierdelorme |
|
||||
| @guillemj | 1 | https://github.com/go-openapi/errors/commits?author=guillemj |
|
||||
| @maxatome | 1 | https://github.com/go-openapi/errors/commits?author=maxatome |
|
||||
| @Simon-Li | 1 | https://github.com/go-openapi/errors/commits?author=Simon-Li |
|
||||
| @ujjwalsh | 1 | https://github.com/go-openapi/errors/commits?author=ujjwalsh |
|
||||
|
||||
_this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_
|
||||
+116
-5
@@ -1,12 +1,123 @@
|
||||
# OpenAPI errors [](https://github.com/go-openapi/errors/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/errors)
|
||||
# errors
|
||||
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/errors)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/errors)
|
||||
<!-- Badges: status -->
|
||||
[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url]
|
||||
<!-- Badges: release & docker images -->
|
||||
<!-- Badges: code quality -->
|
||||
<!-- Badges: license & compliance -->
|
||||
[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url]
|
||||
<!-- Badges: documentation & support -->
|
||||
<!-- Badges: others & stats -->
|
||||
[![GoDoc][godoc-badge]][godoc-url] [![Discord Channel][discord-badge]][discord-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge]
|
||||
|
||||
---
|
||||
|
||||
Shared errors and error interface used throughout the various libraries found in the go-openapi toolkit.
|
||||
|
||||
## Announcements
|
||||
|
||||
* **2025-12-19** : new community chat on discord
|
||||
* a new discord community channel is available to be notified of changes and support users
|
||||
* our venerable Slack channel remains open, and will be eventually discontinued on **2026-03-31**
|
||||
|
||||
You may join the discord community by clicking the invite link on the discord badge (also above). [![Discord Channel][discord-badge]][discord-url]
|
||||
|
||||
Or join our Slack channel: [![Slack Channel][slack-logo]![slack-badge]][slack-url]
|
||||
|
||||
## Status
|
||||
|
||||
API is stable.
|
||||
|
||||
## Import this library in your project
|
||||
|
||||
```cmd
|
||||
go get github.com/go-openapi/errors
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```go
|
||||
const url = "https://www.example.com/#"
|
||||
|
||||
errGeneric := New(401,"onvalid argument: %s", url)
|
||||
|
||||
errNotFound := NotFound("resource not found: %s", url)
|
||||
|
||||
errNotImplemented := NotImplemented("method: %s", url)
|
||||
```
|
||||
|
||||
## Change log
|
||||
|
||||
See <https://github.com/go-openapi/errors/releases>
|
||||
|
||||
<!--
|
||||
## References
|
||||
-->
|
||||
|
||||
## Licensing
|
||||
|
||||
This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE).
|
||||
|
||||
<!--
|
||||
See the license [NOTICE](./NOTICE), which recalls the licensing terms of all the pieces of software
|
||||
on top of which it has been built.
|
||||
-->
|
||||
|
||||
<!--
|
||||
## Limitations
|
||||
-->
|
||||
|
||||
## Other documentation
|
||||
|
||||
* [All-time contributors](./CONTRIBUTORS.md)
|
||||
* [Contributing guidelines](.github/CONTRIBUTING.md)
|
||||
* [Maintainers documentation](docs/MAINTAINERS.md)
|
||||
* [Code style](docs/STYLE.md)
|
||||
|
||||
## Cutting a new release
|
||||
|
||||
Maintainers can cut a new release by either:
|
||||
|
||||
* running [this workflow](https://github.com/go-openapi/errors/actions/workflows/bump-release.yml)
|
||||
* or pushing a semver tag
|
||||
* signed tags are preferred
|
||||
* The tag message is prepended to release notes
|
||||
|
||||
<!-- Badges: status -->
|
||||
[test-badge]: https://github.com/go-openapi/errors/actions/workflows/go-test.yml/badge.svg
|
||||
[test-url]: https://github.com/go-openapi/errors/actions/workflows/go-test.yml
|
||||
[cov-badge]: https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg
|
||||
[cov-url]: https://codecov.io/gh/go-openapi/errors
|
||||
[vuln-scan-badge]: https://github.com/go-openapi/errors/actions/workflows/scanner.yml/badge.svg
|
||||
[vuln-scan-url]: https://github.com/go-openapi/errors/actions/workflows/scanner.yml
|
||||
[codeql-badge]: https://github.com/go-openapi/errors/actions/workflows/codeql.yml/badge.svg
|
||||
[codeql-url]: https://github.com/go-openapi/errors/actions/workflows/codeql.yml
|
||||
<!-- Badges: release & docker images -->
|
||||
[release-badge]: https://badge.fury.io/gh/go-openapi%2Ferrors.svg
|
||||
[release-url]: https://badge.fury.io/gh/go-openapi%2Ferrors
|
||||
[gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Ferrors.svg
|
||||
[gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Ferrors
|
||||
<!-- Badges: code quality -->
|
||||
[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/errors
|
||||
[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/errors
|
||||
[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/errors
|
||||
[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/errors
|
||||
<!-- Badges: documentation & support -->
|
||||
[doc-badge]: https://img.shields.io/badge/doc-site-blue?link=https%3A%2F%2Fgoswagger.io%2Fgo-openapi%2F
|
||||
[doc-url]: https://goswagger.io/go-openapi
|
||||
[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/errors
|
||||
[godoc-url]: http://pkg.go.dev/github.com/go-openapi/errors
|
||||
[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png
|
||||
[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM
|
||||
[slack-url]: https://goswagger.slack.com/archives/C04R30YMU
|
||||
[discord-badge]: https://img.shields.io/discord/1446918742398341256?logo=discord&label=discord&color=blue
|
||||
[discord-url]: https://discord.gg/DrafRmZx
|
||||
|
||||
<!-- Badges: license & compliance -->
|
||||
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
|
||||
[license-url]: https://github.com/go-openapi/errors/?tab=Apache-2.0-1-ov-file#readme
|
||||
<!-- Badges: others & stats -->
|
||||
[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/errors
|
||||
[goversion-url]: https://github.com/go-openapi/errors/blob/master/go.mod
|
||||
[top-badge]: https://img.shields.io/github/languages/top/go-openapi/errors
|
||||
[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/errors/latest
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Security Policy
|
||||
|
||||
This policy outlines the commitment and practices of the go-openapi maintainers regarding security.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.22.x | :white_check_mark: |
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
If you become aware of a security vulnerability that affects the current repository,
|
||||
please report it privately to the maintainers.
|
||||
|
||||
Please follow the instructions provided by github to
|
||||
[Privately report a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability).
|
||||
|
||||
TL;DR: on Github, navigate to the project's "Security" tab then click on "Report a vulnerability".
|
||||
+70
-40
@@ -5,6 +5,7 @@ package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@@ -12,9 +13,11 @@ import (
|
||||
)
|
||||
|
||||
// DefaultHTTPCode is used when the error Code cannot be used as an HTTP code.
|
||||
//
|
||||
//nolint:gochecknoglobals // it should have been a constant in the first place, but now it is mutable so we have to leave it here or introduce a breaking change.
|
||||
var DefaultHTTPCode = http.StatusUnprocessableEntity
|
||||
|
||||
// Error represents a error interface all swagger framework errors implement
|
||||
// Error represents a error interface all swagger framework errors implement.
|
||||
type Error interface {
|
||||
error
|
||||
Code() int32
|
||||
@@ -25,15 +28,17 @@ type apiError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (a *apiError) Error() string {
|
||||
return a.message
|
||||
}
|
||||
|
||||
// Code returns the HTTP status code associated with this error.
|
||||
func (a *apiError) Code() int32 {
|
||||
return a.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
// MarshalJSON implements the JSON encoding interface.
|
||||
func (a apiError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]any{
|
||||
"code": a.code,
|
||||
@@ -41,7 +46,7 @@ func (a apiError) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// New creates a new API error with a code and a message
|
||||
// New creates a new API error with a code and a message.
|
||||
func New(code int32, message string, args ...any) Error {
|
||||
if len(args) > 0 {
|
||||
return &apiError{
|
||||
@@ -55,7 +60,7 @@ func New(code int32, message string, args ...any) Error {
|
||||
}
|
||||
}
|
||||
|
||||
// NotFound creates a new not found error
|
||||
// NotFound creates a new not found error.
|
||||
func NotFound(message string, args ...any) Error {
|
||||
if message == "" {
|
||||
message = "Not found"
|
||||
@@ -63,28 +68,29 @@ func NotFound(message string, args ...any) Error {
|
||||
return New(http.StatusNotFound, message, args...)
|
||||
}
|
||||
|
||||
// NotImplemented creates a new not implemented error
|
||||
// NotImplemented creates a new not implemented error.
|
||||
func NotImplemented(message string) Error {
|
||||
return New(http.StatusNotImplemented, "%s", message)
|
||||
}
|
||||
|
||||
// MethodNotAllowedError represents an error for when the path matches but the method doesn't
|
||||
// MethodNotAllowedError represents an error for when the path matches but the method doesn't.
|
||||
type MethodNotAllowedError struct {
|
||||
code int32
|
||||
Allowed []string
|
||||
message string
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (m *MethodNotAllowedError) Error() string {
|
||||
return m.message
|
||||
}
|
||||
|
||||
// Code the error code
|
||||
// Code returns 405 (Method Not Allowed) as the HTTP status code.
|
||||
func (m *MethodNotAllowedError) Code() int32 {
|
||||
return m.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
// MarshalJSON implements the JSON encoding interface.
|
||||
func (m MethodNotAllowedError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]any{
|
||||
"code": m.code,
|
||||
@@ -104,25 +110,33 @@ func errorAsJSON(err Error) []byte {
|
||||
|
||||
func flattenComposite(errs *CompositeError) *CompositeError {
|
||||
var res []error
|
||||
for _, er := range errs.Errors {
|
||||
switch e := er.(type) {
|
||||
case *CompositeError:
|
||||
if e != nil && len(e.Errors) > 0 {
|
||||
flat := flattenComposite(e)
|
||||
if len(flat.Errors) > 0 {
|
||||
res = append(res, flat.Errors...)
|
||||
}
|
||||
}
|
||||
default:
|
||||
if e != nil {
|
||||
res = append(res, e)
|
||||
}
|
||||
|
||||
for _, err := range errs.Errors {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
e := &CompositeError{}
|
||||
if !errors.As(err, &e) {
|
||||
res = append(res, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if len(e.Errors) == 0 {
|
||||
res = append(res, e)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
flat := flattenComposite(e)
|
||||
res = append(res, flat.Errors...)
|
||||
}
|
||||
|
||||
return CompositeValidationError(res...)
|
||||
}
|
||||
|
||||
// MethodNotAllowed creates a new method not allowed error
|
||||
// MethodNotAllowed creates a new method not allowed error.
|
||||
func MethodNotAllowed(requested string, allow []string) Error {
|
||||
msg := fmt.Sprintf("method %s is not allowed, but [%s] are", requested, strings.Join(allow, ","))
|
||||
return &MethodNotAllowedError{
|
||||
@@ -132,39 +146,55 @@ func MethodNotAllowed(requested string, allow []string) Error {
|
||||
}
|
||||
}
|
||||
|
||||
// ServeError implements the http error handler interface
|
||||
// ServeError implements the http error handler interface.
|
||||
func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
switch e := err.(type) {
|
||||
case *CompositeError:
|
||||
er := flattenComposite(e)
|
||||
|
||||
if err == nil {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
errComposite := &CompositeError{}
|
||||
errMethodNotAllowed := &MethodNotAllowedError{}
|
||||
var errError Error
|
||||
|
||||
switch {
|
||||
case errors.As(err, &errComposite):
|
||||
er := flattenComposite(errComposite)
|
||||
// strips composite errors to first element only
|
||||
if len(er.Errors) > 0 {
|
||||
ServeError(rw, r, er.Errors[0])
|
||||
} else {
|
||||
// guard against empty CompositeError (invalid construct)
|
||||
ServeError(rw, r, nil)
|
||||
|
||||
return
|
||||
}
|
||||
case *MethodNotAllowedError:
|
||||
rw.Header().Add("Allow", strings.Join(e.Allowed, ","))
|
||||
rw.WriteHeader(asHTTPCode(int(e.Code())))
|
||||
|
||||
// guard against empty CompositeError (invalid construct)
|
||||
ServeError(rw, r, nil)
|
||||
|
||||
case errors.As(err, &errMethodNotAllowed):
|
||||
rw.Header().Add("Allow", strings.Join(errMethodNotAllowed.Allowed, ","))
|
||||
rw.WriteHeader(asHTTPCode(int(errMethodNotAllowed.Code())))
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
_, _ = rw.Write(errorAsJSON(e))
|
||||
_, _ = rw.Write(errorAsJSON(errMethodNotAllowed))
|
||||
}
|
||||
case Error:
|
||||
value := reflect.ValueOf(e)
|
||||
|
||||
case errors.As(err, &errError):
|
||||
value := reflect.ValueOf(errError)
|
||||
if value.Kind() == reflect.Ptr && value.IsNil() {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
|
||||
|
||||
return
|
||||
}
|
||||
rw.WriteHeader(asHTTPCode(int(e.Code())))
|
||||
|
||||
rw.WriteHeader(asHTTPCode(int(errError.Code())))
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
_, _ = rw.Write(errorAsJSON(e))
|
||||
_, _ = rw.Write(errorAsJSON(errError))
|
||||
}
|
||||
case nil:
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
|
||||
|
||||
default:
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
if r == nil || r.Method != http.MethodHead {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ package errors
|
||||
|
||||
import "net/http"
|
||||
|
||||
// Unauthenticated returns an unauthenticated error
|
||||
// Unauthenticated returns an unauthenticated error.
|
||||
func Unauthenticated(scheme string) Error {
|
||||
return New(http.StatusUnauthorized, "unauthenticated for %s", scheme)
|
||||
}
|
||||
|
||||
+9
-7
@@ -9,8 +9,8 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Validation represents a failure of a precondition
|
||||
type Validation struct { //nolint: errname
|
||||
// Validation represents a failure of a precondition.
|
||||
type Validation struct { //nolint: errname // changing the name to abide by the naming rule would bring a breaking change.
|
||||
code int32
|
||||
Name string
|
||||
In string
|
||||
@@ -19,16 +19,18 @@ type Validation struct { //nolint: errname
|
||||
Values []any
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (e *Validation) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// Code the error code
|
||||
// Code returns the HTTP status code for this validation error.
|
||||
// Returns 422 (Unprocessable Entity) by default.
|
||||
func (e *Validation) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
// MarshalJSON implements the JSON encoding interface.
|
||||
func (e Validation) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]any{
|
||||
"code": e.code,
|
||||
@@ -40,7 +42,7 @@ func (e Validation) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// ValidateName sets the name for a validation or updates it for a nested property
|
||||
// ValidateName sets the name for a validation or updates it for a nested property.
|
||||
func (e *Validation) ValidateName(name string) *Validation {
|
||||
if name != "" {
|
||||
if e.Name == "" {
|
||||
@@ -59,7 +61,7 @@ const (
|
||||
responseFormatFail = `unsupported media type requested, only %v are available`
|
||||
)
|
||||
|
||||
// InvalidContentType error for an invalid content type
|
||||
// InvalidContentType error for an invalid content type.
|
||||
func InvalidContentType(value string, allowed []string) *Validation {
|
||||
values := make([]any, 0, len(allowed))
|
||||
for _, v := range allowed {
|
||||
@@ -75,7 +77,7 @@ func InvalidContentType(value string, allowed []string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// InvalidResponseFormat error for an unacceptable response format request
|
||||
// InvalidResponseFormat error for an unacceptable response format request.
|
||||
func InvalidResponseFormat(value string, allowed []string) *Validation {
|
||||
values := make([]any, 0, len(allowed))
|
||||
for _, v := range allowed {
|
||||
|
||||
+2
-1
@@ -10,13 +10,14 @@ import (
|
||||
)
|
||||
|
||||
// APIVerificationFailed is an error that contains all the missing info for a mismatched section
|
||||
// between the api registrations and the api spec
|
||||
// between the api registrations and the api spec.
|
||||
type APIVerificationFailed struct { //nolint: errname
|
||||
Section string `json:"section,omitempty"`
|
||||
MissingSpecification []string `json:"missingSpecification,omitempty"`
|
||||
MissingRegistration []string `json:"missingRegistration,omitempty"`
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (v *APIVerificationFailed) Error() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
|
||||
+5
-4
@@ -9,7 +9,7 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ParseError represents a parsing error
|
||||
// ParseError represents a parsing error.
|
||||
type ParseError struct {
|
||||
code int32
|
||||
Name string
|
||||
@@ -19,7 +19,7 @@ type ParseError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// NewParseError creates a new parse error
|
||||
// NewParseError creates a new parse error.
|
||||
func NewParseError(name, in, value string, reason error) *ParseError {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -37,16 +37,17 @@ func NewParseError(name, in, value string, reason error) *ParseError {
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (e *ParseError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// Code returns the http status code for this error
|
||||
// Code returns 400 (Bad Request) as the HTTP status code for parsing errors.
|
||||
func (e *ParseError) Code() int32 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
// MarshalJSON implements the JSON encoding interface.
|
||||
func (e ParseError) MarshalJSON() ([]byte, error) {
|
||||
var reason string
|
||||
if e.Reason != nil {
|
||||
|
||||
+56
-37
@@ -5,6 +5,7 @@ package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -62,14 +63,15 @@ const (
|
||||
const maximumValidHTTPCode = 600
|
||||
|
||||
// All code responses can be used to differentiate errors for different handling
|
||||
// by the consuming program
|
||||
// by the consuming program.
|
||||
const (
|
||||
// CompositeErrorCode remains 422 for backwards-compatibility
|
||||
// and to separate it from validation errors with cause
|
||||
// and to separate it from validation errors with cause.
|
||||
CompositeErrorCode = http.StatusUnprocessableEntity
|
||||
|
||||
// InvalidTypeCode is used for any subclass of invalid types
|
||||
// InvalidTypeCode is used for any subclass of invalid types.
|
||||
InvalidTypeCode = maximumValidHTTPCode + iota
|
||||
// RequiredFailCode indicates a required field is missing.
|
||||
RequiredFailCode
|
||||
TooLongFailCode
|
||||
TooShortFailCode
|
||||
@@ -90,22 +92,26 @@ const (
|
||||
ReadOnlyFailCode
|
||||
)
|
||||
|
||||
// CompositeError is an error that groups several errors together
|
||||
// CompositeError is an error that groups several errors together.
|
||||
type CompositeError struct {
|
||||
Errors []error
|
||||
code int32
|
||||
message string
|
||||
}
|
||||
|
||||
// Code for this error
|
||||
// Code returns the HTTP status code for this composite error.
|
||||
func (c *CompositeError) Code() int32 {
|
||||
return c.code
|
||||
}
|
||||
|
||||
// Error implements the standard error interface.
|
||||
func (c *CompositeError) Error() string {
|
||||
if len(c.Errors) > 0 {
|
||||
msgs := []string{c.message + ":"}
|
||||
for _, e := range c.Errors {
|
||||
if e == nil {
|
||||
continue
|
||||
}
|
||||
msgs = append(msgs, e.Error())
|
||||
}
|
||||
return strings.Join(msgs, "\n")
|
||||
@@ -113,11 +119,12 @@ func (c *CompositeError) Error() string {
|
||||
return c.message
|
||||
}
|
||||
|
||||
// Unwrap implements the [errors.Unwrap] interface.
|
||||
func (c *CompositeError) Unwrap() []error {
|
||||
return c.Errors
|
||||
}
|
||||
|
||||
// MarshalJSON implements the JSON encoding interface
|
||||
// MarshalJSON implements the JSON encoding interface.
|
||||
func (c CompositeError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]any{
|
||||
"code": c.code,
|
||||
@@ -126,7 +133,7 @@ func (c CompositeError) MarshalJSON() ([]byte, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// CompositeValidationError an error to wrap a bunch of other errors
|
||||
// CompositeValidationError an error to wrap a bunch of other errors.
|
||||
func CompositeValidationError(errors ...error) *CompositeError {
|
||||
return &CompositeError{
|
||||
code: CompositeErrorCode,
|
||||
@@ -135,20 +142,33 @@ func CompositeValidationError(errors ...error) *CompositeError {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateName recursively sets the name for all validations or updates them for nested properties
|
||||
// ValidateName recursively sets the name for all validations or updates them for nested properties.
|
||||
func (c *CompositeError) ValidateName(name string) *CompositeError {
|
||||
for i, e := range c.Errors {
|
||||
if ve, ok := e.(*Validation); ok {
|
||||
c.Errors[i] = ve.ValidateName(name)
|
||||
} else if ce, ok := e.(*CompositeError); ok {
|
||||
c.Errors[i] = ce.ValidateName(name)
|
||||
if e == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ce := &CompositeError{}
|
||||
if errors.As(e, &ce) {
|
||||
c.Errors[i] = ce.ValidateName(name)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
ve := &Validation{}
|
||||
if errors.As(e, &ve) {
|
||||
c.Errors[i] = ve.ValidateName(name)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// FailedAllPatternProperties an error for when the property doesn't match a pattern
|
||||
// FailedAllPatternProperties an error for when the property doesn't match a pattern.
|
||||
func FailedAllPatternProperties(name, in, key string) *Validation {
|
||||
msg := fmt.Sprintf(failedAllPatternProps, name, key, in)
|
||||
if in == "" {
|
||||
@@ -163,7 +183,7 @@ func FailedAllPatternProperties(name, in, key string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// PropertyNotAllowed an error for when the property doesn't match a pattern
|
||||
// PropertyNotAllowed an error for when the property doesn't match a pattern.
|
||||
func PropertyNotAllowed(name, in, key string) *Validation {
|
||||
msg := fmt.Sprintf(unallowedProperty, name, key, in)
|
||||
if in == "" {
|
||||
@@ -178,7 +198,7 @@ func PropertyNotAllowed(name, in, key string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooFewProperties an error for an object with too few properties
|
||||
// TooFewProperties an error for an object with too few properties.
|
||||
func TooFewProperties(name, in string, n int64) *Validation {
|
||||
msg := fmt.Sprintf(tooFewProperties, name, in, n)
|
||||
if in == "" {
|
||||
@@ -193,7 +213,7 @@ func TooFewProperties(name, in string, n int64) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooManyProperties an error for an object with too many properties
|
||||
// TooManyProperties an error for an object with too many properties.
|
||||
func TooManyProperties(name, in string, n int64) *Validation {
|
||||
msg := fmt.Sprintf(tooManyProperties, name, in, n)
|
||||
if in == "" {
|
||||
@@ -208,7 +228,7 @@ func TooManyProperties(name, in string, n int64) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// AdditionalItemsNotAllowed an error for invalid additional items
|
||||
// AdditionalItemsNotAllowed an error for invalid additional items.
|
||||
func AdditionalItemsNotAllowed(name, in string) *Validation {
|
||||
msg := fmt.Sprintf(noAdditionalItems, name, in)
|
||||
if in == "" {
|
||||
@@ -222,7 +242,7 @@ func AdditionalItemsNotAllowed(name, in string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// InvalidCollectionFormat another flavor of invalid type error
|
||||
// InvalidCollectionFormat another flavor of invalid type error.
|
||||
func InvalidCollectionFormat(name, in, format string) *Validation {
|
||||
return &Validation{
|
||||
code: InvalidTypeCode,
|
||||
@@ -233,7 +253,7 @@ func InvalidCollectionFormat(name, in, format string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// InvalidTypeName an error for when the type is invalid
|
||||
// InvalidTypeName an error for when the type is invalid.
|
||||
func InvalidTypeName(typeName string) *Validation {
|
||||
return &Validation{
|
||||
code: InvalidTypeCode,
|
||||
@@ -242,7 +262,7 @@ func InvalidTypeName(typeName string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// InvalidType creates an error for when the type is invalid
|
||||
// InvalidType creates an error for when the type is invalid.
|
||||
func InvalidType(name, in, typeName string, value any) *Validation {
|
||||
var message string
|
||||
|
||||
@@ -273,10 +293,9 @@ func InvalidType(name, in, typeName string, value any) *Validation {
|
||||
Value: value,
|
||||
message: message,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DuplicateItems error for when an array contains duplicates
|
||||
// DuplicateItems error for when an array contains duplicates.
|
||||
func DuplicateItems(name, in string) *Validation {
|
||||
msg := fmt.Sprintf(uniqueFail, name, in)
|
||||
if in == "" {
|
||||
@@ -290,7 +309,7 @@ func DuplicateItems(name, in string) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooManyItems error for when an array contains too many items
|
||||
// TooManyItems error for when an array contains too many items.
|
||||
func TooManyItems(name, in string, maximum int64, value any) *Validation {
|
||||
msg := fmt.Sprintf(maximumItemsFail, name, in, maximum)
|
||||
if in == "" {
|
||||
@@ -306,7 +325,7 @@ func TooManyItems(name, in string, maximum int64, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooFewItems error for when an array contains too few items
|
||||
// TooFewItems error for when an array contains too few items.
|
||||
func TooFewItems(name, in string, minimum int64, value any) *Validation {
|
||||
msg := fmt.Sprintf(minItemsFail, name, in, minimum)
|
||||
if in == "" {
|
||||
@@ -321,7 +340,7 @@ func TooFewItems(name, in string, minimum int64, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumInt error for when maximumimum validation fails
|
||||
// ExceedsMaximumInt error for when maximum validation fails.
|
||||
func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -346,7 +365,7 @@ func ExceedsMaximumInt(name, in string, maximum int64, exclusive bool, value any
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximumUint error for when maximumimum validation fails
|
||||
// ExceedsMaximumUint error for when maximum validation fails.
|
||||
func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -371,7 +390,7 @@ func ExceedsMaximumUint(name, in string, maximum uint64, exclusive bool, value a
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMaximum error for when maximumimum validation fails
|
||||
// ExceedsMaximum error for when maximum validation fails.
|
||||
func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -396,7 +415,7 @@ func ExceedsMaximum(name, in string, maximum float64, exclusive bool, value any)
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumInt error for when minimum validation fails
|
||||
// ExceedsMinimumInt error for when minimum validation fails.
|
||||
func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -421,7 +440,7 @@ func ExceedsMinimumInt(name, in string, minimum int64, exclusive bool, value any
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimumUint error for when minimum validation fails
|
||||
// ExceedsMinimumUint error for when minimum validation fails.
|
||||
func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -446,7 +465,7 @@ func ExceedsMinimumUint(name, in string, minimum uint64, exclusive bool, value a
|
||||
}
|
||||
}
|
||||
|
||||
// ExceedsMinimum error for when minimum validation fails
|
||||
// ExceedsMinimum error for when minimum validation fails.
|
||||
func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value any) *Validation {
|
||||
var message string
|
||||
if in == "" {
|
||||
@@ -471,7 +490,7 @@ func ExceedsMinimum(name, in string, minimum float64, exclusive bool, value any)
|
||||
}
|
||||
}
|
||||
|
||||
// NotMultipleOf error for when multiple of validation fails
|
||||
// NotMultipleOf error for when multiple of validation fails.
|
||||
func NotMultipleOf(name, in string, multiple, value any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -488,7 +507,7 @@ func NotMultipleOf(name, in string, multiple, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// EnumFail error for when an enum validation fails
|
||||
// EnumFail error for when an enum validation fails.
|
||||
func EnumFail(name, in string, value any, values []any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -507,7 +526,7 @@ func EnumFail(name, in string, value any, values []any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// Required error for when a value is missing
|
||||
// Required error for when a value is missing.
|
||||
func Required(name, in string, value any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -524,7 +543,7 @@ func Required(name, in string, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// ReadOnly error for when a value is present in request
|
||||
// ReadOnly error for when a value is present in request.
|
||||
func ReadOnly(name, in string, value any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -541,7 +560,7 @@ func ReadOnly(name, in string, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooLong error for when a string is too long
|
||||
// TooLong error for when a string is too long.
|
||||
func TooLong(name, in string, maximum int64, value any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -558,7 +577,7 @@ func TooLong(name, in string, maximum int64, value any) *Validation {
|
||||
}
|
||||
}
|
||||
|
||||
// TooShort error for when a string is too short
|
||||
// TooShort error for when a string is too short.
|
||||
func TooShort(name, in string, minimum int64, value any) *Validation {
|
||||
var msg string
|
||||
if in == "" {
|
||||
@@ -596,7 +615,7 @@ func FailedPattern(name, in, pattern string, value any) *Validation {
|
||||
}
|
||||
|
||||
// MultipleOfMustBePositive error for when a
|
||||
// multipleOf factor is negative
|
||||
// multipleOf factor is negative.
|
||||
func MultipleOfMustBePositive(name, in string, factor any) *Validation {
|
||||
return &Validation{
|
||||
code: MultipleOfMustBePositiveCode,
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
# git-cliff ~ configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
|
||||
[changelog]
|
||||
header = """
|
||||
"""
|
||||
|
||||
footer = """
|
||||
|
||||
-----
|
||||
|
||||
**[{{ remote.github.repo }}]({{ self::remote_url() }}) license terms**
|
||||
|
||||
[![License][license-badge]][license-url]
|
||||
|
||||
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
|
||||
[license-url]: {{ self::remote_url() }}/?tab=Apache-2.0-1-ov-file#readme
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
|
||||
body = """
|
||||
{%- if version %}
|
||||
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{%- else %}
|
||||
## [unreleased]
|
||||
{%- endif %}
|
||||
{%- if message %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ message }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
{%- if version %}
|
||||
{%- if previous.version %}
|
||||
|
||||
**Full Changelog**: <{{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}>
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if statistics %}{% if statistics.commit_count %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ statistics.commit_count }} commits in this release.
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}{% endif %}
|
||||
-----
|
||||
|
||||
{%- for group, commits in commits | group_by(attribute="group") %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
### {{ group | upper_first }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- for commit in commits %}
|
||||
{%- if commit.remote.pr_title %}
|
||||
{%- set commit_message = commit.remote.pr_title %}
|
||||
{%- else %}
|
||||
{%- set commit_message = commit.message %}
|
||||
{%- endif %}
|
||||
* {{ commit_message | split(pat="\n") | first | trim }}
|
||||
{%- if commit.remote.username %}
|
||||
{%- raw %} {% endraw %}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }})
|
||||
{%- endif %}
|
||||
{%- if commit.remote.pr_number %}
|
||||
{%- raw %} {% endraw %}in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})
|
||||
{%- endif %}
|
||||
{%- raw %} {% endraw %}[...]({{ self::remote_url() }}/commit/{{ commit.id }})
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if github %}
|
||||
{%- raw %}\n{% endraw -%}
|
||||
{%- set all_contributors = github.contributors | length %}
|
||||
{%- if github.contributors | filter(attribute="username", value="dependabot[bot]") | length < all_contributors %}
|
||||
-----
|
||||
|
||||
### People who contributed to this release
|
||||
{% endif %}
|
||||
{%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* [@{{ contributor.username }}](https://github.com/{{ contributor.username }})
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||
-----
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
### New Contributors
|
||||
{%- endif %}
|
||||
|
||||
{%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* @{{ contributor.username }} made their first contribution
|
||||
{%- if contributor.pr_number %}
|
||||
in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
# Remove leading and trailing whitespaces from the changelog's body.
|
||||
trim = true
|
||||
# Render body even when there are no releases to process.
|
||||
render_always = true
|
||||
# An array of regex based postprocessors to modify the changelog.
|
||||
postprocessors = [
|
||||
# Replace the placeholder <REPO> with a URL.
|
||||
#{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" },
|
||||
]
|
||||
# output file path
|
||||
# output = "test.md"
|
||||
|
||||
[git]
|
||||
# Parse commits according to the conventional commits specification.
|
||||
# See https://www.conventionalcommits.org
|
||||
conventional_commits = false
|
||||
# Exclude commits that do not match the conventional commits specification.
|
||||
filter_unconventional = false
|
||||
# Require all commits to be conventional.
|
||||
# Takes precedence over filter_unconventional.
|
||||
require_conventional = false
|
||||
# Split commits on newlines, treating each line as an individual commit.
|
||||
split_commits = false
|
||||
# An array of regex based parsers to modify commit messages prior to further processing.
|
||||
commit_preprocessors = [
|
||||
# Replace issue numbers with link templates to be updated in `changelog.postprocessors`.
|
||||
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||
# Check spelling of the commit message using https://github.com/crate-ci/typos.
|
||||
# If the spelling is incorrect, it will be fixed automatically.
|
||||
#{ pattern = '.*', replace_command = 'typos --write-changes -' }
|
||||
]
|
||||
# Prevent commits that are breaking from being excluded by commit parsers.
|
||||
protect_breaking_commits = false
|
||||
# An array of regex based parsers for extracting data from the commit message.
|
||||
# Assigns commits to groups.
|
||||
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
|
||||
commit_parsers = [
|
||||
{ message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true },
|
||||
{ message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true },
|
||||
{ field = "author.name", pattern = "dependabot*", group = "<!-- 0A -->Updates" },
|
||||
{ message = "([Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ body = "(.*[Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "<!-- 05 -->Code quality" },
|
||||
{ message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "<!-- 03 -->Documentation" },
|
||||
{ message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "<!-- 00 -->Implemented enhancements" },
|
||||
{ message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^test", group = "<!-- 06 -->Testing" },
|
||||
{ message = "(^fix)|(panic)", group = "<!-- 01 -->Fixed bugs" },
|
||||
{ message = "(^refact)|(rework)", group = "<!-- 02 -->Refactor" },
|
||||
{ message = "(^[Pp]erf)|(performance)", group = "<!-- 04 -->Performance" },
|
||||
{ message = "(^[Cc]hore)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^[Rr]evert", group = "<!-- 09 -->Reverted changes" },
|
||||
{ message = "(upgrade.*?go)|(go\\s+version)", group = "<!-- 0A -->Updates" },
|
||||
{ message = ".*", group = "<!-- 0B -->Other" },
|
||||
]
|
||||
# Exclude commits that are not matched by any commit parser.
|
||||
filter_commits = false
|
||||
# An array of link parsers for extracting external references, and turning them into URLs, using regex.
|
||||
link_parsers = []
|
||||
# Include only the tags that belong to the current branch.
|
||||
use_branch_tags = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order_commits = true
|
||||
# Order of commits in each group/release within the changelog.
|
||||
# Allowed values: newest, oldest
|
||||
sort_commits = "newest"
|
||||
# Process submodules commits
|
||||
recurse_submodules = false
|
||||
|
||||
#[remote.github]
|
||||
#owner = "go-openapi"
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
secrets.yml
|
||||
*.out
|
||||
*.cov
|
||||
.idea
|
||||
.env
|
||||
|
||||
+10
-19
@@ -2,34 +2,17 @@ version: "2"
|
||||
linters:
|
||||
default: all
|
||||
disable:
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- exhaustruct
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
@@ -41,8 +24,15 @@ linters:
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
cyclop:
|
||||
max-complexity: 20
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
min-complexity: 20
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: true
|
||||
default-case-required: true
|
||||
lll:
|
||||
line-length: 180
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
@@ -58,6 +48,7 @@ formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- gofumpt
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
# Contributors
|
||||
|
||||
- Repository: ['go-openapi/jsonpointer']
|
||||
|
||||
| Total Contributors | Total Contributions |
|
||||
| --- | --- |
|
||||
| 12 | 95 |
|
||||
|
||||
| Username | All Time Contribution Count | All Commits |
|
||||
| --- | --- | --- |
|
||||
| @fredbi | 48 | https://github.com/go-openapi/jsonpointer/commits?author=fredbi |
|
||||
| @casualjim | 33 | https://github.com/go-openapi/jsonpointer/commits?author=casualjim |
|
||||
| @magodo | 3 | https://github.com/go-openapi/jsonpointer/commits?author=magodo |
|
||||
| @youyuanwu | 3 | https://github.com/go-openapi/jsonpointer/commits?author=youyuanwu |
|
||||
| @gaiaz-iusipov | 1 | https://github.com/go-openapi/jsonpointer/commits?author=gaiaz-iusipov |
|
||||
| @gbjk | 1 | https://github.com/go-openapi/jsonpointer/commits?author=gbjk |
|
||||
| @gordallott | 1 | https://github.com/go-openapi/jsonpointer/commits?author=gordallott |
|
||||
| @ianlancetaylor | 1 | https://github.com/go-openapi/jsonpointer/commits?author=ianlancetaylor |
|
||||
| @mfleader | 1 | https://github.com/go-openapi/jsonpointer/commits?author=mfleader |
|
||||
| @Neo2308 | 1 | https://github.com/go-openapi/jsonpointer/commits?author=Neo2308 |
|
||||
| @olivierlemasle | 1 | https://github.com/go-openapi/jsonpointer/commits?author=olivierlemasle |
|
||||
| @testwill | 1 | https://github.com/go-openapi/jsonpointer/commits?author=testwill |
|
||||
|
||||
_this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
Copyright 2015-2025 go-swagger maintainers
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
This software library, github.com/go-openapi/jsonpointer, includes software developed
|
||||
by the go-swagger and go-openapi maintainers ("go-swagger maintainers").
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this software except in compliance with the License.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
This software is copied from, derived from, and inspired by other original software products.
|
||||
It ships with copies of other software which license terms are recalled below.
|
||||
|
||||
The original software was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com).
|
||||
|
||||
github.com/sigh-399/jsonpointer
|
||||
===========================
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+135
-12
@@ -1,16 +1,78 @@
|
||||
# gojsonpointer [](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/jsonpointer)
|
||||
# jsonpointer
|
||||
|
||||
[](https://slackin.goswagger.io)
|
||||
[](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE)
|
||||
[](https://pkg.go.dev/github.com/go-openapi/jsonpointer)
|
||||
[](https://goreportcard.com/report/github.com/go-openapi/jsonpointer)
|
||||
<!-- Badges: status -->
|
||||
[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url]
|
||||
<!-- Badges: release & docker images -->
|
||||
<!-- Badges: code quality -->
|
||||
<!-- Badges: license & compliance -->
|
||||
[![Release][release-badge]][release-url] [![Go Report Card][gocard-badge]][gocard-url] [![CodeFactor Grade][codefactor-badge]][codefactor-url] [![License][license-badge]][license-url]
|
||||
<!-- Badges: documentation & support -->
|
||||
<!-- Badges: others & stats -->
|
||||
[![GoDoc][godoc-badge]][godoc-url] [![Slack Channel][slack-logo]![slack-badge]][slack-url] [![go version][goversion-badge]][goversion-url] ![Top language][top-badge] ![Commits since latest release][commits-badge]
|
||||
|
||||
An implementation of JSON Pointer - Go language
|
||||
---
|
||||
|
||||
An implementation of JSON Pointer for golang, which supports go `struct`.
|
||||
|
||||
## Status
|
||||
Completed YES
|
||||
|
||||
Tested YES
|
||||
API is stable.
|
||||
|
||||
## Import this library in your project
|
||||
|
||||
```cmd
|
||||
go get github.com/go-openapi/jsonpointer
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
See also some [examples](./examples_test.go)
|
||||
|
||||
### Retrieving a value
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/go-openapi/jsonpointer"
|
||||
)
|
||||
|
||||
|
||||
var doc any
|
||||
|
||||
...
|
||||
|
||||
pointer, err := jsonpointer.New("/foo/1")
|
||||
if err != nil {
|
||||
... // error: e.g. invalid JSON pointer specification
|
||||
}
|
||||
|
||||
value, kind, err := pointer.Get(doc)
|
||||
if err != nil {
|
||||
... // error: e.g. key not found, index out of bounds, etc.
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### Setting a value
|
||||
|
||||
```go
|
||||
...
|
||||
var doc any
|
||||
...
|
||||
pointer, err := jsonpointer.New("/foo/1")
|
||||
if err != nil {
|
||||
... // error: e.g. invalid JSON pointer specification
|
||||
}
|
||||
|
||||
doc, err = p.Set(doc, "value")
|
||||
if err != nil {
|
||||
... // error: e.g. key not found, index out of bounds, etc.
|
||||
}
|
||||
```
|
||||
|
||||
## Change log
|
||||
|
||||
See <https://github.com/go-openapi/jsonpointer/releases>
|
||||
|
||||
## References
|
||||
|
||||
@@ -18,9 +80,70 @@ Tested YES
|
||||
|
||||
also known as [RFC6901](https://www.rfc-editor.org/rfc/rfc6901)
|
||||
|
||||
### Note
|
||||
## Licensing
|
||||
|
||||
The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented.
|
||||
This library ships under the [SPDX-License-Identifier: Apache-2.0](./LICENSE).
|
||||
|
||||
That is because our implementation of the JSON pointer only supports explicit references to array elements: the provision in the spec
|
||||
to resolve non-existent members as "the last element in the array", using the special trailing character "-".
|
||||
See the license [NOTICE](./NOTICE), which recalls the licensing terms of all the pieces of software
|
||||
on top of which it has been built.
|
||||
|
||||
## Limitations
|
||||
|
||||
The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array,
|
||||
the reference token MUST contain either...' is not implemented.
|
||||
|
||||
That is because our implementation of the JSON pointer only supports explicit references to array elements:
|
||||
the provision in the spec to resolve non-existent members as "the last element in the array",
|
||||
using the special trailing character "-" is not implemented.
|
||||
|
||||
## Other documentation
|
||||
|
||||
* [All-time contributors](./CONTRIBUTORS.md)
|
||||
* [Contributing guidelines](.github/CONTRIBUTING.md)
|
||||
* [Maintainers documentation](docs/MAINTAINERS.md)
|
||||
* [Code style](docs/STYLE.md)
|
||||
|
||||
## Cutting a new release
|
||||
|
||||
Maintainers can cut a new release by either:
|
||||
|
||||
* running [this workflow](https://github.com/go-openapi/jsonpointer/actions/workflows/bump-release.yml)
|
||||
* or pushing a semver tag
|
||||
* signed tags are preferred
|
||||
* The tag message is prepended to release notes
|
||||
|
||||
<!-- Badges: status -->
|
||||
[test-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg
|
||||
[test-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml
|
||||
[cov-badge]: https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg
|
||||
[cov-url]: https://codecov.io/gh/go-openapi/jsonpointer
|
||||
[vuln-scan-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/scanner.yml/badge.svg
|
||||
[vuln-scan-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/scanner.yml
|
||||
[codeql-badge]: https://github.com/go-openapi/jsonpointer/actions/workflows/codeql.yml/badge.svg
|
||||
[codeql-url]: https://github.com/go-openapi/jsonpointer/actions/workflows/codeql.yml
|
||||
<!-- Badges: release & docker images -->
|
||||
[release-badge]: https://badge.fury.io/gh/go-openapi%2Fjsonpointer.svg
|
||||
[release-url]: https://badge.fury.io/gh/go-openapi%2Fjsonpointer
|
||||
[gomod-badge]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonpointer.svg
|
||||
[gomod-url]: https://badge.fury.io/go/github.com%2Fgo-openapi%2Fjsonpointer
|
||||
<!-- Badges: code quality -->
|
||||
[gocard-badge]: https://goreportcard.com/badge/github.com/go-openapi/jsonpointer
|
||||
[gocard-url]: https://goreportcard.com/report/github.com/go-openapi/jsonpointer
|
||||
[codefactor-badge]: https://img.shields.io/codefactor/grade/github/go-openapi/jsonpointer
|
||||
[codefactor-url]: https://www.codefactor.io/repository/github/go-openapi/jsonpointer
|
||||
<!-- Badges: documentation & support -->
|
||||
[doc-badge]: https://img.shields.io/badge/doc-site-blue?link=https%3A%2F%2Fgoswagger.io%2Fgo-openapi%2F
|
||||
[doc-url]: https://goswagger.io/go-openapi
|
||||
[godoc-badge]: https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer
|
||||
[godoc-url]: http://pkg.go.dev/github.com/go-openapi/jsonpointer
|
||||
[slack-logo]: https://a.slack-edge.com/e6a93c1/img/icons/favicon-32.png
|
||||
[slack-badge]: https://img.shields.io/badge/slack-blue?link=https%3A%2F%2Fgoswagger.slack.com%2Farchives%2FC04R30YM
|
||||
[slack-url]: https://goswagger.slack.com/archives/C04R30YMU
|
||||
<!-- Badges: license & compliance -->
|
||||
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
|
||||
[license-url]: https://github.com/go-openapi/jsonpointer/?tab=Apache-2.0-1-ov-file#readme
|
||||
<!-- Badges: others & stats -->
|
||||
[goversion-badge]: https://img.shields.io/github/go-mod/go-version/go-openapi/jsonpointer
|
||||
[goversion-url]: https://github.com/go-openapi/jsonpointer/blob/master/go.mod
|
||||
[top-badge]: https://img.shields.io/github/languages/top/go-openapi/jsonpointer
|
||||
[commits-badge]: https://img.shields.io/github/commits-since/go-openapi/jsonpointer/latest
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Security Policy
|
||||
|
||||
This policy outlines the commitment and practices of the go-openapi maintainers regarding security.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.22.x | :white_check_mark: |
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
If you become aware of a security vulnerability that affects the current repository,
|
||||
please report it privately to the maintainers.
|
||||
|
||||
Please follow the instructions provided by github to
|
||||
[Privately report a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability).
|
||||
|
||||
TL;DR: on Github, navigate to the project's "Security" tab then click on "Report a vulnerability".
|
||||
+20
-3
@@ -1,5 +1,10 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package jsonpointer
|
||||
|
||||
import "fmt"
|
||||
|
||||
type pointerError string
|
||||
|
||||
func (e pointerError) Error() string {
|
||||
@@ -7,12 +12,24 @@ func (e pointerError) Error() string {
|
||||
}
|
||||
|
||||
const (
|
||||
// ErrPointer is an error raised by the jsonpointer package
|
||||
// ErrPointer is a sentinel error raised by all errors from this package.
|
||||
ErrPointer pointerError = "JSON pointer error"
|
||||
|
||||
// ErrInvalidStart states that a JSON pointer must start with a separator ("/")
|
||||
// ErrInvalidStart states that a JSON pointer must start with a separator ("/").
|
||||
ErrInvalidStart pointerError = `JSON pointer must be empty or start with a "` + pointerSeparator
|
||||
|
||||
// ErrUnsupportedValueType indicates that a value of the wrong type is being set
|
||||
// ErrUnsupportedValueType indicates that a value of the wrong type is being set.
|
||||
ErrUnsupportedValueType pointerError = "only structs, pointers, maps and slices are supported for setting values"
|
||||
)
|
||||
|
||||
func errNoKey(key string) error {
|
||||
return fmt.Errorf("object has no key %q: %w", key, ErrPointer)
|
||||
}
|
||||
|
||||
func errOutOfBounds(length, idx int) error {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", length-1, idx, ErrPointer)
|
||||
}
|
||||
|
||||
func errInvalidReference(token string) error {
|
||||
return fmt.Errorf("invalid token reference %q: %w", token, ErrPointer)
|
||||
}
|
||||
|
||||
+213
-165
@@ -1,28 +1,7 @@
|
||||
// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// author sigu-399
|
||||
// author-github https://github.com/sigu-399
|
||||
// author-mail sigu.399@gmail.com
|
||||
//
|
||||
// repository-name jsonpointer
|
||||
// repository-desc An implementation of JSON Pointer - Go language
|
||||
//
|
||||
// description Main and unique file.
|
||||
//
|
||||
// created 25-02-2013
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 go-swagger maintainers
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package jsonpointer provides a golang implementation for json pointers.
|
||||
package jsonpointer
|
||||
|
||||
import (
|
||||
@@ -41,29 +20,47 @@ const (
|
||||
pointerSeparator = `/`
|
||||
)
|
||||
|
||||
var (
|
||||
jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
|
||||
jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
|
||||
)
|
||||
|
||||
// JSONPointable is an interface for structs to implement when they need to customize the
|
||||
// json pointer process
|
||||
// JSONPointable is an interface for structs to implement,
|
||||
// when they need to customize the json pointer process or want to avoid the use of reflection.
|
||||
type JSONPointable interface {
|
||||
JSONLookup(string) (any, error)
|
||||
// JSONLookup returns a value pointed at this (unescaped) key.
|
||||
JSONLookup(key string) (any, error)
|
||||
}
|
||||
|
||||
// JSONSetable is an interface for structs to implement when they need to customize the
|
||||
// json pointer process
|
||||
// JSONSetable is an interface for structs to implement,
|
||||
// when they need to customize the json pointer process or want to avoid the use of reflection.
|
||||
type JSONSetable interface {
|
||||
JSONSet(string, any) error
|
||||
// JSONSet sets the value pointed at the (unescaped) key.
|
||||
JSONSet(key string, value any) error
|
||||
}
|
||||
|
||||
// Pointer is a representation of a json pointer
|
||||
// Pointer is a representation of a json pointer.
|
||||
//
|
||||
// Use [Pointer.Get] to retrieve a value or [Pointer.Set] to set a value.
|
||||
//
|
||||
// It works with any go type interpreted as a JSON document, which means:
|
||||
//
|
||||
// - if a type implements [JSONPointable], its [JSONPointable.JSONLookup] method is used to resolve [Pointer.Get]
|
||||
// - if a type implements [JSONSetable], its [JSONPointable.JSONSet] method is used to resolve [Pointer.Set]
|
||||
// - a go map[K]V is interpreted as an object, with type K assignable to a string
|
||||
// - a go slice []T is interpreted as an array
|
||||
// - a go struct is interpreted as an object, with exported fields interpreted as keys
|
||||
// - promoted fields from an embedded struct are traversed
|
||||
// - scalars (e.g. int, float64 ...), channels, functions and go arrays cannot be traversed
|
||||
//
|
||||
// For struct s resolved by reflection, key mappings honor the conventional struct tag `json`.
|
||||
//
|
||||
// Fields that do not specify a `json` tag, or specify an empty one, or are tagged as `json:"-"` are ignored.
|
||||
//
|
||||
// # Limitations
|
||||
//
|
||||
// - Unlike go standard marshaling, untagged fields do not default to the go field name and are ignored.
|
||||
// - anonymous fields are not traversed if untagged
|
||||
type Pointer struct {
|
||||
referenceTokens []string
|
||||
}
|
||||
|
||||
// New creates a new json pointer for the given string
|
||||
// New creates a new json pointer from its string representation.
|
||||
func New(jsonPointerString string) (Pointer, error) {
|
||||
var p Pointer
|
||||
err := p.parse(jsonPointerString)
|
||||
@@ -71,34 +68,40 @@ func New(jsonPointerString string) (Pointer, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
// Get uses the pointer to retrieve a value from a JSON document
|
||||
// Get uses the pointer to retrieve a value from a JSON document.
|
||||
//
|
||||
// It returns the value with its type as a [reflect.Kind] or an error.
|
||||
func (p *Pointer) Get(document any) (any, reflect.Kind, error) {
|
||||
return p.get(document, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// Set uses the pointer to set a value from a JSON document
|
||||
// Set uses the pointer to set a value from a data type
|
||||
// that represent a JSON document.
|
||||
//
|
||||
// It returns the updated document.
|
||||
func (p *Pointer) Set(document any, value any) (any, error) {
|
||||
return document, p.set(document, value, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// DecodedTokens returns the decoded tokens of this JSON pointer
|
||||
// DecodedTokens returns the decoded (unescaped) tokens of this JSON pointer.
|
||||
func (p *Pointer) DecodedTokens() []string {
|
||||
result := make([]string, 0, len(p.referenceTokens))
|
||||
for _, t := range p.referenceTokens {
|
||||
result = append(result, Unescape(t))
|
||||
for _, token := range p.referenceTokens {
|
||||
result = append(result, Unescape(token))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// IsEmpty returns true if this is an empty json pointer
|
||||
// this indicates that it points to the root document
|
||||
// IsEmpty returns true if this is an empty json pointer.
|
||||
//
|
||||
// This indicates that it points to the root document.
|
||||
func (p *Pointer) IsEmpty() bool {
|
||||
return len(p.referenceTokens) == 0
|
||||
}
|
||||
|
||||
// Pointer to string representation function
|
||||
// String representation of a pointer.
|
||||
func (p *Pointer) String() string {
|
||||
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return emptyPointer
|
||||
}
|
||||
@@ -137,20 +140,21 @@ func (p *Pointer) Offset(document string) (int64, error) {
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// "Constructor", parses the given string JSON pointer
|
||||
// "Constructor", parses the given string JSON pointer.
|
||||
func (p *Pointer) parse(jsonPointerString string) error {
|
||||
var err error
|
||||
|
||||
if jsonPointerString != emptyPointer {
|
||||
if !strings.HasPrefix(jsonPointerString, pointerSeparator) {
|
||||
err = errors.Join(ErrInvalidStart, ErrPointer)
|
||||
} else {
|
||||
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
|
||||
p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
|
||||
}
|
||||
if jsonPointerString == emptyPointer {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
if !strings.HasPrefix(jsonPointerString, pointerSeparator) {
|
||||
// non empty pointer must start with "/"
|
||||
return errors.Join(ErrInvalidStart, ErrPointer)
|
||||
}
|
||||
|
||||
referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
|
||||
p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, reflect.Kind, error) {
|
||||
@@ -160,7 +164,7 @@ func (p *Pointer) get(node any, nameProvider *jsonname.NameProvider) (any, refle
|
||||
|
||||
kind := reflect.Invalid
|
||||
|
||||
// Full document when empty
|
||||
// full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return node, kind, nil
|
||||
}
|
||||
@@ -186,101 +190,103 @@ func (p *Pointer) set(node, data any, nameProvider *jsonname.NameProvider) error
|
||||
|
||||
if knd != reflect.Pointer && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
|
||||
return errors.Join(
|
||||
fmt.Errorf("unexpected type: %T", node), //nolint:err113 // err wrapping is carried out by errors.Join, not fmt.Errorf.
|
||||
ErrUnsupportedValueType,
|
||||
ErrPointer,
|
||||
)
|
||||
}
|
||||
|
||||
l := len(p.referenceTokens)
|
||||
|
||||
// full document when empty
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if nameProvider == nil {
|
||||
nameProvider = jsonname.DefaultJSONNameProvider
|
||||
}
|
||||
|
||||
// Full document when empty
|
||||
if len(p.referenceTokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
var decodedToken string
|
||||
lastIndex := l - 1
|
||||
|
||||
lastI := len(p.referenceTokens) - 1
|
||||
for i, token := range p.referenceTokens {
|
||||
isLastToken := i == lastI
|
||||
decodedToken := Unescape(token)
|
||||
|
||||
if isLastToken {
|
||||
|
||||
return setSingleImpl(node, data, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
// Check for nil during traversal
|
||||
if isNil(node) {
|
||||
return fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
|
||||
if rValue.Type().Implements(jsonPointableType) {
|
||||
r, err := node.(JSONPointable).JSONLookup(decodedToken)
|
||||
if lastIndex > 0 { // skip if we only have one token in pointer
|
||||
for _, token := range p.referenceTokens[:lastIndex] {
|
||||
decodedToken = Unescape(token)
|
||||
next, err := p.resolveNodeForToken(node, decodedToken, nameProvider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fld := reflect.ValueOf(r)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = r
|
||||
continue
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer {
|
||||
node = fld.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = fld.Interface()
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if !mv.IsValid() {
|
||||
return fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Pointer {
|
||||
node = mv.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = mv.Interface()
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Pointer {
|
||||
node = elem.Addr().Interface()
|
||||
continue
|
||||
}
|
||||
node = elem.Interface()
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
node = next
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// last token
|
||||
decodedToken = Unescape(p.referenceTokens[lastIndex])
|
||||
|
||||
return setSingleImpl(node, data, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
func (p *Pointer) resolveNodeForToken(node any, decodedToken string, nameProvider *jsonname.NameProvider) (next any, err error) {
|
||||
// check for nil during traversal
|
||||
if isNil(node) {
|
||||
return nil, fmt.Errorf("cannot traverse through nil value at %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
pointable, ok := node.(JSONPointable)
|
||||
if ok {
|
||||
r, err := pointable.JSONLookup(decodedToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fld := reflect.ValueOf(r)
|
||||
if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Pointer {
|
||||
return fld.Addr().Interface(), nil
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
kind := rValue.Kind()
|
||||
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
return typeFromValue(rValue.FieldByName(nm)), nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
mv := rValue.MapIndex(kv)
|
||||
|
||||
if !mv.IsValid() {
|
||||
return nil, errNoKey(decodedToken)
|
||||
}
|
||||
|
||||
return typeFromValue(mv), nil
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return nil, errors.Join(err, ErrPointer)
|
||||
}
|
||||
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return nil, errOutOfBounds(sLength, tokenIndex)
|
||||
}
|
||||
|
||||
return typeFromValue(rValue.Index(tokenIndex)), nil
|
||||
|
||||
default:
|
||||
return nil, errInvalidReference(decodedToken)
|
||||
}
|
||||
}
|
||||
|
||||
func isNil(input any) bool {
|
||||
@@ -289,7 +295,7 @@ func isNil(input any) bool {
|
||||
}
|
||||
|
||||
kind := reflect.TypeOf(input).Kind()
|
||||
switch kind { //nolint:exhaustive
|
||||
switch kind {
|
||||
case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Chan:
|
||||
return reflect.ValueOf(input).IsNil()
|
||||
default:
|
||||
@@ -297,12 +303,20 @@ func isNil(input any) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// GetForToken gets a value for a json pointer token 1 level deep
|
||||
func typeFromValue(v reflect.Value) any {
|
||||
if v.CanAddr() && v.Kind() != reflect.Interface && v.Kind() != reflect.Map && v.Kind() != reflect.Slice && v.Kind() != reflect.Pointer {
|
||||
return v.Addr().Interface()
|
||||
}
|
||||
|
||||
return v.Interface()
|
||||
}
|
||||
|
||||
// GetForToken gets a value for a json pointer token 1 level deep.
|
||||
func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
|
||||
return getSingleImpl(document, decodedToken, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
|
||||
// SetForToken gets a value for a json pointer token 1 level deep
|
||||
// SetForToken sets a value for a json pointer token 1 level deep.
|
||||
func SetForToken(document any, decodedToken string, value any) (any, error) {
|
||||
return document, setSingleImpl(document, value, decodedToken, jsonname.DefaultJSONNameProvider)
|
||||
}
|
||||
@@ -325,13 +339,15 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro
|
||||
return getSingleImpl(*typed, decodedToken, nameProvider)
|
||||
}
|
||||
|
||||
switch kind { //nolint:exhaustive
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return nil, kind, fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
fld := rValue.FieldByName(nm)
|
||||
|
||||
return fld.Interface(), kind, nil
|
||||
|
||||
case reflect.Map:
|
||||
@@ -341,78 +357,99 @@ func getSingleImpl(node any, decodedToken string, nameProvider *jsonname.NamePro
|
||||
if mv.IsValid() {
|
||||
return mv.Interface(), kind, nil
|
||||
}
|
||||
return nil, kind, fmt.Errorf("object has no key %q: %w", decodedToken, ErrPointer)
|
||||
|
||||
return nil, kind, errNoKey(decodedToken)
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return nil, kind, err
|
||||
return nil, kind, errors.Join(err, ErrPointer)
|
||||
}
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength-1, tokenIndex, ErrPointer)
|
||||
return nil, kind, errOutOfBounds(sLength, tokenIndex)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
return elem.Interface(), kind, nil
|
||||
|
||||
default:
|
||||
return nil, kind, fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
return nil, kind, errInvalidReference(decodedToken)
|
||||
}
|
||||
}
|
||||
|
||||
func setSingleImpl(node, data any, decodedToken string, nameProvider *jsonname.NameProvider) error {
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
|
||||
// Check for nil to prevent panic when calling rValue.Type()
|
||||
// check for nil to prevent panic when calling rValue.Type()
|
||||
if isNil(node) {
|
||||
return fmt.Errorf("cannot set field %q on nil value: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
if ns, ok := node.(JSONSetable); ok { // pointer impl
|
||||
if ns, ok := node.(JSONSetable); ok {
|
||||
return ns.JSONSet(decodedToken, data)
|
||||
}
|
||||
|
||||
if rValue.Type().Implements(jsonSetableType) {
|
||||
return node.(JSONSetable).JSONSet(decodedToken, data)
|
||||
}
|
||||
rValue := reflect.Indirect(reflect.ValueOf(node))
|
||||
|
||||
switch rValue.Kind() { //nolint:exhaustive
|
||||
switch rValue.Kind() {
|
||||
case reflect.Struct:
|
||||
nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
|
||||
if !ok {
|
||||
return fmt.Errorf("object has no field %q: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
fld := rValue.FieldByName(nm)
|
||||
if fld.IsValid() {
|
||||
fld.Set(reflect.ValueOf(data))
|
||||
if !fld.CanSet() {
|
||||
return fmt.Errorf("can't set struct field %s to %v: %w", nm, data, ErrPointer)
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(data)
|
||||
valueType := value.Type()
|
||||
assignedType := fld.Type()
|
||||
|
||||
if !valueType.AssignableTo(assignedType) {
|
||||
return fmt.Errorf("can't set value with type %T to field %s with type %v: %w", data, nm, assignedType, ErrPointer)
|
||||
}
|
||||
|
||||
fld.Set(value)
|
||||
|
||||
return nil
|
||||
|
||||
case reflect.Map:
|
||||
kv := reflect.ValueOf(decodedToken)
|
||||
rValue.SetMapIndex(kv, reflect.ValueOf(data))
|
||||
|
||||
return nil
|
||||
|
||||
case reflect.Slice:
|
||||
tokenIndex, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Join(err, ErrPointer)
|
||||
}
|
||||
|
||||
sLength := rValue.Len()
|
||||
if tokenIndex < 0 || tokenIndex >= sLength {
|
||||
return fmt.Errorf("index out of bounds array[0,%d] index '%d': %w", sLength, tokenIndex, ErrPointer)
|
||||
return errOutOfBounds(sLength, tokenIndex)
|
||||
}
|
||||
|
||||
elem := rValue.Index(tokenIndex)
|
||||
if !elem.CanSet() {
|
||||
return fmt.Errorf("can't set slice index %s to %v: %w", decodedToken, data, ErrPointer)
|
||||
}
|
||||
elem.Set(reflect.ValueOf(data))
|
||||
|
||||
value := reflect.ValueOf(data)
|
||||
valueType := value.Type()
|
||||
assignedType := elem.Type()
|
||||
|
||||
if !valueType.AssignableTo(assignedType) {
|
||||
return fmt.Errorf("can't set value with type %T to slice element %d with type %v: %w", data, tokenIndex, assignedType, ErrPointer)
|
||||
}
|
||||
|
||||
elem.Set(value)
|
||||
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid token reference %q: %w", decodedToken, ErrPointer)
|
||||
return errInvalidReference(decodedToken)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,13 +480,14 @@ func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
return 0, fmt.Errorf("invalid token %#v: %w", tk, ErrPointer)
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
idx, err := strconv.Atoi(decodedToken)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("token reference %q is not a number: %v: %w", decodedToken, err, ErrPointer)
|
||||
return 0, fmt.Errorf("token reference %q is not a number: %w: %w", decodedToken, err, ErrPointer)
|
||||
}
|
||||
var i int
|
||||
for i = 0; i < idx && dec.More(); i++ {
|
||||
@@ -475,10 +513,12 @@ func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
|
||||
if !dec.More() {
|
||||
return 0, fmt.Errorf("token reference %q not found: %w", decodedToken, ErrPointer)
|
||||
}
|
||||
|
||||
return dec.InputOffset(), nil
|
||||
}
|
||||
|
||||
// drainSingle drains a single level of object or array.
|
||||
//
|
||||
// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed.
|
||||
func drainSingle(dec *json.Decoder) error {
|
||||
for dec.More() {
|
||||
@@ -500,14 +540,15 @@ func drainSingle(dec *json.Decoder) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Consumes the ending delim
|
||||
// consumes the ending delim
|
||||
if _, err := dec.Token(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Specific JSON pointer encoding here
|
||||
// JSON pointer encoding:
|
||||
// ~0 => ~
|
||||
// ~1 => /
|
||||
// ... and vice versa
|
||||
@@ -520,16 +561,23 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
encRefTokReplacer = strings.NewReplacer(encRefTok1, decRefTok1, encRefTok0, decRefTok0)
|
||||
decRefTokReplacer = strings.NewReplacer(decRefTok1, encRefTok1, decRefTok0, encRefTok0)
|
||||
encRefTokReplacer = strings.NewReplacer(encRefTok1, decRefTok1, encRefTok0, decRefTok0) //nolint:gochecknoglobals // it's okay to declare a replacer as a private global
|
||||
decRefTokReplacer = strings.NewReplacer(decRefTok1, encRefTok1, decRefTok0, encRefTok0) //nolint:gochecknoglobals // it's okay to declare a replacer as a private global
|
||||
)
|
||||
|
||||
// Unescape unescapes a json pointer reference token string to the original representation
|
||||
// Unescape unescapes a json pointer reference token string to the original representation.
|
||||
func Unescape(token string) string {
|
||||
return encRefTokReplacer.Replace(token)
|
||||
}
|
||||
|
||||
// Escape escapes a pointer reference token string
|
||||
// Escape escapes a pointer reference token string.
|
||||
//
|
||||
// The JSONPointer specification defines "/" as a separator and "~" as an escape prefix.
|
||||
//
|
||||
// Keys containing such characters are escaped with the following rules:
|
||||
//
|
||||
// - "~" is escaped as "~0"
|
||||
// - "/" is escaped as "~1"
|
||||
func Escape(token string) string {
|
||||
return decRefTokReplacer.Replace(token)
|
||||
}
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
# git-cliff ~ configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
|
||||
[changelog]
|
||||
header = """
|
||||
"""
|
||||
|
||||
footer = """
|
||||
|
||||
-----
|
||||
|
||||
**[{{ remote.github.repo }}]({{ self::remote_url() }}) license terms**
|
||||
|
||||
[![License][license-badge]][license-url]
|
||||
|
||||
[license-badge]: http://img.shields.io/badge/license-Apache%20v2-orange.svg
|
||||
[license-url]: {{ self::remote_url() }}/?tab=Apache-2.0-1-ov-file#readme
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
|
||||
body = """
|
||||
{%- if version %}
|
||||
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{%- else %}
|
||||
## [unreleased]
|
||||
{%- endif %}
|
||||
{%- if message %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ message }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
{%- if version %}
|
||||
{%- if previous.version %}
|
||||
|
||||
**Full Changelog**: <{{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}>
|
||||
{%- endif %}
|
||||
{%- else %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if statistics %}{% if statistics.commit_count %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{{ statistics.commit_count }} commits in this release.
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- endif %}{% endif %}
|
||||
-----
|
||||
|
||||
{%- for group, commits in commits | group_by(attribute="group") %}
|
||||
{%- raw %}\n{% endraw %}
|
||||
### {{ group | upper_first }}
|
||||
{%- raw %}\n{% endraw %}
|
||||
{%- for commit in commits %}
|
||||
{%- if commit.remote.pr_title %}
|
||||
{%- set commit_message = commit.remote.pr_title %}
|
||||
{%- else %}
|
||||
{%- set commit_message = commit.message %}
|
||||
{%- endif %}
|
||||
* {{ commit_message | split(pat="\n") | first | trim }}
|
||||
{%- if commit.remote.username %}
|
||||
{%- raw %} {% endraw %}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }})
|
||||
{%- endif %}
|
||||
{%- if commit.remote.pr_number %}
|
||||
{%- raw %} {% endraw %}in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})
|
||||
{%- endif %}
|
||||
{%- raw %} {% endraw %}[...]({{ self::remote_url() }}/commit/{{ commit.id }})
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if github %}
|
||||
{%- raw %}\n{% endraw -%}
|
||||
{%- set all_contributors = github.contributors | length %}
|
||||
{%- if github.contributors | filter(attribute="username", value="dependabot[bot]") | length < all_contributors %}
|
||||
-----
|
||||
|
||||
### People who contributed to this release
|
||||
{% endif %}
|
||||
{%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* [@{{ contributor.username }}](https://github.com/{{ contributor.username }})
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||
-----
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
### New Contributors
|
||||
{%- endif %}
|
||||
|
||||
{%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
|
||||
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
|
||||
* @{{ contributor.username }} made their first contribution
|
||||
{%- if contributor.pr_number %}
|
||||
in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{%- raw %}\n{% endraw %}
|
||||
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
"""
|
||||
# Remove leading and trailing whitespaces from the changelog's body.
|
||||
trim = true
|
||||
# Render body even when there are no releases to process.
|
||||
render_always = true
|
||||
# An array of regex based postprocessors to modify the changelog.
|
||||
postprocessors = [
|
||||
# Replace the placeholder <REPO> with a URL.
|
||||
#{ pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" },
|
||||
]
|
||||
# output file path
|
||||
# output = "test.md"
|
||||
|
||||
[git]
|
||||
# Parse commits according to the conventional commits specification.
|
||||
# See https://www.conventionalcommits.org
|
||||
conventional_commits = false
|
||||
# Exclude commits that do not match the conventional commits specification.
|
||||
filter_unconventional = false
|
||||
# Require all commits to be conventional.
|
||||
# Takes precedence over filter_unconventional.
|
||||
require_conventional = false
|
||||
# Split commits on newlines, treating each line as an individual commit.
|
||||
split_commits = false
|
||||
# An array of regex based parsers to modify commit messages prior to further processing.
|
||||
commit_preprocessors = [
|
||||
# Replace issue numbers with link templates to be updated in `changelog.postprocessors`.
|
||||
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||
# Check spelling of the commit message using https://github.com/crate-ci/typos.
|
||||
# If the spelling is incorrect, it will be fixed automatically.
|
||||
#{ pattern = '.*', replace_command = 'typos --write-changes -' }
|
||||
]
|
||||
# Prevent commits that are breaking from being excluded by commit parsers.
|
||||
protect_breaking_commits = false
|
||||
# An array of regex based parsers for extracting data from the commit message.
|
||||
# Assigns commits to groups.
|
||||
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
|
||||
commit_parsers = [
|
||||
{ message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true },
|
||||
{ message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true },
|
||||
{ field = "author.name", pattern = "dependabot*", group = "<!-- 0A -->Updates" },
|
||||
{ message = "([Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ body = "(.*[Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
|
||||
{ message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "<!-- 05 -->Code quality" },
|
||||
{ message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "<!-- 03 -->Documentation" },
|
||||
{ message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "<!-- 00 -->Implemented enhancements" },
|
||||
{ message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^test", group = "<!-- 06 -->Testing" },
|
||||
{ message = "(^fix)|(panic)", group = "<!-- 01 -->Fixed bugs" },
|
||||
{ message = "(^refact)|(rework)", group = "<!-- 02 -->Refactor" },
|
||||
{ message = "(^[Pp]erf)|(performance)", group = "<!-- 04 -->Performance" },
|
||||
{ message = "(^[Cc]hore)", group = "<!-- 07 -->Miscellaneous tasks" },
|
||||
{ message = "^[Rr]evert", group = "<!-- 09 -->Reverted changes" },
|
||||
{ message = "(upgrade.*?go)|(go\\s+version)", group = "<!-- 0A -->Updates" },
|
||||
{ message = ".*", group = "<!-- 0B -->Other" },
|
||||
]
|
||||
# Exclude commits that are not matched by any commit parser.
|
||||
filter_commits = false
|
||||
# An array of link parsers for extracting external references, and turning them into URLs, using regex.
|
||||
link_parsers = []
|
||||
# Include only the tags that belong to the current branch.
|
||||
use_branch_tags = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order = false
|
||||
# Order releases topologically instead of chronologically.
|
||||
topo_order_commits = true
|
||||
# Order of commits in each group/release within the changelog.
|
||||
# Allowed values: newest, oldest
|
||||
sort_commits = "newest"
|
||||
# Process submodules commits
|
||||
recurse_submodules = false
|
||||
|
||||
#[remote.github]
|
||||
#owner = "go-openapi"
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Set default charset
|
||||
[*.{js,py,go,scala,rb,java,html,css,less,sass,md}]
|
||||
charset = utf-8
|
||||
|
||||
# Tab indentation (no size specified)
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
# Matches the exact files either package.json or .travis.yml
|
||||
[{package.json,.travis.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
+10
-19
@@ -2,34 +2,17 @@ version: "2"
|
||||
linters:
|
||||
default: all
|
||||
disable:
|
||||
- cyclop
|
||||
- depguard
|
||||
- errchkjson
|
||||
- errorlint
|
||||
- exhaustruct
|
||||
- forcetypeassert
|
||||
- funlen
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- gosmopolitan
|
||||
- inamedparam
|
||||
#- intrange # disabled while < go1.22
|
||||
- ireturn
|
||||
- lll
|
||||
- musttag
|
||||
- nestif
|
||||
- exhaustruct
|
||||
- nlreturn
|
||||
- nonamedreturns
|
||||
- noinlineerr
|
||||
- paralleltest
|
||||
- recvcheck
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unparam
|
||||
- varnamelen
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
@@ -41,8 +24,15 @@ linters:
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 3
|
||||
cyclop:
|
||||
max-complexity: 20
|
||||
gocyclo:
|
||||
min-complexity: 45
|
||||
min-complexity: 20
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: true
|
||||
default-case-required: true
|
||||
lll:
|
||||
line-length: 180
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
@@ -58,6 +48,7 @@ formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
- gofumpt
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# Contributors
|
||||
|
||||
- Repository: ['go-openapi/jsonreference']
|
||||
|
||||
| Total Contributors | Total Contributions |
|
||||
| --- | --- |
|
||||
| 9 | 68 |
|
||||
|
||||
| Username | All Time Contribution Count | All Commits |
|
||||
| --- | --- | --- |
|
||||
| @fredbi | 31 | https://github.com/go-openapi/jsonreference/commits?author=fredbi |
|
||||
| @casualjim | 25 | https://github.com/go-openapi/jsonreference/commits?author=casualjim |
|
||||
| @youyuanwu | 5 | https://github.com/go-openapi/jsonreference/commits?author=youyuanwu |
|
||||
| @olivierlemasle | 2 | https://github.com/go-openapi/jsonreference/commits?author=olivierlemasle |
|
||||
| @apelisse | 1 | https://github.com/go-openapi/jsonreference/commits?author=apelisse |
|
||||
| @gbjk | 1 | https://github.com/go-openapi/jsonreference/commits?author=gbjk |
|
||||
| @honza | 1 | https://github.com/go-openapi/jsonreference/commits?author=honza |
|
||||
| @Neo2308 | 1 | https://github.com/go-openapi/jsonreference/commits?author=Neo2308 |
|
||||
| @erraggy | 1 | https://github.com/go-openapi/jsonreference/commits?author=erraggy |
|
||||
|
||||
_this file was generated by the [Contributors GitHub Action](https://github.com/github/contributors)_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user