Skip to content

Commit

Permalink
make dependencies persistence across all compliance
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Kumar Sahu <[email protected]>
  • Loading branch information
viveksahu26 committed Sep 30, 2024
1 parent ad35777 commit 2556e37
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 151 deletions.
114 changes: 85 additions & 29 deletions pkg/compliance/bsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"strings"

"github.com/interlynk-io/sbomqs/pkg/compliance/common"
db "github.com/interlynk-io/sbomqs/pkg/compliance/db"
"github.com/interlynk-io/sbomqs/pkg/logger"
"github.com/interlynk-io/sbomqs/pkg/sbom"
Expand Down Expand Up @@ -307,24 +308,37 @@ func bsiSbomURI(doc sbom.Document) *db.Record {
return db.NewRecordStmt(SBOM_URI, "doc", "", 0, "")
}

var (
bsiCompIDWithName = make(map[string]string)
bsiComponentList = make(map[string]bool)
bsiPrimaryDependencies = make(map[string]bool)
bsiGetAllPrimaryDepenciesByName = []string{}
)

func bsiComponents(doc sbom.Document) []*db.Record {
records := []*db.Record{}

if len(doc.Components()) == 0 {
records := append(records, db.NewRecordStmt(SBOM_COMPONENTS, "doc", "", 0.0, ""))
return records
}
// map package ID to Package Name
for _, component := range doc.Components() {
CompIDWithName[component.GetID()] = component.GetName()

bsiCompIDWithName = common.ComponentsNamesMapToIDs(doc)
bsiComponentList = common.ComponentsLists(doc)
bsiPrimaryDependencies = common.MapPrimaryDependencies(doc)
dependencies := common.GetAllPrimaryComponentDependencies(doc)
isBsiAllDepesPresentInCompList := common.CheckPrimaryDependenciesInComponentList(dependencies, bsiComponentList)

if isBsiAllDepesPresentInCompList {
bsiGetAllPrimaryDepenciesByName = common.GetDependenciesByName(dependencies, bsiCompIDWithName)
}

for _, component := range doc.Components() {
records = append(records, bsiComponentCreator(component))
records = append(records, bsiComponentName(component))
records = append(records, bsiComponentVersion(component))
records = append(records, bsiComponentLicense(component))
records = append(records, bsiComponentDepth(component))
records = append(records, bsiComponentDepth(doc, component))
records = append(records, bsiComponentHash(component))
records = append(records, bsiComponentSourceCodeURL(component))
records = append(records, bsiComponentDownloadURL(component))
Expand All @@ -337,20 +351,62 @@ func bsiComponents(doc sbom.Document) []*db.Record {
return records
}

func bsiComponentDepth(component sbom.GetComponent) *db.Record {
if !component.HasRelationShips() {
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "no-relationships", 0.0, "")
}
func bsiComponentDepth(doc sbom.Document, component sbom.GetComponent) *db.Record {
result, score := "", SCORE_ZERO
var dependencies []string
var allDepByName []string

if component.RelationShipState() == "complete" {
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "complete", 10.0, "")
}
if doc.Spec().GetSpecType() == "spdx" {
if component.GetPrimaryCompInfo().IsPresent() {
result = strings.Join(bsiGetAllPrimaryDepenciesByName, ", ")
score = 10.0
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, score, "")
}

if component.HasRelationShips() {
return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "unattested-has-relationships", 5.0, "")
dependencies = doc.GetRelationships(component.GetID())
if dependencies == nil {
if bsiPrimaryDependencies[common.GetID(component.GetSpdxID())] {
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "included-in", 10.0, "")
}
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "no-relationship", 0.0, "")
} else {
allDepByName = common.GetDependenciesByName(dependencies, bsiCompIDWithName)
if bsiPrimaryDependencies[common.GetID(component.GetSpdxID())] {
allDepByName = append([]string{"included-in"}, allDepByName...)
result = strings.Join(allDepByName, ", ")
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, 10.0, "")
} else {
result = strings.Join(allDepByName, ", ")
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, 10.0, "")
}
}
} else if doc.Spec().GetSpecType() == "cyclonedx" {
if component.GetPrimaryCompInfo().IsPresent() {
result = strings.Join(bsiGetAllPrimaryDepenciesByName, ", ")
score = 10.0
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, score, "")
}
id := component.GetID()
dependencies = doc.GetRelationships(id)
if len(dependencies) == 0 {
if bsiPrimaryDependencies[id] {
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "included-in", 10.0, "")
}
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "no-relationship", 0.0, "")
} else {
allDepByName = common.GetDependenciesByName(dependencies, bsiCompIDWithName)
if bsiPrimaryDependencies[id] {
allDepByName = append([]string{"included-in"}, allDepByName...)
result = strings.Join(allDepByName, ", ")
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, 10.0, "")
} else {
result = strings.Join(allDepByName, ", ")
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), result, 10.0, "")
}
}
}

