-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(profile/token): Allow user to specify how long token must be val…
…id. (#1340) * feat(profile/token): Allow user to specify how long token must be valid. The default token validity period for 'fastly profile token' is 5 minutes, but users may want to ensure that the token is valid for a longer period (or only a shorter period). This PR adds 'fastly profile token --ttl=<period>', allowing the user to specify the validity period in seconds, minutes, or hours (or some combination). * Restore support for non-OIDC tokens in `fastly profile token`. Profiles with non-OIDC tokens (tokens generated using the traditional Fastly token-creation methods) do not contain expiration information, so the validity-checking in the `fastly profile token` command should not attempt to validate them. * Emit proper suggested command when an OIDC token needs to be refreshed. The `fastly profile update` command is not the best suggestion in this situation; the user should directly invoke `fastly sso` instead.
- Loading branch information
Showing
3 changed files
with
94 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -404,7 +404,7 @@ func TestProfileToken(t *testing.T) { | |
|
||
scenarios := []testutil.CLIScenario{ | ||
{ | ||
Name: "validate the active profile token is displayed by default", | ||
Name: "validate the active profile non-OIDC token is displayed by default", | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
Copy: []testutil.FileIO{ | ||
|
@@ -421,25 +421,21 @@ func TestProfileToken(t *testing.T) { | |
ConfigFile: &config.File{ | ||
Profiles: config.Profiles{ | ||
"foo": &config.Profile{ | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
}, | ||
"bar": &config.Profile{ | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
}, | ||
}, | ||
}, | ||
WantOutput: "123", | ||
}, | ||
{ | ||
Name: "validate token is displayed for the specified profile", | ||
Name: "validate non-OIDC token is displayed for the specified profile", | ||
Args: "bar", // we choose a non-default profile | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
|
@@ -457,25 +453,21 @@ func TestProfileToken(t *testing.T) { | |
ConfigFile: &config.File{ | ||
Profiles: config.Profiles{ | ||
"foo": &config.Profile{ | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
}, | ||
"bar": &config.Profile{ | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
}, | ||
}, | ||
}, | ||
WantOutput: "456", | ||
}, | ||
{ | ||
Name: "validate token is displayed for the specified profile using global --profile", | ||
Name: "validate non-OIDC token is displayed for the specified profile using global --profile", | ||
Args: "--profile bar", // we choose a non-default profile | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
|
@@ -493,18 +485,14 @@ func TestProfileToken(t *testing.T) { | |
ConfigFile: &config.File{ | ||
Profiles: config.Profiles{ | ||
"foo": &config.Profile{ | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
}, | ||
"bar": &config.Profile{ | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 600, | ||
Default: false, | ||
Email: "[email protected]", | ||
Token: "456", | ||
}, | ||
}, | ||
}, | ||
|
@@ -529,7 +517,7 @@ func TestProfileToken(t *testing.T) { | |
WantError: "profile 'unknown' does not exist", | ||
}, | ||
{ | ||
Name: "validate that an expired token generates an error", | ||
Name: "validate that an expired OIDC token generates an error", | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
Copy: []testutil.FileIO{ | ||
|
@@ -557,7 +545,7 @@ func TestProfileToken(t *testing.T) { | |
WantError: fmt.Sprintf("the token in profile 'foo' expired at '%s'", now.Add(time.Duration(-600)*time.Second).UTC().Format(fsttime.Format)), | ||
}, | ||
{ | ||
Name: "validate that a soon-to-expire token generates an error", | ||
Name: "validate that a soon-to-expire OIDC token generates an error", | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
Copy: []testutil.FileIO{ | ||
|
@@ -584,6 +572,64 @@ func TestProfileToken(t *testing.T) { | |
}, | ||
WantError: fmt.Sprintf("the token in profile 'foo' will expire at '%s'", now.Add(time.Duration(30)*time.Second).UTC().Format(fsttime.Format)), | ||
}, | ||
{ | ||
Name: "validate that a soon-to-expire OIDC token with a non-default TTL does not generate an error", | ||
Args: "--ttl 30s", | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
Copy: []testutil.FileIO{ | ||
{ | ||
Src: filepath.Join("testdata", "config.toml"), | ||
Dst: "config.toml", | ||
}, | ||
}, | ||
}, | ||
EditScenario: func(scenario *testutil.CLIScenario, rootdir string) { | ||
scenario.ConfigPath = filepath.Join(rootdir, "config.toml") | ||
}, | ||
}, | ||
ConfigFile: &config.File{ | ||
Profiles: config.Profiles{ | ||
"foo": &config.Profile{ | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 60, | ||
}, | ||
}, | ||
}, | ||
WantOutput: "123", | ||
}, | ||
{ | ||
Name: "validate that an OIDC token with a long non-default TTL generates an error", | ||
Args: "--ttl 1800s", | ||
Env: &testutil.EnvConfig{ | ||
Opts: &testutil.EnvOpts{ | ||
Copy: []testutil.FileIO{ | ||
{ | ||
Src: filepath.Join("testdata", "config.toml"), | ||
Dst: "config.toml", | ||
}, | ||
}, | ||
}, | ||
EditScenario: func(scenario *testutil.CLIScenario, rootdir string) { | ||
scenario.ConfigPath = filepath.Join(rootdir, "config.toml") | ||
}, | ||
}, | ||
ConfigFile: &config.File{ | ||
Profiles: config.Profiles{ | ||
"foo": &config.Profile{ | ||
Default: true, | ||
Email: "[email protected]", | ||
Token: "123", | ||
RefreshTokenCreated: now.Unix(), | ||
RefreshTokenTTL: 1200, | ||
}, | ||
}, | ||
}, | ||
WantError: fmt.Sprintf("the token in profile 'foo' will expire at '%s'", now.Add(time.Duration(1200)*time.Second).UTC().Format(fsttime.Format)), | ||
}, | ||
} | ||
|
||
testutil.RunCLIScenarios(t, []string{root.CommandName, "token"}, scenarios) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters