Skip to content

Commit

Permalink
Decouple types objects from parsed model
Browse files Browse the repository at this point in the history
  • Loading branch information
Yevhen Zavhorodnii committed Jun 9, 2024
1 parent b7492b2 commit 38635e4
Show file tree
Hide file tree
Showing 41 changed files with 586 additions and 634 deletions.
6 changes: 3 additions & 3 deletions pkg/model/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,17 +373,17 @@ func ParseModel(config technologyMapConfigReader, modelInput *input.Model, built

// If CIA is lower than that of its data assets, it is implicitly set to the highest CIA value of its data assets
for id, techAsset := range parsedModel.TechnicalAssets {
dataAssetConfidentiality := techAsset.HighestConfidentiality(&parsedModel)
dataAssetConfidentiality := parsedModel.HighestTechnicalAssetConfidentiality(techAsset)
if techAsset.Confidentiality < dataAssetConfidentiality {
techAsset.Confidentiality = dataAssetConfidentiality
}

dataAssetIntegrity := techAsset.HighestIntegrity(&parsedModel)
dataAssetIntegrity := parsedModel.HighestIntegrity(techAsset)
if techAsset.Integrity < dataAssetIntegrity {
techAsset.Integrity = dataAssetIntegrity
}

dataAssetAvailability := techAsset.HighestAvailability(&parsedModel)
dataAssetAvailability := parsedModel.HighestAvailability(techAsset)
if techAsset.Availability < dataAssetAvailability {
techAsset.Availability = dataAssetAvailability
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/model/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ func applyRiskGeneration(parsedModel *types.Model, rules types.RiskRules,
}

// save also in map keyed by synthetic risk-id
for _, category := range types.SortedRiskCategories(parsedModel) {
someRisks := types.SortedRisksOfCategory(parsedModel, category)
for _, category := range parsedModel.SortedRiskCategories() {
someRisks := parsedModel.SortedRisksOfCategory(category)
for _, risk := range someRisks {
parsedModel.GeneratedRisksBySyntheticId[strings.ToLower(risk.SyntheticId)] = risk
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/report/excel.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ func WriteRisksExcelToFile(parsedModel *types.Model, filename string, config rep

// get sorted risks
riskItems := make([]RiskItem, 0)
for _, category := range types.SortedRiskCategories(parsedModel) {
risks := types.SortedRisksOfCategory(parsedModel, category)
for _, category := range parsedModel.SortedRiskCategories() {
risks := parsedModel.SortedRisksOfCategory(category)
for _, risk := range risks {
techAsset := parsedModel.TechnicalAssets[risk.MostRelevantTechnicalAssetId]
techAssetTitle := ""
Expand Down
10 changes: 5 additions & 5 deletions pkg/report/graphviz.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ func makeDiagramSameRankNodeTweaks(parsedModel *types.Model) (string, error) {
if err != nil {
return "", fmt.Errorf("error while checking technical asset existence: %s", err)
}
if len(parsedModel.TechnicalAssets[id].GetTrustBoundaryId(parsedModel)) > 0 {
if len(parsedModel.GetTechnicalAssetTrustBoundaryId(parsedModel.TechnicalAssets[id])) > 0 {
return "", fmt.Errorf("technical assets (referenced in same rank diagram tweak) are inside trust boundaries: " +
fmt.Sprintf("%v", parsedModel.DiagramTweakSameRankAssets))
}
Expand Down Expand Up @@ -586,8 +586,8 @@ func WriteDataAssetDiagramGraphvizDOT(parsedModel *types.Model, diagramFilenameD

func sortByDataAssetDataBreachProbabilityAndTitle(parsedModel *types.Model, assets []*types.DataAsset) {
sort.Slice(assets, func(i, j int) bool {
highestDataBreachProbabilityLeft := assets[i].IdentifiedDataBreachProbability(parsedModel)
highestDataBreachProbabilityRight := assets[j].IdentifiedDataBreachProbability(parsedModel)
highestDataBreachProbabilityLeft := parsedModel.IdentifiedDataBreachProbability(assets[i])
highestDataBreachProbabilityRight := parsedModel.IdentifiedDataBreachProbability(assets[j])
if highestDataBreachProbabilityLeft == highestDataBreachProbabilityRight {
return assets[i].Title < assets[j].Title
}
Expand Down Expand Up @@ -617,8 +617,8 @@ func makeTechAssetNode(parsedModel *types.Model, technicalAsset *types.Technical
if simplified {
color := rgbHexColorOutOfScope()
if !technicalAsset.OutOfScope {
generatedRisks := technicalAsset.GeneratedRisks(parsedModel)
switch types.HighestSeverityStillAtRisk(parsedModel, generatedRisks) {
generatedRisks := parsedModel.GeneratedRisks(technicalAsset)
switch types.HighestSeverityStillAtRisk(generatedRisks) {
case types.CriticalSeverity:
color = rgbHexColorCriticalRisk()
case types.HighSeverity:
Expand Down
11 changes: 8 additions & 3 deletions pkg/report/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func WriteRisksJSON(parsedModel *types.Model, filename string) error {
jsonBytes, err := json.Marshal(types.AllRisks(parsedModel))
jsonBytes, err := json.Marshal(parsedModel.AllRisks())
if err != nil {
return fmt.Errorf("failed to marshal risks to JSON: %w", err)
}
Expand Down Expand Up @@ -46,8 +46,8 @@ func WriteStatsJSON(parsedModel *types.Model, filename string) error {
return nil
}

func overallRiskStatistics(parsedModel *types.Model) types.RiskStatistics {
result := types.RiskStatistics{}
func overallRiskStatistics(parsedModel *types.Model) riskStatistics {
result := riskStatistics{}
result.Risks = make(map[string]map[string]int)
result.Risks[types.CriticalSeverity.String()] = make(map[string]int)
result.Risks[types.CriticalSeverity.String()][types.Unchecked.String()] = 0
Expand Down Expand Up @@ -91,3 +91,8 @@ func overallRiskStatistics(parsedModel *types.Model) types.RiskStatistics {
}
return result
}

type riskStatistics struct {
// TODO add also some more like before / after (i.e. with mitigation applied)
Risks map[string]map[string]int `yaml:"risks" json:"risks"`
}
68 changes: 34 additions & 34 deletions pkg/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,9 @@ func (r *pdfReporter) createTableOfContents(parsedModel *types.Model) {
r.pdf.Text(175, y, "{intro-risks-by-vulnerability-category}")
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())
for _, category := range types.SortedRiskCategories(parsedModel) {
newRisksStr := types.SortedRisksOfCategory(parsedModel, category)
switch types.HighestSeverityStillAtRisk(parsedModel, newRisksStr) {
for _, category := range parsedModel.SortedRiskCategories() {
newRisksStr := parsedModel.SortedRisksOfCategory(category)
switch types.HighestSeverityStillAtRisk(newRisksStr) {
case types.CriticalSeverity:
colorCriticalRisk(r.pdf)
case types.HighSeverity:
Expand Down Expand Up @@ -448,7 +448,7 @@ 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())
for _, technicalAsset := range sortedTechnicalAssetsByRiskSeverityAndTitle(parsedModel) {
newRisksStr := technicalAsset.GeneratedRisks(parsedModel)
newRisksStr := parsedModel.GeneratedRisks(technicalAsset)
y += 6
if y > 275 {
r.pageBreakInLists()
Expand All @@ -463,7 +463,7 @@ func (r *pdfReporter) createTableOfContents(parsedModel *types.Model) {
r.pdfColorOutOfScope()
suffix = "out-of-scope"
} else {
switch types.HighestSeverityStillAtRisk(parsedModel, newRisksStr) {
switch types.HighestSeverityStillAtRisk(newRisksStr) {
case types.CriticalSeverity:
colorCriticalRisk(r.pdf)
case types.HighSeverity:
Expand Down Expand Up @@ -513,7 +513,7 @@ func (r *pdfReporter) createTableOfContents(parsedModel *types.Model) {
r.pageBreakInLists()
y = 40
}
newRisksStr := dataAsset.IdentifiedDataBreachProbabilityRisks(parsedModel)
newRisksStr := parsedModel.IdentifiedDataBreachProbabilityRisks(dataAsset)
countStillAtRisk := len(types.ReduceToOnlyStillAtRisk(newRisksStr))
suffix := strconv.Itoa(countStillAtRisk) + " / " + strconv.Itoa(len(newRisksStr)) + " Risk"
if len(newRisksStr) != 1 {
Expand Down Expand Up @@ -673,10 +673,10 @@ func sortedTechnicalAssetsByRiskSeverityAndTitle(parsedModel *types.Model) []*ty

func sortByTechnicalAssetRiskSeverityAndTitleStillAtRisk(assets []*types.TechnicalAsset, parsedModel *types.Model) {
sort.Slice(assets, func(i, j int) bool {
risksLeft := types.ReduceToOnlyStillAtRisk(assets[i].GeneratedRisks(parsedModel))
risksRight := types.ReduceToOnlyStillAtRisk(assets[j].GeneratedRisks(parsedModel))
highestSeverityLeft := types.HighestSeverityStillAtRisk(parsedModel, risksLeft)
highestSeverityRight := types.HighestSeverityStillAtRisk(parsedModel, risksRight)
risksLeft := types.ReduceToOnlyStillAtRisk(parsedModel.GeneratedRisks(assets[i]))
risksRight := types.ReduceToOnlyStillAtRisk(parsedModel.GeneratedRisks(assets[j]))
highestSeverityLeft := types.HighestSeverityStillAtRisk(risksLeft)
highestSeverityRight := types.HighestSeverityStillAtRisk(risksRight)
var result bool
if highestSeverityLeft == highestSeverityRight {
if len(risksLeft) == 0 && len(risksRight) > 0 {
Expand Down Expand Up @@ -1315,7 +1315,7 @@ func filteredByRiskFunction(parsedModel *types.Model, function types.RiskFunctio
filteredRisks := make([]*types.Risk, 0)
for categoryId, risks := range parsedModel.GeneratedRisksByCategory {
for _, risk := range risks {
category := types.GetRiskCategory(parsedModel, categoryId)
category := parsedModel.GetRiskCategory(categoryId)
if category.Function == function {
filteredRisks = append(filteredRisks, risk)
}
Expand Down Expand Up @@ -1575,7 +1575,7 @@ func (r *pdfReporter) createModelFailures(parsedModel *types.Model) {
func filterByModelFailures(parsedModel *types.Model, risksByCat map[string][]*types.Risk) map[string][]*types.Risk {
result := make(map[string][]*types.Risk)
for categoryId, risks := range risksByCat {
category := types.GetRiskCategory(parsedModel, categoryId)
category := parsedModel.GetRiskCategory(categoryId)
if category.ModelFailurePossibleReason {
result[categoryId] = risks
}
Expand Down Expand Up @@ -1621,8 +1621,8 @@ func (r *pdfReporter) createRAA(parsedModel *types.Model, introTextRAA string) {
} else {
strBuilder.WriteString("<br><br>")
}
newRisksStr := technicalAsset.GeneratedRisks(parsedModel)
switch types.HighestSeverityStillAtRisk(parsedModel, newRisksStr) {
newRisksStr := parsedModel.GeneratedRisks(technicalAsset)
switch types.HighestSeverityStillAtRisk(newRisksStr) {
case types.HighSeverity:
colorHighRisk(r.pdf)
case types.MediumSeverity:
Expand Down Expand Up @@ -1777,7 +1777,7 @@ func (r *pdfReporter) addCategories(parsedModel *types.Model, riskCategories []*
r.pdfColorBlack()
prefix = ""
}
switch types.HighestSeverityStillAtRisk(parsedModel, risksStr) {
switch types.HighestSeverityStillAtRisk(risksStr) {
case types.CriticalSeverity:
colorCriticalRisk(r.pdf)
case types.HighSeverity:
Expand Down Expand Up @@ -2014,7 +2014,7 @@ func reduceToFunctionRisk(parsedModel *types.Model, risksByCategory map[string][
result := make(map[string][]*types.Risk)
for categoryId, risks := range risksByCategory {
for _, risk := range risks {
category := types.GetRiskCategory(parsedModel, categoryId)
category := parsedModel.GetRiskCategory(categoryId)
if category.Function == function {
result[categoryId] = append(result[categoryId], risk)
}
Expand Down Expand Up @@ -2239,7 +2239,7 @@ func countRisks(risksByCategory map[string][]*types.Risk) int {
func getRiskCategories(parsedModel *types.Model, categoryIDs []string) []*types.RiskCategory {
categoryMap := make(map[string]*types.RiskCategory)
for _, categoryId := range categoryIDs {
category := types.GetRiskCategory(parsedModel, categoryId)
category := parsedModel.GetRiskCategory(categoryId)
if category != nil {
categoryMap[categoryId] = category
}
Expand Down Expand Up @@ -2295,7 +2295,7 @@ func reduceToSTRIDERisk(parsedModel *types.Model, risksByCategory map[string][]*
result := make(map[string][]*types.Risk)
for categoryId, risks := range risksByCategory {
for _, risk := range risks {
category := types.GetRiskCategory(parsedModel, categoryId)
category := parsedModel.GetRiskCategory(categoryId)
if category != nil && category.STRIDE == stride {
result[categoryId] = append(result[categoryId], risk)
}
Expand Down Expand Up @@ -2557,11 +2557,11 @@ func (r *pdfReporter) createRiskCategories(parsedModel *types.Model) {
html.Write(5, text.String())
text.Reset()
r.currentChapterTitleBreadcrumb = title
for _, category := range types.SortedRiskCategories(parsedModel) {
risksStr := types.SortedRisksOfCategory(parsedModel, category)
for _, category := range parsedModel.SortedRiskCategories() {
risksStr := parsedModel.SortedRisksOfCategory(category)

// category color
switch types.HighestSeverityStillAtRisk(parsedModel, risksStr) {
switch types.HighestSeverityStillAtRisk(risksStr) {
case types.CriticalSeverity:
colorCriticalRisk(r.pdf)
case types.HighSeverity:
Expand Down Expand Up @@ -2826,7 +2826,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
text.Reset()
r.currentChapterTitleBreadcrumb = title
for _, technicalAsset := range sortedTechnicalAssetsByRiskSeverityAndTitle(parsedModel) {
risksStr := technicalAsset.GeneratedRisks(parsedModel)
risksStr := parsedModel.GeneratedRisks(technicalAsset)
countStillAtRisk := len(types.ReduceToOnlyStillAtRisk(risksStr))
suffix := strconv.Itoa(countStillAtRisk) + " / " + strconv.Itoa(len(risksStr)) + " Risk"
if len(risksStr) != 1 {
Expand All @@ -2836,7 +2836,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdfColorOutOfScope()
suffix = "out-of-scope"
} else {
switch types.HighestSeverityStillAtRisk(parsedModel, risksStr) {
switch types.HighestSeverityStillAtRisk(risksStr) {
case types.CriticalSeverity:
colorCriticalRisk(r.pdf)
case types.HighSeverity:
Expand Down Expand Up @@ -3142,7 +3142,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Data Processed:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
dataAssetsProcessedText := ""
for _, dataAsset := range technicalAsset.DataAssetsProcessedSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsProcessedSorted(technicalAsset) {
if len(dataAssetsProcessedText) > 0 {
dataAssetsProcessedText += ", "
}
Expand All @@ -3159,7 +3159,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Data Stored:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
dataAssetsStoredText := ""
for _, dataAsset := range technicalAsset.DataAssetsStoredSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsStoredSorted(technicalAsset) {
if len(dataAssetsStoredText) > 0 {
dataAssetsStoredText += ", "
}
Expand Down Expand Up @@ -3410,7 +3410,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdf.CellFormat(35, 6, "Data Sent:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
dataAssetsSentText := ""
for _, dataAsset := range outgoingCommLink.DataAssetsSentSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsSentSorted(outgoingCommLink) {
if len(dataAssetsSentText) > 0 {
dataAssetsSentText += ", "
}
Expand All @@ -3426,7 +3426,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdf.CellFormat(35, 6, "Data Received:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
dataAssetsReceivedText := ""
for _, dataAsset := range outgoingCommLink.DataAssetsReceivedSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsReceivedSorted(outgoingCommLink) {
if len(dataAssetsReceivedText) > 0 {
dataAssetsReceivedText += ", "
}
Expand Down Expand Up @@ -3581,7 +3581,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdfColorBlack()
dataAssetsSentText := ""
// yep, here we reverse the sent/received direction, as it's the incoming stuff
for _, dataAsset := range incomingCommLink.DataAssetsSentSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsSentSorted(incomingCommLink) {
if len(dataAssetsSentText) > 0 {
dataAssetsSentText += ", "
}
Expand All @@ -3598,7 +3598,7 @@ func (r *pdfReporter) createTechnicalAssets(parsedModel *types.Model) {
r.pdfColorBlack()
dataAssetsReceivedText := ""
// yep, here we reverse the sent/received direction, as it's the incoming stuff
for _, dataAsset := range incomingCommLink.DataAssetsReceivedSorted(parsedModel) {
for _, dataAsset := range parsedModel.DataAssetsReceivedSorted(incomingCommLink) {
if len(dataAssetsReceivedText) > 0 {
dataAssetsReceivedText += ", "
}
Expand Down Expand Up @@ -3669,7 +3669,7 @@ func (r *pdfReporter) createDataAssets(parsedModel *types.Model) {
if !isDataBreachPotentialStillAtRisk(parsedModel, dataAsset) {
r.pdfColorBlack()
}
risksStr := dataAsset.IdentifiedDataBreachProbabilityRisks(parsedModel)
risksStr := parsedModel.IdentifiedDataBreachProbabilityRisks(dataAsset)
countStillAtRisk := len(types.ReduceToOnlyStillAtRisk(risksStr))
suffix := strconv.Itoa(countStillAtRisk) + " / " + strconv.Itoa(len(risksStr)) + " Risk"
if len(risksStr) != 1 {
Expand Down Expand Up @@ -3804,7 +3804,7 @@ func (r *pdfReporter) createDataAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Processed by:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
processedByText := ""
for _, dataAsset := range dataAsset.ProcessedByTechnicalAssetsSorted(parsedModel) {
for _, dataAsset := range parsedModel.ProcessedByTechnicalAssetsSorted(dataAsset) {
if len(processedByText) > 0 {
processedByText += ", "
}
Expand All @@ -3825,7 +3825,7 @@ func (r *pdfReporter) createDataAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Stored by:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
storedByText := ""
for _, dataAsset := range dataAsset.StoredByTechnicalAssetsSorted(parsedModel) {
for _, dataAsset := range parsedModel.StoredByTechnicalAssetsSorted(dataAsset) {
if len(storedByText) > 0 {
storedByText += ", "
}
Expand All @@ -3846,7 +3846,7 @@ func (r *pdfReporter) createDataAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Sent via:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
sentViaText := ""
for _, commLink := range dataAsset.SentViaCommLinksSorted(parsedModel) {
for _, commLink := range parsedModel.SentViaCommLinksSorted(dataAsset) {
if len(sentViaText) > 0 {
sentViaText += ", "
}
Expand All @@ -3867,7 +3867,7 @@ func (r *pdfReporter) createDataAssets(parsedModel *types.Model) {
r.pdf.CellFormat(40, 6, "Received via:", "0", 0, "", false, 0, "")
r.pdfColorBlack()
receivedViaText := ""
for _, commLink := range dataAsset.ReceivedViaCommLinksSorted(parsedModel) {
for _, commLink := range parsedModel.ReceivedViaCommLinksSorted(dataAsset) {
if len(receivedViaText) > 0 {
receivedViaText += ", "
}
Expand Down
Loading

0 comments on commit 38635e4

Please sign in to comment.