Skip to content

Commit a2b349d

Browse files
committed
fix: use static rbac method for getting site roles instead of API call
1 parent 681ecba commit a2b349d

File tree

2 files changed

+79
-28
lines changed

2 files changed

+79
-28
lines changed

cli/usereditroles.go

+18-28
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
package cli
22

33
import (
4+
"fmt"
45
"slices"
56
"sort"
67
"strings"
78

89
"golang.org/x/xerrors"
910

1011
"github.com/coder/coder/v2/cli/cliui"
12+
"github.com/coder/coder/v2/coderd/rbac"
1113
"github.com/coder/coder/v2/codersdk"
1214
"github.com/coder/serpent"
1315
)
1416

1517
func (r *RootCmd) userEditRoles() *serpent.Command {
1618
client := new(codersdk.Client)
1719

20+
roles := rbac.SiteRoles()
21+
22+
siteRoles := make([]string, 0)
23+
for _, role := range roles {
24+
siteRoles = append(siteRoles, role.Identifier.Name)
25+
}
26+
sort.Strings(siteRoles)
27+
1828
var givenRoles []string
1929

2030
cmd := &serpent.Command{
@@ -24,7 +34,7 @@ func (r *RootCmd) userEditRoles() *serpent.Command {
2434
cliui.SkipPromptOption(),
2535
{
2636
Name: "roles",
27-
Description: "A list of roles to give to the user. This removes any existing roles the user may have.",
37+
Description: fmt.Sprintf("A list of roles to give to the user. This removes any existing roles the user may have. The available roles are: %s.", strings.Join(siteRoles, ", ")),
2838
Flag: "roles",
2939
Value: serpent.StringArrayOf(&givenRoles)},
3040
},
@@ -37,42 +47,22 @@ func (r *RootCmd) userEditRoles() *serpent.Command {
3747
return xerrors.Errorf("fetch user: %w", err)
3848
}
3949

40-
roles, err := client.ListSiteRoles(ctx)
41-
if err != nil {
42-
return xerrors.Errorf("fetch site roles: %w", err)
43-
}
44-
45-
siteRoles := make([]string, 0)
46-
for _, role := range roles {
47-
if role.Assignable {
48-
siteRoles = append(siteRoles, role.Name)
49-
}
50-
}
51-
sort.Strings(siteRoles)
52-
5350
userRoles, err := client.UserRoles(ctx, user.Username)
5451
if err != nil {
5552
return xerrors.Errorf("fetch user roles: %w", err)
5653
}
5754

5855
var selectedRoles []string
5956
if len(givenRoles) > 0 {
60-
// If the none role is present ignore all other roles.
61-
// This is so there is a way to clear roles from the CLI without making a
62-
// new command.
63-
if slices.Contains(givenRoles, "none") {
64-
selectedRoles = []string{}
65-
} else {
66-
// Make sure all of the given roles are valid site roles
67-
for _, givenRole := range givenRoles {
68-
if !slices.Contains(siteRoles, givenRole) {
69-
siteRolesPretty := strings.Join(siteRoles, ", ")
70-
return xerrors.Errorf("The role %s is not valid. Please use one or more of the following roles: %s, or none\n", givenRole, siteRolesPretty)
71-
}
57+
// Make sure all of the given roles are valid site roles
58+
for _, givenRole := range givenRoles {
59+
if !slices.Contains(siteRoles, givenRole) {
60+
siteRolesPretty := strings.Join(siteRoles, ", ")
61+
return xerrors.Errorf("The role %s is not valid. Please use one or more of the following roles: %s\n", givenRole, siteRolesPretty)
7262
}
73-
74-
selectedRoles = givenRoles
7563
}
64+
65+
selectedRoles = givenRoles
7666
} else {
7767
selectedRoles, err = cliui.MultiSelect(inv, cliui.MultiSelectOptions{
7868
Message: "Select the roles you'd like to assign to the user",

cli/usereditroles_test.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cli_test
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/coder/coder/v2/cli/clitest"
11+
"github.com/coder/coder/v2/coderd/coderdtest"
12+
"github.com/coder/coder/v2/coderd/rbac"
13+
"github.com/coder/coder/v2/testutil"
14+
)
15+
16+
var roles = []string{"auditor", "user-admin"}
17+
18+
func TestUserEditRoles(t *testing.T) {
19+
t.Parallel()
20+
21+
t.Run("UpdateUserRoles", func(t *testing.T) {
22+
t.Parallel()
23+
24+
client := coderdtest.New(t, nil)
25+
owner := coderdtest.CreateFirstUser(t, client)
26+
_, member := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleMember())
27+
28+
inv, root := clitest.New(t, "users", "edit-roles", member.Username, fmt.Sprintf("--roles=%s", strings.Join(roles, ",")))
29+
clitest.SetupConfig(t, client, root)
30+
31+
// Create context with timeout
32+
ctx := testutil.Context(t, testutil.WaitShort)
33+
34+
err := inv.WithContext(ctx).Run()
35+
require.NoError(t, err)
36+
37+
memberRoles, err := client.UserRoles(ctx, member.Username)
38+
require.NoError(t, err)
39+
40+
require.ElementsMatch(t, memberRoles.Roles, roles)
41+
})
42+
43+
t.Run("UserNotFound", func(t *testing.T) {
44+
t.Parallel()
45+
46+
client := coderdtest.New(t, nil)
47+
owner := coderdtest.CreateFirstUser(t, client)
48+
userAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleUserAdmin())
49+
50+
// Setup command with non-existent user
51+
inv, root := clitest.New(t, "users", "edit-roles", "nonexistentuser")
52+
clitest.SetupConfig(t, userAdmin, root)
53+
54+
// Create context with timeout
55+
ctx := testutil.Context(t, testutil.WaitShort)
56+
57+
err := inv.WithContext(ctx).Run()
58+
require.Error(t, err)
59+
require.Contains(t, err.Error(), "fetch user")
60+
})
61+
}

0 commit comments

Comments
 (0)