Extend TestCLILoginOIDC to test refresh flow.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
Matt Moyer 2020-10-22 17:35:06 -05:00
parent 3508a28369
commit 07001e5ee3
No known key found for this signature in database
GPG Key ID: EAE88AD172C5AE2D

View File

@ -26,6 +26,8 @@ import (
"gopkg.in/square/go-jose.v2" "gopkg.in/square/go-jose.v2"
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
"go.pinniped.dev/internal/oidcclient"
"go.pinniped.dev/internal/oidcclient/filesession"
"go.pinniped.dev/test/library" "go.pinniped.dev/test/library"
) )
@ -176,18 +178,12 @@ func TestCLILoginOIDC(t *testing.T) {
sessionCachePath := t.TempDir() + "/sessions.yaml" sessionCachePath := t.TempDir() + "/sessions.yaml"
// Start the CLI running the "alpha login oidc [...]" command with stdout/stderr connected to pipes. // Start the CLI running the "alpha login oidc [...]" command with stdout/stderr connected to pipes.
t.Logf("starting CLI subprocess") cmd := oidcLoginCommand(ctx, t, pinnipedExe, sessionCachePath)
cmd := exec.CommandContext(ctx, pinnipedExe, "alpha", "login", "oidc",
"--issuer", env.OIDCUpstream.Issuer,
"--client-id", env.OIDCUpstream.ClientID,
"--listen-port", strconv.Itoa(env.OIDCUpstream.LocalhostPort),
"--session-cache", sessionCachePath,
"--skip-browser",
)
stderr, err := cmd.StderrPipe() stderr, err := cmd.StderrPipe()
require.NoError(t, err) require.NoError(t, err)
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
require.NoError(t, err) require.NoError(t, err)
t.Logf("starting CLI subprocess")
require.NoError(t, cmd.Start()) require.NoError(t, cmd.Start())
t.Cleanup(func() { t.Cleanup(func() {
err := cmd.Wait() err := cmd.Wait()
@ -312,23 +308,44 @@ func TestCLILoginOIDC(t *testing.T) {
// Run the CLI again with the same session cache and login parameters. // Run the CLI again with the same session cache and login parameters.
t.Logf("starting second CLI subprocess to test session caching") t.Logf("starting second CLI subprocess to test session caching")
secondCtx, secondCancel := context.WithTimeout(ctx, 5*time.Second) cmd2Output, err := oidcLoginCommand(ctx, t, pinnipedExe, sessionCachePath).CombinedOutput()
defer secondCancel() require.NoError(t, err, string(cmd2Output))
cmdOutput, err := exec.CommandContext(secondCtx, pinnipedExe, "alpha", "login", "oidc",
"--issuer", env.OIDCUpstream.Issuer,
"--client-id", env.OIDCUpstream.ClientID,
"--listen-port", strconv.Itoa(env.OIDCUpstream.LocalhostPort),
"--session-cache", sessionCachePath,
"--skip-browser",
).CombinedOutput()
require.NoError(t, err)
// Expect the CLI to output the same ExecCredential in JSON format. // Expect the CLI to output the same ExecCredential in JSON format.
t.Logf("validating second ExecCredential") t.Logf("validating second ExecCredential")
var credOutput2 clientauthenticationv1beta1.ExecCredential var credOutput2 clientauthenticationv1beta1.ExecCredential
require.NoErrorf(t, json.Unmarshal(cmdOutput, &credOutput2), require.NoErrorf(t, json.Unmarshal(cmd2Output, &credOutput2),
"command returned something other than an ExecCredential:\n%s", string(cmdOutput)) "command returned something other than an ExecCredential:\n%s", string(cmd2Output))
require.Equal(t, credOutput, credOutput2) require.Equal(t, credOutput, credOutput2)
// Overwrite the cache entry to remove the access and ID tokens.
t.Logf("overwriting cache to remove valid ID token")
cache := filesession.New(sessionCachePath)
cacheKey := oidcclient.SessionCacheKey{
Issuer: env.OIDCUpstream.Issuer,
ClientID: env.OIDCUpstream.ClientID,
Scopes: []string{"email", "offline_access", "openid", "profile"},
RedirectURI: fmt.Sprintf("http://localhost:%d/callback", env.OIDCUpstream.LocalhostPort),
}
cached := cache.GetToken(cacheKey)
require.NotNil(t, cached)
require.NotNil(t, cached.RefreshToken)
require.NotEmpty(t, cached.RefreshToken.Token)
cached.IDToken = nil
cached.AccessToken = nil
cache.PutToken(cacheKey, cached)
// Run the CLI a third time with the same session cache and login parameters.
t.Logf("starting third CLI subprocess to test refresh flow")
cmd3Output, err := oidcLoginCommand(ctx, t, pinnipedExe, sessionCachePath).CombinedOutput()
require.NoError(t, err, string(cmd2Output))
// Expect the CLI to output a new ExecCredential in JSON format (different from the one returned the first two times).
t.Logf("validating third ExecCredential")
var credOutput3 clientauthenticationv1beta1.ExecCredential
require.NoErrorf(t, json.Unmarshal(cmd3Output, &credOutput3),
"command returned something other than an ExecCredential:\n%s", string(cmd2Output))
require.NotEqual(t, credOutput2.Status.Token, credOutput3.Status.Token)
} }
func waitForVisibleElements(t *testing.T, page *agouti.Page, selectors ...string) { func waitForVisibleElements(t *testing.T, page *agouti.Page, selectors ...string) {
@ -375,3 +392,14 @@ func spawnTestGoroutine(t *testing.T, f func() error) {
}) })
eg.Go(f) eg.Go(f)
} }
func oidcLoginCommand(ctx context.Context, t *testing.T, pinnipedExe string, sessionCachePath string) *exec.Cmd {
env := library.IntegrationEnv(t)
return exec.CommandContext(ctx, pinnipedExe, "alpha", "login", "oidc",
"--issuer", env.OIDCUpstream.Issuer,
"--client-id", env.OIDCUpstream.ClientID,
"--listen-port", strconv.Itoa(env.OIDCUpstream.LocalhostPort),
"--session-cache", sessionCachePath,
"--skip-browser",
)
}