111 lines
3.3 KiB
Go
111 lines
3.3 KiB
Go
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
|
|
}
|