Skip to content

Commit

Permalink
feat: add create service data (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
FemiNoviaLina authored May 21, 2024
1 parent fe57407 commit b0cb03f
Show file tree
Hide file tree
Showing 34 changed files with 2,579 additions and 713 deletions.
3 changes: 3 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ packages:
RuleService:
config:
filename: "rule_service.go"
ServiceDataService:
config:
filename: "servicedata_service.go"
UserService:
config:
filename: "user_service.go"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 := "8a9467fbc5539da13276eb858b4d91245fb43edd"
PROTON_COMMIT := "7e380e055d82cd8378989354785f6434d8615d70"

install:
@echo "Clean up imports..."
Expand Down
31 changes: 18 additions & 13 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/goto/shield/core/relation"
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/role"
"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/adapter"
"github.com/goto/shield/internal/api"
Expand Down Expand Up @@ -92,7 +93,7 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
return err
}

schemaMigrationConfig := schema.NewSchemaMigrationConfig(cfg.App.DefaultSystemEmail)
schemaMigrationConfig := schema.NewSchemaMigrationConfig(cfg.App.DefaultSystemEmail, cfg.App.BootstrapServiceDataKey)

appConfig := activity.AppConfig{Version: config.Version}
var activityRepository activity.Repository
Expand Down Expand Up @@ -220,21 +221,25 @@ func BuildAPIDependencies(
resourceService := resource.NewService(
logger, resourcePGRepository, resourceBlobRepository, relationService, userService, projectService, organizationService, groupService, activityService)

serviceDataRepository := postgres.NewServiceDataRepository(dbc)
serviceDataService := servicedata.NewService(serviceDataRepository, resourceService, relationService, projectService, userService)

relationAdapter := adapter.NewRelation(groupService, userService, relationService)

dependencies := api.Deps{
OrgService: organizationService,
UserService: userService,
ProjectService: projectService,
GroupService: groupService,
RelationService: relationService,
ResourceService: resourceService,
RoleService: roleService,
PolicyService: policyService,
ActionService: actionService,
NamespaceService: namespaceService,
RelationAdapter: relationAdapter,
ActivityService: activityService,
OrgService: organizationService,
UserService: userService,
ProjectService: projectService,
GroupService: groupService,
RelationService: relationService,
ResourceService: resourceService,
RoleService: roleService,
PolicyService: policyService,
ActionService: actionService,
NamespaceService: namespaceService,
RelationAdapter: relationAdapter,
ActivityService: activityService,
ServiceDataService: serviceDataService,
}
return dependencies, nil
}
Expand Down
7 changes: 6 additions & 1 deletion core/namespace/definition.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package namespace

var systemIdsDefinition = []string{DefinitionTeam.ID, DefinitionUser.ID, DefinitionOrg.ID, DefinitionProject.ID}
var systemIdsDefinition = []string{DefinitionTeam.ID, DefinitionUser.ID, DefinitionOrg.ID, DefinitionProject.ID, DefinitionServiceDataKey.ID}

