Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple policy in on block event #857

Merged
merged 7 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
36 changes: 35 additions & 1 deletion utils/coreutils/tableutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var DefaultMaxColWidth = 25
// In case the struct you want to print contains a field that is a slice of other structs,
// you can print it in the table too with the 'embed-table' tag which can be set on slices of structs only.
// Fields with the 'extended' tag will be printed iff the 'printExtended' bool input is true.
// You can merge cells horizontally with the 'auto-merge' tag, it will merge cells with the same value.
//
// Example:
// These are the structs Customer and Product:
Expand Down Expand Up @@ -91,6 +92,38 @@ var DefaultMaxColWidth = 25
// ┌─────────────────────────┐
// │ No customers were found │
// └─────────────────────────┘
//
// Example(auto-merge):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Example(auto-merge): --> // Example (auto-merge):

// These are the structs Customer:
//
// type Customer struct {
// name string `col-name:"Name" auto-merge:"true"`
// age string `col-name:"Age" auto-merge:"true"`
// title string `col-name:"Product Title" auto-merge:"true"`
// CatNumber string `col-name:"Product\nCatalog #" auto-merge:"true"`
// Color string `col-name:"Color" extended:"true" auto-merge:"true"`
// }
//
// customersSlice := []Customer{
asafambar marked this conversation as resolved.
Show resolved Hide resolved
// {name: "Gai", age: "350", title: "SpiderFrog Shirt - Medium", CatNumber: "123456", Color: "Green"},
// {name: "Gai", age: "350", title: "Floral Bottle", CatNumber: "147585", Color: "Blue"},
// {name: "Noah", age: "21", title: "Pouch", CatNumber: "456789", Color: "Red"},
// }
//
// Customers
// ┌──────┬─────┬───────────────────────────┬───────────┐
// │ NAME │ AGE │ PRODUCT TITLE │ PRODUCT │
// │ │ │ │ CATALOG # │
// ├──────┼─────┼───────────────────────────┼───────────┤
// │ Gai │ 350 │ SpiderFrog Shirt - Medium │ 123456 │
// │ │ ├───────────────────────────┼───────────┤
// │ │ │ Floral Bottle │ 147585 │
// ├──────┼─────┼───────────────────────────┼───────────┤
// │ Noah │ 21 │ Pouch │ 456789 │
// └──────┴─────┴───────────────────────────┴───────────┘
//
//
asafambar marked this conversation as resolved.
Show resolved Hide resolved

