Skip to content

Commit

Permalink
fix(server): add licenses to the Result message (aquasecurity#4955)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin committed Aug 8, 2023
1 parent e8cf281 commit 798ef1b
Show file tree
Hide file tree
Showing 7 changed files with 577 additions and 142 deletions.
75 changes: 64 additions & 11 deletions pkg/rpc/convert.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package rpc

import (
"strings"
"time"

"github.com/golang/protobuf/ptypes"
"github.com/samber/lo"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/golang/protobuf/ptypes/timestamp"
"google.golang.org/protobuf/types/known/structpb"

dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
Expand Down Expand Up @@ -161,7 +161,7 @@ func ConvertToRPCVulns(vulns []types.DetectedVulnerability) []*common.Vulnerabil
vensorSeverityMap[string(vendor)] = common.Severity(vendorSeverity)
}

var lastModifiedDate, publishedDate *timestamp.Timestamp
var lastModifiedDate, publishedDate *timestamppb.Timestamp
if vuln.LastModifiedDate != nil {
lastModifiedDate = timestamppb.New(*vuln.LastModifiedDate) // nolint: errcheck
}
Expand Down Expand Up @@ -295,11 +295,36 @@ func ConvertFromRPCResults(rpcResults []*scanner.Result) []types.Result {
Packages: ConvertFromRPCPkgs(result.Packages),
CustomResources: ConvertFromRPCCustomResources(result.CustomResources),
Secrets: ConvertFromRPCSecretFindings(result.Secrets),
Licenses: ConvertFromRPCLicenses(result.Licenses),
})
}
return results
}

func ConvertFromRPCLicenses(rpcLicenses []*common.DetectedLicense) []types.DetectedLicense {
var licenses []types.DetectedLicense
for _, l := range rpcLicenses {
severity := dbTypes.Severity(l.Severity)
licenses = append(licenses, types.DetectedLicense{
Severity: severity.String(),
Category: ConvertFromRPCLicenseCategory(l.Category),
PkgName: l.PkgName,
FilePath: l.FilePath,
Name: l.Name,
Confidence: float64(l.Confidence),
Link: l.Link,
})
}
return licenses
}

func ConvertFromRPCLicenseCategory(rpcCategory common.DetectedLicense_LicenseCategory) ftypes.LicenseCategory {
if rpcCategory == common.DetectedLicense_UNSPECIFIED {
return ""
}
return ftypes.LicenseCategory(strings.ToLower(rpcCategory.String()))
}

// ConvertFromRPCCustomResources converts array of cache.CustomResource to fanal.CustomResource
func ConvertFromRPCCustomResources(rpcCustomResources []*common.CustomResource) []ftypes.CustomResource {
var resources []ftypes.CustomResource
Expand Down Expand Up @@ -390,12 +415,10 @@ func ConvertFromRPCVulns(rpcVulns []*common.Vulnerability) []types.DetectedVulne

var lastModifiedDate, publishedDate *time.Time
if vuln.LastModifiedDate != nil {
t, _ := ptypes.Timestamp(vuln.LastModifiedDate) // nolint: errcheck
lastModifiedDate = &t
lastModifiedDate = lo.ToPtr(vuln.LastModifiedDate.AsTime())
}
if vuln.PublishedDate != nil {
t, _ := ptypes.Timestamp(vuln.PublishedDate) // nolint: errcheck
publishedDate = &t
publishedDate = lo.ToPtr(vuln.PublishedDate.AsTime())
}

vulns = append(vulns, types.DetectedVulnerability{
Expand Down Expand Up @@ -591,11 +614,10 @@ func ConvertFromRPCMisconfResults(rpcResults []*common.MisconfResult) []ftypes.M

// ConvertFromRPCPutArtifactRequest converts cache.PutArtifactRequest to fanal.PutArtifactRequest
func ConvertFromRPCPutArtifactRequest(req *cache.PutArtifactRequest) ftypes.ArtifactInfo {
created, _ := ptypes.Timestamp(req.ArtifactInfo.Created) // nolint: errcheck
return ftypes.ArtifactInfo{
SchemaVersion: int(req.ArtifactInfo.SchemaVersion),
Architecture: req.ArtifactInfo.Architecture,
Created: created,
Created: req.ArtifactInfo.Created.AsTime(),
DockerVersion: req.ArtifactInfo.DockerVersion,
OS: req.ArtifactInfo.Os,
HistoryPackages: ConvertFromRPCPkgs(req.ArtifactInfo.HistoryPackages),
Expand Down Expand Up @@ -643,8 +665,9 @@ func ConvertToRPCRepository(repo *ftypes.Repository) *common.Repository {

// ConvertToRPCArtifactInfo returns PutArtifactRequest
func ConvertToRPCArtifactInfo(imageID string, imageInfo ftypes.ArtifactInfo) *cache.PutArtifactRequest {
t, err := ptypes.TimestampProto(imageInfo.Created)
if err != nil {

t := timestamppb.New(imageInfo.Created)
if err := t.CheckValid(); err != nil {
log.Logger.Warnf("invalid timestamp: %s", err)
}

Expand Down Expand Up @@ -765,6 +788,7 @@ func ConvertToRPCScanResponse(results types.Results, fos ftypes.OS) *scanner.Sca
Packages: ConvertToRPCPkgs(result.Packages),
CustomResources: ConvertToRPCCustomResources(result.CustomResources),
Secrets: ConvertToRPCSecretFindings(result.Secrets),
Licenses: ConvertToRPCLicenses(result.Licenses),
})
}

Expand All @@ -774,6 +798,35 @@ func ConvertToRPCScanResponse(results types.Results, fos ftypes.OS) *scanner.Sca
}
}

func ConvertToRPCLicenses(licenses []types.DetectedLicense) []*common.DetectedLicense {
var rpcLicenses []*common.DetectedLicense
for _, l := range licenses {
severity, err := dbTypes.NewSeverity(l.Severity)
if err != nil {
log.Logger.Warn(err)
}
rpcLicenses = append(rpcLicenses, &common.DetectedLicense{
Severity: common.Severity(severity),
Category: ConvertToRPCLicenseCategory(l.Category),
PkgName: l.PkgName,
FilePath: l.FilePath,
Name: l.Name,
Confidence: float32(l.Confidence),
Link: l.Link,
})
}

return rpcLicenses
}

func ConvertToRPCLicenseCategory(category ftypes.LicenseCategory) common.DetectedLicense_LicenseCategory {
rpcCategory, ok := common.DetectedLicense_LicenseCategory_value[strings.ToUpper(string(category))]
if !ok {
return common.DetectedLicense_UNSPECIFIED
}
return common.DetectedLicense_LicenseCategory(rpcCategory)
}

func ConvertToDeleteBlobsRequest(blobIDs []string) *cache.DeleteBlobsRequest {
return &cache.DeleteBlobsRequest{BlobIds: blobIDs}
}
Expand Down
144 changes: 144 additions & 0 deletions pkg/rpc/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,3 +669,147 @@ func TestConvertToRPCMiconfs(t *testing.T) {
})
}
}

