feat: add cli command to remove organization member (#13619)

This commit is contained in:
Steven Masley
2024-06-21 05:35:59 -10:00
committed by GitHub
parent cbdaa63b68
commit 75e7213ac2
3 changed files with 87 additions and 2 deletions

View File

@ -20,6 +20,7 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
r.listOrganizationMembers(), r.listOrganizationMembers(),
r.assignOrganizationRoles(), r.assignOrganizationRoles(),
r.addOrganizationMember(), r.addOrganizationMember(),
r.removeOrganizationMember(),
}, },
Handler: func(inv *serpent.Invocation) error { Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv) return inv.Command.HelpHandler(inv)
@ -29,6 +30,37 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
return cmd return cmd
} }
func (r *RootCmd) removeOrganizationMember() *serpent.Command {
client := new(codersdk.Client)
cmd := &serpent.Command{
Use: "remove <username | user_id>",
Short: "Remove a new member to the current organization",
Middleware: serpent.Chain(
r.InitClient(client),
serpent.RequireNArgs(1),
),
Handler: func(inv *serpent.Invocation) error {
ctx := inv.Context()
organization, err := CurrentOrganization(r, inv, client)
if err != nil {
return err
}
user := inv.Args[0]
err = client.DeleteOrganizationMember(ctx, organization.ID, user)
if err != nil {
return xerrors.Errorf("could not remove member from organization %q: %w", organization.HumanName(), err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Organization member removed from %q\n", organization.HumanName())
return nil
},
}
return cmd
}
func (r *RootCmd) addOrganizationMember() *serpent.Command { func (r *RootCmd) addOrganizationMember() *serpent.Command {
client := new(codersdk.Client) client := new(codersdk.Client)
@ -49,10 +81,10 @@ func (r *RootCmd) addOrganizationMember() *serpent.Command {
_, err = client.PostOrganizationMember(ctx, organization.ID, user) _, err = client.PostOrganizationMember(ctx, organization.ID, user)
if err != nil { if err != nil {
return xerrors.Errorf("could not add member to organization: %w", err) return xerrors.Errorf("could not add member to organization %q: %w", organization.HumanName(), err)
} }
_, _ = fmt.Fprintln(inv.Stdout, "Organization member added") _, _ = fmt.Fprintf(inv.Stdout, "Organization member added to %q\n", organization.HumanName())
return nil return nil
}, },
} }

View File

@ -72,3 +72,49 @@ func TestAddOrganizationMembers(t *testing.T) {
require.Len(t, members, 2) require.Len(t, members, 2)
}) })
} }
func TestRemoveOrganizationMembers(t *testing.T) {
t.Parallel()
t.Run("OK", func(t *testing.T) {
t.Parallel()
ownerClient := coderdtest.New(t, &coderdtest.Options{})
owner := coderdtest.CreateFirstUser(t, ownerClient)
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
_, user := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
ctx := testutil.Context(t, testutil.WaitMedium)
inv, root := clitest.New(t, "organization", "members", "remove", "--organization", owner.OrganizationID.String(), user.Username)
clitest.SetupConfig(t, orgAdminClient, root)
buf := new(bytes.Buffer)
inv.Stdout = buf
err := inv.WithContext(ctx).Run()
require.NoError(t, err)
members, err := orgAdminClient.OrganizationMembers(ctx, owner.OrganizationID)
require.NoError(t, err)
require.Len(t, members, 2)
})
t.Run("UserNotExists", func(t *testing.T) {
t.Parallel()
ownerClient := coderdtest.New(t, &coderdtest.Options{})
owner := coderdtest.CreateFirstUser(t, ownerClient)
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
ctx := testutil.Context(t, testutil.WaitMedium)
inv, root := clitest.New(t, "organization", "members", "remove", "--organization", owner.OrganizationID.String(), "random_name")
clitest.SetupConfig(t, orgAdminClient, root)
buf := new(bytes.Buffer)
inv.Stdout = buf
err := inv.WithContext(ctx).Run()
require.ErrorContains(t, err, "must be an existing uuid or username")
})
}

View File

@ -50,6 +50,13 @@ type Organization struct {
Icon string `table:"icon" json:"icon"` Icon string `table:"icon" json:"icon"`
} }
func (o Organization) HumanName() string {
if o.DisplayName == "" {
return o.Name
}
return o.DisplayName
}
type OrganizationMember struct { type OrganizationMember struct {
UserID uuid.UUID `table:"user id" json:"user_id" format:"uuid"` UserID uuid.UUID `table:"user id" json:"user_id" format:"uuid"`
OrganizationID uuid.UUID `table:"organization id" json:"organization_id" format:"uuid"` OrganizationID uuid.UUID `table:"organization id" json:"organization_id" format:"uuid"`