func PrintTable(rows interface{}, title string, emptyTableMessage string, printExtended bool) (err error) {
tableWriter, err := PrepareTable(rows, emptyTableMessage, printExtended)
if err != nil || tableWriter == nil {
Expand Down Expand Up @@ -140,6 +173,7 @@ func PrepareTable(rows interface{}, emptyTableMessage string, printExtended bool
columnName, columnNameExist := field.Tag.Lookup("col-name")
embedTable, embedTableExist := field.Tag.Lookup("embed-table")
extended, extendedExist := field.Tag.Lookup("extended")
_, autoMerge := field.Tag.Lookup("auto-merge")
_, omitEmptyColumn := field.Tag.Lookup("omitempty")
if !printExtended && extendedExist && extended == "true" {
continue
Expand All @@ -161,7 +195,7 @@ func PrepareTable(rows interface{}, emptyTableMessage string, printExtended bool
} else {
columnsNames = append(columnsNames, columnName)
fieldsProperties = append(fieldsProperties, fieldProperties{index: i})
columnConfigs = append(columnConfigs, table.ColumnConfig{Name: columnName})
columnConfigs = append(columnConfigs, table.ColumnConfig{Name: columnName, AutoMerge: autoMerge})
}
}
tableWriter.AppendHeader(columnsNames)
Expand Down
76 changes: 46 additions & 30 deletions xray/commands/curation/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,23 @@ type PackageStatus struct {
}

type Policy struct {
asafambar marked this conversation as resolved.
Show resolved Hide resolved
Policy string `json:"policy"`
Condition string `json:"condition"`
Policy string `json:"policy"`
Condition string `json:"condition"`
Explanation string `json:"explanation"`
Recommendation string `json:"recommendation"`
}

type PackageStatusTable struct {
Status string `col-name:"Action"`
ParentName string `col-name:"Direct Dependency\nPackage Name"`
ParentVersion string `col-name:"Direct Dependency\nPackage Version"`
BlockedPackageUrl string `col-name:"Blocked Package URL"`
PackageName string `col-name:"Blocked Package\nName"`
PackageVersion string `col-name:"Blocked Package\nVersion"`
BlockingReason string `col-name:"Blocking Reason"`
PkgType string `col-name:"Package Type"`
Policy []policyTable `embed-table:"true"`
}

type policyTable struct {
Policy string `col-name:"Violated Policy\nName"`
Condition string `col-name:"Violated Condition\nName"`
ParentName string `col-name:"Direct\nDependency\nPackage\nName" auto-merge:"true"`
ParentVersion string `col-name:"Direct\nDependency\nPackage\nVersion" auto-merge:"true"`
PackageName string `col-name:"Blocked\nPackage\nName" auto-merge:"true"`
PackageVersion string `col-name:"Blocked\nPackage\nVersion" auto-merge:"true"`
BlockingReason string `col-name:"Blocking Reason" auto-merge:"true"`
PkgType string `col-name:"Package\nType" auto-merge:"true"`
Policy string `col-name:"Violated\nPolicy\nName"`
Condition string `col-name:"Violated Condition\nName"`
Explanation string `col-name:"Explanation Name"`
Recommendation string `col-name:"Recommendation Name"`
}

type treeAnalyzer struct {
Expand Down Expand Up @@ -279,24 +277,34 @@ func printResult(format utils.OutputFormat, projectPath string, packagesStatus [

func convertToPackageStatusTable(packagesStatus []*PackageStatus) []PackageStatusTable {
var pkgStatusTable []PackageStatusTable
for _, pkgStatus := range packagesStatus {
for index, pkgStatus := range packagesStatus {
// We use auto-merge supported by the 'go-pretty' library. It doesn't have an option to merge lines by a group of unique fields.
// In order to so, we make each group merge only with itself by adding or not adding space. This way, it won't be merged with the next group.
uniqLineSep := ""
if index%2 == 0 {
uniqLineSep = " "
}
pkgTable := PackageStatusTable{
Status: pkgStatus.Action,
ParentName: pkgStatus.ParentName,
ParentVersion: pkgStatus.ParentVersion,
BlockedPackageUrl: pkgStatus.BlockedPackageUrl,
PackageName: pkgStatus.PackageName,
PackageVersion: pkgStatus.PackageVersion,
BlockingReason: pkgStatus.BlockingReason,
PkgType: pkgStatus.PkgType,
ParentName: pkgStatus.ParentName + uniqLineSep,
ParentVersion: pkgStatus.ParentVersion + uniqLineSep,
PackageName: pkgStatus.PackageName + uniqLineSep,
PackageVersion: pkgStatus.PackageVersion + uniqLineSep,
BlockingReason: pkgStatus.BlockingReason + uniqLineSep,
PkgType: pkgStatus.PkgType + uniqLineSep,
}
if len(pkgStatus.Policy) == 0 {
pkgStatusTable = append(pkgStatusTable, pkgTable)
continue
}
var policiesCondTable []policyTable
for _, policyCond := range pkgStatus.Policy {
policiesCondTable = append(policiesCondTable, policyTable(policyCond))
pkgTable.Policy = policyCond.Policy
pkgTable.Explanation = policyCond.Explanation
pkgTable.Recommendation = policyCond.Recommendation
pkgTable.Condition = policyCond.Condition
pkgStatusTable = append(pkgStatusTable, pkgTable)
}
pkgTable.Policy = policiesCondTable
pkgStatusTable = append(pkgStatusTable, pkgTable)
}

return pkgStatusTable
}

Expand Down Expand Up @@ -450,7 +458,7 @@ func (nc *treeAnalyzer) getBlockedPackageDetails(packageUrl string, name string,
}

// Return policies and conditions names from the FORBIDDEN HTTP error message.
// Message structure: Package %s:%s download was blocked by JFrog Packages Curation service due to the following policies violated {%s, %s},{%s, %s}.
// Message structure: Package %s:%s download was blocked by JFrog Packages Curation service due to the following policies violated {%s, %s, %s, %s},{%s, %s, %s, %s}.
func (nc *treeAnalyzer) extractPoliciesFromMsg(respError *ErrorsResp) []Policy {
var policies []Policy
msg := respError.Errors[0].Message
Expand All @@ -463,6 +471,14 @@ func (nc *treeAnalyzer) extractPoliciesFromMsg(respError *ErrorsResp) []Policy {
cond := polCond[1]
policies = append(policies, Policy{Policy: strings.TrimSpace(pol), Condition: strings.TrimSpace(cond)})
}
if len(polCond) == 4 {
pol := polCond[0]
cond := polCond[1]
asafambar marked this conversation as resolved.
Show resolved Hide resolved
exp := strings.ReplaceAll(strings.Replace(polCond[2], ": ", ":\n", 1), " | ", "\n")
rec := strings.ReplaceAll(strings.Replace(polCond[3], ": ", ":\n", 1), " | ", "\n")
asafambar marked this conversation as resolved.
Show resolved Hide resolved
policies = append(policies, Policy{Policy: strings.TrimSpace(pol),
Condition: strings.TrimSpace(cond), Explanation: strings.TrimSpace(exp), Recommendation: strings.TrimSpace(rec)})
}
}
return policies
}
Expand Down
8 changes: 5 additions & 3 deletions xray/commands/curation/audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,16 @@ func getTestCasesForExtractPoliciesFromMsg() []struct {
Errors: []ErrorResp{
{
Status: 403,
Message: "Package test:1.0.0 download was blocked by JFrog Packages Curation service due to the following policies violated {policy1, condition1}.",
Message: "Package test:1.0.0 download was blocked by JFrog Packages Curation service due to the following policies violated {policy1, condition1, Package is 3339 days old, Upgrade to version 0.2.4 (latest)}.",
},
},
},
expect: []Policy{
{
Policy: "policy1",
Condition: "condition1",
Policy: "policy1",
Condition: "condition1",
Explanation: "Package is 3339 days old",
Recommendation: "Upgrade to version 0.2.4 (latest)",
},
},
},
Expand Down
Loading