From c1ee4dff9ef74eaa2ffef2e2594441d002059fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=A4fer?= Date: Wed, 25 Sep 2024 14:59:51 +0200 Subject: [PATCH 1/5] give the chapters some space so other chapters can be inserted inbetween --- pkg/report/adocReport.go | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/pkg/report/adocReport.go b/pkg/report/adocReport.go index 92000aff..a53acda6 100644 --- a/pkg/report/adocReport.go +++ b/pkg/report/adocReport.go @@ -330,7 +330,7 @@ func (adoc *adocReport) initReport() error { if err != nil { return err } - adoc.mainFile, err = os.Create(filepath.Join(adoc.targetDirectory, "00_main.adoc")) + adoc.mainFile, err = os.Create(filepath.Join(adoc.targetDirectory, "000_main.adoc")) if err != nil { return err } @@ -360,7 +360,7 @@ func (adoc adocReport) writeTitleAndPreamble() { } func (adoc adocReport) writeManagementSummery() error { - filename := "01_ManagementSummary.adoc" + filename := "010_ManagementSummary.adoc" ms, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = ms.Close() }() if err != nil { @@ -596,7 +596,7 @@ func (adoc adocReport) impactAnalysis(f *os.File, initialRisks bool) { } func (adoc adocReport) writeImpactInitialRisks() error { - filename := "02_ImpactIntialRisks.adoc" + filename := "020_ImpactIntialRisks.adoc" ir, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = ir.Close() }() if err != nil { @@ -758,7 +758,7 @@ pie showData } func (adoc adocReport) writeRiskMitigationStatus() error { - filename := "03_RiskMitigationStatus.adoc" + filename := "030_RiskMitigationStatus.adoc" rms, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = rms.Close() }() if err != nil { @@ -772,7 +772,7 @@ func (adoc adocReport) writeRiskMitigationStatus() error { } func (adoc adocReport) writeImpactRemainingRisks() error { - filename := "04_ImpactRemainingRisks.adoc" + filename := "040_ImpactRemainingRisks.adoc" irr, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = irr.Close() }() if err != nil { @@ -829,7 +829,7 @@ func (adoc adocReport) targetDescription(f *os.File, baseFolder string) { } func (adoc adocReport) writeTargetDescription(baseFolder string) error { - filename := "05_TargetDescription.adoc" + filename := "050_TargetDescription.adoc" td, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = td.Close() }() if err != nil { @@ -869,7 +869,7 @@ func imageIsWiderThanHigh(diagramFilenamePNG string) bool { } func (adoc adocReport) writeDataFlowDiagram(diagramFilenamePNG string) error { - filename := "06_DataFlowDiagram.adoc" + filename := "060_DataFlowDiagram.adoc" dfd, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = dfd.Close() }() if err != nil { @@ -911,7 +911,7 @@ func (adoc adocReport) securityRequirements(f *os.File) { } func (adoc adocReport) writeSecurityRequirements() error { - filename := "07_SecurityRequirements.adoc" + filename := "070_SecurityRequirements.adoc" sr, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = sr.Close() }() if err != nil { @@ -939,7 +939,7 @@ func (adoc adocReport) abuseCases(f *os.File) { } func (adoc adocReport) writeAbuseCases() error { - filename := "08_AbuseCases.adoc" + filename := "080_AbuseCases.adoc" ac, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = ac.Close() }() if err != nil { @@ -1009,7 +1009,7 @@ func (adoc adocReport) tagListing(f *os.File) { } func (adoc adocReport) writeTagListing() error { - filename := "09_TagListing.adoc" + filename := "090_TagListing.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1078,7 +1078,7 @@ func (adoc adocReport) stride(f *os.File) { } func (adoc adocReport) writeSTRIDE() error { - filename := "10_STRIDE.adoc" + filename := "100_STRIDE.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1139,7 +1139,7 @@ func (adoc adocReport) assignmentByFunction(f *os.File) { } func (adoc adocReport) writeAssignmentByFunction() error { - filename := "11_AssignmentByFunction.adoc" + filename := "110_AssignmentByFunction.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1194,7 +1194,7 @@ func (adoc adocReport) raa(f *os.File, introTextRAA string) { } func (adoc adocReport) writeRAA(introTextRAA string) error { - filename := "12_RAA.adoc" + filename := "120_RAA.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1220,7 +1220,7 @@ refer to the PNG image file alongside this report.`) } func (adoc adocReport) writeDataRiskMapping(dataAssetDiagramFilenamePNG string) error { - filename := "13_DataRiskMapping.adoc" + filename := "130_DataRiskMapping.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1276,7 +1276,7 @@ Each one should be checked in the model whether it should better be included in } func (adoc adocReport) writeOutOfScopeAssets() error { - filename := "14_OutOfScopeAssets.adoc" + filename := "140_OutOfScopeAssets.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1326,7 +1326,7 @@ in the model against the architecture design:{fn-risk-findings}`) } func (adoc adocReport) writeModelFailures() error { - filename := "15_ModelFailures.adoc" + filename := "150_ModelFailures.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1375,7 +1375,7 @@ func (adoc adocReport) questions(f *os.File) { } func (adoc adocReport) writeQuestions() error { - filename := "16_Questions.adoc" + filename := "160_Questions.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1573,7 +1573,7 @@ func (adoc adocReport) riskCategories(f *os.File) { } func (adoc adocReport) writeRiskCategories() error { - filename := "17_RiskCategories.adoc" + filename := "170_RiskCategories.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1813,7 +1813,7 @@ func (adoc adocReport) technicalAssets(f *os.File) { } func (adoc adocReport) writeTechnicalAssets() error { - filename := "18_TechnicalAssets.adoc" + filename := "180_TechnicalAssets.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1918,7 +1918,7 @@ func (adoc adocReport) dataAssets(f *os.File) { } func (adoc adocReport) writeDataAssets() error { - filename := "19_DataAssets.adoc" + filename := "190_DataAssets.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -1971,7 +1971,7 @@ func (adoc adocReport) trustBoundaries(f *os.File) { } func (adoc adocReport) writeTrustBoundaries() error { - filename := "20_TrustBoundaries.adoc" + filename := "200_TrustBoundaries.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -2013,7 +2013,7 @@ func (adoc adocReport) sharedRuntimes(f *os.File) { } func (adoc adocReport) writeSharedRuntimes() error { - filename := "21_SharedRuntimes.adoc" + filename := "210_SharedRuntimes.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -2110,7 +2110,7 @@ func (adoc adocReport) riskRulesChecked(f *os.File, modelFilename string, skipRi } func (adoc adocReport) writeRiskRulesChecked(modelFilename string, skipRiskRules []string, buildTimestamp string, threagileVersion string, modelHash string, customRiskRules types.RiskRules) error { - filename := "22_RiskRulesChecked.adoc" + filename := "220_RiskRulesChecked.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { @@ -2172,7 +2172,7 @@ func (adoc adocReport) disclaimer(f *os.File) { } func (adoc adocReport) writeDisclaimer() error { - filename := "23_Disclaimer.adoc" + filename := "230_Disclaimer.adoc" f, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) defer func() { _ = f.Close() }() if err != nil { From 81cb9a4c25a46ebd35073a3d90128e5732f980cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=A4fer?= Date: Wed, 25 Sep 2024 15:17:50 +0200 Subject: [PATCH 2/5] enable build of pdf report now both the pdf and the adoc files are build if you run: `task create-example-project` --- Taskfile.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index b58adaa2..4c89c303 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -62,10 +62,10 @@ tasks: --ignore-orphaned-risk-tracking --app-dir . --generate-report-adoc - --generate-report-pdf=0 + --generate-report-pdf=1 --verbose --config ${CONFIG} - # --background ./report/template/background.pdf + --background ./report/template/background.pdf golangci-lint: desc: run golangci-lint on current code From 826be60dbb65ed1ea78b614657431d2646f2beac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=A4fer?= Date: Wed, 25 Sep 2024 15:18:15 +0200 Subject: [PATCH 3/5] add Asset register to showchapter configuration --- pkg/report/report-configuration.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/report/report-configuration.go b/pkg/report/report-configuration.go index 6f445c7d..e6b3c3ff 100644 --- a/pkg/report/report-configuration.go +++ b/pkg/report/report-configuration.go @@ -4,6 +4,7 @@ type ChaptersToShowHide string const ( RiskRulesCheckedByThreagile ChaptersToShowHide = "RiskRulesCheckedByThreagile" + AssetRegister ChaptersToShowHide = "AssetRegister" ) type ReportConfiguation struct { From 876e47eebbb4d47574f07b37e37a9a74a9ad0ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=A4fer?= Date: Wed, 25 Sep 2024 15:00:34 +0200 Subject: [PATCH 4/5] add asset register to adoc report --- pkg/report/adocReport.go | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/pkg/report/adocReport.go b/pkg/report/adocReport.go index a53acda6..9b1f0052 100644 --- a/pkg/report/adocReport.go +++ b/pkg/report/adocReport.go @@ -239,6 +239,12 @@ func (adoc adocReport) WriteReport(model *types.Model, if err != nil { return fmt.Errorf("error creating risk mitigation status: %w", err) } + if val := hideChapters[AssetRegister]; !val { + err = adoc.writeAssetRegister() + if err != nil { + return fmt.Errorf("error creating asset register status: %w", err) + } + } err = adoc.writeImpactRemainingRisks() if err != nil { return fmt.Errorf("error creating impact remaining risks: %w", err) @@ -771,6 +777,47 @@ func (adoc adocReport) writeRiskMitigationStatus() error { return nil } +func (adoc adocReport) assetRegister(f *os.File) { + writeLine(f, "= Asset Register") + writeLine(f, "") + + writeLine(f, "== Technical Assets") + writeLine(f, "") + for _, technicalAsset := range sortedTechnicalAssetsByTitle(adoc.model) { + + fullLine := "<<" + technicalAsset.Id + ",*" + technicalAsset.Title + "*" + if technicalAsset.OutOfScope { + fullLine += ": out-of-scope" + } + writeLine(f, fullLine+">>::") + writeLine(f, " "+technicalAsset.Description) + writeLine(f, "") + } + + writeLine(f, "== Data Assets") + writeLine(f, "") + + for _, dataAsset := range sortedDataAssetsByTitle(adoc.model) { + writeLine(f, "<<"+dataAsset.Id+",*"+dataAsset.Title+"*"+">>::") + writeLine(f, " "+dataAsset.Description) + writeLine(f, "") + } +} + +func (adoc adocReport) writeAssetRegister() error { + filename := "035_AssetRegister.adoc" + ar, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) + defer func() { _ = ar.Close() }() + if err != nil { + return err + } + adoc.writeMainLine("<<<") + adoc.writeMainLine("include::" + filename + "[leveloffset=+1]") + + adoc.assetRegister(ar) + return nil +} + func (adoc adocReport) writeImpactRemainingRisks() error { filename := "040_ImpactRemainingRisks.adoc" irr, err := os.Create(filepath.Join(adoc.targetDirectory, filename)) From 983b8b44410f0a0a9b5bfeb691cff2d0b3fadd59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sch=C3=A4fer?= Date: Wed, 25 Sep 2024 15:19:02 +0200 Subject: [PATCH 5/5] add asset register to direct pdf report --- pkg/report/report.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/pkg/report/report.go b/pkg/report/report.go index 8608e6be..f6824617 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -87,6 +87,9 @@ func (r *pdfReporter) WriteReportPDF(reportFilename string, if err != nil { return fmt.Errorf("error creating risk mitigation status: %w", err) } + if val := hideChapters[AssetRegister]; !val { + r.createAssetRegister(model) + } r.createImpactRemainingRisks(model) err = r.createTargetDescription(model, filepath.Dir(modelFilename)) if err != nil { @@ -252,6 +255,12 @@ func (r *pdfReporter) createTableOfContents(parsedModel *types.Model) { r.pdf.Line(15.6, y+1.3, 11+171.5, y+1.3) r.pdf.Link(10, y-5, 172.5, 6.5, r.pdf.AddLink()) + y += 6 + r.pdf.Text(11, y, " "+"Asset Register") + r.pdf.Text(175, y, "{asset-register}") + r.pdf.Line(15.6, y+1.3, 11+171.5, y+1.3) + r.pdf.Link(10, y-5, 172.5, 6.5, r.pdf.AddLink()) + y += 6 risksStr = "Risks" catStr = "Categories" @@ -1293,6 +1302,82 @@ func (r *pdfReporter) createRiskMitigationStatus(parsedModel *types.Model, tempF return nil } +func (r *pdfReporter) createAssetRegister(parsedModel *types.Model) { + uni := r.pdf.UnicodeTranslatorFromDescriptor("") + r.pdf.SetTextColor(0, 0, 0) + chapTitle := "Asset Register" + r.addHeadline(chapTitle, false) + r.defineLinkTarget("{asset-register}") + r.currentChapterTitleBreadcrumb = chapTitle + + html := r.pdf.HTMLBasicNew() + var strBuilder strings.Builder + r.pdf.SetFont("Helvetica", "", fontSizeBody) + + subTitle := "Technical Assets" + r.addHeadline(subTitle, true) + r.currentChapterTitleBreadcrumb = subTitle + for _, technicalAsset := range sortedTechnicalAssetsByTitle(parsedModel) { + if r.pdf.GetY() > 250 { + r.pageBreak() + r.pdf.SetY(36) + } else { + strBuilder.WriteString("

") + } + + r.pdf.SetTextColor(0, 0, 0) + + html.Write(5, strBuilder.String()) + strBuilder.Reset() + posY := r.pdf.GetY() + strBuilder.WriteString("") + strBuilder.WriteString(uni(technicalAsset.Title)) + strBuilder.WriteString("") + if technicalAsset.OutOfScope { + strBuilder.WriteString(": out-of-scope") + } + strBuilder.WriteString("
") + html.Write(5, strBuilder.String()) + strBuilder.Reset() + strBuilder.WriteString(uni(technicalAsset.Description)) + html.Write(5, strBuilder.String()) + strBuilder.Reset() + r.pdf.Link(9, posY, 190, r.pdf.GetY()-posY+4, r.tocLinkIdByAssetId[technicalAsset.Id]) + } + + subTitle = "Data Assets" + r.addHeadline(subTitle, true) + r.currentChapterTitleBreadcrumb = subTitle + + for _, dataAsset := range sortedDataAssetsByTitle(parsedModel) { + if r.pdf.GetY() > 250 { + r.pageBreak() + r.pdf.SetY(36) + } else { + strBuilder.WriteString("

") + } + + r.pdf.SetTextColor(0, 0, 0) + + html.Write(5, strBuilder.String()) + strBuilder.Reset() + posY := r.pdf.GetY() + strBuilder.WriteString("") + strBuilder.WriteString(uni(dataAsset.Title)) + strBuilder.WriteString("") + strBuilder.WriteString("
") + html.Write(5, strBuilder.String()) + strBuilder.Reset() + strBuilder.WriteString(uni(dataAsset.Description)) + html.Write(5, strBuilder.String()) + strBuilder.Reset() + r.pdf.Link(9, posY, 190, r.pdf.GetY()-posY+4, r.tocLinkIdByAssetId[dataAsset.Id]) + } + + r.pdf.SetDrawColor(0, 0, 0) + r.pdf.SetDashPattern([]float64{}, 0) +} + // CAUTION: Long labels might cause endless loop, then remove labels and render them manually later inside the PDF func (r *pdfReporter) embedStackedBarChart(sbcChart chart.StackedBarChart, x float64, y float64, tempFolder string) error { tmpFilePNG, err := os.CreateTemp(tempFolder, "chart-*-.png")