Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions cmd/awscliauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ type Root struct {
// ChannelOut io.Writer
// ChannelErr io.Writer
// viperConf *viper.Viper
rootFlags *rootCmdFlags
rootFlags *RootCmdFlags
Datadir string
}

type rootCmdFlags struct {
cfgSectionName string
storeInProfile bool
killHangingProcess bool
roleChain []string
verbose bool
duration int
type RootCmdFlags struct {
CfgSectionName string
StoreInProfile bool
RoleChain []string
Verbose bool
Duration int
CustomIniLocation string
}

func New() *Root {
rf := &rootCmdFlags{}
rf := &RootCmdFlags{}
r := &Root{
rootFlags: rf,
Cmd: &cobra.Command{
Expand All @@ -49,15 +49,17 @@ Stores them under the $HOME/.aws/credentials file under a specified path or retu
},
}

r.Cmd.PersistentFlags().StringSliceVarP(&rf.roleChain, "role-chain", "", []string{}, "If specified it will assume the roles from the base credentials, in order they are specified in")
r.Cmd.PersistentFlags().BoolVarP(&rf.storeInProfile, "store-profile", "s", false, `By default the credentials are returned to stdout to be used by the credential_process.
r.Cmd.PersistentFlags().StringSliceVarP(&rf.RoleChain, "role-chain", "", []string{}, "If specified it will assume the roles from the base credentials, in order they are specified in")
r.Cmd.PersistentFlags().BoolVarP(&rf.StoreInProfile, "store-profile", "s", false, `By default the credentials are returned to stdout to be used by the credential_process.
Set this flag to instead store the credentials under a named profile section. You can then reference that profile name via the CLI or for use in an SDK`)
r.Cmd.PersistentFlags().StringVarP(&rf.cfgSectionName, "cfg-section", "", "", "Config section name in the default AWS credentials file. To enable priofi")
r.Cmd.PersistentFlags().StringVarP(&rf.CfgSectionName, "cfg-section", "", "", "Config section name to use in the look up of the config ini file (~/.aws-cli-auth.ini) and in the AWS credentials file")
// When specifying store in profile the config section name must be provided
r.Cmd.MarkFlagsRequiredTogether("store-profile", "cfg-section")
r.Cmd.PersistentFlags().IntVarP(&rf.duration, "max-duration", "d", 900, `Override default max session duration, in seconds, of the role session [900-43200].
r.Cmd.PersistentFlags().IntVarP(&rf.Duration, "max-duration", "d", 900, `Override default max session duration, in seconds, of the role session [900-43200].
NB: This cannot be higher than the 3600 as the API does not allow for AssumeRole for sessions longer than an hour`)
r.Cmd.PersistentFlags().BoolVarP(&rf.verbose, "verbose", "v", false, "Verbose output")
r.Cmd.PersistentFlags().BoolVarP(&rf.Verbose, "verbose", "v", false, "Verbose output")
r.Cmd.PersistentFlags().StringVarP(&rf.CustomIniLocation, "config-file", "c", "", "Specify the custom location of config file")

_ = r.dataDirInit()
return r
}
Expand Down
52 changes: 52 additions & 0 deletions cmd/awscliauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
"context"
"errors"
"io"
"os"
"strings"
"testing"

"github.com/DevLabFoundry/aws-cli-auth/cmd"
"github.com/DevLabFoundry/aws-cli-auth/internal/credentialexchange"
"github.com/DevLabFoundry/aws-cli-auth/internal/web"
)

Expand Down Expand Up @@ -81,3 +84,52 @@ func Test_Saml_timeout(t *testing.T) {
// }
})
}

func Test_SpecificCommand(t *testing.T) {

t.Run("Specific command should fail with wrong method", func(t *testing.T) {
_, _, err := cmdHelperExecutor(t, []string{"specific", "--method=unknown", "--role",
"arn:aws:iam::1234111111111:role/Role-ReadOnly"})
if err == nil {
t.Error("got nil, wanted an error")
}
if !errors.Is(err, cmd.ErrUnsupportedMethod) {
t.Errorf("got %v, wanted %v", err, cmd.ErrUnsupportedMethod)
}
})

t.Run("Specific command fails on missing env AWS_WEB_IDENTITY_TOKEN_FILE", func(t *testing.T) {
os.Setenv("AWS_ROLE_ARN", "arn:aws:iam::1234111111111:role/Role-ReadOnly")
defer os.Unsetenv("AWS_ROLE_ARN")
_, _, err := cmdHelperExecutor(t, []string{"specific", "--method=WEB_ID", "--role",
"arn:aws:iam::1234111111111:role/Role-ReadOnly"})
if err == nil {
t.Error("got nil, wanted an error")
}
if !errors.Is(err, credentialexchange.ErrMissingEnvVar) {
t.Errorf("got %v, wanted %v", err, cmd.ErrUnsupportedMethod)
}
})
}

func Test_ClearCommand(t *testing.T) {

t.Run("should pass without --force", func(t *testing.T) {
_, _, err := cmdHelperExecutor(t, []string{"clear-cache"})
if err != nil {
t.Error("got nil, wanted an error")
}
})
t.Run("should warn user to manually delete data dir", func(t *testing.T) {
stdout, _, err := cmdHelperExecutor(t, []string{"clear-cache", "--force"})
if err != nil {
t.Error("got nil, wanted an error")
}
if len(stdout.String()) < 1 {
t.Fatal("got nil, wanted output")
}
if !strings.Contains(stdout.String(), "manually") {
t.Errorf("incorrect messasge displayed, got %s, wanted to include manually", stdout.String())
}
})
}
19 changes: 10 additions & 9 deletions cmd/clear.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"errors"
"fmt"
"os"
"os/user"
Expand All @@ -13,6 +14,10 @@ type clearFlags struct {
force bool
}

var (
ErrCannotReadConfig = errors.New("cannot open config file")
)

func newClearCmd(r *Root) {
flags := &clearFlags{}

Expand All @@ -26,7 +31,8 @@ func newClearCmd(r *Root) {
if err != nil {
return err
}
if err := samlInitConfig(); err != nil {
iniCfg, err := samlInitConfig(r.rootFlags.CustomIniLocation)
if err != nil {
return err
}
secretStore, err := credentialexchange.NewSecretStore("",
Expand All @@ -38,15 +44,11 @@ func newClearCmd(r *Root) {
}

if flags.force {
fmt.Fprint(os.Stderr, "delete ~/.aws-cli-auth-data/ manually")
fmt.Fprint(cmd.OutOrStderr(), "delete ~/.aws-cli-auth-data/ manually")
}

if err := secretStore.ClearAll(); err != nil {
fmt.Fprint(os.Stderr, err.Error())
}

if err := os.Remove(credentialexchange.ConfigIniFile("")); err != nil {
return err
if err := secretStore.ClearAll(iniCfg); err != nil {
fmt.Fprint(cmd.OutOrStderr(), err.Error())
}

return nil
Expand All @@ -64,6 +66,5 @@ Use with caution.
If for any reason the local ini file and the secret store on your OS (keyring on GNU, keychain MacOS, windows secret store) are out of sync and the secrets cannot be retrieved by name but still exists,
you might want to use CLI or GUI interface to the secret backing store on your OS and search for a secret prefixed with aws-cli-* and delete manually
`)

r.Cmd.AddCommand(cmd)
}
Loading
Loading