Add ListUsers handler implementation. (#160)

pull/164/head
Todd Knight 6 years ago committed by GitHub
parent d0a846823a
commit c017da7087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -44,9 +44,16 @@ func NewService(repo func() (*iam.Repository, error)) (Service, error) {
var _ pbs.UserServiceServer = Service{}
// CreateUser is not yet implemented but will implement the interface pbs.UserServiceServer.
func (s Service) ListUsers(context.Context, *pbs.ListUsersRequest) (*pbs.ListUsersResponse, error) {
return nil, status.Error(codes.Unimplemented, "List not enabled for this resource.")
// ListUsers implements the interface pbs.UserServiceServer.
func (s Service) ListUsers(ctx context.Context, req *pbs.ListUsersRequest) (*pbs.ListUsersResponse, error) {
if err := validateListRequest(req); err != nil {
return nil, err
}
ul, err := s.listFromRepo(ctx, req.GetOrgId())
if err != nil {
return nil, err
}
return &pbs.ListUsersResponse{Items: ul}, nil
}
// GetUsers implements the interface pbs.UserServiceServer.
@ -190,6 +197,22 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
return rows > 0, nil
}
func (s Service) listFromRepo(ctx context.Context, orgId string) ([]*pb.User, error) {
repo, err := s.repoFn()
if err != nil {
return nil, err
}
ul, err := repo.ListUsers(ctx, orgId)
if err != nil {
return nil, err
}
var outUl []*pb.User
for _, u := range ul {
outUl = append(outUl, toProto(u))
}
return outUl, nil
}
// toDbUpdateMask converts the wire format's FieldMask into a list of strings containing FieldMask paths used
func toDbUpdateMask(paths []string) ([]string, error) {
var dbPaths []string
@ -300,6 +323,14 @@ func validateDeleteRequest(req *pbs.DeleteUserRequest) error {
return nil
}
func validateListRequest(req *pbs.ListUsersRequest) error {
badFields := validateAncestors(req)
if len(badFields) > 0 {
return handlers.InvalidArgumentErrorf("Improperly formatted identifier.", badFields)
}
return nil
}
func validId(id, prefix string) bool {
if !strings.HasPrefix(id, prefix) {
return false

@ -12,6 +12,7 @@ import (
pbs "github.com/hashicorp/watchtower/internal/gen/controller/api/services"
"github.com/hashicorp/watchtower/internal/iam"
"github.com/hashicorp/watchtower/internal/servers/controller/handlers/users"
"github.com/hashicorp/watchtower/internal/types/scope"
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -107,6 +108,85 @@ func TestGet(t *testing.T) {
}
}
func TestList(t *testing.T) {
assert, require := assert.New(t), require.New(t)
cleanup, conn, _ := db.TestSetup(t, "postgres")
t.Cleanup(func() {
if err := conn.Close(); err != nil {
t.Errorf("Error when closing gorm DB: %v", err)
}
if err := cleanup(); err != nil {
t.Errorf("Error when cleaning up TestSetup: %v", err)
}
})
rw := db.New(conn)
wrap := db.TestWrapper(t)
repoFn := func() (*iam.Repository, error) {
return iam.NewRepository(rw, rw, wrap)
}
repo, err := repoFn()
require.NoError(err)
oNoUsers, _ := iam.TestScopes(t, conn)
oWithUsers, _ := iam.TestScopes(t, conn)
var wantUsers []*pb.User
for i := 0; i < 10; i++ {
newU, err := iam.NewUser(oWithUsers.GetPublicId())
require.NoError(err)
u, err := repo.CreateUser(context.Background(), newU)
require.NoError(err)
wantUsers = append(wantUsers, &pb.User{
Id: u.GetPublicId(),
CreatedTime: u.GetCreateTime().GetTimestamp(),
UpdatedTime: u.GetUpdateTime().GetTimestamp(),
})
}
cases := []struct {
name string
req *pbs.ListUsersRequest
res *pbs.ListUsersResponse
errCode codes.Code
}{
{
name: "List Many Users",
req: &pbs.ListUsersRequest{OrgId: oWithUsers.GetPublicId()},
res: &pbs.ListUsersResponse{Items: wantUsers},
errCode: codes.OK,
},
{
name: "List No Users",
req: &pbs.ListUsersRequest{OrgId: oNoUsers.GetPublicId()},
res: &pbs.ListUsersResponse{},
errCode: codes.OK,
},
{
name: "Invalid Org Id",
req: &pbs.ListUsersRequest{OrgId: iam.UserPrefix + "_this is invalid"},
res: nil,
errCode: codes.InvalidArgument,
},
// TODO: When an org doesn't exist, we should return a 404 instead of an empty list.
{
name: "Unfound Org",
req: &pbs.ListUsersRequest{OrgId: scope.Organization.Prefix() + "_DoesntExis"},
res: &pbs.ListUsersResponse{},
errCode: codes.OK,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
s, err := users.NewService(repoFn)
require.NoError(err, "Couldn't create new user service.")
got, gErr := s.ListUsers(context.Background(), tc.req)
assert.Equal(tc.errCode, status.Code(gErr), "ListUsers(%+v) got error %v, wanted %v", tc.req, gErr, tc.errCode)
assert.True(proto.Equal(got, tc.res), "ListUsers(%q) got response %q, wanted %q", tc.req, got, tc.res)
})
}
}
func TestDelete(t *testing.T) {
require := require.New(t)
u, repo := createDefaultUserAndRepo(t)

Loading…
Cancel
Save