From c30df778b293da0d7b82bcb591d48d312acd3019 Mon Sep 17 00:00:00 2001 From: joobisb Date: Thu, 26 Sep 2024 09:32:07 +0530 Subject: [PATCH 1/3] feat: create a token on behalf of another user in the cli --- .../coder_tokens_create_--help.golden | 3 ++ cli/tokens.go | 14 +++++- cli/tokens_test.go | 46 ++++++++++++++++++- docs/reference/cli/tokens_create.md | 9 ++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/cli/testdata/coder_tokens_create_--help.golden b/cli/testdata/coder_tokens_create_--help.golden index f36d80f229783..fe9936988ef23 100644 --- a/cli/testdata/coder_tokens_create_--help.golden +++ b/cli/testdata/coder_tokens_create_--help.golden @@ -12,5 +12,8 @@ OPTIONS: -n, --name string, $CODER_TOKEN_NAME Specify a human-readable name. + -u, --user string, $CODER_TOKEN_USER + Specify the user to create the token for (Only works if logged in user is admin). + ——— Run `coder --help` for a list of global options. diff --git a/cli/tokens.go b/cli/tokens.go index 4961ac7e3e9b5..30eda97e17623 100644 --- a/cli/tokens.go +++ b/cli/tokens.go @@ -48,6 +48,7 @@ func (r *RootCmd) createToken() *serpent.Command { var ( tokenLifetime time.Duration name string + user string ) client := new(codersdk.Client) cmd := &serpent.Command{ @@ -58,7 +59,11 @@ func (r *RootCmd) createToken() *serpent.Command { r.InitClient(client), ), Handler: func(inv *serpent.Invocation) error { - res, err := client.CreateToken(inv.Context(), codersdk.Me, codersdk.CreateTokenRequest{ + userID := codersdk.Me + if user != "" { + userID = user + } + res, err := client.CreateToken(inv.Context(), userID, codersdk.CreateTokenRequest{ Lifetime: tokenLifetime, TokenName: name, }) @@ -87,6 +92,13 @@ func (r *RootCmd) createToken() *serpent.Command { Description: "Specify a human-readable name.", Value: serpent.StringOf(&name), }, + { + Flag: "user", + FlagShorthand: "u", + Env: "CODER_TOKEN_USER", + Description: "Specify the user to create the token for (Only works if logged in user is admin).", + Value: serpent.StringOf(&user), + }, } return cmd diff --git a/cli/tokens_test.go b/cli/tokens_test.go index fdb062b959a3b..787acf52c1c68 100644 --- a/cli/tokens_test.go +++ b/cli/tokens_test.go @@ -17,7 +17,10 @@ import ( func TestTokens(t *testing.T) { t.Parallel() client := coderdtest.New(t, nil) - _ = coderdtest.CreateFirstUser(t, client) + adminUser := coderdtest.CreateFirstUser(t, client) + + secondUserClient, secondUser := coderdtest.CreateAnotherUser(t, client, adminUser.OrganizationID) + _, thirdUser := coderdtest.CreateAnotherUser(t, client, adminUser.OrganizationID) ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancelFunc() @@ -42,6 +45,19 @@ func TestTokens(t *testing.T) { require.NotEmpty(t, res) id := res[:10] + // Test creating a token for second user from first user's (admin) session + inv, root = clitest.New(t, "tokens", "create", "--name", "token-two", "--user", secondUser.ID.String()) + clitest.SetupConfig(t, client, root) + buf = new(bytes.Buffer) + inv.Stdout = buf + err = inv.WithContext(ctx).Run() + // Test should succeed in creating token for second user + require.NoError(t, err) + res = buf.String() + require.NotEmpty(t, res) + secondTokenID := res[:10] + + // Test listing tokens from the first user's (admin) session inv, root = clitest.New(t, "tokens", "ls") clitest.SetupConfig(t, client, root) buf = new(bytes.Buffer) @@ -50,11 +66,39 @@ func TestTokens(t *testing.T) { require.NoError(t, err) res = buf.String() require.NotEmpty(t, res) + // Result should only contain the token created for the admin user require.Contains(t, res, "ID") require.Contains(t, res, "EXPIRES AT") require.Contains(t, res, "CREATED AT") require.Contains(t, res, "LAST USED") require.Contains(t, res, id) + // Result should not contain the token created for the second user + require.NotContains(t, res, secondTokenID) + + // Test listing tokens from the second user's session + inv, root = clitest.New(t, "tokens", "ls") + clitest.SetupConfig(t, secondUserClient, root) + buf = new(bytes.Buffer) + inv.Stdout = buf + err = inv.WithContext(ctx).Run() + require.NoError(t, err) + res = buf.String() + require.NotEmpty(t, res) + require.Contains(t, res, "ID") + require.Contains(t, res, "EXPIRES AT") + require.Contains(t, res, "CREATED AT") + require.Contains(t, res, "LAST USED") + // Result should contain the token created for the second user + require.Contains(t, res, secondTokenID) + + // Test creating a token for third user from second user's (non-admin) session + inv, root = clitest.New(t, "tokens", "create", "--name", "token-two", "--user", thirdUser.ID.String()) + clitest.SetupConfig(t, secondUserClient, root) + buf = new(bytes.Buffer) + inv.Stdout = buf + err = inv.WithContext(ctx).Run() + // User (non-admin) should not be able to create a token for another user + require.Error(t, err) inv, root = clitest.New(t, "tokens", "ls", "--output=json") clitest.SetupConfig(t, client, root) diff --git a/docs/reference/cli/tokens_create.md b/docs/reference/cli/tokens_create.md index e6b613fa0090a..09a4a5d200ea5 100644 --- a/docs/reference/cli/tokens_create.md +++ b/docs/reference/cli/tokens_create.md @@ -30,3 +30,12 @@ Specify a duration for the lifetime of the token. | Environment | $CODER_TOKEN_NAME | Specify a human-readable name. + +### -u, --user + +| | | +| ----------- | ------------------------------ | +| Type | string | +| Environment | $CODER_TOKEN_USER | + +Specify the user to create the token for (Only works if logged in user is admin). From aff6207ed13fd12cf9352b7f7794395621fe77b2 Mon Sep 17 00:00:00 2001 From: joobisb Date: Mon, 30 Sep 2024 10:57:35 +0530 Subject: [PATCH 2/3] fix: gocritic lint --- cli/tokens_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/tokens_test.go b/cli/tokens_test.go index 787acf52c1c68..7c024f3ad1a6f 100644 --- a/cli/tokens_test.go +++ b/cli/tokens_test.go @@ -27,6 +27,7 @@ func TestTokens(t *testing.T) { // helpful empty response inv, root := clitest.New(t, "tokens", "ls") + //nolint:gocritic // This should be run as the owner user. clitest.SetupConfig(t, client, root) buf := new(bytes.Buffer) inv.Stdout = buf From d1836ed70214c34377cfd8624999960526b732b4 Mon Sep 17 00:00:00 2001 From: joobisb Date: Mon, 30 Sep 2024 23:37:27 +0530 Subject: [PATCH 3/3] fix: generate golden file --- cli/testdata/coder_tokens_create_--help.golden | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/testdata/coder_tokens_create_--help.golden b/cli/testdata/coder_tokens_create_--help.golden index fe9936988ef23..f887c38acd00c 100644 --- a/cli/testdata/coder_tokens_create_--help.golden +++ b/cli/testdata/coder_tokens_create_--help.golden @@ -13,7 +13,8 @@ OPTIONS: Specify a human-readable name. -u, --user string, $CODER_TOKEN_USER - Specify the user to create the token for (Only works if logged in user is admin). + Specify the user to create the token for (Only works if logged in user + is admin). ——— Run `coder --help` for a list of global options.