Skip to content

Commit 75e7213

Browse files
authored
feat: add cli command to remove organization member (#13619)
1 parent cbdaa63 commit 75e7213

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

cli/organizationmembers.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
2020
r.listOrganizationMembers(),
2121
r.assignOrganizationRoles(),
2222
r.addOrganizationMember(),
23+
r.removeOrganizationMember(),
2324
},
2425
Handler: func(inv *serpent.Invocation) error {
2526
return inv.Command.HelpHandler(inv)
@@ -29,6 +30,37 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
2930
return cmd
3031
}
3132

33+
func (r *RootCmd) removeOrganizationMember() *serpent.Command {
34+
client := new(codersdk.Client)
35+
36+
cmd := &serpent.Command{
37+
Use: "remove <username | user_id>",
38+
Short: "Remove a new member to the current organization",
39+
Middleware: serpent.Chain(
40+
r.InitClient(client),
41+
serpent.RequireNArgs(1),
42+
),
43+
Handler: func(inv *serpent.Invocation) error {
44+
ctx := inv.Context()
45+
organization, err := CurrentOrganization(r, inv, client)
46+
if err != nil {
47+
return err
48+
}
49+
user := inv.Args[0]
50+
51+
err = client.DeleteOrganizationMember(ctx, organization.ID, user)
52+
if err != nil {
53+
return xerrors.Errorf("could not remove member from organization %q: %w", organization.HumanName(), err)
54+
}
55+
56+
_, _ = fmt.Fprintf(inv.Stdout, "Organization member removed from %q\n", organization.HumanName())
57+
return nil
58+
},
59+
}
60+
61+
return cmd
62+
}
63+
3264
func (r *RootCmd) addOrganizationMember() *serpent.Command {
3365
client := new(codersdk.Client)
3466

@@ -49,10 +81,10 @@ func (r *RootCmd) addOrganizationMember() *serpent.Command {
4981

5082
_, err = client.PostOrganizationMember(ctx, organization.ID, user)
5183
if err != nil {
52-
return xerrors.Errorf("could not add member to organization: %w", err)
84+
return xerrors.Errorf("could not add member to organization %q: %w", organization.HumanName(), err)
5385
}
5486

55-
_, _ = fmt.Fprintln(inv.Stdout, "Organization member added")
87+
_, _ = fmt.Fprintf(inv.Stdout, "Organization member added to %q\n", organization.HumanName())
5688
return nil
5789
},
5890
}

cli/organizationmembers_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,49 @@ func TestAddOrganizationMembers(t *testing.T) {
7272
require.Len(t, members, 2)
7373
})
7474
}
75+
76+
func TestRemoveOrganizationMembers(t *testing.T) {
77+
t.Parallel()
78+
79+
t.Run("OK", func(t *testing.T) {
80+
t.Parallel()
81+
82+
ownerClient := coderdtest.New(t, &coderdtest.Options{})
83+
owner := coderdtest.CreateFirstUser(t, ownerClient)
84+
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
85+
_, user := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
86+
87+
ctx := testutil.Context(t, testutil.WaitMedium)
88+
89+
inv, root := clitest.New(t, "organization", "members", "remove", "--organization", owner.OrganizationID.String(), user.Username)
90+
clitest.SetupConfig(t, orgAdminClient, root)
91+
92+
buf := new(bytes.Buffer)
93+
inv.Stdout = buf
94+
err := inv.WithContext(ctx).Run()
95+
require.NoError(t, err)
96+
97+
members, err := orgAdminClient.OrganizationMembers(ctx, owner.OrganizationID)
98+
require.NoError(t, err)
99+
100+
require.Len(t, members, 2)
101+
})
102+
103+
t.Run("UserNotExists", func(t *testing.T) {
104+
t.Parallel()
105+
106+
ownerClient := coderdtest.New(t, &coderdtest.Options{})
107+
owner := coderdtest.CreateFirstUser(t, ownerClient)
108+
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
109+
110+
ctx := testutil.Context(t, testutil.WaitMedium)
111+
112+
inv, root := clitest.New(t, "organization", "members", "remove", "--organization", owner.OrganizationID.String(), "random_name")
113+
clitest.SetupConfig(t, orgAdminClient, root)
114+
115+
buf := new(bytes.Buffer)
116+
inv.Stdout = buf
117+
err := inv.WithContext(ctx).Run()
118+
require.ErrorContains(t, err, "must be an existing uuid or username")
119+
})
120+
}

codersdk/organizations.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ type Organization struct {
5050
Icon string `table:"icon" json:"icon"`
5151
}
5252

53+
func (o Organization) HumanName() string {
54+
if o.DisplayName == "" {
55+
return o.Name
56+
}
57+
return o.DisplayName
58+
}
59+
5360
type OrganizationMember struct {
5461
UserID uuid.UUID `table:"user id" json:"user_id" format:"uuid"`
5562
OrganizationID uuid.UUID `table:"organization id" json:"organization_id" format:"uuid"`

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy