Skip to content
Merged
Show file tree
Hide file tree
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
54 changes: 54 additions & 0 deletions cmd/format/bomsw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package format

import (
"encoding/json"
"io"

"github.com/xmirrorsecurity/opensca-cli/v3/cmd/detail"
"github.com/xmirrorsecurity/opensca-cli/v3/opensca/model"
)

func BomSWJson(report Report, out string) {
outWrite(out, func(w io.Writer) error {
doc := bomSWDoc(report)
encoder := json.NewEncoder(w)
encoder.SetIndent("", " ")
return encoder.Encode(doc)
})
}

func bomSWDoc(report Report) *model.BomSWDocument {

doc := model.NewBomSWDocument(report.TaskInfo.AppName, "opensca-cli")

report.DepDetailGraph.ForEach(func(n *detail.DepDetailGraph) bool {

if n.Name == "" {
return true
}

lics := []string{}
for _, lic := range n.Licenses {
lics = append(lics, lic.ShortName)
}
doc.AppendComponents(func(swc *model.BomSWComponent) {
swc.ID = n.Purl()
swc.Name = n.Name
swc.Version = n.Version
swc.License = lics
})

children := []string{}
for _, c := range n.Children {
if c.Name == "" {
continue
}
children = append(children, c.Purl())
}
doc.AppendDependencies(n.Purl(), children)

return true
})

return doc
}
117 changes: 0 additions & 117 deletions cmd/format/dpsbom.go

This file was deleted.

14 changes: 4 additions & 10 deletions cmd/format/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ func Save(report Report, output string) {
switch filepath.Ext(out) {
case ".html":
Html(genReport(report), out)
case ".zip":
if strings.HasSuffix(out, ".dpsbom.zip") {
DpSbomZip(report, out)
} else {
Json(genReport(report), out)
}
case ".json":
if strings.HasSuffix(out, ".spdx.json") {
SpdxJson(report, out)
Expand All @@ -54,13 +48,13 @@ func Save(report Report, output string) {
CycloneDXJson(report, out)
} else if strings.HasSuffix(out, ".swid.json") {
SwidJson(report, out)
} else if strings.HasSuffix(out, ".dpsbom.json") {
DpSbomZip(report, out)
} else if strings.HasSuffix(out, ".bomsw.json") {
BomSWJson(report, out)
} else {
Json(genReport(report), out)
}
case ".dpsbom":
DpSbomZip(report, out)
case ".sw", ".bom-sw", ".bomsw":
BomSWJson(report, out)
case ".dsdx":
Dsdx(report, out)
case ".spdx":
Expand Down
125 changes: 125 additions & 0 deletions opensca/model/bomsw.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package model

import (
"time"
)

type BomSWDocument struct {
Basic swBasicInfo `json:"documentBasicInfo"`
Software swSoftwareCompositionInfo `json:"softwareCompositionInfo"`
}

type swBasicInfo struct {
// 文档名称
DocumentName string `json:"documentName"`
// 文档版本
DocumentVersion string `json:"documentVersion"`
// 文档创建/更新时间 yyyy-MM-ddTHH:mm:ssTZD
DocumentTime string `json:"timestamp"`
// 文档格式
SbomFormat string `json:"sbomFormat"`
// 生成工具
ToolInfo string `json:"toolInfo"`
// bom作者
SbomAuthor string `json:"sbomAuthor"`
// 文档作者注释
SbomAuthorComments string `json:"sbomAuthorComments"`
// 文档注释
SbomComments string `json:"sbomComments"`
// 文档类型
SbomType string `json:"sbomType"`
}

type swSoftwareCompositionInfo struct {
// 组件列表
Components []BomSWComponent `json:"components"`
// 依赖关系
Dependencies []swDependencies `json:"dependencies"`
}

type BomSWComponent struct {
Author map[string]string `json:"componentAuthor"`
Provider map[string]string `json:"componentProvider"`
Name string `json:"componentName"`
Version string `json:"componentVersion"`
// map[hash算法]hash值
HashValue []swChecksumValue `json:"componentHashValue"`
ID string `json:"componentId"`
License []string `json:"license"`
// 组件信息更新时间 yyyy-MM-ddTHH:mm:ssTZD
Timestamp string `json:"componentTimestamp"`
}

type swChecksumValue struct {
Algorithm string `json:"algorithm"`
Value string `json:"hashValue"`
}

type swDependencies struct {
Ref string `json:"ref"`
DependsOn []struct {
Ref string `json:"ref"`
} `json:"dependsOn"`
}

func newDependencies(ref string, dependsOn []string) swDependencies {
deps := swDependencies{Ref: ref}
deps.DependsOn = make([]struct {
Ref string `json:"ref"`
}, len(dependsOn))
for i, d := range dependsOn {
deps.DependsOn[i].Ref = d
}
return deps
}

func NewBomSWDocument(name, creator string) *BomSWDocument {
version := "1.0.0"
timestamp := time.Now().Format("2006-01-02T15:04:05MST")
return &BomSWDocument{
Basic: swBasicInfo{
DocumentName: name,
DocumentVersion: version,
DocumentTime: timestamp,
SbomFormat: "BOM-SW 1.0",
ToolInfo: creator,
SbomAuthor: "",
SbomAuthorComments: "",
SbomComments: "",
SbomType: "analyzed",
},
Software: swSoftwareCompositionInfo{
Dependencies: []swDependencies{},
},
}
}

func (doc *BomSWDocument) AppendComponents(fn func(*BomSWComponent)) {
c := BomSWComponent{
Author: map[string]string{
"name": "NONE",
},
Provider: map[string]string{
"shortName": "NONE",
"fullName": "NONE",
},
HashValue: []swChecksumValue{},
License: []string{},
}
if fn != nil {
fn(&c)
}
if c.Timestamp == "" {
c.Timestamp = time.Now().Format("2006-01-02T15:04:05MST")
}
doc.Software.Components = append(doc.Software.Components, c)
}

func (doc *BomSWDocument) AppendDependencies(parentId string, childrenIds []string) {
if doc.Software.Dependencies == nil {
doc.Software.Dependencies = []swDependencies{}
}
if len(childrenIds) > 0 {
doc.Software.Dependencies = append(doc.Software.Dependencies, newDependencies(parentId, childrenIds))
}
}
Loading
Loading