token.go (3385B)
1 package logincreds 2 3 import ( 4 "crypto/sha256" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 "path/filepath" 9 "strings" 10 "time" 11 12 "github.com/aws/aws-sdk-go-v2/aws" 13 "github.com/aws/aws-sdk-go-v2/internal/sdk" 14 "github.com/aws/aws-sdk-go-v2/internal/shareddefaults" 15 "github.com/aws/aws-sdk-go-v2/service/signin" 16 ) 17 18 var userHomeDir = shareddefaults.UserHomeDir 19 20 // StandardCachedTokenFilepath returns the filepath for the cached login token 21 // file. Key that will be used to compute a SHA256 value that is hex encoded. 22 // 23 // An overriden root dir can be provided, if not set the path defaults to 24 // ~/.aws/sso/cache. 25 func StandardCachedTokenFilepath(session, dir string) (string, error) { 26 session = strings.TrimSpace(session) 27 28 if len(dir) == 0 { 29 dir = userHomeDir() 30 if len(dir) == 0 { 31 return "", errors.New("user home dir is blank") 32 } 33 dir = filepath.Join(dir, ".aws", "login", "cache") 34 } 35 36 h := sha256.New() 37 h.Write([]byte(session)) 38 39 filename := strings.ToLower(hex.EncodeToString(h.Sum(nil))) + ".json" 40 return filepath.Join(dir, filename), nil 41 } 42 43 // contents of the token as they appear on disk 44 type loginToken struct { 45 AccessToken *loginTokenAccessToken `json:"accessToken"` 46 TokenType string `json:"tokenType"` 47 RefreshToken string `json:"refreshToken"` 48 IdentityToken string `json:"identityToken"` 49 ClientID string `json:"clientId"` 50 DPOPKey string `json:"dpopKey"` 51 } 52 53 type loginTokenAccessToken struct { 54 AccessKeyID string `json:"accessKeyId"` 55 SecretAccessKey string `json:"secretAccessKey"` 56 SessionToken string `json:"sessionToken"` 57 AccountID string `json:"accountId"` 58 ExpiresAt time.Time `json:"expiresAt"` 59 } 60 61 func (t *loginToken) Validate() error { 62 if t.AccessToken == nil { 63 return fmt.Errorf("missing accessToken") 64 } 65 if t.AccessToken.AccessKeyID == "" { 66 return fmt.Errorf("missing accessToken.accessKeyId") 67 } 68 if t.AccessToken.SecretAccessKey == "" { 69 return fmt.Errorf("missing accessToken.secretAccessKey") 70 } 71 if t.AccessToken.SessionToken == "" { 72 return fmt.Errorf("missing accessToken.sessionToken") 73 } 74 if t.AccessToken.AccountID == "" { 75 return fmt.Errorf("missing accessToken.accountId") 76 } 77 if t.AccessToken.ExpiresAt.IsZero() { 78 return fmt.Errorf("missing accessToken.expiresAt") 79 } 80 if t.ClientID == "" { 81 return fmt.Errorf("missing clientId") 82 } 83 if t.RefreshToken == "" { 84 return fmt.Errorf("missing refreshToken") 85 } 86 if t.DPOPKey == "" { 87 return fmt.Errorf("missing dpopKey") 88 } 89 return nil 90 } 91 92 func (t *loginToken) Credentials() aws.Credentials { 93 return aws.Credentials{ 94 AccessKeyID: t.AccessToken.AccessKeyID, 95 SecretAccessKey: t.AccessToken.SecretAccessKey, 96 SessionToken: t.AccessToken.SessionToken, 97 Source: ProviderName, 98 CanExpire: true, 99 Expires: t.AccessToken.ExpiresAt, 100 AccountID: t.AccessToken.AccountID, 101 } 102 } 103 104 func (t *loginToken) Update(out *signin.CreateOAuth2TokenOutput) { 105 t.AccessToken.AccessKeyID = *out.TokenOutput.AccessToken.AccessKeyId 106 t.AccessToken.SecretAccessKey = *out.TokenOutput.AccessToken.SecretAccessKey 107 t.AccessToken.SessionToken = *out.TokenOutput.AccessToken.SessionToken 108 t.AccessToken.ExpiresAt = sdk.NowTime().Add(time.Duration(*out.TokenOutput.ExpiresIn) * time.Second) 109 t.RefreshToken = *out.TokenOutput.RefreshToken 110 }