Skip to content

Commit f3eb58c

Browse files
feat: add supplier information toggle for latest SBOM to approvable infos retrieval (#208)
Co-authored-by: Kostyantyn Zagorodniy <kostyantyn.zagorodniy@mercedes-benz.com>
1 parent c13e4ea commit f3eb58c

7 files changed

Lines changed: 89 additions & 19 deletions

File tree

backend/domain/approval/approval.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ type ProjectApprovable struct {
106106
SpdxTag string
107107
SpdxUploaded *time.Time
108108
IsSpdxRecent bool
109+
110+
Supplier *string
109111
}
110112

111113
type Info struct {

backend/domain/approval/rest.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func (p *ProjectApprovable) ToDto() ProjectApprovableDto {
7373
SpdxTag: p.SpdxTag,
7474
SpdxUploaded: p.SpdxUploaded,
7575
IsSpdxRecent: p.IsSpdxRecent,
76+
Supplier: p.Supplier,
7677
}
7778
}
7879

@@ -87,6 +88,7 @@ type ProjectApprovableDto struct {
8788
SpdxTag string `json:"spdxtag"`
8889
SpdxUploaded *time.Time `json:"spdxUploaded"`
8990
IsSpdxRecent bool `json:"isSpdxRecent"`
91+
Supplier *string `json:"supplier"`
9092
}
9193

9294
type ApproveStateDto struct {
@@ -102,14 +104,14 @@ func (s *ApproveState) ToDto() ApproveStateDto {
102104
}
103105

104106
type ExternalApprovalDto struct {
105-
Vehicel bool `json:"vehicle"`
107+
Vehicle bool `json:"vehicle"`
106108
State StateInfo `json:"state"`
107109
ApproveComment string `json:"comment"`
108110
}
109111

110112
func (ea *ExternalApproval) ToDto() ExternalApprovalDto {
111113
return ExternalApprovalDto{
112-
Vehicel: ea.Vehicle,
114+
Vehicle: ea.Vehicle,
113115
State: ea.State,
114116
ApproveComment: ea.Comment,
115117
}

backend/infra/rest/project.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,9 @@ func (projectHandler *ProjectHandler) ProjectGetApprovableInfo(w http.ResponseWr
461461
PolicyDecisionsRepo: projectHandler.PolicyDecisionsRepository,
462462
}
463463

464-
res := as.GetApprovalInfo(pr)
464+
takeLatestSbom := len(r.URL.Query().Get("latestSbom")) > 0
465+
466+
res := as.GetApprovalInfo(pr, takeLatestSbom)
465467
dto := res.ToDto()
466468

467469
for _, appPr := range dto.Projects {

backend/infra/service/approval/approval.go

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,24 @@ import (
1010
"sort"
1111
"time"
1212

13-
license2 "github.com/eclipse-disuko/disuko/domain/license"
14-
"github.com/eclipse-disuko/disuko/helper/hash"
15-
"github.com/eclipse-disuko/disuko/infra/repository/licenserules"
16-
"github.com/eclipse-disuko/disuko/infra/repository/policydecisions"
17-
1813
"github.com/eclipse-disuko/disuko/domain/approval"
1914
"github.com/eclipse-disuko/disuko/domain/audit"
15+
license2 "github.com/eclipse-disuko/disuko/domain/license"
2016
"github.com/eclipse-disuko/disuko/domain/project"
17+
"github.com/eclipse-disuko/disuko/domain/project/approvable"
2118
"github.com/eclipse-disuko/disuko/domain/project/components"
2219
"github.com/eclipse-disuko/disuko/domain/project/sbomlist"
2320
user2 "github.com/eclipse-disuko/disuko/domain/user"
2421
auditHelper "github.com/eclipse-disuko/disuko/helper/audit"
2522
"github.com/eclipse-disuko/disuko/helper/exception"
23+
"github.com/eclipse-disuko/disuko/helper/hash"
2624
"github.com/eclipse-disuko/disuko/helper/message"
2725
"github.com/eclipse-disuko/disuko/infra/repository/approvallist"
2826
"github.com/eclipse-disuko/disuko/infra/repository/auditloglist"
2927
"github.com/eclipse-disuko/disuko/infra/repository/labels"
3028
"github.com/eclipse-disuko/disuko/infra/repository/license"
29+
"github.com/eclipse-disuko/disuko/infra/repository/licenserules"
30+
"github.com/eclipse-disuko/disuko/infra/repository/policydecisions"
3131
"github.com/eclipse-disuko/disuko/infra/repository/policyrules"
3232
projectRepo "github.com/eclipse-disuko/disuko/infra/repository/project"
3333
sbomListRepo "github.com/eclipse-disuko/disuko/infra/repository/sbomlist"
@@ -91,8 +91,8 @@ func (s *ApprovalService) ProcessRandomApprovalUpdate(pr *project.Project, appId
9191
return targetApproval
9292
}
9393

94-
func (s *ApprovalService) GetApprovalInfo(targetProject *project.Project) approval.Info {
95-
return s.getApprovalInfo(targetProject, nil, false)
94+
func (s *ApprovalService) GetApprovalInfo(targetProject *project.Project, takeLatestSbom bool) approval.Info {
95+
return s.getApprovalInfo(targetProject, nil, false, takeLatestSbom)
9696
}
9797

9898
func (s *ApprovalService) AdminAbortRandomApproval(pr *project.Project, app *approval.Approval) {
@@ -106,7 +106,7 @@ func (s *ApprovalService) AdminAbortRandomApproval(pr *project.Project, app *app
106106
}
107107
}
108108

109-
func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projectFilter *[]string, includeNoFOSS bool) approval.Info {
109+
func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projectFilter *[]string, includeNoFOSS bool, takeLatestSbom bool) approval.Info {
110110
res := approval.Info{
111111
CompStats: &components.ComponentStats{},
112112
}
@@ -143,22 +143,47 @@ func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projec
143143
logy.Warnf(s.RequestSession, "Child project is marked as deprecated, uuid: %s parent: %s", prKey, pr.Key)
144144
continue
145145
}
146-
if pr.ApprovableSPDX.SpdxKey == "" || pr.ApprovableSPDX.VersionKey == "" || (!includeNoFOSS && pr.IsNoFoss) {
146+
147+
var supplier *project.ProjectMemberEntity
148+
for _, u := range pr.UserManagement.Users {
149+
if u.UserType == project.SUPPLIER {
150+
supplier = u
151+
break
152+
}
153+
}
154+
var supplierUserId *string
155+
if supplier != nil {
156+
supplierUserId = &supplier.UserId
157+
}
158+
159+
approvableSPDX := pr.ApprovableSPDX
160+
var sbomList *sbomlist.SbomList
161+
var sbom *project.SpdxFileBase
162+
163+
if takeLatestSbom {
164+
approvableSPDX, sbomList, sbom = s.findLatestSpdx(pr)
165+
}
166+
167+
if approvableSPDX.SpdxKey == "" || approvableSPDX.VersionKey == "" || (!includeNoFOSS && pr.IsNoFoss) {
147168
res.Projects = append(res.Projects, approval.ProjectApprovable{
148169
ProjectKey: pr.Key,
149170
ProjectName: pr.Name,
150171
CustomerDiffers: pr.CustomerMeta.Diff(targetProject.CustomerMeta),
151172
SupplierDiffers: pr.DocumentMeta.Diff(targetProject.DocumentMeta),
173+
Supplier: supplierUserId,
152174
})
153175
continue
154176
}
155-
sbomList, sbom := s.SpdxRetriever.RetrieveSbomListAndFile(s.RequestSession, pr.ApprovableSPDX.VersionKey, pr.ApprovableSPDX.SpdxKey)
156-
if sbom == nil {
177+
if !takeLatestSbom {
178+
sbomList, sbom = s.SpdxRetriever.RetrieveSbomListAndFile(s.RequestSession, approvableSPDX.VersionKey, approvableSPDX.SpdxKey)
179+
}
180+
if sbom == nil || sbomList == nil {
157181
res.Projects = append(res.Projects, approval.ProjectApprovable{
158182
ProjectKey: pr.Key,
159183
ProjectName: pr.Name,
160184
CustomerDiffers: pr.CustomerMeta.Diff(targetProject.CustomerMeta),
161185
SupplierDiffers: pr.DocumentMeta.Diff(targetProject.DocumentMeta),
186+
Supplier: supplierUserId,
162187
})
163188
continue
164189
}
@@ -192,7 +217,7 @@ func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projec
192217
if sbom.TotalStatsHash != nil && *sbom.TotalStatsHash == *currentTotalStatsHash {
193218
sbomStats = sbom.Stats
194219
} else {
195-
compsInfo := s.SpdxService.GetComponentInfos(s.RequestSession, pr, pr.ApprovableSPDX.VersionKey, sbom)
220+
compsInfo := s.SpdxService.GetComponentInfos(s.RequestSession, pr, approvableSPDX.VersionKey, sbom)
196221
isVehicle := s.ProjectLabelService.HasVehiclePlatformLabel(s.RequestSession, pr)
197222
evalRes := compsInfo.EvaluatePolicyRules(rules, policyDecisions, isVehicle, sbom.Uploaded, sbom.Key)
198223

@@ -208,7 +233,8 @@ func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projec
208233
ProjectName: pr.Name,
209234
CustomerDiffers: pr.CustomerMeta.Diff(targetProject.CustomerMeta),
210235
SupplierDiffers: pr.DocumentMeta.Diff(targetProject.DocumentMeta),
211-
ApprovableSPDX: pr.ApprovableSPDX,
236+
Supplier: supplierUserId,
237+
ApprovableSPDX: approvableSPDX,
212238
SpdxName: sbom.MetaInfo.Name,
213239
SpdxTag: sbom.Tag,
214240
ApprovableStats: sbomStats,
@@ -219,6 +245,44 @@ func (s *ApprovalService) getApprovalInfo(targetProject *project.Project, projec
219245
return res
220246
}
221247

248+
func (s *ApprovalService) findLatestSpdx(pr *project.Project) (approvable.ApprovableSPDX, *sbomlist.SbomList, *project.SpdxFileBase) {
249+
var latest *project.SpdxFileBase
250+
var latestSBOMList *sbomlist.SbomList
251+
var latestVersionKey string
252+
var latestVersionName string
253+
254+
for _, version := range pr.Versions {
255+
if version.Deleted {
256+
continue
257+
}
258+
259+
sbomList := s.SBOMListRepo.FindByKey(s.RequestSession, version.Key, false)
260+
if sbomList == nil {
261+
continue
262+
}
263+
264+
for _, spdx := range sbomList.SpdxFileHistory {
265+
if latest == nil || spdx.Uploaded.After(*latest.Uploaded) {
266+
latest = spdx
267+
latestSBOMList = sbomList
268+
latestVersionKey = version.Key
269+
latestVersionName = version.Name
270+
}
271+
}
272+
}
273+
274+
if latest == nil {
275+
return approvable.ApprovableSPDX{}, nil, nil
276+
}
277+
278+
approvableSpdx := approvable.ApprovableSPDX{
279+
SpdxKey: latest.Key,
280+
VersionKey: latestVersionKey,
281+
VersionName: latestVersionName,
282+
}
283+
return approvableSpdx, latestSBOMList, latest
284+
}
285+
222286
func (s *ApprovalService) setTaskDone(username string, app *approval.Approval, taskType user2.TaskType, taskStatus user2.TaskStatus) {
223287
targetUser := s.UserRepo.FindByUserId(s.RequestSession, username)
224288
targetBefore := targetUser.ToUserAudit()

backend/infra/service/approval/external_approval.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func (s *ApprovalService) CreateExternalApproval(pr *project.Project, req approv
2222
exception.ThrowExceptionBadRequestResponse()
2323
}
2424

25-
info := s.getApprovalInfo(pr, &req.SelectedProjects, false)
25+
info := s.getApprovalInfo(pr, &req.SelectedProjects, false, false)
2626
if len(info.Projects) == 0 {
2727
exception.ThrowExceptionBadRequestResponse()
2828
}

backend/infra/service/approval/internal_approval.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (s *ApprovalService) CreateInternalApproval(pr *project.Project, req approv
3030
exception.ThrowExceptionBadRequestResponse()
3131
}
3232

33-
info := s.getApprovalInfo(pr, nil, false)
33+
info := s.getApprovalInfo(pr, nil, false, false)
3434
if len(info.Projects) == 0 {
3535
exception.ThrowExceptionBadRequestResponse()
3636
}

backend/infra/service/approval/plausibility_check.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
)
2828

2929
func (s *ApprovalService) CreatePlausibilityCheck(pr *project.Project, req approval.RequestPlausibilityCheckDto, creator string) string {
30-
info := s.getApprovalInfo(pr, nil, true)
30+
info := s.getApprovalInfo(pr, nil, true, false)
3131
appr := approval.Approval{
3232
ChildEntity: domain.SetChildEntity(uuid.New().String()),
3333
Type: approval.TypePlausibility,

0 commit comments

Comments
 (0)