From 5e9ffd57d4a2261d4862bef5381328a5aada5562 Mon Sep 17 00:00:00 2001 From: Stan Ryzhov <60649800+stasryzhov@users.noreply.github.com> Date: Mon, 17 Apr 2023 22:16:55 -0400 Subject: [PATCH] test(e2e): add test to verify user is logged out on its auth-token deletion (#3160) --- testing/internal/e2e/boundary/authenticate.go | 8 +- testing/internal/e2e/boundary/authtoken.go | 36 ++++++++ .../tests/static/auth_token_delete_test.go | 87 +++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 testing/internal/e2e/boundary/authtoken.go create mode 100644 testing/internal/e2e/tests/static/auth_token_delete_test.go diff --git a/testing/internal/e2e/boundary/authenticate.go b/testing/internal/e2e/boundary/authenticate.go index 1b06914bc..56c8fcce2 100644 --- a/testing/internal/e2e/boundary/authenticate.go +++ b/testing/internal/e2e/boundary/authenticate.go @@ -53,11 +53,12 @@ func AuthenticateAdminCli(t testing.TB, ctx context.Context) { } // AuthenticateCli uses the cli to authenticate the specified Boundary instance -func AuthenticateCli(t testing.TB, ctx context.Context, authMethodId string, loginName string, password string) { +func AuthenticateCli(t testing.TB, ctx context.Context, authMethodId string, loginName string, password string, opt ...e2e.Option) { c, err := LoadConfig() require.NoError(t, err) - output := e2e.RunCommand(ctx, "boundary", + var options []e2e.Option + options = append(options, e2e.WithArgs( "authenticate", "password", "-addr", c.Address, @@ -67,6 +68,9 @@ func AuthenticateCli(t testing.TB, ctx context.Context, authMethodId string, log ), e2e.WithEnv("E2E_TEST_BOUNDARY_PASSWORD", password), ) + options = append(options, opt...) + + output := e2e.RunCommand(ctx, "boundary", options...) require.NoError(t, output.Err, string(output.Stderr)) } diff --git a/testing/internal/e2e/boundary/authtoken.go b/testing/internal/e2e/boundary/authtoken.go new file mode 100644 index 000000000..8c38c8e80 --- /dev/null +++ b/testing/internal/e2e/boundary/authtoken.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package boundary + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/hashicorp/boundary/api/authtokens" + "github.com/hashicorp/boundary/testing/internal/e2e" + "github.com/stretchr/testify/require" +) + +// GetAuthenticationTokenIdByTokenNameCli uses the CLI to get an auth-token ID by its name +// The operation is performed by the user associated with the auth-token +func GetAuthenticationTokenIdByTokenNameCli(t testing.TB, ctx context.Context, tokenName string) string { + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "auth-tokens", "list", + "-token-name", tokenName, + "-format", "json", + ), + ) + require.NoError(t, output.Err, string(output.Stderr)) + + var authTokenListResult authtokens.AuthTokenListResult + err := json.Unmarshal(output.Stdout, &authTokenListResult) + require.NoError(t, err) + userAuthTokenID := fmt.Sprint(authTokenListResult.Items[0].Id) + t.Logf("Retrieved Auth-Token: %s", userAuthTokenID) + + return userAuthTokenID +} diff --git a/testing/internal/e2e/tests/static/auth_token_delete_test.go b/testing/internal/e2e/tests/static/auth_token_delete_test.go new file mode 100644 index 000000000..07d42e297 --- /dev/null +++ b/testing/internal/e2e/tests/static/auth_token_delete_test.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package static_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/boundary/testing/internal/e2e" + "github.com/hashicorp/boundary/testing/internal/e2e/boundary" + "github.com/stretchr/testify/require" +) + +const testAccountName = "test-account" + +// TestUserIsLoggedOutWhenAuthTokenIsDeletedCli validates that a user +// gets logged out if admin deletes its auth-token. +// The test authenticates a new user and verifies that it can perform +// operations requiring to be logged in (e.g. 'boundary auth-tokens list'). +// Then the test deletes the user's auth-token by admin and verifies that +// the user cannot perform operations requiring to be logged in anymore. +func TestUserIsLoggedOutWhenAuthTokenIsDeletedCli(t *testing.T) { + e2e.MaybeSkipTest(t) + bc, err := boundary.LoadConfig() + require.NoError(t, err) + + ctx := context.Background() + boundary.AuthenticateAdminCli(t, ctx) + newAccountId, acctPassword := boundary.CreateNewAccountCli(t, ctx, bc.AuthMethodId, testAccountName) + t.Cleanup(func() { + boundary.AuthenticateAdminCli(t, context.Background()) + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs("accounts", "delete", "-id", newAccountId), + ) + require.NoError(t, output.Err, string(output.Stderr)) + }) + newUserId := boundary.CreateNewUserCli(t, ctx, "global") + t.Cleanup(func() { + boundary.AuthenticateAdminCli(t, context.Background()) + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs("users", "delete", "-id", newUserId), + ) + require.NoError(t, output.Err, string(output.Stderr)) + }) + boundary.SetAccountToUserCli(t, ctx, newUserId, newAccountId) + + // Authenticate user and assign a name to its auth token + boundary.AuthenticateCli(t, context.Background(), bc.AuthMethodId, testAccountName, acctPassword, + e2e.WithArgs("-token-name", testAccountName), + ) + + // As the user, execute the command requiring to be logged in. + // Provide the user's token name to the command so that it is executed by the user, not admin + output := e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "auth-tokens", "list", + "-token-name", testAccountName, + ), + ) + require.NoError(t, output.Err, string(output.Stderr)) + + // As admin, delete the user's auth token + userAuthTokenID := boundary.GetAuthenticationTokenIdByTokenNameCli(t, ctx, testAccountName) + boundary.AuthenticateAdminCli(t, ctx) + output = e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "auth-tokens", "delete", + "-id", userAuthTokenID, + ), + ) + require.NoError(t, output.Err, string(output.Stderr)) + t.Logf("Sucessfully deleted user auth-token: %s", userAuthTokenID) + + // As the user, try to execute the command requiring to be logged in again + output = e2e.RunCommand(ctx, "boundary", + e2e.WithArgs( + "auth-tokens", "list", + "-token-name", testAccountName, + ), + ) + + // Expect error as the user got logged out + require.Error(t, output.Err, fmt.Sprintf("User '%s' is still logged in", testAccountName)) + t.Logf("Successfully verified that token name is invalid") +}