mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat: add cli command to remove organization member (#13619)
This commit is contained in:
@ -20,6 +20,7 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
|
||||
r.listOrganizationMembers(),
|
||||
r.assignOrganizationRoles(),
|
||||
r.addOrganizationMember(),
|
||||
r.removeOrganizationMember(),
|
||||
},
|
||||
Handler: func(inv *serpent.Invocation) error {
|
||||
return inv.Command.HelpHandler(inv)
|
||||
@ -29,6 +30,37 @@ func (r *RootCmd) organizationMembers() *serpent.Command {
|
||||
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 {
|
||||
client := new(codersdk.Client)
|
||||
|
||||
@ -49,10 +81,10 @@ func (r *RootCmd) addOrganizationMember() *serpent.Command {
|
||||
|
||||
_, err = client.PostOrganizationMember(ctx, organization.ID, user)
|
||||
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
|
||||
},
|
||||
}
|
||||
|
@ -72,3 +72,49 @@ func TestAddOrganizationMembers(t *testing.T) {
|
||||
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")
|
||||
})
|
||||
}
|
||||
|
@ -50,6 +50,13 @@ type Organization struct {
|
||||
Icon string `table:"icon" json:"icon"`
|
||||
}
|
||||
|
||||
func (o Organization) HumanName() string {
|
||||
if o.DisplayName == "" {
|
||||
return o.Name
|
||||
}
|
||||
return o.DisplayName
|
||||
}
|
||||
|
||||
type OrganizationMember struct {
|
||||
UserID uuid.UUID `table:"user id" json:"user_id" format:"uuid"`
|
||||
OrganizationID uuid.UUID `table:"organization id" json:"organization_id" format:"uuid"`
|
||||
|
Reference in New Issue
Block a user