return db.NewRecordStmt(COMP_DEPTH, component.GetID(), "non-compliant", 0.0, "")
return db.NewRecordStmt(COMP_DEPTH, component.GetName(), "no-relationships", 0.0, "")
}

func bsiComponentLicense(component sbom.GetComponent) *db.Record {
Expand All @@ -359,7 +415,7 @@ func bsiComponentLicense(component sbom.GetComponent) *db.Record {

if len(licenses) == 0 {
// fmt.Printf("component %s : %s has no licenses\n", component.Name(), component.Version())
return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "not-compliant", score, "")
return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "not-compliant", score, "")
}

var spdx, aboutcode, custom int
Expand Down Expand Up @@ -387,10 +443,10 @@ func bsiComponentLicense(component sbom.GetComponent) *db.Record {

if total != len(licenses) {
score = 0.0
return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "not-compliant", score, "")
return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "not-compliant", score, "")
}

return db.NewRecordStmt(COMP_LICENSE, component.GetID(), "compliant", 10.0, "")
return db.NewRecordStmt(COMP_LICENSE, component.GetName(), "compliant", 10.0, "")
}

func bsiComponentSourceHash(component sbom.GetComponent) *db.Record {
Expand Down Expand Up @@ -464,27 +520,27 @@ func bsiComponentHash(component sbom.GetComponent) *db.Record {
}
}

return db.NewRecordStmt(COMP_HASH, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_HASH, component.GetName(), result, score, "")
}

func bsiComponentVersion(component sbom.GetComponent) *db.Record {
result := component.GetVersion()

if result != "" {
return db.NewRecordStmt(COMP_VERSION, component.GetID(), result, 10.0, "")
return db.NewRecordStmt(COMP_VERSION, component.GetName(), result, 10.0, "")
}

return db.NewRecordStmt(COMP_VERSION, component.GetID(), "", 0.0, "")
return db.NewRecordStmt(COMP_VERSION, component.GetName(), "", 0.0, "")
}

func bsiComponentName(component sbom.GetComponent) *db.Record {
result := component.GetName()

if result != "" {
return db.NewRecordStmt(COMP_NAME, component.GetID(), result, 10.0, "")
return db.NewRecordStmt(COMP_NAME, component.GetName(), result, 10.0, "")
}

return db.NewRecordStmt(COMP_NAME, component.GetID(), "", 0.0, "")
return db.NewRecordStmt(COMP_NAME, component.GetName(), "", 0.0, "")
}

func bsiComponentCreator(component sbom.GetComponent) *db.Record {
Expand All @@ -499,7 +555,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}

if supplier.GetURL() != "" {
Expand All @@ -508,7 +564,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}

if supplier.GetContacts() != nil {
Expand All @@ -521,7 +577,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}
}
}
Expand All @@ -535,7 +591,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}

if manufacturer.GetURL() != "" {
Expand All @@ -544,7 +600,7 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}

