diff --git a/CHANGELOG.md b/CHANGELOG.md index e07a5427..70210247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [v2.0.0] - ????-??-?? + +### Bugs + + * Fix fatal error with `time` command #1008 + ### Changes * No longer show help for sub-commands by default @@ -761,7 +767,8 @@ Initial release -[Unreleased]: https://github.com/synfinatic/aws-sso-cli/compare/v1.17.0...main +[Unreleased]: https://github.com/synfinatic/aws-sso-cli/compare/v2.0.0...main +[v2.0.0]: https://github.com/synfinatic/aws-sso-cli/compare/v2.0.0...v1.17.0 [v1.17.0]: https://github.com/synfinatic/aws-sso-cli/releases/tag/v1.17.0 [v1.16.1]: https://github.com/synfinatic/aws-sso-cli/releases/tag/v1.16.1 [v1.16.0]: https://github.com/synfinatic/aws-sso-cli/releases/tag/v1.16.0 diff --git a/internal/ecs/server/testdata/config.ssl b/internal/ecs/server/testdata/config.ssl deleted file mode 100644 index 8fffb13e..00000000 --- a/internal/ecs/server/testdata/config.ssl +++ /dev/null @@ -1,8 +0,0 @@ -[dn] -CN=localhost -[req] -distinguished_name = dn -[EXT] -subjectAltName=DNS:localhost,IP:127.0.0.1 -keyUsage=digitalSignature -extendedKeyUsage=serverAuth diff --git a/internal/ecs/server/testdata/gen_certs.sh b/internal/ecs/server/testdata/gen_certs.sh index 152ff740..0230f32e 100755 --- a/internal/ecs/server/testdata/gen_certs.sh +++ b/internal/ecs/server/testdata/gen_certs.sh @@ -11,7 +11,7 @@ keyUsage=digitalSignature extendedKeyUsage=serverAuth EOF -openssl req -x509 -out localhost.crt -keyout localhost.key \ +openssl req -x509 -out localhost.crt -keyout localhost.key -days 3065 \ -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config config.ssl rm config.ssl diff --git a/internal/ecs/server/testdata/localhost.crt b/internal/ecs/server/testdata/localhost.crt index ede7f4ef..0e6ec3e9 100644 --- a/internal/ecs/server/testdata/localhost.crt +++ b/internal/ecs/server/testdata/localhost.crt @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDFTCCAf2gAwIBAgIUaCLt3LBmowSA1M5l18uClR6gEowwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDYyODIzMTYyNFoXDTI0MDcy -ODIzMTYyNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArdOPM3TbUxPmbQ3wrEfh1WPV4JuY5qzv86UHbG01pen4 -NSxWraRi6F6PrSRL8PFJeW/8IiK122jc/LOI04SgDam7tkmjzhoPVJrKERWhV6QH -WuQC4iTI8XYmNvVtj+vlDK6tESl40evqkYLzFKjRj6sjX5/6iXViIxRzFugMY7DO -RUy7Pt52dc0xyWU2N5PjtCMwNVuTSoCiJRgqCN/j7/hYhi7o+nd6Ip6AzhePIu10 -yV45jZ96GA4G2B6qKRz48O/eJEW+g+E6h95BD1mqUCFb7K175F+YnhIlZXsGunEK -BqO1nK4A3BWYAgG2EDvLkmejHB0dF7ENh1cV9PbhBQIDAQABo18wXTAaBgNVHREE +MIIDFTCCAf2gAwIBAgIUeMWgpG0ZvnZBwrc2F0hiNp0GBNAwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDczMDAxMTE0NFoXDTMyMTIy +MDAxMTE0NFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA8m/bBGzD7u4u/lE9RqYVhyci1QWygZT2LVrFQ4WQuw+D +2hGcP2JnQ3aS9zFgYcQylb0zQzHRSgwjVI6+WIcAMPVPHHG+zq/fHxJgtKSqBr+H +nNOUJUFQKXvY5rex4CJgNS7S+MHqPblxPs5BAjW5Gg02y2YbkLTQU6aV8u6JQsxh +hiuSwGOcdtLPxlfM7Ts9RGSCvMgnYcKosSHuqu+sWZ8BthiOFha5SoLrz3UAvSL8 +F9r6lb3oroX04sRP7h42mgZsqB22kLyVkJWEBDQOXoNlIMlCMnzdzyONpOo2EWH3 +7JML/mcmTvq/ZEygtPcFmupyZswTM7Q4OI/I7sPSowIDAQABo18wXTAaBgNVHREE EzARgglsb2NhbGhvc3SHBH8AAAEwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsG -AQUFBwMBMB0GA1UdDgQWBBRdOEFXAt/YgKN/7K/CFkOavjXmDTANBgkqhkiG9w0B -AQsFAAOCAQEAcAbC/5tr69pLAJrqMnMsnwxFw+N/1R23w52iU53N7fIt1Sxbjm0m -uMwGtbZUIwrjEU/rOkvOxVriWy+MS3Jdv87rM3XfXA6H152rsdLU+Gq5EWICgxf6 -5dzBpKYq3lJ2xvCqGKFFpPDSji9gs836CNyEsBiAiZZrk+BXc7htJI4htQNIBx+G -fiSKTpXGSJgxlTZ30gtiCQeHtqNMHJwwD5uygjcE84lC9HWmCKFOIeMv14jb5bD2 -8CLN1diSoIe14K4O4jLCmauOVCkpGc2yLM8Vr/cSLXoIDRVr92y/JAqH7ojZ22mx -J+JADQUtWA1QorM5BSqpx+V1fRPNqJ603A== +AQUFBwMBMB0GA1UdDgQWBBQP6i7LzlC037icQfsUG7nQ33YBDTANBgkqhkiG9w0B +AQsFAAOCAQEAx0Hg2QKIfyLyXQXDeOPYhYWul1eF6Zmf4K2oGGoHydrAeCTPn2N+ +PZtfhSvvHCAoxkKaHwL4OfwF8HEK+JPVGAnvobBWudymcu7oWxuSd6cTKIJ65bWl +Ms0XZMFmC3lj922Cf3ncFvb4WlCWUK4fGZoRzIDDD1oySWZaFPLrFpFdC3oOPtoE +aboycKPkVNP08MdOxj56tm7FaHw7KlOGZrT/tniwiXLal42KhuJjEact5r9i6ThN +mSjKxrbkUu5MR3Pf03ckXLecVEXYPjPOzxRJJK2als71DDqCUXWU32J1zOJqPpGN +2AHH0K5+K7/wyQ62pjVhSlj30FqKP4yt1w== -----END CERTIFICATE----- diff --git a/internal/ecs/server/testdata/localhost.key b/internal/ecs/server/testdata/localhost.key index 4a8079a7..99e80c63 100644 --- a/internal/ecs/server/testdata/localhost.key +++ b/internal/ecs/server/testdata/localhost.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCt048zdNtTE+Zt -DfCsR+HVY9Xgm5jmrO/zpQdsbTWl6fg1LFatpGLoXo+tJEvw8Ul5b/wiIrXbaNz8 -s4jThKANqbu2SaPOGg9UmsoRFaFXpAda5ALiJMjxdiY29W2P6+UMrq0RKXjR6+qR -gvMUqNGPqyNfn/qJdWIjFHMW6AxjsM5FTLs+3nZ1zTHJZTY3k+O0IzA1W5NKgKIl -GCoI3+Pv+FiGLuj6d3oinoDOF48i7XTJXjmNn3oYDgbYHqopHPjw794kRb6D4TqH -3kEPWapQIVvsrXvkX5ieEiVlewa6cQoGo7WcrgDcFZgCAbYQO8uSZ6McHR0XsQ2H -VxX09uEFAgMBAAECggEAHKLQIgV7xkVufgPAZNlYsmtGhkCL4WCXDRfgT7P0FRek -zLm3s9Zzdt1xJPBoVFKjrI5Oxp7aP8GYOkcnYNUl+uo94sth4We4o9L2O/dIw6Ph -lE8gzHmL4v94TzCCcqXFb5/tIfknjsmjNIKSohInp9flNXEo+HEukCHjzd+/fsKR -t/L/V+7UV9gsvbsqTHO80KKdqwy1JCazSNMr7ZJXxC/9KktNZkJ15vGkCnBJBKh7 -94EzAA0oOgN2Xd8II1A1DbxngrkdDX4n5nF45xGhYlT+QC4De74TqlAz4Drhk4Ir -+LlBb3zn27xLRAxuagm/1CoiixA5DWcQwq1bFYh4cQKBgQDeGz+2F+Gs4XqEWGld -nV7N1ix+Fg469YtktjAREvh/5UmW4+/ciPn74lhIB0fBmvYKV6XZC8LlZNGHvsD1 -BrnPnzsnpoaT36bH6oEiMt4KAnBjv/ZrZDA7KJfTcQNFK8CZ1md3aWLJb/h7xwWc -hW9Mrd0JjKms2K1fBHUx9SeZyQKBgQDIWjcl+HMi4ltRepzhnCOUgC/PMEI7Uwd8 -xxENjLOuGoECPZebJhppSt9NiLc6Hmc/YnU/+y1e7jbC27sPH2pNOz2ImEPWTC7X -8WZiLUpg9Zs8aXUYcyd4q5oo+K6tHutxyppZhZ+e7lhLOuixYPfRzTjcnIiG6Uh2 -7Q8pTGVrXQKBgBY/uokeKVAtIh3B0YQ8MHQEIV7cDL7hO/5xtazwLo55RH7mBHAe -FJSj3t4QRKLjSARPNWDhqbta9xZXCHNDIjfnJoDZUJ/dhpJ+LkNjvxRXnDSR1Th6 -x84VSeg3aPFz6Y4/iQvQNcIiAk076Zb9UuHmhL7hJVoYNn3PL4I6oaXpAoGAIlAR -EdezIE5UBWhSZfEvxscNaRaCwVY++ge9y+xE+ZRgc9nIlTG5ZD8Gb2jyuGlslVZv -bj2+T3vMtSKcrsJamk+DAlnRhGoXu7QELNxE2MY3h+knvMA8ClaZWFr+z3d0K1Df -jmVsKPP4+yljoL1StAPJsT69wx1A491Fs3T6CaECgYEAn7fgHvRcy0RwspGVKtgm -plj44c61sACWaQHGo1a5w3oPFDACiXo7VAt5jtY6D19ObmHpXVLgGhtv0F8XmLI6 -qUQ7+87Z9/EzpeF/ZUQC/2GV8nN+X8FoUCrs9i27BBXMfMJsYDjAK0gPMVpCUp7l -GsZ2w5GbjToPUIcpbPlsnCE= +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDyb9sEbMPu7i7+ +UT1GphWHJyLVBbKBlPYtWsVDhZC7D4PaEZw/YmdDdpL3MWBhxDKVvTNDMdFKDCNU +jr5YhwAw9U8ccb7Or98fEmC0pKoGv4ec05QlQVApe9jmt7HgImA1LtL4weo9uXE+ +zkECNbkaDTbLZhuQtNBTppXy7olCzGGGK5LAY5x20s/GV8ztOz1EZIK8yCdhwqix +Ie6q76xZnwG2GI4WFrlKguvPdQC9IvwX2vqVveiuhfTixE/uHjaaBmyoHbaQvJWQ +lYQENA5eg2UgyUIyfN3PI42k6jYRYffskwv+ZyZO+r9kTKC09wWa6nJmzBMztDg4 +j8juw9KjAgMBAAECggEABQN2TVHWfk6ROoFvS/cnAxqkOnoZ0+0L+aoivVaVVutC +ylhmBzfR4W/9TcXtfME9N7Re8AReJldvWL/hO4qU4NwGZhTm8/Zoi4eF6Ci4KI61 +s/L6c77HmXZODY9ipnIUHUDefpq7/4A0Y8Eb4sQ97vz8ZYeOm83oS9lqNm111OzD +ouu8Z5kebQDyxEK8lKf+UtnumDQZIiiW8B6z0a6O/+HW4PiIuuFQTWO9dE5m5mSo +zOegi+2BjiYdRRI+Ot1bY1cdRTRCeiQ/E/fbK5X4nEw/oO/DFo9tv1AXcuFrGJV8 ++dCqtPUvGFAtxtFhszVK77ClyY7kaRR783OvrblIyQKBgQD+N6wKlLI26naOx/0e +szWUv++sBYt/igUtyNLDl+3l3Dbegktl5XFsprWxIJxEP6PQMIaoPCbBWMo9WUeT +M+cW0IngHhaLqahUTK+ziN6tomvfNeZl3Qk902c2NMagpVw86oftFNC/yYh7FILu +0OLbLebBfSmBlzd260Qf+0XIvQKBgQD0Iwl+vng2YjG3TqU20/CkLN793xHgN+kY +cVKNhXT6PlIp2W8Xn9b4UOXeTpgEF10Nw3eqsx1IRFY7GrpP/MFzrzeECG4lWVsZ +6Jhls8/ZdzNbmSGDd7R9tUh9Mb/aqcl6Da/sVXbfc7Fko7TD4s/XWC4gzfuRpLzI +cBfFgQgu3wKBgQC5HfsmnU8FFEkPAex9LYyn6/hwMH17exr4UxO/IGQ5DNnbv899 +vM2Si/ckq5V/UURNdvini13BT5G9iMTJGXN+to6f5+kM/Jc6A7myJ8nXcL3ShaJn +rMRtBANVgqrdEm0PYs1mQ9Eax3ud/Lq3gt6fMlalsSnHV0EpVHqAO25+lQKBgQC3 +v38wA8+arwFYRDsZLx9ZkeQsE67yoWIxYWmO1rmadzmEAgEZONalgs3gKitEOQly +iIIS2kjZ0YVNaup7tXMszN3t5CJyvfRRZbz+Hv37YTooYPLWbkxMqRrsD3uk6lGY +KaEVMaYMvJjxdD1jidyA6f+d9Sq5DdKA0c0ye9Fa5QKBgF5ZQPJoT6vZ+qofxJZL +b+KcCREkY2qUJ5L80dXefdKXCyi/gnq+vOEpGNElJGfm8eMxmrAVRgK06meVNhwR +qQO31xdVt0QI5njrqNIpOuIZz9LBZcbZM7DtXZtoz9cEpqiIZsPFaYDmD+yygl+r +LsTUuAPYRrjFw8ixKS/QtQZ2 -----END PRIVATE KEY----- diff --git a/internal/sso/settings.go b/internal/sso/settings.go index 495d1510..e9670c85 100644 --- a/internal/sso/settings.go +++ b/internal/sso/settings.go @@ -39,8 +39,7 @@ import ( ) const ( - AWS_SSO_SESSION_EXPIRATION_FORMAT = "2006-01-02 15:04:05 -0700 MST" - NIX_STORE_PREFIX = "/nix/store/" + NIX_STORE_PREFIX = "/nix/store/" ) type Settings struct { diff --git a/internal/utils/utils.go b/internal/utils/utils.go index a1c0ad27..edf2d702 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -71,19 +71,19 @@ func ParseRoleARN(arn string) (int64, string, error) { accountid = s[4] s = strings.Split(s[5], "/") if len(s) != 2 { - return 0, "", fmt.Errorf("Unable to parse ARN: %s", arn) + return 0, "", fmt.Errorf("unable to parse ARN: %s", arn) } role = s[1] default: - return 0, "", fmt.Errorf("Unable to parse ARN: %s", arn) + return 0, "", fmt.Errorf("unable to parse ARN: %s", arn) } aId, err := strconv.ParseInt(accountid, 10, 64) if err != nil { - return 0, "", fmt.Errorf("Unable to parse ARN: %s", arn) + return 0, "", fmt.Errorf("unable to parse ARN: %s", arn) } if aId < 0 { - return 0, "", fmt.Errorf("Invalid AccountID: %d", aId) + return 0, "", fmt.Errorf("invalid AccountID: %d", aId) } return aId, role, nil } @@ -97,7 +97,7 @@ func ParseUserARN(arn string) (int64, string, error) { func MakeRoleARN(account int64, name string) string { a, err := AccountIdToString(account) if err != nil { - log.WithError(err).Panicf("Unable to MakeRoleARN") + log.WithError(err).Panicf("unable to MakeRoleARN") } return fmt.Sprintf("arn:aws:iam::%s:role/%s", a, name) } @@ -106,7 +106,7 @@ func MakeRoleARN(account int64, name string) string { func MakeUserARN(account int64, name string) string { a, err := AccountIdToString(account) if err != nil { - log.WithError(err).Panicf("Unable to MakeUserARN") + log.WithError(err).Panicf("unable to MakeUserARN") } return fmt.Sprintf("arn:aws:iam::%s:user/%s", a, name) } @@ -115,7 +115,7 @@ func MakeUserARN(account int64, name string) string { func MakeRoleARNs(account, name string) string { x, err := AccountIdToInt64(account) if err != nil { - log.WithError(err).Panicf("Unable to AccountIdToInt64 in MakeRoleARNs") + log.WithError(err).Panicf("unable to AccountIdToInt64 in MakeRoleARNs") } a, _ := AccountIdToString(x) @@ -129,7 +129,7 @@ func EnsureDirExists(filename string) error { f, err := os.Open(storeDir) if os.IsNotExist(err) { if err := os.MkdirAll(storeDir, 0700); err != nil { - return fmt.Errorf("Unable to create %s: %s", storeDir, err.Error()) + return fmt.Errorf("unable to create %s: %s", storeDir, err.Error()) } return nil } else if err != nil { @@ -137,19 +137,19 @@ func EnsureDirExists(filename string) error { } info, err := f.Stat() if err != nil { - return fmt.Errorf("Unable to stat %s: %s", storeDir, err.Error()) + return fmt.Errorf("unable to stat %s: %s", storeDir, err.Error()) } if !info.IsDir() { - return fmt.Errorf("%s exists and is not a directory!", storeDir) + return fmt.Errorf("%s exists and is not a directory", storeDir) } return nil } -// ParseTimeString converts a standard time string to Unix Epoch +// ParseTimeString converts a standard RFC3339 time string to Unix Epoch func ParseTimeString(t string) (int64, error) { - i, err := time.Parse("2006-01-02 15:04:05 -0700 MST", t) + i, err := time.Parse(time.RFC3339, t) if err != nil { - return 0, fmt.Errorf("Unable to parse %s: %s", t, err.Error()) + return 0, fmt.Errorf("unable to parse %s: %s", t, err.Error()) } return i.Unix(), nil } @@ -186,7 +186,7 @@ func TimeRemain(expires int64, space bool) (string, error) { // AccountIdToString returns a string version of AWS AccountID func AccountIdToString(a int64) (string, error) { if a < 0 || a > MAX_AWS_ACCOUNTID { - return "", fmt.Errorf("Invalid AWS AccountId: %d", a) + return "", fmt.Errorf("invalid AWS AccountId: %d", a) } return fmt.Sprintf("%012d", a), nil } @@ -198,7 +198,7 @@ func AccountIdToInt64(a string) (int64, error) { return 0, err } if x < 0 { - return 0, fmt.Errorf("Invalid AWS AccountId: %s", a) + return 0, fmt.Errorf("invalid AWS AccountId: %s", a) } return x, nil } diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index ac71c3c8..53f512dc 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -40,6 +40,7 @@ func TestUtilsSuite(t *testing.T) { func (suite *UtilsTestSuite) TestParseRoleARN() { t := suite.T() + t.Parallel() a, r, err := ParseRoleARN("arn:aws:iam::11111:role/Foo") assert.NoError(t, err) @@ -84,6 +85,7 @@ func (suite *UtilsTestSuite) TestParseRoleARN() { func (suite *UtilsTestSuite) TestMakeRoleARN() { t := suite.T() + t.Parallel() assert.Equal(t, "arn:aws:iam::000000011111:role/Foo", MakeRoleARN(11111, "Foo")) assert.Equal(t, "arn:aws:iam::000000711111:role/Foo", MakeRoleARN(711111, "Foo")) @@ -94,6 +96,7 @@ func (suite *UtilsTestSuite) TestMakeRoleARN() { func (suite *UtilsTestSuite) TestMakeUserARN() { t := suite.T() + t.Parallel() assert.Equal(t, "arn:aws:iam::000000011111:user/Foo", MakeUserARN(11111, "Foo")) assert.Equal(t, "arn:aws:iam::000000711111:user/Foo", MakeUserARN(711111, "Foo")) @@ -104,6 +107,7 @@ func (suite *UtilsTestSuite) TestMakeUserARN() { func (suite *UtilsTestSuite) TestMakeRoleARNs() { t := suite.T() + t.Parallel() assert.Equal(t, "arn:aws:iam::000000011111:role/Foo", MakeRoleARNs("11111", "Foo")) assert.Equal(t, "arn:aws:iam::000000711111:role/Foo", MakeRoleARNs("711111", "Foo")) @@ -115,6 +119,7 @@ func (suite *UtilsTestSuite) TestMakeRoleARNs() { func (suite *UtilsTestSuite) TestEnsureDirExists() { t := suite.T() + t.Parallel() defer os.RemoveAll("./does_not_exist_dir") assert.NoError(t, EnsureDirExists("./testdata/role_tags.yaml")) @@ -133,6 +138,7 @@ func (suite *UtilsTestSuite) TestEnsureDirExists() { func (suite *UtilsTestSuite) TestGetHomePath() { t := suite.T() + t.Parallel() assert.Equal(t, "/", GetHomePath("/")) assert.Equal(t, ".", GetHomePath(".")) @@ -146,6 +152,7 @@ func (suite *UtilsTestSuite) TestGetHomePath() { func (suite *UtilsTestSuite) TestAccountToString() { t := suite.T() + t.Parallel() a, err := AccountIdToString(0) assert.NoError(t, err) @@ -171,6 +178,7 @@ func (suite *UtilsTestSuite) TestAccountToString() { func (suite *UtilsTestSuite) TestAccountToInt64() { t := suite.T() + t.Parallel() _, err := AccountIdToInt64("") assert.Error(t, err) @@ -195,8 +203,9 @@ func (suite *UtilsTestSuite) TestAccountToInt64() { func (suite *UtilsTestSuite) TestParseTimeString() { t := suite.T() + t.Parallel() - x, e := ParseTimeString("1970-01-01 00:00:00 +0000 GMT") + x, e := ParseTimeString("1970-01-01T00:00:00Z") assert.NoError(t, e) assert.Equal(t, int64(0), x) @@ -206,6 +215,7 @@ func (suite *UtilsTestSuite) TestParseTimeString() { func (suite *UtilsTestSuite) TestTimeRemain() { t := suite.T() + t.Parallel() x, e := TimeRemain(0, false) assert.NoError(t, e) @@ -246,6 +256,7 @@ func (suite *UtilsTestSuite) TestTimeRemain() { } func TestStrListContains(t *testing.T) { + t.Parallel() x := []string{"yes", "no"} assert.True(t, StrListContains("yes", x)) assert.False(t, StrListContains("nope", x))