Skip to content
This repository was archived by the owner on Nov 9, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 5 additions & 14 deletions activities/fellowship of the ring/gandalf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,10 @@ settings:
application: "gandalf" # e.g. from deployment
team: "fellowship of the ring"

# TODO optional fields results in null values in the output is good?
includes:
- infrastructure/infrastructure.yaml

activities:
Source Control Protection:
components:
- url: "https://test1.com"
date: 2023-01-01
- date: 2022-05-01
url: "https://test1.com"
- date: 2021-05-01
url: "https://test1.com"
- date: 2023-12-19
url: "https://test1.com"


Conduction of simple threat modeling on technical level:
components:
- date: "2008-11-01"
Expand All @@ -42,4 +31,6 @@ activities:
links:
- title: "testtitle"
url: "https://test1.com"

Reduction of the attack surface:
components:
- date: "2024-01-01"
18 changes: 18 additions & 0 deletions activities/infrastructure/infrastructure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v1
kind: application
settings:
desired level: Level 2
application: "kube"
team: "ops"

activities:
Source Control Protection:
components:
- url: "https://test1.com"
date: 2023-01-01
- date: 2022-05-01
url: "https://test1.com"
- date: 2021-05-01
url: "https://test1.com"
- date: 2023-12-19
url: "https://test1.com"
38 changes: 38 additions & 0 deletions activities/infrastructure/team.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: v1
kind: team

settings:
team: "ops"

activities:
Security requirements:
components:
- url: "https://test1.com"
date: 2023-01-01
- date: 2022-05-01
url: "https://test1.com"
- date: 2021-05-01
url: "https://test1.com"
- date: 2023-12-19
url: "https://test1.com"

Data privacy requirements:
components:
- date: 2022-05-01
- date: 2021-05-01
- date: 2023-12-19

Security champion:
components:
- firstname: "Max"
lastname: "Mustermann"
date: "2020-11-01"

Security Training:
components:
- date: "2020-11-01"
people: 2
hours: 5
- date: "2023-11-01"
people: 2
hours: 5
24 changes: 16 additions & 8 deletions activities/two towers/sauron.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,32 @@ settings:
application: "sauron" # e.g. from deployment
team: "two towers"

includes:
- infrastructure/infrastructure.yaml

activities:
Source Control Protection:
components:
- url: "https://test1.com"
date: 2023-01-01
- date: 2022-10-01
- date: 2022-05-01
url: "https://test1.com"
- date: 2000-01-01
- date: 2021-05-01
url: "https://test1.com"
- date: 2023-12-19
url: "https://test1.com"

Defined build process:
components:
- url: "https://test1.com"
date: 2023-01-01
- date: 2022-05-01
url: "https://test2.com"
url: "https://test1.com"
- date: 2021-05-01
url: "https://test1.com"
- date: 2023-12-19
url: "https://test2.com"
url: "https://test1.com"

Conduction of simple threat modeling on technical level:
components:
- date: "2009-11-01"
Expand All @@ -44,10 +55,7 @@ activities:
links:
- title: "testtitle"
url: "https://test1.com"
Reduction of the attack surface:
components:
- date: "2023-01-01"
# sast:
# confirmation:
# - confirmed by: "Max Mustermann"
# confirmed date: "2020-01-01"
# confirmed date: "2020-01-01"
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private List<SkeletonActivity> getDeserializeSkeletons() throws IOException, Git

