Skip to content

Commit

Permalink
Writing the aws creds file became broken with all the other v2 work.
Browse files Browse the repository at this point in the history
Discussed in issue #114
  • Loading branch information
monde committed Oct 5, 2023
1 parent 9722e54 commit 36c0373
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 34 deletions.
19 changes: 12 additions & 7 deletions internal/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,21 @@ import (

// Credential Convenience representation of an AWS credential.
type Credential struct {
AccessKeyID string `ini:"aws_access_key_id" json:"AccessKeyId,omitempty"`
SecretAccessKey string `ini:"aws_secret_access_key" json:"SecretAccessKey,omitempty"`
SessionToken string `ini:"aws_session_token" json:"SessionToken,omitempty"`
Version int `ini:"aws_version" json:"Version,omitempty"`
Expiration *time.Time `ini:"aws_expiration" json:"Expiration,omitempty"`
AccessKeyID string `ini:"aws_access_key_id" json:"AccessKeyId,omitempty"`
SecretAccessKey string `ini:"aws_secret_access_key" json:"SecretAccessKey,omitempty"`
SessionToken string `ini:"aws_session_token" json:"SessionToken,omitempty"`
}

// ProcessCredential Convenience representation of an AWS credential used for process credential format.
type ProcessCredential struct {
Credential
Version int `json:"Version,omitempty"`
Expiration *time.Time `json:"Expiration,omitempty"`
}

// MarshalJSON ensure Expiration date time is formatted RFC 3339 format.
func (c *Credential) MarshalJSON() ([]byte, error) {
type Alias Credential
func (c *ProcessCredential) MarshalJSON() ([]byte, error) {
type Alias ProcessCredential
var exp string
if c.Expiration != nil {
exp = c.Expiration.Format(time.RFC3339)
Expand Down
2 changes: 1 addition & 1 deletion internal/aws/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

func TestCredentialJSON(t *testing.T) {
hbtGo := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
c := Credential{
c := ProcessCredential{
Expiration: &hbtGo,
}
credStr, err := json.Marshal(c)
Expand Down
3 changes: 2 additions & 1 deletion internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"strings"

oaws "github.com/okta/okta-aws-cli/internal/aws"
"github.com/okta/okta-aws-cli/internal/utils"
)

// Exec is a executor / a process runner
Expand Down Expand Up @@ -86,7 +87,7 @@ func (e *Exec) Run(oc *oaws.Credential) error {
if ee, ok := err.(*osexec.ExitError); ok {
fmt.Fprintf(os.Stderr, "error running process\n")
fmt.Fprintf(os.Stderr, "%s %s\n", e.name, strings.Join(e.args, " "))
fmt.Fprintf(os.Stderr, "%s\n", ee.Stderr)
fmt.Fprintf(os.Stderr, utils.PassThroughStringNewLineFMT, ee.Stderr)
}
if err != nil {
return err
Expand Down
17 changes: 8 additions & 9 deletions internal/m2mauth/m2mauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,31 +91,31 @@ func (m *M2MAuthentication) EstablishIAMCredentials() error {
return err
}

cred, err := m.awsAssumeRoleWithWebIdentity(at)
oc, ac, err := m.awsAssumeRoleWithWebIdentity(at)
if err != nil {
return err
}

err = output.RenderAWSCredential(m.config, cred)
err = output.RenderAWSCredential(m.config, oc, ac)
if err != nil {
return err
}

if m.config.Exec() {
exe, _ := exec.NewExec()
if err := exe.Run(cred); err != nil {
if err := exe.Run(oc); err != nil {
return err
}
}

return nil
}

func (m *M2MAuthentication) awsAssumeRoleWithWebIdentity(at *okta.AccessToken) (credential *oaws.Credential, err error) {
func (m *M2MAuthentication) awsAssumeRoleWithWebIdentity(at *okta.AccessToken) (oc *oaws.Credential, ac *sts.Credentials, err error) {
awsCfg := aws.NewConfig().WithHTTPClient(m.config.HTTPClient())
sess, err := session.NewSession(awsCfg)
if err != nil {
return nil, err
return
}

svc := sts.New(sess)
Expand All @@ -127,17 +127,16 @@ func (m *M2MAuthentication) awsAssumeRoleWithWebIdentity(at *okta.AccessToken) (
}
svcResp, err := svc.AssumeRoleWithWebIdentity(input)
if err != nil {
return nil, err
return
}

credential = &oaws.Credential{
oc = &oaws.Credential{
AccessKeyID: *svcResp.Credentials.AccessKeyId,
SecretAccessKey: *svcResp.Credentials.SecretAccessKey,
SessionToken: *svcResp.Credentials.SessionToken,
Expiration: svcResp.Credentials.Expiration,
}

return credential, nil
return oc, svcResp.Credentials, nil
}

func (m *M2MAuthentication) createKeySigner() (jose.Signer, error) {
Expand Down
3 changes: 2 additions & 1 deletion internal/output/aws_credentials_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"reflect"
"strings"

"github.com/aws/aws-sdk-go/service/sts"
dynamicstruct "github.com/ompluscator/dynamic-struct"
"github.com/pkg/errors"
"gopkg.in/ini.v1"
Expand Down Expand Up @@ -178,7 +179,7 @@ func NewAWSCredentialsFile(legacyVars bool, expiryVars bool, expiry string) *AWS

// Output Satisfies the Outputter interface and appends AWS credentials to
// credentials file.
func (e *AWSCredentialsFile) Output(c *config.Config, oc *oaws.Credential) error {
func (e *AWSCredentialsFile) Output(c *config.Config, oc *oaws.Credential, ac *sts.Credentials) error {
if c.WriteAWSCredentials() {
return e.writeConfig(c, oc)
}
Expand Down
3 changes: 2 additions & 1 deletion internal/output/envvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"runtime"

"github.com/aws/aws-sdk-go/service/sts"
oaws "github.com/okta/okta-aws-cli/internal/aws"
"github.com/okta/okta-aws-cli/internal/config"
)
Expand All @@ -38,7 +39,7 @@ func NewEnvVar(legacyVars bool) *EnvVar {

// Output Satisfies the Outputter interface and outputs AWS credentials as shell
// export statements to STDOUT
func (e *EnvVar) Output(c *config.Config, oc *oaws.Credential) error {
func (e *EnvVar) Output(c *config.Config, oc *oaws.Credential, ac *sts.Credentials) error {
if runtime.GOOS == "windows" {
fmt.Printf("setx AWS_ACCESS_KEY_ID %s\n", oc.AccessKeyID)
fmt.Printf("setx AWS_SECRET_ACCESS_KEY %s\n", oc.SecretAccessKey)
Expand Down
3 changes: 2 additions & 1 deletion internal/output/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package output

import (
"github.com/aws/aws-sdk-go/service/sts"
oaws "github.com/okta/okta-aws-cli/internal/aws"
"github.com/okta/okta-aws-cli/internal/config"
)
Expand All @@ -30,7 +31,7 @@ func NewNoopCredentials() *NoopCredentials {
}

// Output Satisfies the Outputter interface and outputs nothing
func (n *NoopCredentials) Output(c *config.Config, oc *oaws.Credential) error {
func (n *NoopCredentials) Output(c *config.Config, oc *oaws.Credential, ac *sts.Credentials) error {
// no-op
return nil
}
7 changes: 4 additions & 3 deletions internal/output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ import (
"os"
"time"

"github.com/aws/aws-sdk-go/service/sts"
oaws "github.com/okta/okta-aws-cli/internal/aws"
"github.com/okta/okta-aws-cli/internal/config"
)

// Outputter Interface to output AWS credentials in different formats.
type Outputter interface {
Output(c *config.Config, oc *oaws.Credential) error
Output(c *config.Config, oc *oaws.Credential, ac *sts.Credentials) error
}

// RenderAWSCredential Renders the credentials in the prescribed format.
func RenderAWSCredential(cfg *config.Config, oc *oaws.Credential) error {
func RenderAWSCredential(cfg *config.Config, oc *oaws.Credential, ac *sts.Credentials) error {
var o Outputter
switch cfg.Format() {
case config.AWSCredentialsFormat:
Expand All @@ -46,5 +47,5 @@ func RenderAWSCredential(cfg *config.Config, oc *oaws.Credential) error {
fmt.Fprintf(os.Stderr, "\n")
}

return o.Output(cfg, oc)
return o.Output(cfg, oc, ac)
}
11 changes: 8 additions & 3 deletions internal/output/process_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"

"github.com/aws/aws-sdk-go/service/sts"
oaws "github.com/okta/okta-aws-cli/internal/aws"
"github.com/okta/okta-aws-cli/internal/config"
)
Expand All @@ -35,12 +36,16 @@ func NewProcessCredentials() *ProcessCredentials {

// Output Satisfies the Outputter interface and outputs AWS credentials as JSON
// to STDOUT
func (p *ProcessCredentials) Output(c *config.Config, oc *oaws.Credential) error {
func (p *ProcessCredentials) Output(c *config.Config, oc *oaws.Credential, ac *sts.Credentials) error {
// See AWS docs: "Note As of this writing, the Version key must be set to 1.
// This might increment over time as the structure evolves."
oc.Version = 1
poc := &oaws.ProcessCredential{
Credential: *oc,
Expiration: ac.Expiration,
Version: 1,
}

credJSON, err := json.MarshalIndent(oc, "", " ")
credJSON, err := json.MarshalIndent(poc, "", " ")
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/output/process_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestProcessCredentials(t *testing.T) {
"SessionToken": "the AWS session token for temporary credentials",
"Expiration": "2009-11-10T23:00:00Z"
}`
result := aws.Credential{}
result := aws.ProcessCredential{}
err := json.Unmarshal([]byte(credsJSON), &result)
require.NoError(t, err)
require.Equal(t, "an AWS access key", result.AccessKeyID)
Expand Down
2 changes: 2 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ const (
XOktaAWSCLIWebOperation = "web"
// XOktaAWSCLIM2MOperation m2m op value for the x okta aws cli header
XOktaAWSCLIM2MOperation = "m2m"
// PassThroughStringNewLineFMT string formatter to make lint happy
PassThroughStringNewLineFMT = "%s\n"
)
11 changes: 5 additions & 6 deletions internal/webssoauth/webssoauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ func (w *WebSSOAuthentication) establishTokenWithFedAppID(clientID, fedAppID str
return err
}

oc, err := w.awsAssumeRoleWithSAML(iar, assertion)
oc, ac, err := w.awsAssumeRoleWithSAML(iar, assertion)
if err != nil {
return err
}

err = output.RenderAWSCredential(w.config, oc)
err = output.RenderAWSCredential(w.config, oc, ac)
if err != nil {
return err
}
Expand All @@ -325,7 +325,7 @@ func (w *WebSSOAuthentication) establishTokenWithFedAppID(clientID, fedAppID str

// awsAssumeRoleWithSAML Get AWS Credentials with an STS Assume Role With SAML AWS
// API call.
func (w *WebSSOAuthentication) awsAssumeRoleWithSAML(iar *idpAndRole, assertion string) (oc *oaws.Credential, err error) {
func (w *WebSSOAuthentication) awsAssumeRoleWithSAML(iar *idpAndRole, assertion string) (oc *oaws.Credential, ac *sts.Credentials, err error) {
awsCfg := aws.NewConfig().WithHTTPClient(w.config.HTTPClient())
sess, err := session.NewSession(awsCfg)
if err != nil {
Expand All @@ -347,9 +347,8 @@ func (w *WebSSOAuthentication) awsAssumeRoleWithSAML(iar *idpAndRole, assertion
AccessKeyID: *svcResp.Credentials.AccessKeyId,
SecretAccessKey: *svcResp.Credentials.SecretAccessKey,
SessionToken: *svcResp.Credentials.SessionToken,
Expiration: svcResp.Credentials.Expiration,
}
return oc, nil
return oc, svcResp.Credentials, nil
}

// choiceFriendlyLabelRole returns a friendly choice for pretty printing Role
Expand Down Expand Up @@ -637,7 +636,7 @@ func (w *WebSSOAuthentication) promptAuthentication(da *okta.DeviceAuthorization
buf := bytes.NewBufferString("")
qrterminal.GenerateHalfBlock(da.VerificationURIComplete, qrterminal.L, buf)
if _, err := buf.Read(qrBuf); err == nil {
qrCode = fmt.Sprintf("%s\n", qrBuf)
qrCode = fmt.Sprintf(utils.PassThroughStringNewLineFMT, qrBuf)
}
}

Expand Down

0 comments on commit 36c0373

Please sign in to comment.