Skip to content

Commit b0cb03f

Browse files
feat: add create service data (#54)
1 parent fe57407 commit b0cb03f

34 files changed

+2579
-713
lines changed

.mockery.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ packages:
3939
RuleService:
4040
config:
4141
filename: "rule_service.go"
42+
ServiceDataService:
43+
config:
44+
filename: "servicedata_service.go"
4245
UserService:
4346
config:
4447
filename: "user_service.go"

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ GOVERSION := $(shell go version | cut -d ' ' -f 3 | cut -d '.' -f 2)
22

33
.PHONY: build check fmt lint test test-race vet test-cover-html help install proto
44
.DEFAULT_GOAL := build
5-
PROTON_COMMIT := "8a9467fbc5539da13276eb858b4d91245fb43edd"
5+
PROTON_COMMIT := "7e380e055d82cd8378989354785f6434d8615d70"
66

77
install:
88
@echo "Clean up imports..."

cmd/serve.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/goto/shield/core/relation"
2828
"github.com/goto/shield/core/resource"
2929
"github.com/goto/shield/core/role"
30+
"github.com/goto/shield/core/servicedata"
3031
"github.com/goto/shield/core/user"
3132
"github.com/goto/shield/internal/adapter"
3233
"github.com/goto/shield/internal/api"
@@ -92,7 +93,7 @@ func StartServer(logger *log.Zap, cfg *config.Shield) error {
9293
return err
9394
}
9495

95-
schemaMigrationConfig := schema.NewSchemaMigrationConfig(cfg.App.DefaultSystemEmail)
96+
schemaMigrationConfig := schema.NewSchemaMigrationConfig(cfg.App.DefaultSystemEmail, cfg.App.BootstrapServiceDataKey)
9697

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

224+
serviceDataRepository := postgres.NewServiceDataRepository(dbc)
225+
serviceDataService := servicedata.NewService(serviceDataRepository, resourceService, relationService, projectService, userService)
226+
223227
relationAdapter := adapter.NewRelation(groupService, userService, relationService)
224228

225229
dependencies := api.Deps{
226-
OrgService: organizationService,
227-
UserService: userService,
228-
ProjectService: projectService,
229-
GroupService: groupService,
230-
RelationService: relationService,
231-
ResourceService: resourceService,
232-
RoleService: roleService,
233-
PolicyService: policyService,
234-
ActionService: actionService,
235-
NamespaceService: namespaceService,
236-
RelationAdapter: relationAdapter,
237-
ActivityService: activityService,
230+
OrgService: organizationService,
231+
UserService: userService,
232+
ProjectService: projectService,
233+
GroupService: groupService,
234+
RelationService: relationService,
235+
ResourceService: resourceService,
236+
RoleService: roleService,
237+
PolicyService: policyService,
238+
ActionService: actionService,
239+
NamespaceService: namespaceService,
240+
RelationAdapter: relationAdapter,
241+
ActivityService: activityService,
242+
ServiceDataService: serviceDataService,
238243
}
239244
return dependencies, nil
240245
}

core/namespace/definition.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package namespace
22

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