private List<Application> getDeserializedApplications(List<SkeletonActivity> skeletonActivities) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, GitAPIException {
List<Application> applications = new ArrayList<>();
YamlApplicationNodes yamlApplicationNodes = new YamlApplicationNodes();
YamlApplicationNodes yamlApplicationNodes = new YamlApplicationNodes(yamlScanner.getYamlApplicationFolderPath());
HashMap<String, List<Activity>> teamActivities = new HashMap<>();
for (File yamlApplicationFilePath : yamlScanner.getApplicationYamls()) {
logger.info("yamlApplicationFilePath: " + yamlApplicationFilePath.getPath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

Expand All @@ -12,10 +13,17 @@ public class YamlApplicationNodes {
// Key: Team name
protected HashMap<String, ArrayList<JsonNode>> nodes;

protected String yamlBasePath = "";

public YamlApplicationNodes() {
this.nodes = new HashMap<String, ArrayList<JsonNode>>();
}

public YamlApplicationNodes(String yamlBasePath) {
this.yamlBasePath = yamlBasePath;
this.nodes = new HashMap<String, ArrayList<JsonNode>>();
}

public void addJsonNode(JsonNode node) {
JsonNode settings = node.get("settings");
String team = settings.get("team").asText();
Expand All @@ -32,6 +40,22 @@ public HashMap<String, ArrayList<JsonNode>> getNodes() {
return nodes;
}

public ArrayList<JsonNode> getNodes(String team, String kind) throws IOException {
ArrayList<JsonNode> applicationNodes = new ArrayList<JsonNode>();

for (JsonNode node : getNodesForTeam(team)) {
if (node.get("kind").asText().equals(kind)) {
if (yamlBasePath != null && !yamlBasePath.isEmpty()) {
YamlScannerIncludes yamlScannerIncludes = new YamlScannerIncludes(node, yamlBasePath);
node = yamlScannerIncludes.getNode();
}
applicationNodes.add(node);
}
}

return applicationNodes;
}

public ArrayList<JsonNode> getNodesForTeam(String team) {
ArrayList<JsonNode> allNodes = new ArrayList<JsonNode>();

Expand All @@ -44,15 +68,4 @@ public ArrayList<JsonNode> getNodesForTeam(String team) {
}
return allNodes;
}

public ArrayList<JsonNode> getNodes(String team, String kind) {
ArrayList<JsonNode> applicationNodes = new ArrayList<JsonNode>();

for (JsonNode node : getNodesForTeam(team)) {
if (node.get("kind").asText().equals(kind)) {
applicationNodes.add(node);
}
}
return applicationNodes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ private String getYamlSkeletonFilePath() {
return yamlSkeletonFilePath;
}

private String getYamlApplicationFolderPath() {
logger.info("yamlApplicationFolderPath() " + yamlApplicationFolderPath);
public String getYamlApplicationFolderPath() {
logger.debug("yamlApplicationFolderPath() " + yamlApplicationFolderPath);
if (isGit()) {
return yamlGitTargetPath + "/" + yamlApplicationFolderPath;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.owasp.dsomm.metricca.analyzer.deserialization;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import java.io.File;
import java.io.IOException;

public class YamlScannerIncludes {
private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
private final String yamlBasePath;
private final JsonNode applicationJsonNode;

public YamlScannerIncludes(JsonNode applicationJsonNode, String basePath) {
this.applicationJsonNode = applicationJsonNode;
this.yamlBasePath = basePath;
}

public JsonNode getNode() throws IOException {
processIncludes(applicationJsonNode);
return applicationJsonNode;
}

private void processIncludes(JsonNode node) throws IOException {
if (node.has("includes")) {
ArrayNode includesArray = (ArrayNode) node.get("includes");
for (JsonNode includeNode : includesArray) {
if (includeNode.isTextual()) {
String includePath = includeNode.asText();
File includeFile = new File(yamlBasePath + File.separator + includePath);
JsonNode includeContent = mapper.readTree(includeFile);
if (includeContent.has("includes")) {
processIncludes(includeContent);
}
mergeJsonNodes(node, includeContent);
}
}
((ObjectNode) node).remove("includes");
}


}

private void mergeJsonNodes(JsonNode destinationNode, JsonNode sourceNode) {
if (destinationNode instanceof ObjectNode destObjectNode && sourceNode instanceof ObjectNode srcObjectNode) {

// Merge fields from source node to destination node
srcObjectNode.fieldNames().forEachRemaining(fieldName -> {
JsonNode srcFieldValue = srcObjectNode.get(fieldName);
JsonNode destFieldValue = destObjectNode.get(fieldName);

if (destFieldValue != null && destFieldValue.isObject() && srcFieldValue.isObject()) {
// Recursive deep merge for nested objects
mergeJsonNodes(destFieldValue, srcFieldValue);
} else {
// If the field exists in the destination node but not in the source node, or if the field is null in the destination
// and exists in the source node, or if the included YAML is overriding the including YAML, override the value in the destination
if (destFieldValue == null || (!destObjectNode.has(fieldName) && srcObjectNode.has(fieldName))) {
destObjectNode.set(fieldName, srcFieldValue);
}
}
});
} else {
throw new IllegalArgumentException("Both nodes must be ObjectNodes");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public ApplicationNotFoundException(String applicationName, String teamName) {
this.teamName = teamName;
}

private String teamName;
private final String teamName;
private String applicationName;

public String getApplicationName() {
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application-debugging.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
logging.level.root=INFO
metricCA.resource.path=/app/resources
spring.config.import: ${metricCA.resource.path}/application-prod.properties
spring.config.import= ${metricCA.resource.path}/application-prod.properties
logging.level.org.eclipse.jgit=DEBUG
2 changes: 1 addition & 1 deletion src/main/resources/application-heroku.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
metricCA.resource.path=/app/src/main/resources/
spring.config.import: ${metricCA.resource.path}/application-prod.properties
spring.config.import= ${metricCA.resource.path}/application-prod.properties
2 changes: 1 addition & 1 deletion src/main/resources/application-prod.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
logging.level.org.owasp=${LOGGING_LEVEL_OWASP}
metricCA.git.targetPath=/tmp/metricCA
metricCA.resource.path=${RESOURCE_PATH}
spring.config.import: ${metricCA.resource.path}/application.properties
spring.config.import= ${metricCA.resource.path}/application.properties
metricCA.application.path=${metricCA.git.targetPath}/activities
metricCA.teams.path=${metricCA.git.targetPath}/teams.yaml
# only internal http://metric-analyzer:8080
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public void testShowEndDateWithEndDateToShowForSingleDate() throws Exception {
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
isoFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

Date existingDate = isoFormat.parse("2000-01-01");
Date existingDate = isoFormat.parse("2023-12-19");
DatePeriod endDateForExistingDate = activity.getThresholdDatePeriodMap().get("Level 1").getDatePeriodForDate(existingDate);
assertNotNull(endDateForExistingDate);
assertTrue(endDateForExistingDate.getShowEndDate());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.owasp.dsomm.metricca.analyzer.deserialization.YamlApplicationNodes;
import org.springframework.test.util.ReflectionTestUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

Expand Down Expand Up @@ -91,7 +92,7 @@ void shouldGetNodesForTeam() {
}

@Test
void testGetNodesForTeam() throws JsonProcessingException {
void testGetNodesForTeam() throws IOException {
HashMap<String, ArrayList<JsonNode>> nodes = new HashMap<>();
ArrayList<JsonNode> jsonNodes = new ArrayList<>();
jsonNodes.add(objectMapper.readTree(jsonNodeString));
Expand Down
Loading