Skip to content

Commit

Permalink
add more fsct features
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 13, 2024
1 parent 31a5505 commit 1db2012
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 27 deletions.
179 changes: 152 additions & 27 deletions pkg/compliance/fsct/fsct.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ package fsct

import (
"context"
"strings"
"time"

"github.com/interlynk-io/sbomqs/pkg/compliance"
"github.com/interlynk-io/sbomqs/pkg/compliance/common"
"github.com/interlynk-io/sbomqs/pkg/compliance/db"
"github.com/interlynk-io/sbomqs/pkg/logger"
"github.com/interlynk-io/sbomqs/pkg/sbom"
"github.com/samber/lo"
)

func fsctResult(ctx context.Context, doc sbom.Document, fileName string, outFormat string) {

Check failure on line 30 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctResult` is unused (unused)
Expand All @@ -38,11 +41,25 @@ func fsctResult(ctx context.Context, doc sbom.Document, fileName string, outForm

// component Level
dtb.AddRecords(fsctComponents(doc))

var pp FsctReport
// Generate BSI report
if outFormat == "json" {
common.JSONReport(dtb, fileName, pp)
}
}

func fsctSbomPrimaryComponent(doc sbom.Document) *db.Record {
// result, score, maturity := "", 0.0, ""
return nil
func fsctSbomPrimaryComponent(_ sbom.Document) *db.Record {

Check failure on line 52 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctSbomPrimaryComponent` is unused (unused)
result, score, maturity := "", 0.0, "None"

// // waiting for NTIA to get merged
// primary := doc.GetPrimaryComp.IsPresent()

// if primary {
// score = 10.0
// maturity = "Minimum"
// }
return db.NewRecordStmt(compliance.SBOM_PRIMARY_COMPONENT, "doc", result, score, maturity)
}