func TestConvertFromRPCLicenses(t *testing.T) {
tests := []struct {
name string
rpcLicenses []*common.DetectedLicense
want []types.DetectedLicense
}{
{
name: "happy",
rpcLicenses: []*common.DetectedLicense{
{
Severity: common.Severity_HIGH,
Category: common.DetectedLicense_RESTRICTED,
PkgName: "alpine-baselayout",
FilePath: "some-path",
Name: "GPL-2.0",
Confidence: 1,
Link: "https://some-link",
},
},
want: []types.DetectedLicense{
{
Severity: "HIGH",
Category: "restricted",
PkgName: "alpine-baselayout",
FilePath: "some-path",
Name: "GPL-2.0",
Confidence: 1,
Link: "https://some-link",
},
},
},
{
name: "no licenses",
rpcLicenses: nil,
want: nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ConvertFromRPCLicenses(tt.rpcLicenses)
assert.Equal(t, tt.want, got)
})
}
}

func TestConvertToRPCLicenses(t *testing.T) {
tests := []struct {
name string
licenses []types.DetectedLicense
want []*common.DetectedLicense
}{
{
name: "happy",
licenses: []types.DetectedLicense{
{
Severity: "HIGH",
Category: "restricted",
PkgName: "alpine-baselayout",
FilePath: "some-path",
Name: "GPL-2.0",
Confidence: 1,
Link: "https://some-link",
},
},
want: []*common.DetectedLicense{
{
Severity: common.Severity_HIGH,
Category: common.DetectedLicense_RESTRICTED,
PkgName: "alpine-baselayout",
FilePath: "some-path",
Name: "GPL-2.0",
Confidence: 1,
Link: "https://some-link",
},
},
},
{
name: "no licenses",
licenses: nil,
want: nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ConvertToRPCLicenses(tt.licenses)
assert.Equal(t, tt.want, got)
})
}
}

func TestConvertToRPCLicenseCategory(t *testing.T) {
tests := []struct {
name string
category ftypes.LicenseCategory
want common.DetectedLicense_LicenseCategory
}{
{
name: "happy",
category: ftypes.CategoryNotice,
want: common.DetectedLicense_NOTICE,
},
{
name: "unspecified",
category: "",
want: common.DetectedLicense_UNSPECIFIED,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ConvertToRPCLicenseCategory(tt.category)
assert.Equal(t, tt.want, got)
})
}
}

func TestConvertFromRPCLicenseCategory(t *testing.T) {
tests := []struct {
name string
rpcCategory common.DetectedLicense_LicenseCategory
want ftypes.LicenseCategory
}{
{
name: "happy",
rpcCategory: common.DetectedLicense_RESTRICTED,
want: ftypes.CategoryRestricted,
},
{
name: "unspecified",
rpcCategory: common.DetectedLicense_UNSPECIFIED,
want: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ConvertFromRPCLicenseCategory(tt.rpcCategory)
assert.Equal(t, tt.want, got)
})
}
}
Loading

0 comments on commit 798ef1b

Please sign in to comment.