var DefinitionOrg = Namespace{
ID: "shield/organization",
Expand All @@ -21,3 +21,8 @@ var DefinitionUser = Namespace{
ID: "shield/user",
Name: "User",
}

var DefinitionServiceDataKey = Namespace{
ID: "shield/servicedata_key",
Name: "Service Data Key",
}
8 changes: 8 additions & 0 deletions core/servicedata/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package servicedata

import "errors"

var (
ErrInvalidDetail = errors.New("invalid service data detail")
ErrConflict = errors.New("key already exist")
)
110 changes: 110 additions & 0 deletions core/servicedata/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package servicedata

import (
"context"
"fmt"

"github.com/goto/shield/core/project"
"github.com/goto/shield/core/relation"
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/schema"
"github.com/goto/shield/pkg/uuid"
)

const keyNamespace = "shield/servicedata_key"

type ResourceService interface {
Create(ctx context.Context, res resource.Resource) (resource.Resource, error)
}

type RelationService interface {
Create(ctx context.Context, rel relation.RelationV2) (relation.RelationV2, error)
}

type ProjectService interface {
Get(ctx context.Context, idOrSlug string) (project.Project, error)
}

type UserService interface {
FetchCurrentUser(ctx context.Context) (user.User, error)
}

type Service struct {
repository Repository
resourceService ResourceService
relationService RelationService
projectService ProjectService
userService UserService
}

func NewService(repository Repository, resourceService ResourceService, relationService RelationService, projectService ProjectService, userService UserService) *Service {
return &Service{
repository: repository,
resourceService: resourceService,
relationService: relationService,
projectService: projectService,
userService: userService,
}
}

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

// fetch current user
currentUser, err := s.userService.FetchCurrentUser(ctx)
if err != nil {
return Key{}, fmt.Errorf("%w: %s", user.ErrInvalidEmail, err.Error())
}

// convert project slug to project id
if !uuid.IsValid(key.ProjectID) {
project, err := s.projectService.Get(ctx, key.ProjectID)
if err != nil {
return Key{}, err
}
key.ProjectID = project.ID
}

// create URN
key.URN = key.CreateURN()

// insert the service data key
resource, err := s.resourceService.Create(ctx, resource.Resource{
Name: key.URN,
NamespaceID: keyNamespace,
ProjectID: key.ProjectID,
UserID: currentUser.ID,
})
if err != nil {
return Key{}, err
}
key.ResourceID = resource.Idxa

// insert service data key to the servicedata_keys table
createdServiceDataKey, err := s.repository.CreateKey(ctx, key)
if err != nil {
return Key{}, err
}

// create relation
_, err = s.relationService.Create(ctx, relation.RelationV2{
Object: relation.Object{
ID: resource.Idxa,
NamespaceID: schema.ServiceDataKeyNamespace,
},
Subject: relation.Subject{
ID: currentUser.ID,
RoleID: schema.OwnerRole,
Namespace: schema.UserPrincipal,
},
})
if err != nil {
return Key{}, err
}

return createdServiceDataKey, nil
}
23 changes: 23 additions & 0 deletions core/servicedata/servicedata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package servicedata

import (
"context"
"fmt"
)

type Repository interface {
CreateKey(ctx context.Context, key Key) (Key, error)
}

type Key struct {
ID string
URN string
ProjectID string
Key string
Description string
ResourceID string
}

func (key Key) CreateURN() string {
return fmt.Sprintf("%s:servicedata_key:%s", key.ProjectID, key.Key)
}
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
Expand Down Expand Up @@ -1949,6 +1950,7 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
Expand Down
28 changes: 15 additions & 13 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ import (
"github.com/goto/shield/core/resource"
"github.com/goto/shield/core/role"
"github.com/goto/shield/core/rule"
"github.com/goto/shield/core/servicedata"
"github.com/goto/shield/core/user"
"github.com/goto/shield/internal/adapter"
)

type Deps struct {
OrgService *organization.Service
ProjectService *project.Service
GroupService *group.Service
RoleService *role.Service
PolicyService *policy.Service
UserService *user.Service
NamespaceService *namespace.Service
ActionService *action.Service
RelationService *relation.Service
RelationAdapter *adapter.Relation
ResourceService *resource.Service
RuleService *rule.Service
ActivityService *activity.Service
OrgService *organization.Service
ProjectService *project.Service
GroupService *group.Service
RoleService *role.Service
PolicyService *policy.Service
UserService *user.Service
NamespaceService *namespace.Service
ActionService *action.Service
RelationService *relation.Service
RelationAdapter *adapter.Relation
ResourceService *resource.Service
RuleService *rule.Service
ActivityService *activity.Service
ServiceDataService *servicedata.Service
}
94 changes: 94 additions & 0 deletions internal/api/v1beta1/mocks/servicedata_service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b0cb03f

Please sign in to comment.