Skip to content

Commit

Permalink
Merge pull request #152 from okta/fix_nil_prompt_for_idp
Browse files Browse the repository at this point in the history
prep v2.0.0-beta.6
  • Loading branch information
monde authored Nov 2, 2023
2 parents 2e98960 + a10827b commit 589ad31
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ awscli:
Ops
```

## 2.0.0-beta.6 (November 2, 2023)

* New m2m flag `--private-key-file` read private key from file
* Bug fix panic when okta.yaml is not established (it doesn't have to be established either)
* Bug fix allowing `--version` w/o sub command [#150](https://github.com/okta/okta-aws-cli/pull/150), thanks [@malept](https://github.com/malept)!

## 2.0.0-beta.5 (October 13, 2023)

Friendly label matching for IdPs and Roles with `$HOME/.okta/okta.yaml` file can be regular expressions.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ These settings are optional unless marked otherwise:
| Name | Description | Command line flag | ENV var and .env file value |
|-----|-----|-----|-----|
| Key ID (kid) (**required**) | The ID of the key stored in the service app | `--key-id [value]` | `OKTA_AWSCLI_KEY_ID` |
| Private Key (**required**) | PEM (pkcs#1 or pkcs#9) private key whose public key is stored on the service app | `--private-key [value]` | `OKTA_AWSCLI_PRIVATE_KEY` |
| Private Key (**required** in lieu of private key file) | PEM (pkcs#1 or pkcs#9) private key whose public key is stored on the service app | `--private-key [value]` | `OKTA_AWSCLI_PRIVATE_KEY` |
| Private Key File (**required** in lieu of private key) | File holding PEM (pkcs#1 or pkcs#9) private key whose public key is stored on the service app | `--private-key-file [value]` | `OKTA_AWSCLI_PRIVATE_KEY_FILE` |
| Authorization Server ID | The ID of the Okta authorization server, set ID for a custom authorization server, will use default otherwise. Default `default` | `--authz-id [value]` | `OKTA_AWSCLI_AUTHZ_ID` |
| Custom scope name | The custom scope established in the custom authorization server. Default `okta-m2m-access` | `--custom-scope [value]` | `OKTA_AWSCLI_CUSTOM_SCOPE` |

Expand Down
11 changes: 9 additions & 2 deletions cmd/root/m2m/m2m.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ var (
Name: config.PrivateKeyFlag,
Short: "k",
Value: "",
Usage: "Private Key",
Usage: "Private Key (string value)",
EnvVar: config.PrivateKeyEnvVar,
},
{
Name: config.PrivateKeyFileFlag,
Short: "b",
Value: "",
Usage: "Private Key File",
EnvVar: config.PrivateKeyFileEnvVar,
},
{
Name: config.CustomScopeFlag,
Short: "m",
Expand All @@ -55,7 +62,7 @@ var (
EnvVar: config.AuthzIDEnvVar,
},
}
requiredFlags = []string{"org-domain", "oidc-client-id", "aws-iam-role", "key-id", "private-key"}
requiredFlags = []interface{}{"org-domain", "oidc-client-id", "aws-iam-role", "key-id", []string{"private-key", "private-key-file"}}
)

// NewM2MCommand Sets up the m2m cobra sub command
Expand Down
2 changes: 1 addition & 1 deletion cmd/root/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ var (
EnvVar: config.AllProfilesEnvVar,
},
}
requiredFlags = []string{"org-domain", "oidc-client-id"}
requiredFlags = []interface{}{"org-domain", "oidc-client-id"}
)

// NewWebCommand Sets up the web cobra sub command
Expand Down
24 changes: 23 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func init() {

const (
// Version app version
Version = "2.0.0-beta.5"
Version = "2.0.0-beta.6"

// AWSCredentialsFormat format const
AWSCredentialsFormat = "aws-credentials"
Expand Down Expand Up @@ -82,6 +82,8 @@ const (
OrgDomainFlag = "org-domain"
// PrivateKeyFlag cli flag const
PrivateKeyFlag = "private-key"
// PrivateKeyFileFlag cli flag const
PrivateKeyFileFlag = "private-key-file"
// KeyIDFlag cli flag const
KeyIDFlag = "key-id"
// ProfileFlag cli flag const
Expand Down Expand Up @@ -145,6 +147,8 @@ const (
OpenBrowserCommandEnvVar = "OKTA_AWSCLI_OPEN_BROWSER_COMMAND"
// PrivateKeyEnvVar env var const
PrivateKeyEnvVar = "OKTA_AWSCLI_PRIVATE_KEY"
// PrivateKeyFileEnvVar env var const
PrivateKeyFileEnvVar = "OKTA_AWSCLI_PRIVATE_KEY_FILE"
// KeyIDEnvVar env var const
KeyIDEnvVar = "OKTA_AWSCLI_KEY_ID"
// ProfileEnvVar env var const
Expand Down Expand Up @@ -207,6 +211,7 @@ type Config struct {
openBrowserCommand string
orgDomain string
privateKey string
privateKeyFile string
profile string
qrCode bool
writeAWSCredentials bool
Expand Down Expand Up @@ -236,6 +241,7 @@ type Attributes struct {
OpenBrowserCommand string
OrgDomain string
PrivateKey string
PrivateKeyFile string
Profile string
QRCode bool
WriteAWSCredentials bool
Expand Down Expand Up @@ -274,6 +280,7 @@ func NewConfig(attrs *Attributes) (*Config, error) {
openBrowser: attrs.OpenBrowser,
openBrowserCommand: attrs.OpenBrowserCommand,
privateKey: attrs.PrivateKey,
privateKeyFile: attrs.PrivateKeyFile,
keyID: attrs.KeyID,
profile: attrs.Profile,
qrCode: attrs.QRCode,
Expand Down Expand Up @@ -325,6 +332,7 @@ func readConfig() (Attributes, error) {
OpenBrowserCommand: viper.GetString(OpenBrowserCommandFlag),
OrgDomain: viper.GetString(OrgDomainFlag),
PrivateKey: viper.GetString(PrivateKeyFlag),
PrivateKeyFile: viper.GetString(PrivateKeyFileFlag),
KeyID: viper.GetString(KeyIDFlag),
Profile: viper.GetString(ProfileFlag),
QRCode: viper.GetBool(QRCodeFlag),
Expand Down Expand Up @@ -376,6 +384,9 @@ func readConfig() (Attributes, error) {
if attrs.PrivateKey == "" {
attrs.PrivateKey = viper.GetString(downCase(PrivateKeyEnvVar))
}
if attrs.PrivateKeyFile == "" {
attrs.PrivateKeyFile = viper.GetString(downCase(PrivateKeyFileEnvVar))
}
if attrs.KeyID == "" {
attrs.KeyID = viper.GetString(downCase(KeyIDEnvVar))
}
Expand Down Expand Up @@ -724,6 +735,17 @@ func (c *Config) SetPrivateKey(privateKey string) error {
return nil
}

// PrivateKeyFile --
func (c *Config) PrivateKeyFile() string {
return c.privateKeyFile
}

// SetPrivateKeyFile --
func (c *Config) SetPrivateKeyFile(privateKeyFile string) error {
c.privateKeyFile = privateKeyFile
return nil
}

// KeyID --
func (c *Config) KeyID() string {
return c.keyID
Expand Down
24 changes: 20 additions & 4 deletions internal/flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,28 @@ func MakeFlagBindings(cmd *cobra.Command, flags []Flag, persistent bool) {
}

// CheckRequiredFlags Checks if flags in the list are all set in Viper
func CheckRequiredFlags(flags []string) error {
func CheckRequiredFlags(flags []interface{}) error {
unsetFlags := []string{}
for _, f := range flags {
altName := altFlagName(f)
if !viper.GetViper().IsSet(f) && !viper.GetViper().IsSet(altName) {
unsetFlags = append(unsetFlags, fmt.Sprintf(" --%s", f))
if arr, ok := f.([]string); ok {
found := false
for _, flag := range arr {
altName := altFlagName(flag)
if viper.GetViper().IsSet(flag) || viper.GetViper().IsSet(altName) {
found = true
}
}

if !found {
unsetFlags = append(unsetFlags, fmt.Sprintf(" --(%s)", strings.Join(arr, " or ")))
}

continue
}
flag := f.(string)
altName := altFlagName(flag)
if !viper.GetViper().IsSet(flag) && !viper.GetViper().IsSet(altName) {
unsetFlags = append(unsetFlags, fmt.Sprintf(" --%s", flag))
}
}
if len(unsetFlags) > 0 {
Expand Down
17 changes: 15 additions & 2 deletions internal/m2mauth/m2mauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"io"
"net/http"
"net/url"
"os"
"strings"
"time"

Expand Down Expand Up @@ -142,11 +143,23 @@ func (m *M2MAuthentication) awsAssumeRoleWithWebIdentity(at *okta.AccessToken) (

func (m *M2MAuthentication) createKeySigner() (jose.Signer, error) {
signerOptions := (&jose.SignerOptions{}).WithHeader("kid", m.config.KeyID())
priv := []byte(strings.ReplaceAll(m.config.PrivateKey(), `\n`, "\n"))
var priv []byte
switch {
case m.config.PrivateKey() != "":
priv = []byte(strings.ReplaceAll(m.config.PrivateKey(), `\n`, "\n"))
case m.config.PrivateKeyFile() != "":
var err error
priv, err = os.ReadFile(m.config.PrivateKeyFile())
if err != nil {
return nil, err
}
default:
return nil, errors.New("either private key or private key file is a required m2m argument")
}

privPem, _ := pem.Decode(priv)
if privPem == nil {
return nil, errors.New("invalid private key")
return nil, errors.New("invalid private key value")
}

if privPem.Type == "RSA PRIVATE KEY" {
Expand Down
3 changes: 1 addition & 2 deletions internal/webssoauth/webssoauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,8 @@ func (w *WebSSOAuthentication) promptForRole(idp string, roleARNs []string) (rol
// If the fedApp has already been selected via an ask one survey we don't need
// to pretty print out the IdP name again.
func (w *WebSSOAuthentication) promptForIDP(idpARNs []string) (idpARN string, err error) {
oktaConfig, _ := w.config.OktaConfig()
var configIDPs map[string]string
if err == nil {
if oktaConfig, cErr := w.config.OktaConfig(); cErr == nil {
configIDPs = oktaConfig.AWSCLI.IDPS
}

Expand Down

0 comments on commit 589ad31

Please sign in to comment.