func fsctSbomType(doc sbom.Document) *db.Record {

Check failure on line 65 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctSbomType` is unused (unused)
Expand All @@ -58,8 +75,7 @@ func fsctSbomType(doc sbom.Document) *db.Record {
maturity = "None"
}

// result, score, maturity := "", 0.0, ""
return db.NewRecordStmt(compliance.SBOM_TYPE, "SPDX Elements", result, score, maturity)
return db.NewRecordStmt(compliance.SBOM_TYPE, "doc", result, score, maturity)
}

func fsctSbomTimestamp(doc sbom.Document) *db.Record {

Check failure on line 81 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctSbomTimestamp` is unused (unused)
Expand All @@ -71,7 +87,7 @@ func fsctSbomTimestamp(doc sbom.Document) *db.Record {
_, err := time.Parse(time.RFC3339, result)
if err != nil {
score = 0.0
maturity = "NONE"
maturity = "None"
} else {
score = 10.0
maturity = "Minimum"
Expand All @@ -80,7 +96,7 @@ func fsctSbomTimestamp(doc sbom.Document) *db.Record {
score = 0.0
maturity = "NONE"
}
return db.NewRecordStmt(compliance.SBOM_TIMESTAMP, "SPDX Elements", result, score, maturity)
return db.NewRecordStmt(compliance.SBOM_TIMESTAMP, "doc", result, score, maturity)
}

func fsctSbomAuthor(doc sbom.Document) *db.Record {

Check failure on line 102 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctSbomAuthor` is unused (unused)
Expand Down Expand Up @@ -181,47 +197,40 @@ func fsctComponents(doc sbom.Document) []*db.Record {
records = append(records, fsctPackageVersion(component))
records = append(records, fsctPackageSupplier(component))
records = append(records, fsctPackageUniqIDs(component))
// records = append(records, fsctPackageHash(component))
// records = append(records, fsctPackageDependencies(component))
// records = append(records, fsctPackageLicense(component))
// records = append(records, fsctPackageCopyright(component))
records = append(records, fsctPackageHash(component))
records = append(records, fsctPackageDependencies(component))
records = append(records, fsctPackageLicense(component))
records = append(records, fsctPackageCopyright(component))
}
return records
}

func fsctPackageName(component sbom.GetComponent) *db.Record {

Check failure on line 208 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctPackageName` is unused (unused)
result := component.GetName()
score, maturity := 0.0, ""
score, maturity := 0.0, "None"

if result != "" {
score = 10.0
maturity = "MINIMUM"
} else {
score = 0.0
maturity = "NONE"
maturity = "Minimum"
}

return db.NewRecordStmt(compliance.COMP_NAME, component.GetName(), result, score, maturity)
}

func fsctPackageVersion(component sbom.GetComponent) *db.Record {

Check failure on line 220 in pkg/compliance/fsct/fsct.go

View workflow job for this annotation

GitHub Actions / lint

func `fsctPackageVersion` is unused (unused)
result := component.GetVersion()
score, maturity := 0.0, ""
score, maturity := 0.0, "None"

if result != "" {
score = 10.0
maturity = "MINIMUM"
} else {
score = 0.0
maturity = "NONE"
maturity = "Minimum"
}

return db.NewRecordStmt(compliance.COMP_NAME, component.GetName(), result, score, maturity)
}

func fsctPackageSupplier(component sbom.GetComponent) *db.Record {
result := ""
score, maturity := 0.0, ""
result, score, maturity := "", 0.0, ""
supplierPresent := false

supplier := component.Suppliers()
Expand Down Expand Up @@ -265,12 +274,14 @@ func fsctPackageSupplier(component sbom.GetComponent) *db.Record {
}
}

if supplierPresent {
// Determine maturity level using switch
switch {
case supplierPresent:
score = 10.0
maturity = "MINIMUM"
} else {
maturity = "Minimum"
default:
score = 0.0
maturity = "NONE"
maturity = "None"
}

return db.NewRecordStmt(compliance.COMP_NAME, component.GetName(), result, score, maturity)
Expand All @@ -295,6 +306,30 @@ func fsctPackageUniqIDs(component sbom.GetComponent) *db.Record {
}
}

if !uniqIDPresent {
omni := component.OmniborIDs()
if len(omni) > 0 {
result = string(omni[0])
uniqIDPresent = true
}
}

if !uniqIDPresent {
swhids := component.Swhids()
if len(swhids) > 0 {
result = string(swhids[0])
uniqIDPresent = true
}
}

if !uniqIDPresent {
swids := component.Swids()
if len(swids) > 0 {
result = string(swids[0].GetTagID()) + ", " + string(swids[0].GetName())
uniqIDPresent = true
}
}

if uniqIDPresent {
score = 10.0
maturity = "Minimum"
Expand All @@ -305,3 +340,93 @@ func fsctPackageUniqIDs(component sbom.GetComponent) *db.Record {

return db.NewRecordStmt(compliance.COMP_OTHER_UNIQ_IDS, component.GetName(), result, score, maturity)
}

func fsctPackageHash(component sbom.GetComponent) *db.Record {
result, score, maturity := "", 0.0, "None"
algos := []string{"SHA256", "SHA-256", "sha256", "sha-256", "SHA1", "SHA-1", "sha1", "sha-1", "MD5", "md5"}
recommendedAlgos := []string{"SHA-512"}

checksums := component.GetChecksums()

for _, checksum := range checksums {
algo := checksum.GetAlgo()
if lo.Contains(algos, algo) {
result = checksum.GetContent()
score = 10.0
maturity = "Minimum"

if component.IsPrimaryComponent() && lo.Contains(recommendedAlgos, algo) {
result = checksum.GetContent()
score = 12.0
maturity = "Recommended"
break
}
break
}
}

return db.NewRecordStmt(compliance.COMP_HASH, component.GetName(), result, score, maturity)
}

func fsctPackageDependencies(_ sbom.GetComponent) *db.Record {
// result, score, maturity := "no-relationships", 0.0, "None"

// var results []string

// dependencies := doc.GetRelationships(component.GetID())
return nil
}

func fsctPackageLicense(component sbom.GetComponent) *db.Record {
result, score, maturity := "", 0.0, "None"

licenses := component.Licenses()
if len(licenses) == 0 {
return db.NewRecordStmt(compliance.COMP_LICENSE, component.GetName(), result, score, maturity)
}

hasFullName, hasIdentifier, hasText, hasURL, hasSpdx := false, false, false, false, false

for _, license := range licenses {
if license.Name() != "" {
hasFullName = true
}
if license.ShortID() != "" {
hasIdentifier = true
}
if license.Source() != "" {
hasText = true
}
if license.Source() == "spdx" {
hasSpdx = true
}
// Assuming URL is part of the license source or text
if strings.HasPrefix(license.Source(), "http") {
hasURL = true
}
}
switch {
case hasFullName && hasIdentifier && hasText && hasURL && hasSpdx:
score = 15.0
maturity = "Aspirational"
case hasFullName && hasIdentifier && (hasText || hasURL):
score = 12.0
maturity = "Recommended"
default:
score = 10
maturity = "Minimum"

}
return db.NewRecordStmt(compliance.COMP_LICENSE, component.GetName(), result, score, maturity)
}

func fsctPackageCopyright(component sbom.GetComponent) *db.Record {
result, score, maturity := "", 0.0, "None"

if result = component.GetCopyRight(); result != "" && result != "NOASSERTION" && result != "NONE" {
score = 10.0
maturity = "Minimum"
}

return db.NewRecordStmt(compliance.PACK_COPYRIGHT, component.GetName(), result, score, maturity)
}
48 changes: 48 additions & 0 deletions pkg/compliance/fsct/fsct_report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2024 Interlynk.io
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fsct

type FsctReport struct{}

func (o FsctReport) GetName() string {
return "NTIA #rd Edition"
}

func (o FsctReport) GetSubtitle() string {
return "Framing Third Edition Of Compliance Checks"
}

func (o FsctReport) GetRevision() string {
return "3rd"
}

// func (o FsctReportGenerator) GetSectionDetails() common.SectionDetails {
// return common.SectionDetails{
// // Define the section details specific to OCT report
// }
// }

// func (o FsctReportGenerator) AggregateScore(dtb *db.DB) common.Summary {
// // Implement the logic to calculate the aggregate score for OCT report
// return common.Summary{}
// }

// func (b FsctReportGenerator) GetSectionDetails() compliance.SectionDetails {
// return compliance.SectionDetails{
// SBOM_SPEC: {Title: "SBOM formats", ID: "4", Required: true, DataField: "specification"},
// }
// }

// var SBOM_SPEC int

0 comments on commit 1db2012

Please sign in to comment.