feat: implement feature to create a token on behalf of another user in the cli (#14813)

This PR addresses https://github.com/coder/coder/issues/13160
This commit is contained in:
Joobi S B
2024-09-30 20:15:28 +00:00
committed by GitHub
parent e70ad2b4b3
commit ba90bb0ab3
4 changed files with 73 additions and 3 deletions
+4
View File
@@ -12,5 +12,9 @@ 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.
+13 -1
View File
@@ -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
+47 -2
View File
@@ -17,13 +17,17 @@ 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()
// 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
@@ -42,6 +46,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 +67,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")
require.Contains(t, res, id)
// 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)
+9
View File
@@ -30,3 +30,12 @@ Specify a duration for the lifetime of the token.
| Environment | <code>$CODER_TOKEN_NAME</code> |
Specify a human-readable name.
### -u, --user
| | |
| ----------- | ------------------------------ |
| Type | <code>string</code> |
| Environment | <code>$CODER_TOKEN_USER</code> |
Specify the user to create the token for (Only works if logged in user is admin).