From 450055f33ec6e9c876b731f8fe79866984787b7a Mon Sep 17 00:00:00 2001 From: Chen Noylander Date: Thu, 16 May 2024 10:53:48 +0300 Subject: [PATCH] Added new HTML template for email integrations --- cfg.yaml | 2 + rego-templates/vuls-email.rego | 391 +++++++++++++++++++++++++++++++++ router/api_test.go | 2 +- 3 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 rego-templates/vuls-email.rego diff --git a/cfg.yaml b/cfg.yaml index bc026cd1..e6313d50 100644 --- a/cfg.yaml +++ b/cfg.yaml @@ -36,6 +36,8 @@ templates: rego-package: postee.vuls.slack # Slack template REGO package (available out of the box) - name: vuls-html # Out of the box HTML template rego-package: postee.vuls.html # HTML template REGO package (available out of the box) +- name: vuls-email # Out of the box HTML template for email + rego-package: postee.vuls.email # HTML template REGO package (available out of the box) - name: raw-html # Raw message json rego-package: postee.rawmessage.html # HTML template REGO package (available out of the box) - name: legacy # Out of the box legacy Golang template diff --git a/rego-templates/vuls-email.rego b/rego-templates/vuls-email.rego new file mode 100644 index 00000000..2bfe7feb --- /dev/null +++ b/rego-templates/vuls-email.rego @@ -0,0 +1,391 @@ +package postee.vuls.email + +import data.postee.by_flag +import data.postee.with_default +import future.keywords.if + + +#import common.by_flag +################################################ Templates ################################################ +#main template to render message +tpl := ` + + + + + %s + Aqua security - Scan report + + +
+ +
+
+
+
+ %s name: + %s +
+
+ Malware found: + %s +
+
+
+
+ Registry: + %s +
+
+ Sensitive data found: + %s +
+
+
+
+ %s +
+
+
+
+
+
Vulnerabilities summary
+
+
%d
+
%d
+
%d
+
%d
+
%d
+
+
+
+
Assurance controls
+ + + + + + + + %s + + + + + + + + + + + + +
#ControlPolicy NameStatus
1MalwareMalware-Default-PolicyPASS
2Sensitive_dataSensitive-Data-Default-PolicyFAIL
+
+
+
+
+
+ Response policy name: + %s +
+
+
+
+ Response policy application scopes: + %s +
+
+
+
+ See more +
+ + + +` + +cell_tpl:=`%s` + +row_tpl:=` + +%s +` + +style:=` + +` + +########################################################################################################### + +############################################## Html rendering ############################################# + +render_table_content(content_array) = s { + rows := [tr | + cells:=content_array[_] + tds:= [td | + ctext:=cells[_] + td := sprintf(cell_tpl, [ctext]) + ] + tr=sprintf(row_tpl, [concat("", tds)]) + ] + + s:= concat("", rows) +} + +####################################### Template specific functions ####################################### + +# TODO refactor to support different properties +check_failed(item) = false { +not item.failed #Either absent or false +} +check_failed(item) = true { + item.failed +} + +# 2 dimension array for assurance controls +assurance_controls := [ control | + item := input.image_assurance_results.checks_performed[i] + control := [format_int(i+1, 10), item.control,item.policy_name, + by_flag( + "FAIL", + "PASS", + check_failed(item) + ) + ] +] + +########################################################################################################### + +report_type := "Function" if{ + input.entity_type == 1 +} else = "VM" if{ + input.entity_type == 2 +} else = "Image" + +title = sprintf(`Aqua security | %s | %s | Scan report`, [report_type, input.image]) + +aggregation_pkg := "postee.vuls.html.aggregation" + +urls := regex.find_n(`^([^:/?#]+:\/\/)?([^/?#]+)`, with_default(input, "url", ""), 1) +base_url := urls[0] { + count(urls) > 0 +} else = "" + +result = msg { + msg := sprintf(tpl, [ + style, + base_url, + report_type, + input.image, + by_flag( # Malware found + "Yes", + "No", + with_default(input.vulnerability_summary, "malware", 0) > 0 #reflects current logic + ), + input.registry, + by_flag( # Sensitive data found + "Yes", + "No", + with_default(input.vulnerability_summary, "sensitive", 0) > 0 #reflects current logic + ), + by_flag( + sprintf("%s is non-compliant", [report_type]), + sprintf("%s is compliant", [report_type]), + with_default(input.image_assurance_results, "disallowed", false) + ), + with_default(input.vulnerability_summary, "critical", 0), + with_default(input.vulnerability_summary, "high", 0), + with_default(input.vulnerability_summary, "medium", 0), + with_default(input.vulnerability_summary, "low", 0), + with_default(input.vulnerability_summary, "negligible", 0), + render_table_content(assurance_controls), + input.response_policy_name, + concat(", ", with_default(input, "application_scope", [])), + with_default(input, "url", ""), + ]) +} diff --git a/router/api_test.go b/router/api_test.go index 975c99ed..28550a44 100644 --- a/router/api_test.go +++ b/router/api_test.go @@ -390,7 +390,7 @@ func TestEditTemplate(t *testing.T) { err := UpdateTemplate(templ) if err != nil { - t.Errorf("unexpected errpr: %v", err) + t.Errorf("unexpected error: %v", err) } assert.Equal(t, 1, syncMapLen(&Instance().templates), "one template expected")