55
var DefinitionOrg = Namespace{
66
ID: "shield/organization",
@@ -21,3 +21,8 @@ var DefinitionUser = Namespace{
2121
ID: "shield/user",
2222
Name: "User",
2323
}
24+
25+
var DefinitionServiceDataKey = Namespace{
26+
ID: "shield/servicedata_key",
27+
Name: "Service Data Key",
28+
}

core/servicedata/errors.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package servicedata
2+
3+
import "errors"
4+
5+
var (
6+
ErrInvalidDetail = errors.New("invalid service data detail")
7+
ErrConflict = errors.New("key already exist")
8+
)

core/servicedata/service.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package servicedata
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/goto/shield/core/project"
8+
"github.com/goto/shield/core/relation"
9+
"github.com/goto/shield/core/resource"
10+
"github.com/goto/shield/core/user"
11+
"github.com/goto/shield/internal/schema"
12+
"github.com/goto/shield/pkg/uuid"
13+
)
14+
15+
const keyNamespace = "shield/servicedata_key"
16+
17+
type ResourceService interface {
18+
Create(ctx context.Context, res resource.Resource) (resource.Resource, error)
19+
}
20+
21+
type RelationService interface {
22+
Create(ctx context.Context, rel relation.RelationV2) (relation.RelationV2, error)
23+
}
24+
25+
type ProjectService interface {
26+
Get(ctx context.Context, idOrSlug string) (project.Project, error)
27+
}
28+
29+
type UserService interface {
30+
FetchCurrentUser(ctx context.Context) (user.User, error)
31+
}
32+
33+
type Service struct {
34+
repository Repository
35+
resourceService ResourceService
36+
relationService RelationService
37+
projectService ProjectService
38+
userService UserService
39+
}
40+
41+
func NewService(repository Repository, resourceService ResourceService, relationService RelationService, projectService ProjectService, userService UserService) *Service {
42+
return &Service{
43+
repository: repository,
44+
resourceService: resourceService,
45+
relationService: relationService,
46+
projectService: projectService,
47+
userService: userService,
48+
}
49+
}
50+
51+
func (s Service) CreateKey(ctx context.Context, key Key) (Key, error) {
52+
// check if key contains ':'
53+
if key.Key == "" {
54+
return Key{}, ErrInvalidDetail
55+
}
56+
57+
// fetch current user
58+
currentUser, err := s.userService.FetchCurrentUser(ctx)
59+
if err != nil {
60+
return Key{}, fmt.Errorf("%w: %s", user.ErrInvalidEmail, err.Error())
61+
}
62+
63+
// convert project slug to project id
64+
if !uuid.IsValid(key.ProjectID) {
65+
project, err := s.projectService.Get(ctx, key.ProjectID)
66+
if err != nil {
67+
return Key{}, err
68+
}
69+
key.ProjectID = project.ID
70+
}
71+
72+
// create URN
73+
key.URN = key.CreateURN()
74+
75+
// insert the service data key
76+
resource, err := s.resourceService.Create(ctx, resource.Resource{
77+
Name: key.URN,
78+
NamespaceID: keyNamespace,
79+
ProjectID: key.ProjectID,
80+
UserID: currentUser.ID,
81+
})
82+
if err != nil {
83+
return Key{}, err
84+
}
85+
key.ResourceID = resource.Idxa
86+
87+
// insert service data key to the servicedata_keys table
88+
createdServiceDataKey, err := s.repository.CreateKey(ctx, key)
89+
if err != nil {
90+
return Key{}, err
91+
}
92+
93+
// create relation
94+
_, err = s.relationService.Create(ctx, relation.RelationV2{
95+
Object: relation.Object{
96+
ID: resource.Idxa,
97+
NamespaceID: schema.ServiceDataKeyNamespace,
98+
},
99+
Subject: relation.Subject{
100+
ID: currentUser.ID,
101+
RoleID: schema.OwnerRole,
102+
Namespace: schema.UserPrincipal,
103+
},
104+
})
105+
if err != nil {
106+
return Key{}, err
107+
}
108+
109+
return createdServiceDataKey, nil
110+
}

core/servicedata/servicedata.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package servicedata
2+
3+
import (
4+
"context"
5+
"fmt"
6+
)
7+
8+
type Repository interface {
9+
CreateKey(ctx context.Context, key Key) (Key, error)
10+
}
11+
12+
type Key struct {
13+
ID string
14+
URN string
15+
ProjectID string
16+
Key string
17+
Description string
18+
ResourceID string
19+
}
20+
21+
func (key Key) CreateURN() string {
22+
return fmt.Sprintf("%s:servicedata_key:%s", key.ProjectID, key.Key)
23+
}

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
640640
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
641641
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
642642
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
643+
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
643644
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
644645
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
645646
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -1949,6 +1950,7 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
19491950
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
19501951
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
19511952
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
1953+
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
19521954
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
19531955
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
19541956
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=

internal/api/api.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,24 @@ import (
1212
"github.com/goto/shield/core/resource"
1313
"github.com/goto/shield/core/role"
1414
"github.com/goto/shield/core/rule"
15+
"github.com/goto/shield/core/servicedata"
1516
"github.com/goto/shield/core/user"
1617
"github.com/goto/shield/internal/adapter"
1718
)
1819

1920
type Deps struct {
20-
OrgService *organization.Service
21-
ProjectService *project.Service
22-
GroupService *group.Service
23-
RoleService *role.Service
24-
PolicyService *policy.Service
25-
UserService *user.Service
26-
NamespaceService *namespace.Service
27-
ActionService *action.Service
28-
RelationService *relation.Service
29-
RelationAdapter *adapter.Relation
30-
ResourceService *resource.Service
31-
RuleService *rule.Service
32-
ActivityService *activity.Service
21+
OrgService *organization.Service
22+
ProjectService *project.Service
23+
GroupService *group.Service
24+
RoleService *role.Service
25+
PolicyService *policy.Service
26+
UserService *user.Service
27+
NamespaceService *namespace.Service
28+
ActionService *action.Service
29+
RelationService *relation.Service
30+
RelationAdapter *adapter.Relation
31+
ResourceService *resource.Service
32+
RuleService *rule.Service
33+
ActivityService *activity.Service
34+
ServiceDataService *servicedata.Service
3335
}

internal/api/v1beta1/mocks/servicedata_service.go

Lines changed: 94 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)