Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: servicedata #71

Merged
merged 25 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4c3e2ad
feat: user service data to serve metadata
ishanarya0 Jun 11, 2024
12cde75
fix: should not return error if user email is missing
ishanarya0 Jun 11, 2024
0b50f68
Merge branch 'main' into servicedata-for-metadata
ishanarya0 Jun 11, 2024
01b2c34
chore: remove unwanted imports
ishanarya0 Jun 11, 2024
8c67023
feat: get group metadata from servicedata
ishanarya0 Jun 11, 2024
9c0db8b
feat: update APIs to use servicedata (#74)
ishanarya0 Jun 18, 2024
354e510
Merge branch 'main' into servicedata-for-metadata
ishanarya0 Jun 18, 2024
3e8af74
fix: field name
ishanarya0 Jun 18, 2024
455e4c7
lint: format
ishanarya0 Jun 18, 2024
6e0bdb8
fix: check permission on keys before create/update
ishanarya0 Jun 19, 2024
b9bc243
lint: formatting
ishanarya0 Jun 19, 2024
3215c13
fix: check permission on keys before create/update
ishanarya0 Jun 19, 2024
ce3fca3
refactor: change field name
ishanarya0 Jun 21, 2024
c09e507
fix: add consistency to lookup resource
ishanarya0 Jun 24, 2024
78426bf
feat: make servicedata key public (#86)
ishanarya0 Jul 10, 2024
03c372b
Merge branch 'main' into servicedata-for-metadata
ishanarya0 Jul 10, 2024
ed2baea
test: fix
ishanarya0 Jul 10, 2024
4d9f17e
test: fix
ishanarya0 Jul 10, 2024
1c30d4b
test: fix
ishanarya0 Jul 10, 2024
8d51441
test: fix wrong response
ishanarya0 Jul 10, 2024
7f4f8b2
fix: self API
ishanarya0 Jul 11, 2024
6cddb8d
test
ishanarya0 Jul 18, 2024
7316920
test
ishanarya0 Jul 18, 2024
45b9046
test: update create group test
ishanarya0 Jul 18, 2024
9b70dd8
test: update update group test
ishanarya0 Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions internal/api/v1beta1/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"github.com/goto/shield/pkg/metadata"
"github.com/goto/shield/pkg/str"
"github.com/goto/shield/pkg/uuid"
"golang.org/x/exp/maps"

grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"

"github.com/goto/shield/core/group"
"github.com/goto/shield/core/organization"
"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"

shieldv1beta1 "github.com/goto/shield/proto/v1beta1"
Expand Down Expand Up @@ -131,6 +133,31 @@ func (h Handler) GetGroup(ctx context.Context, request *shieldv1beta1.GetGroupRe
}
}

filter := servicedata.Filter{
ID: fetchedGroup.ID,
Namespace: groupNamespaceID,
Entities: maps.Values(map[string]string{
"group": groupNamespaceID,
}),
}

groupSD, err := h.serviceDataService.Get(ctx, filter)
if err != nil {
logger.Error(err.Error())
switch {
case errors.Is(err, user.ErrInvalidEmail), errors.Is(err, user.ErrMissingEmail):
break
default:
return nil, grpcInternalServerError
}
} else {
metadata := map[string]any{}
for _, sd := range groupSD {
metadata[sd.Key.Key] = sd.Value
}
fetchedGroup.Metadata = metadata
}

groupPB, err := transformGroupToPB(fetchedGroup)
if err != nil {
logger.Error(err.Error())
Expand Down
31 changes: 24 additions & 7 deletions internal/api/v1beta1/group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import (

"github.com/goto/shield/core/group"
"github.com/goto/shield/core/organization"
"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/api/v1beta1/mocks"
"github.com/goto/shield/internal/schema"
"github.com/goto/shield/pkg/errors"
"github.com/goto/shield/pkg/metadata"
"github.com/goto/shield/pkg/uuid"
shieldv1beta1 "github.com/goto/shield/proto/v1beta1"
"golang.org/x/exp/maps"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -417,14 +419,14 @@ func TestHandler_GetGroup(t *testing.T) {
someGroupID := uuid.NewString()
tests := []struct {
name string
setup func(gs *mocks.GroupService)
setup func(gs *mocks.GroupService, sds *mocks.ServiceDataService)
request *shieldv1beta1.GetGroupRequest
want *shieldv1beta1.GetGroupResponse
wantErr error
}{
{
name: "should return internal error if group service return some error",
setup: func(gs *mocks.GroupService) {
setup: func(gs *mocks.GroupService, sds *mocks.ServiceDataService) {
gs.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), someGroupID).Return(group.Group{}, errors.New("some error"))
},
request: &shieldv1beta1.GetGroupRequest{Id: someGroupID},
Expand All @@ -433,7 +435,7 @@ func TestHandler_GetGroup(t *testing.T) {
},
{
name: "should return not found error if id is invalid",
setup: func(gs *mocks.GroupService) {
setup: func(gs *mocks.GroupService, sds *mocks.ServiceDataService) {
gs.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), "").Return(group.Group{}, group.ErrInvalidID)
},
request: &shieldv1beta1.GetGroupRequest{},
Expand All @@ -442,7 +444,7 @@ func TestHandler_GetGroup(t *testing.T) {
},
{
name: "should return not found error if group not exist",
setup: func(gs *mocks.GroupService) {
setup: func(gs *mocks.GroupService, sds *mocks.ServiceDataService) {
gs.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), "").Return(group.Group{}, group.ErrNotExist)
},
request: &shieldv1beta1.GetGroupRequest{},
Expand All @@ -451,8 +453,21 @@ func TestHandler_GetGroup(t *testing.T) {
},
{
name: "should return success if group service return nil",
setup: func(gs *mocks.GroupService) {
setup: func(gs *mocks.GroupService, sds *mocks.ServiceDataService) {
gs.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), testGroupID).Return(testGroupMap[testGroupID], nil)

sds.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), servicedata.Filter{
ID: testGroupID,
Namespace: groupNamespaceID,
Entities: maps.Values(map[string]string{
"group": groupNamespaceID,
}),
}).Return([]servicedata.ServiceData{{
Key: servicedata.Key{
Key: "foo",
},
Value: "bar",
}}, nil)
},
request: &shieldv1beta1.GetGroupRequest{Id: testGroupID},
want: &shieldv1beta1.GetGroupResponse{
Expand All @@ -476,11 +491,13 @@ func TestHandler_GetGroup(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockGroupSvc := new(mocks.GroupService)
mockServiceDataSvc := new(mocks.ServiceDataService)
if tt.setup != nil {
tt.setup(mockGroupSvc)
tt.setup(mockGroupSvc, mockServiceDataSvc)
}
h := Handler{
groupService: mockGroupSvc,
groupService: mockGroupSvc,
serviceDataService: mockServiceDataSvc,
}
got, err := h.GetGroup(context.TODO(), tt.request)
assert.EqualValues(t, got, tt.want)
Expand Down
27 changes: 27 additions & 0 deletions internal/api/v1beta1/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (
"strings"

grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"golang.org/x/exp/maps"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"
"github.com/goto/shield/pkg/metadata"

Expand Down Expand Up @@ -178,6 +180,31 @@ func (h Handler) GetUser(ctx context.Context, request *shieldv1beta1.GetUserRequ
}
}

filter := servicedata.Filter{
ID: fetchedUser.ID,
Namespace: userNamespaceID,
Entities: maps.Values(map[string]string{
"user": userNamespaceID,
}),
}

userSD, err := h.serviceDataService.Get(ctx, filter)
if err != nil {
logger.Error(err.Error())
switch {
case errors.Is(err, user.ErrInvalidEmail), errors.Is(err, user.ErrMissingEmail):
break
default:
return nil, grpcInternalServerError
}
} else {
metadata := map[string]any{}
for _, sd := range userSD {
metadata[sd.Key.Key] = sd.Value
}
fetchedUser.Metadata = metadata
}

userPB, err := transformUserToPB(fetchedUser)
if err != nil {
logger.Error(err.Error())
Expand Down
55 changes: 33 additions & 22 deletions internal/api/v1beta1/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import (
"time"

"github.com/goto/shield/core/group"
"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/api/v1beta1/mocks"
"github.com/goto/shield/pkg/metadata"
"github.com/goto/shield/pkg/uuid"
"golang.org/x/exp/maps"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -311,13 +313,13 @@ func TestGetUser(t *testing.T) {
table := []struct {
title string
req *shieldv1beta1.GetUserRequest
setup func(us *mocks.UserService)
setup func(us *mocks.UserService, sd *mocks.ServiceDataService)
want *shieldv1beta1.GetUserResponse
err error
}{
{
title: "should return not found error if user does not exist",
setup: func(us *mocks.UserService) {
setup: func(us *mocks.UserService, sd *mocks.ServiceDataService) {
us.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), randomID).Return(user.User{}, user.ErrNotExist)
},
req: &shieldv1beta1.GetUserRequest{
Expand All @@ -328,7 +330,7 @@ func TestGetUser(t *testing.T) {
},
{
title: "should return not found error if user id is not uuid",
setup: func(us *mocks.UserService) {
setup: func(us *mocks.UserService, sd *mocks.ServiceDataService) {
us.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), "some-id").Return(user.User{}, user.ErrInvalidUUID)
},
req: &shieldv1beta1.GetUserRequest{
Expand All @@ -339,7 +341,7 @@ func TestGetUser(t *testing.T) {
},
{
title: "should return not found error if user id is invalid",
setup: func(us *mocks.UserService) {
setup: func(us *mocks.UserService, sd *mocks.ServiceDataService) {
us.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), "").Return(user.User{}, user.ErrInvalidID)
},
req: &shieldv1beta1.GetUserRequest{},
Expand All @@ -348,18 +350,30 @@ func TestGetUser(t *testing.T) {
},
{
title: "should return user if user service return nil error",
setup: func(us *mocks.UserService) {
setup: func(us *mocks.UserService, sd *mocks.ServiceDataService) {
us.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), randomID).Return(
user.User{
ID: randomID,
Name: "some user",
Email: "[email protected]",
Metadata: metadata.Metadata{
"foo": "bar",
},
ID: randomID,
Name: "some user",
Email: "[email protected]",
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
}, nil)

sd.EXPECT().Get(mock.AnythingOfType("context.todoCtx"), servicedata.Filter{
ID: randomID,
Namespace: userNamespaceID,
Entities: maps.Values(map[string]string{
"user": userNamespaceID,
}),
}).Return([]servicedata.ServiceData{
{
Key: servicedata.Key{
Key: "foo",
},
Value: "bar",
},
}, nil)
},
req: &shieldv1beta1.GetUserRequest{
Id: randomID,
Expand All @@ -383,10 +397,12 @@ func TestGetUser(t *testing.T) {
for _, tt := range table {
t.Run(tt.title, func(t *testing.T) {
mockUserSrv := new(mocks.UserService)
mockServiceDataSrv := new(mocks.ServiceDataService)

if tt.setup != nil {
tt.setup(mockUserSrv)
tt.setup(mockUserSrv, mockServiceDataSrv)
}
mockDep := Handler{userService: mockUserSrv}
mockDep := Handler{userService: mockUserSrv, serviceDataService: mockServiceDataSrv}
resp, err := mockDep.GetUser(context.TODO(), tt.req)
assert.EqualValues(t, resp, tt.want)
assert.EqualValues(t, err, tt.err)
Expand Down Expand Up @@ -431,12 +447,9 @@ func TestGetCurrentUser(t *testing.T) {
setup: func(ctx context.Context, us *mocks.UserService) context.Context {
us.EXPECT().GetByEmail(mock.AnythingOfType("*context.valueCtx"), email).Return(
user.User{
ID: "user-id-1",
Name: "some user",
Email: "[email protected]",
Metadata: metadata.Metadata{
"foo": "bar",
},
ID: "user-id-1",
Name: "some user",
Email: "[email protected]",
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
}, nil)
Expand All @@ -447,9 +460,7 @@ func TestGetCurrentUser(t *testing.T) {
Name: "some user",
Email: "[email protected]",
Metadata: &structpb.Struct{
Fields: map[string]*structpb.Value{
"foo": structpb.NewStringValue("bar"),
},
Fields: map[string]*structpb.Value{},
},
CreatedAt: timestamppb.New(time.Time{}),
UpdatedAt: timestamppb.New(time.Time{}),
Expand Down
Loading
Loading