if manufacturer.GetContacts() != nil {
Expand All @@ -557,10 +613,10 @@ func bsiComponentCreator(component sbom.GetComponent) *db.Record {
}

if result != "" {
return db.NewRecordStmt(COMP_CREATOR, component.GetID(), result, score, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), result, score, "")
}
}
}

return db.NewRecordStmt(COMP_CREATOR, component.GetID(), "", 0.0, "")
return db.NewRecordStmt(COMP_CREATOR, component.GetName(), "", 0.0, "")
}
96 changes: 96 additions & 0 deletions pkg/compliance/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,99 @@ func ConvertMapToString(m map[string]string) string {
func CheckCopyright(cp string) (string, bool) {
return cp, cp != "NOASSERTION" && cp != "NONE"
}

func GetPrimaryDependencies(component sbom.GetComponent) {
}

// ComponentsLists return component lists as a map
func ComponentsLists(doc sbom.Document) map[string]bool {
componentList := make(map[string]bool)
for _, component := range doc.Components() {
if doc.Spec().GetSpecType() == "spdx" {
id := "SPDXRef-" + component.GetSpdxID()
componentList[id] = true

} else if doc.Spec().GetSpecType() == "cyclonedx" {
componentList[component.GetID()] = true
}
}
return componentList
}

// ComponentsNamesMapToIDs returns map of component ID as key and component Name as value
func ComponentsNamesMapToIDs(doc sbom.Document) map[string]string {
compIDWithName := make(map[string]string)
for _, component := range doc.Components() {
if doc.Spec().GetSpecType() == "spdx" {
id := "SPDXRef-" + component.GetSpdxID()
compIDWithName[id] = component.GetName()

} else if doc.Spec().GetSpecType() == "cyclonedx" {
compIDWithName[component.GetID()] = component.GetName()
}
}
return compIDWithName
}

// GetAllPrimaryComponentDependencies return all list of primary component dependencies by it's ID.
func GetAllPrimaryComponentDependencies(doc sbom.Document) []string {
var dependencies []string
for _, component := range doc.Components() {
if doc.Spec().GetSpecType() == "spdx" {
if component.GetPrimaryCompInfo().IsPresent() {
id := "SPDXRef-" + component.GetSpdxID()
dependencies = doc.GetRelationships(id)
}
} else if doc.Spec().GetSpecType() == "cyclonedx" {
if component.GetPrimaryCompInfo().IsPresent() {
dependencies = doc.GetRelationships(component.GetID())
}
}
}
return dependencies
}

// MapPrimaryDependencies returns a map of all primary dependencies with bool.
// Primary dependencies marked as true else false.
func MapPrimaryDependencies(doc sbom.Document) map[string]bool {
primaryDependencies := make(map[string]bool)
for _, component := range doc.Components() {
if doc.Spec().GetSpecType() == "spdx" {
id := "SPDXRef-" + component.GetSpdxID()
if component.GetPrimaryCompInfo().IsPresent() {
dependencies := doc.GetRelationships(id)
for _, d := range dependencies {
primaryDependencies[d] = true
}
}
} else if doc.Spec().GetSpecType() == "cyclonedx" {
if component.GetPrimaryCompInfo().IsPresent() {
dependencies := doc.GetRelationships(component.GetID())
for _, d := range dependencies {
primaryDependencies[d] = true
}
}
}
}
return primaryDependencies
}

// CheckPrimaryDependenciesInComponentList checks if all primary dependencies are part of the component list.
func CheckPrimaryDependenciesInComponentList(dependencies []string, componentList map[string]bool) bool {
return lo.EveryBy(dependencies, func(id string) bool {
return componentList[id]
})
}

// GetDependenciesByName returns the names of all dependencies based on their IDs.
func GetDependenciesByName(dependencies []string, compIDWithName map[string]string) []string {
var allDepByName []string
for _, dep := range dependencies {
allDepByName = append(allDepByName, compIDWithName[dep])
}
return allDepByName
}

func GetID(componentID string) string {
return "SPDXRef-" + componentID
}
Loading

0 comments on commit 2556e37

Please sign in to comment.