Skip to content

Commit

Permalink
Remove a member from a group
Browse files Browse the repository at this point in the history
This commit incorporates the changes from this PR and improves the test
coverage.

#21

[#159094401]
  • Loading branch information
Jeremy Morony committed Jul 2, 2019
1 parent 25db2c6 commit 3cdfe1d
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
64 changes: 64 additions & 0 deletions cmd/remove_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cmd

import (
"errors"

"code.cloudfoundry.org/uaa-cli/cli"
cli_config "code.cloudfoundry.org/uaa-cli/config"
"code.cloudfoundry.org/uaa-cli/utils"
"github.com/cloudfoundry-community/go-uaa"
"github.com/spf13/cobra"
)

func RemoveMemberPreRunValidations(config cli_config.Config, args []string) error {
if err := EnsureContextInConfig(config); err != nil {
return err
}

if len(args) != 2 {
return errors.New("The positional arguments GROUPNAME and USERNAME must be specified.")
}

return nil
}

func RemoveMemberCmd(api *uaa.API, groupName, username string, log cli.Logger) error {
group, err := api.GetGroupByName(groupName, "")
if err != nil {
return err
}

user, err := api.GetUserByUsername(username, "", "")
if err != nil {
return err
}

err = api.RemoveGroupMember(group.ID, user.ID, "", "")
if err != nil {
return err
}

log.Infof("User %v successfully removed from group %v", utils.Emphasize(username), utils.Emphasize(groupName))

return nil
}

var removeMemberCmd = &cobra.Command{
Use: "remove-member GROUPNAME USERNAME",
Short: "Remove a user from a group",
PreRun: func(cmd *cobra.Command, args []string) {
cfg := GetSavedConfig()
NotifyValidationErrors(RemoveMemberPreRunValidations(cfg, args), cmd, log)
},
Run: func(cmd *cobra.Command, args []string) {
groupName := args[0]
userName := args[1]
NotifyErrorsWithRetry(RemoveMemberCmd(GetAPIFromSavedTokenInContext(), groupName, userName, log), log)
},
}

func init() {
RootCmd.AddCommand(removeMemberCmd)
removeMemberCmd.Annotations = make(map[string]string)
removeMemberCmd.Annotations[GROUP_CRUD_CATEGORY] = "true"
}
119 changes: 119 additions & 0 deletions cmd/remove_member_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package cmd_test

import (
. "code.cloudfoundry.org/uaa-cli/cmd"
"code.cloudfoundry.org/uaa-cli/fixtures"
"net/http"

"code.cloudfoundry.org/uaa-cli/config"
"github.com/cloudfoundry-community/go-uaa"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"
. "github.com/onsi/gomega/gexec"
. "github.com/onsi/gomega/ghttp"
)

var _ = Describe("RemoveMember", func() {
Describe("when a target is set", func() {
BeforeEach(func() {
c := config.NewConfigWithServerURL(server.URL())
c.AddContext(config.NewContextWithToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"))
config.WriteConfig(c)
})

Describe("when the user belongs to the group", func() {
It("removes a membership in a group", func() {
membershipJson := `{"origin":"uaa","type":"USER","value":"fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70"}`

server.RouteToHandler("DELETE", "/Groups/05a0c169-3592-4a45-b109-a16d9246e0ab/members/fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70", CombineHandlers(
VerifyRequest("DELETE", "/Groups/05a0c169-3592-4a45-b109-a16d9246e0ab/members/fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70"),
VerifyHeaderKV("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"),
VerifyHeaderKV("Accept", "application/json"),
RespondWith(http.StatusOK, membershipJson, contentTypeJson),
))

server.RouteToHandler("GET", "/Groups", CombineHandlers(
VerifyRequest("GET", "/Groups", "filter=displayName+eq+%22uaa.admin%22&count=100&startIndex=1"),
RespondWith(http.StatusOK, fixtures.PaginatedResponse(uaa.Group{ID: "05a0c169-3592-4a45-b109-a16d9246e0ab", DisplayName: "uaa.admin"})),
))

server.RouteToHandler("GET", "/Users", CombineHandlers(
VerifyRequest("GET", "/Users", "filter=userName+eq+%[email protected]%22&count=100&startIndex=1"),
RespondWith(http.StatusOK, fixtures.PaginatedResponse(uaa.User{ID: "fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70", Username: "[email protected]"})),
))

session := runCommand("remove-member", "uaa.admin", "[email protected]")

Eventually(session).Should(Exit(0))
Expect(session).To(Say("User [email protected] successfully removed from group uaa.admin"))
})
})

Describe("when the user belongs to the group", func() {
It("removes a membership in a group", func() {
errorJson := `{"error_description":"Member 88553b0f-af97-489a-a884-d05f54e3b9ce does not exist in group 9c7c01bc-d234-4b43-b93d-35bb3ec5b906","error":"member_not_found","message":"Member 88553b0f-af97-489a-a884-d05f54e3b9ce does not exist in group 9c7c01bc-d234-4b43-b93d-35bb3ec5b906"}`

server.RouteToHandler("DELETE", "/Groups/05a0c169-3592-4a45-b109-a16d9246e0ab/members/fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70", CombineHandlers(
VerifyRequest("DELETE", "/Groups/05a0c169-3592-4a45-b109-a16d9246e0ab/members/fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70"),
VerifyHeaderKV("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"),
VerifyHeaderKV("Accept", "application/json"),
RespondWith(http.StatusNotFound, errorJson, contentTypeJson),
))

server.RouteToHandler("GET", "/Groups", CombineHandlers(
VerifyRequest("GET", "/Groups", "filter=displayName+eq+%22uaa.admin%22&count=100&startIndex=1"),
RespondWith(http.StatusOK, fixtures.PaginatedResponse(uaa.Group{ID: "05a0c169-3592-4a45-b109-a16d9246e0ab", DisplayName: "uaa.admin"})),
))

server.RouteToHandler("GET", "/Users", CombineHandlers(
VerifyRequest("GET", "/Users", "filter=userName+eq+%[email protected]%22&count=100&startIndex=1"),
RespondWith(http.StatusOK, fixtures.PaginatedResponse(uaa.User{ID: "fb5f32e1-5cb3-49e6-93df-6df9c8c8bd70", Username: "[email protected]"})),
))

session := runCommand("remove-member", "uaa.admin", "[email protected]")

Eventually(session).Should(Exit(1))
Expect(session).To(Say("Retry with --verbose for more information."))
})
})
})

Describe("when no target was previously set", func() {
BeforeEach(func() {
c := config.Config{}
config.WriteConfig(c)
})

It("tells the user to set a target", func() {
session := runCommand("remove-member", "uaa.admin", "woodstock")

Eventually(session).Should(Exit(1))
Expect(session.Err).To(Say(MISSING_TARGET))
})
})

Describe("when no token in context", func() {
BeforeEach(func() {
c := config.NewConfigWithServerURL(server.URL())
config.WriteConfig(c)
})

It("tells the user to get a token", func() {
session := runCommand("remove-member", "uaa.admin", "woodstock")

Eventually(session).Should(Exit(1))
Expect(session.Err).To(Say(MISSING_CONTEXT))
})
})

Describe("validations", func() {
It("only accepts groupname and username", func() {
session := runCommand("remove-member", "first-arg", "second-arg", "third-arg")
Eventually(session).Should(Exit(1))

session = runCommand("remove-member", "woodstock")
Eventually(session).Should(Exit(1))
})
})
})

0 comments on commit 3cdfe1d

Please sign in to comment.