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

refactor: user servicedata service to serve metadata #82

Merged
merged 8 commits into from
Jun 18, 2024
Merged
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ GOVERSION := $(shell go version | cut -d ' ' -f 3 | cut -d '.' -f 2)

.PHONY: build check fmt lint test test-race vet test-cover-html help install proto
.DEFAULT_GOAL := build
PROTON_COMMIT := "e8a584e192f23f999844b027d17bd738c3981973"
PROTON_COMMIT := "6ee59f2d0cbeedf1d5fe48adee5e5e41f54f081e"

install:
@echo "Clean up imports..."
4 changes: 3 additions & 1 deletion core/group/filter.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package group

type Filter struct {
OrganizationID string
OrganizationID string
ProjectID string
ServicedataKeyResourceIDs []string
}
4 changes: 2 additions & 2 deletions core/servicedata/service.go
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ func NewService(repository Repository, resourceService ResourceService, relation

func (s Service) CreateKey(ctx context.Context, key Key) (Key, error) {
// check if key contains ':'
if key.Key == "" {
if key.Name == "" {
return Key{}, ErrInvalidDetail
}

@@ -138,7 +138,7 @@ func (s Service) CreateKey(ctx context.Context, key Key) (Key, error) {
}

func (s Service) Upsert(ctx context.Context, sd ServiceData) (ServiceData, error) {
if sd.Key.Key == "" {
if sd.Key.Name == "" {
return ServiceData{}, ErrInvalidDetail
}

14 changes: 7 additions & 7 deletions core/servicedata/service_test.go
Original file line number Diff line number Diff line change
@@ -26,21 +26,21 @@ var (
testProjectSlug = "test-project-slug"
testKey = servicedata.Key{
ProjectID: "test-project-slug",
Key: "test-key",
Name: "test-key",
Description: "test key no 01",
}
testCreateKey = servicedata.Key{
URN: "test-project-slug:servicedata_key:test-key",
ProjectID: testProjectID,
ProjectSlug: testProjectSlug,
Key: "test-key",
Name: "test-key",
Description: "test key no 01",
ResourceID: testResourceID,
}
testCreatedKey = servicedata.Key{
URN: "test-project-slug:servicedata_key:test-key",
ProjectID: testProjectID,
Key: "test-key",
Name: "test-key",
Description: "test key no 01",
ResourceID: testResourceID,
}
@@ -125,7 +125,7 @@ func TestService_CreateKey(t *testing.T) {
name: "CreateKeyEmpty",
key: servicedata.Key{
ProjectID: testKey.ProjectID,
Key: "",
Name: "",
Description: testKey.Description,
},
setup: func(t *testing.T) *servicedata.Service {
@@ -174,7 +174,7 @@ func TestService_CreateKey(t *testing.T) {
name: "CreateKeyInvalidProjectID",
key: servicedata.Key{
ProjectID: "invalid-test-project-slug",
Key: testKey.Key,
Name: testKey.Name,
Description: testKey.Description,
},
email: "jane.doe@gotocompany.com",
@@ -352,7 +352,7 @@ func TestService_Upsert(t *testing.T) {
name: "UpsertKeyEmpty",
data: servicedata.ServiceData{
Key: servicedata.Key{
Key: "",
Name: "",
},
},
setup: func(t *testing.T) *servicedata.Service {
@@ -386,7 +386,7 @@ func TestService_Upsert(t *testing.T) {
name: "UpsertInvalidProjectID",
data: servicedata.ServiceData{
Key: servicedata.Key{
Key: testKey.Key,
Name: testKey.Name,
ProjectID: "invalid-test-project-slug",
},
},
6 changes: 3 additions & 3 deletions core/servicedata/servicedata.go
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ type Key struct {
URN string
ProjectID string
ProjectSlug string
Key string
Name string
Description string
ResourceID string
}
@@ -34,7 +34,7 @@ type ServiceData struct {
NamespaceID string
EntityID string
Key Key
Value string
Value any
}

type Filter struct {
@@ -46,5 +46,5 @@ type Filter struct {
}

func (key Key) CreateURN() string {
return fmt.Sprintf("%s:servicedata_key:%s", key.ProjectSlug, key.Key)
return fmt.Sprintf("%s:servicedata_key:%s", key.ProjectSlug, key.Name)
}
8 changes: 5 additions & 3 deletions core/user/filter.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package user

type Filter struct {
Limit int32
Page int32
Keyword string
Limit int32
Page int32
Keyword string
ProjectID string
ServiceDataKeyResourceIds []string
}
103 changes: 83 additions & 20 deletions internal/api/v1beta1/group.go
Original file line number Diff line number Diff line change
@@ -39,14 +39,46 @@ type GroupService interface {
}

var grpcGroupNotFoundErr = status.Errorf(codes.NotFound, "group doesn't exist")
var grpcInvalidOrgIDErr = status.Errorf(codes.InvalidArgument, "ordIs is not valid uuid")

func (h Handler) ListGroups(ctx context.Context, request *shieldv1beta1.ListGroupsRequest) (*shieldv1beta1.ListGroupsResponse, error) {
logger := grpczap.Extract(ctx)

if request.GetOrgId() != "" {
if !uuid.IsValid(request.GetOrgId()) {
return nil, grpcInvalidOrgIDErr
}

_, err := h.orgService.Get(ctx, request.GetOrgId())
if err != nil {
return &shieldv1beta1.ListGroupsResponse{Groups: nil}, nil
}
}

var groups []*shieldv1beta1.Group

currentUser, err := h.userService.FetchCurrentUser(ctx)
if err != nil {
logger.Error(err.Error())
return nil, grpcInternalServerError
}

servicedataKeyResourceIds, err := h.relationService.LookupResources(ctx, schema.ServiceDataKeyNamespace, schema.ViewPermission, schema.UserPrincipal, currentUser.ID)
if err != nil {
logger.Error(err.Error())
return nil, grpcInternalServerError
}

prj, err := h.projectService.Get(ctx, h.serviceDataConfig.DefaultServiceDataProject)
if err != nil {
logger.Error(err.Error())
return nil, grpcInternalServerError
}

groupList, err := h.groupService.List(ctx, group.Filter{
OrganizationID: request.GetOrgId(),
OrganizationID: request.GetOrgId(),
ProjectID: prj.ID,
ServicedataKeyResourceIDs: servicedataKeyResourceIds,
})
if err != nil {
logger.Error(err.Error())
@@ -73,6 +105,13 @@ func (h Handler) CreateGroup(ctx context.Context, request *shieldv1beta1.CreateG
return nil, grpcBadBodyError
}

_, err := h.userService.FetchCurrentUser(ctx)
if err != nil {
logger.Error(err.Error())
return nil, grpcInternalServerError
}

//TODO: change this
metaDataMap, err := metadata.Build(request.GetBody().GetMetadata().AsMap())
if err != nil {
logger.Error(err.Error())
@@ -83,7 +122,7 @@ func (h Handler) CreateGroup(ctx context.Context, request *shieldv1beta1.CreateG
Name: request.GetBody().GetName(),
Slug: request.GetBody().GetSlug(),
OrganizationID: request.GetBody().GetOrgId(),
Metadata: metaDataMap,
Metadata: nil,
}

if strings.TrimSpace(grp.Slug) == "" {
@@ -106,21 +145,44 @@ func (h Handler) CreateGroup(ctx context.Context, request *shieldv1beta1.CreateG
}
}

metaData, err := newGroup.Metadata.ToStructPB()
serviceDataMap := map[string]any{}
for k, v := range metaDataMap {
serviceDataResp, err := h.serviceDataService.Upsert(ctx, servicedata.ServiceData{
EntityID: newGroup.ID,
NamespaceID: groupNamespaceID,
Key: servicedata.Key{
Name: k,
ProjectID: h.serviceDataConfig.DefaultServiceDataProject,
},
Value: v,
})
if err != nil {
logger.Error(err.Error())

switch {
case errors.Is(err, user.ErrInvalidEmail), errors.Is(err, user.ErrMissingEmail):
return nil, grpcUnauthenticated
case errors.Is(err, project.ErrNotExist), errors.Is(err, servicedata.ErrInvalidDetail),
errors.Is(err, relation.ErrInvalidDetail), errors.Is(err, servicedata.ErrNotExist):
return nil, grpcBadBodyError
case errors.Is(err, errorsPkg.ErrForbidden):
return nil, status.Error(codes.PermissionDenied, fmt.Sprintf("you are not authorized to update %s key", k))
default:
return nil, grpcInternalServerError
}
}
serviceDataMap[serviceDataResp.Key.Name] = serviceDataResp.Value
}

newGroup.Metadata = metaDataMap

groupPB, err := transformGroupToPB(newGroup)
if err != nil {
logger.Error(err.Error())
return nil, grpcInternalServerError
return nil, ErrInternalServer
}

return &shieldv1beta1.CreateGroupResponse{Group: &shieldv1beta1.Group{
Id: newGroup.ID,
Name: newGroup.Name,
Slug: newGroup.Slug,
OrgId: newGroup.OrganizationID,
Metadata: metaData,
CreatedAt: timestamppb.New(newGroup.CreatedAt),
UpdatedAt: timestamppb.New(newGroup.UpdatedAt),
}}, nil
return &shieldv1beta1.CreateGroupResponse{Group: &groupPB}, nil
}

func (h Handler) GetGroup(ctx context.Context, request *shieldv1beta1.GetGroupRequest) (*shieldv1beta1.GetGroupResponse, error) {
@@ -157,7 +219,7 @@ func (h Handler) GetGroup(ctx context.Context, request *shieldv1beta1.GetGroupRe
} else {
metadata := map[string]any{}
for _, sd := range groupSD {
metadata[sd.Key.Key] = sd.Value
metadata[sd.Key.Name] = sd.Value
}
fetchedGroup.Metadata = metadata
}
@@ -178,6 +240,7 @@ func (h Handler) UpdateGroup(ctx context.Context, request *shieldv1beta1.UpdateG
return nil, grpcBadBodyError
}

//TODO: change this implementation
metaDataMap, err := metadata.Build(request.GetBody().GetMetadata().AsMap())
if err != nil {
return nil, grpcBadBodyError
@@ -190,14 +253,14 @@ func (h Handler) UpdateGroup(ctx context.Context, request *shieldv1beta1.UpdateG
Name: request.GetBody().GetName(),
Slug: request.GetBody().GetSlug(),
OrganizationID: request.GetBody().GetOrgId(),
Metadata: metaDataMap,
Metadata: nil,
})
} else {
updatedGroup, err = h.groupService.Update(ctx, group.Group{
Name: request.GetBody().GetName(),
Slug: request.GetId(),
OrganizationID: request.GetBody().GetOrgId(),
Metadata: metaDataMap,
Metadata: nil,
})
}
if err != nil {
@@ -227,10 +290,10 @@ func (h Handler) UpdateGroup(ctx context.Context, request *shieldv1beta1.UpdateG
EntityID: updatedGroup.ID,
NamespaceID: groupNamespaceID,
Key: servicedata.Key{
Key: k,
Name: k,
ProjectID: h.serviceDataConfig.DefaultServiceDataProject,
},
Value: v.(string),
Value: v,
})
if err != nil {
logger.Error(err.Error())
@@ -247,11 +310,11 @@ func (h Handler) UpdateGroup(ctx context.Context, request *shieldv1beta1.UpdateG
return nil, grpcInternalServerError
}
}
serviceDataMap[serviceDataResp.Key.Key] = serviceDataResp.Value
serviceDataMap[serviceDataResp.Key.Name] = serviceDataResp.Value
}

//Note: this would return only the keys that are updated in the current request
updatedGroup.Metadata = serviceDataMap
updatedGroup.Metadata = metaDataMap

groupPB, err := transformGroupToPB(updatedGroup)
if err != nil {
Loading
Loading