Skip to content

Commit 20336fe

Browse files
authored
feat(referrers): add public property (#438)
Signed-off-by: Miguel Martinez Trivino <[email protected]>
1 parent 90e1cc5 commit 20336fe

32 files changed

+1233
-106
lines changed

app/cli/internal/action/referrer_discover.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type ReferrerItem struct {
3030
Digest string `json:"digest"`
3131
Kind string `json:"kind"`
3232
Downloadable bool `json:"downloadable"`
33+
Public bool `json:"public"`
3334
CreatedAt *time.Time `json:"createdAt"`
3435
References []*ReferrerItem `json:"references"`
3536
}
@@ -58,6 +59,7 @@ func pbReferrerItemToAction(in *pb.ReferrerItem) *ReferrerItem {
5859
out := &ReferrerItem{
5960
Digest: in.GetDigest(),
6061
Downloadable: in.GetDownloadable(),
62+
Public: in.GetPublic(),
6163
Kind: in.GetKind(),
6264
CreatedAt: toTimePtr(in.GetCreatedAt().AsTime()),
6365
References: make([]*ReferrerItem, 0, len(in.GetReferences())),

app/controlplane/api/controlplane/v1/referrer.pb.go

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

app/controlplane/api/controlplane/v1/referrer.pb.validate.go

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

app/controlplane/api/controlplane/v1/referrer.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ message ReferrerItem {
4747
string kind = 2;
4848
// Whether the referrer is downloadable or not from CAS
4949
bool downloadable = 3;
50+
// Whether the referrer is public since it belongs to a public workflow
51+
bool public = 6;
5052
repeated ReferrerItem references = 4;
5153
google.protobuf.Timestamp created_at = 5;
5254
}

app/controlplane/api/gen/frontend/controlplane/v1/referrer.ts

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/cmd/wire_gen.go

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

app/controlplane/internal/biz/referrer.go

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ type Referrer struct {
3939
Kind string
4040
// Wether the item is downloadable from CAS or not
4141
Downloadable bool
42-
References []*Referrer
42+
// If this referrer is part of a public workflow
43+
InPublicWorkflow bool
44+
References []*Referrer
4345
}
4446

4547
// Actual referrer stored in the DB which includes a nested list of storedReferences
@@ -48,53 +50,75 @@ type StoredReferrer struct {
4850
ID uuid.UUID
4951
CreatedAt *time.Time
5052
// Fully expanded list of 1-level off references
51-
References []*StoredReferrer
52-
OrgIDs []uuid.UUID
53+
References []*StoredReferrer
54+
OrgIDs, WorkflowIDs []uuid.UUID
5355
}
5456

5557
type ReferrerRepo interface {
56-
Save(ctx context.Context, input []*Referrer, orgID uuid.UUID) error
58+
Save(ctx context.Context, input []*Referrer, workflowID uuid.UUID) error
5759
// GetFromRoot returns the referrer identified by the provided content digest, including its first-level references
5860
// For example if sha:deadbeef represents an attestation, the result will contain the attestation + materials associated to it
5961
// OrgIDs represent an allowList of organizations where the referrers should be looked for
60-
GetFromRoot(ctx context.Context, digest, kind string, orgIDS []uuid.UUID) (*StoredReferrer, error)
62+
GetFromRoot(ctx context.Context, digest string, orgIDS []uuid.UUID, filters ...GetFromRootFilter) (*StoredReferrer, error)
63+
}
64+
65+
type GetFromRootFilters struct {
66+
// RootKind is the kind of the root referrer, i.e ATTESTATION
67+
RootKind *string
68+
// Wether to filter by visibility or not
69+
Public *bool
70+
}
71+
72+
type GetFromRootFilter func(*GetFromRootFilters)
73+
74+
func WithKind(kind string) func(*GetFromRootFilters) {
75+
return func(o *GetFromRootFilters) {
76+
o.RootKind = &kind
77+
}
78+
}
79+
80+
func WithPublicVisibility(public bool) func(*GetFromRootFilters) {
81+
return func(o *GetFromRootFilters) {
82+
o.Public = &public
83+
}
6184
}
6285

6386
type ReferrerUseCase struct {
6487
repo ReferrerRepo
65-
orgRepo OrganizationRepo
6688
membershipRepo MembershipRepo
89+
workflowRepo WorkflowRepo
6790
logger *log.Helper
6891
}
6992

70-
func NewReferrerUseCase(repo ReferrerRepo, orgRepo OrganizationRepo, mRepo MembershipRepo, l log.Logger) *ReferrerUseCase {
93+
func NewReferrerUseCase(repo ReferrerRepo, wfRepo WorkflowRepo, mRepo MembershipRepo, l log.Logger) *ReferrerUseCase {
7194
if l == nil {
7295
l = log.NewStdLogger(io.Discard)
7396
}
7497

75-
return &ReferrerUseCase{repo, orgRepo, mRepo, servicelogger.ScopedHelper(l, "biz/Referrer")}
98+
return &ReferrerUseCase{repo, mRepo, wfRepo, servicelogger.ScopedHelper(l, "biz/Referrer")}
7699
}
77100

78101
// ExtractAndPersist extracts the referrers (subject + materials) from the given attestation
79102
// and store it as part of the referrers index table
80-
func (s *ReferrerUseCase) ExtractAndPersist(ctx context.Context, att *dsse.Envelope, orgID string) error {
81-
orgUUID, err := uuid.Parse(orgID)
103+
func (s *ReferrerUseCase) ExtractAndPersist(ctx context.Context, att *dsse.Envelope, workflowID string) error {
104+
workflowUUID, err := uuid.Parse(workflowID)
82105
if err != nil {
83106
return NewErrInvalidUUID(err)
84107
}
85108

86-
if org, err := s.orgRepo.FindByID(ctx, orgUUID); err != nil {
87-
return fmt.Errorf("finding organization: %w", err)
88-
} else if org == nil {
89-
return NewErrNotFound("organization")
109+
// Check that the workflow belongs to the organization
110+
if wf, err := s.workflowRepo.FindByID(ctx, workflowUUID); err != nil {
111+
return fmt.Errorf("finding workflow: %w", err)
112+
} else if wf == nil {
113+
return NewErrNotFound("workflow")
90114
}
91115

92116
m, err := extractReferrers(att)
93117
if err != nil {
94118
return fmt.Errorf("extracting referrers: %w", err)
95119
}
96120

97-
if err := s.repo.Save(ctx, m, orgUUID); err != nil {
121+
if err := s.repo.Save(ctx, m, workflowUUID); err != nil {
98122
return fmt.Errorf("saving referrers: %w", err)
99123
}
100124

@@ -110,6 +134,10 @@ func (s *ReferrerUseCase) GetFromRoot(ctx context.Context, digest string, rootKi
110134
return nil, NewErrInvalidUUID(err)
111135
}
112136

137+
if _, err = cr_v1.NewHash(digest); err != nil {
138+
return nil, NewErrValidation(fmt.Errorf("invalid digest format: %w", err))
139+
}
140+
113141
// We pass the list of organizationsIDs from where to look for the referrer
114142
// For now we just pass the list of organizations the user is member of
115143
// in the future we will expand this to publicly available orgs and so on.
@@ -123,7 +151,12 @@ func (s *ReferrerUseCase) GetFromRoot(ctx context.Context, digest string, rootKi
123151
orgIDs = append(orgIDs, m.OrganizationID)
124152
}
125153

126-
ref, err := s.repo.GetFromRoot(ctx, digest, rootKind, orgIDs)
154+
filters := make([]GetFromRootFilter, 0)
155+
if rootKind != "" {
156+
filters = append(filters, WithKind(rootKind))
157+
}
158+
159+
ref, err := s.repo.GetFromRoot(ctx, digest, orgIDs, filters...)
127160
if err != nil {
128161
if errors.As(err, &ErrAmbiguousReferrer{}) {
129162
return nil, NewErrValidation(fmt.Errorf("please provide the referrer kind: %w", err))

0 commit comments

Comments
 (0)