diff --git a/README.md b/README.md index 4162d3c..a312715 100644 --- a/README.md +++ b/README.md @@ -22,19 +22,26 @@ All the tool is needed is a data flow code file described in th More detailed instructions can be found on the [github wiki](https://github.com/rusakovichma/TicTaaC/wiki). The latest CLI can be downloaded from github in the [releases section](https://github.com/rusakovichma/TicTaaC/releases).
-On *nix +On *nix: ``` $ ./bin/tic-taac.sh -h -$ ./bin/tic-taac.sh --out . --threatModel [path to threat model file] +$ ./bin/tic-taac.sh --out . --threatModel [path to threat model file(s) or folder to scan] ``` -On Windows +On Windows: ``` > .\bin\tic-taac.bat -h -> .\bin\tic-taac.bat --out . --threatModel [path to threat model file] +> .\bin\tic-taac.bat --out . --threatModel [path to threat model file(s) or folder to scan] ``` ### Docker See [TicTaaC Docker Hub repository](https://hub.docker.com/r/rusakovichma/tic-taac). + +Quickstart on Windows: +``` +> docker run --volume /D/threat-model:/threat-model --volume /D/report:/report rusakovichma/tic-taac:latest --threatModel /threat-model/ --out /report +``` + +*nix script: ```console #!/bin/sh @@ -50,12 +57,13 @@ docker run --rm \ --volume $THREAT_MODEL_DIR:/threat-model:z \ --volume $(pwd)/report:/report:z \ rusakovichma/tic-taac:$TT_VERSION \ - --threatModel /threat-model/simpest-threat-model.yml \ + --threatModel /threat-model \ --outFormat html \ --out /report # Set mitigation strategy for the corresponding threats # see https://github.com/rusakovichma/TicTaaC/blob/master/expl/mitigations.yml - # --mitigations /threat-model/mitigations.yml + # --mitigations /threat-model/mitigations.yml + # or set the folder where scan the mitigations files: --mitigations /mitigations ``` ### Jenkins pipeline For TicTaaC usage at Jenkins pipeline, see [Jenkinsfile example](https://github.com/rusakovichma/TicTaaC/blob/master/cicd/Jenkinsfile). diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index abf7bde..7f899c3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1 +1,8 @@ -# Release Notes \ No newline at end of file +# Release Notes + +## [Version 1.2.3](https://github.com/jeremylong/DependencyCheck/releases/tag/v7.1.1) (2022-07-03) + +**Changes** + +- Bug fixes. +- Multiple Threat Modeling files support and files scan ([see #1](https://github.com/rusakovichma/TicTaaC/issues/1)). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 85f1a62..a17168a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.rusakovichma tictaac - 1.1.4 + 1.2.3 TicTaaC https://github.com/rusakovichma/TicTaaC.git @@ -30,7 +30,7 @@ scm:git:https://github.com/rusakovichma/TicTaaC.git https://github.com/rusakovichma/TicTaaC scm:git:https://github.com/rusakovichma/TicTaaC.git - v1.0.3 + v1.2.3 github diff --git a/src/main/java/com/github/rusakovichma/tictaac/Launcher.java b/src/main/java/com/github/rusakovichma/tictaac/Launcher.java index fb9a767..22cfaa3 100644 --- a/src/main/java/com/github/rusakovichma/tictaac/Launcher.java +++ b/src/main/java/com/github/rusakovichma/tictaac/Launcher.java @@ -27,21 +27,23 @@ import com.github.rusakovichma.tictaac.provider.mitigation.*; import com.github.rusakovichma.tictaac.provider.model.StandardThreatModelProvider; import com.github.rusakovichma.tictaac.provider.model.ThreatModelProvider; +import com.github.rusakovichma.tictaac.provider.reader.ThreatModelFilter; import com.github.rusakovichma.tictaac.provider.rules.StandardThreatRulesProvider; import com.github.rusakovichma.tictaac.provider.rules.ThreatRulesProvider; import com.github.rusakovichma.tictaac.reporter.*; import com.github.rusakovichma.tictaac.util.ConsoleUtil; +import com.github.rusakovichma.tictaac.util.FileUtil; import com.github.rusakovichma.tictaac.util.ResourceUtil; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; public class Launcher { + private static final String DEFAULT_REPORT_NAME = "threat-model-report"; private static final String OUT_PATH_DEFAULT = "."; private static final ReportFormat DEFAULT_OUT_FORMAT = ReportFormat.html; private static final String DEFAULT_THREAT_LIBRARY = "classpath:/threats-library/default-threats-library.yml"; @@ -64,6 +66,36 @@ private static ThreatModelProvider getThreatModel(Map params) { private static Mitigator getMitigator(Map params) { String mitigationsPath = params.get("mitigations"); + + String threatModelPath = params.get("threatModel"); + if (threatModelPath != null || !threatModelPath.isEmpty()) { + String threatModelDir = FileUtil.getParentFolderFromFilePath(threatModelPath); + String threatModelName = FileUtil.getFilenameWithoutExtensionFromPath(threatModelPath); + + File threatModelMitigationsFile = new File( + threatModelDir + File.separator + threatModelName + "-mitigations.yml"); + if (threatModelMitigationsFile.exists()) { + mitigationsPath = threatModelMitigationsFile.getAbsolutePath(); + } + } + + if (mitigationsPath != null && !mitigationsPath.isEmpty()) { + File mitigationsFile = new File(mitigationsPath); + if (mitigationsFile.exists() && mitigationsFile.isDirectory()) { + if (threatModelPath != null || !threatModelPath.isEmpty()) { + String threatModelName = FileUtil.getFilenameWithoutExtensionFromPath(threatModelPath); + + File threatModelMitigationsFile = new File( + mitigationsFile.getAbsolutePath() + File.separator + threatModelName + "-mitigations.yml"); + if (threatModelMitigationsFile.exists()) { + mitigationsPath = threatModelMitigationsFile.getAbsolutePath(); + } else { + mitigationsPath = null; + } + } + } + } + if (mitigationsPath == null) { return new DullMitigator(); } @@ -87,64 +119,97 @@ private static ThreatsReporter getThreatsReporter(Map params) { if (outFormat == null) { outFormat = DEFAULT_OUT_FORMAT; } + + String reportName = DEFAULT_REPORT_NAME; + String threatModelPath = params.get("threatModel"); + if (threatModelPath != null || !threatModelPath.isEmpty()) { + reportName = FileUtil.getFilenameWithoutExtensionFromPath(threatModelPath); + } + try { - return new FileStreamThreatsReporter(outPath, outFormat); + return new FileStreamThreatsReporter(outPath, reportName, outFormat); } catch (FileNotFoundException ex) { throw new IllegalStateException(ex); } } - private static void checkQualityGate(Map params, Collection threats) { - String failOnThreatRiskParam = params.get("failOnThreatRisk"); - if (failOnThreatRiskParam != null) { - ThreatRisk qualityGate = ThreatRisk.fromString(failOnThreatRiskParam.trim()); + private static void checkQualityGate(Map> params, Map> threats) { + List failOnThreatRiskParam = params.get("failOnThreatRisk"); + if (failOnThreatRiskParam != null && failOnThreatRiskParam.size() != 0) { + ThreatRisk qualityGate = ThreatRisk.fromString(failOnThreatRiskParam.get(0).trim()); if (qualityGate != ThreatRisk.Undefined) { - String notCompliantThreats = threats.stream() - .filter(threat -> threat.getRisk().getOrder() >= qualityGate.getOrder()) - .filter(threat -> threat.getMitigationStatus() == MitigationStatus.NotMitigated) - .map(threat -> threat.getId()) - .collect(Collectors.joining(", ")); - - if (notCompliantThreats != null && !notCompliantThreats.isEmpty()) { - throw new QualityGateFailed(String.format("Non-compliant threats found [%s]", notCompliantThreats)); + StringBuilder nonComplianceAccumulator = new StringBuilder(); + + for (Map.Entry> entry : threats.entrySet()) { + String notCompliantThreats = entry.getValue().stream() + .filter(threat -> threat.getRisk().getOrder() >= qualityGate.getOrder()) + .filter(threat -> threat.getMitigationStatus() == MitigationStatus.NotMitigated) + .map(threat -> threat.getId()) + .collect(Collectors.joining(", ")); + + if (notCompliantThreats != null && !notCompliantThreats.isEmpty()) { + nonComplianceAccumulator.append(String.format("%s: [%s]", entry.getKey(), notCompliantThreats)) + .append(System.lineSeparator()); + } + } + + if (nonComplianceAccumulator.length() != 0) { + throw new QualityGateFailed(String.format("Non-compliant threats found: ", + nonComplianceAccumulator.toString())); } } } } public static void main(String[] args) { - final Map params = ConsoleUtil.getParamsMap(args); - if (params.isEmpty() || !ConsoleUtil.hasOnlyAllowed(params) - || params.containsKey("help") || params.containsKey("-h")) { + final Map> multipleValueParams = ConsoleUtil.getParamsMap(args); + if (multipleValueParams.isEmpty() || !ConsoleUtil.hasOnlyAllowed(multipleValueParams) + || multipleValueParams.containsKey("help") || multipleValueParams.containsKey("-h")) { System.out.println(ResourceUtil.readResource("/help-info")); System.exit(0); } - if (params.containsKey("version") || params.containsKey("-v")) { + if (multipleValueParams.containsKey("version") || multipleValueParams.containsKey("-v")) { System.out.println(ResourceUtil.readResource("/version")); System.exit(0); } - ThreatRulesProvider rulesProvider = getRulesProvider(params); - Mitigator mitigator = getMitigator(params); + List threatModelsParams = multipleValueParams.get("threatModel"); - ThreatEngine threatEngine = getThreatEngine(rulesProvider, mitigator); + if (threatModelsParams == null || threatModelsParams.isEmpty()) { + throw new IllegalStateException("Threat modeling files: '--threatModel %path_to_files_or_folder%' parameters should be provided"); + } - ThreatModelProvider threatModelProvider = getThreatModel(params); - ThreatsCollection threats = threatEngine.generateThreats(threatModelProvider.getModel()); + List threatModelsFilesOnlyParams = FileUtil.extractFiles(threatModelsParams, new ThreatModelFilter()); + Map> modelThreats = new LinkedHashMap<>(); - try { - getThreatsReporter(params).publish( - new ReportHeader( - threats.getName(), threats.getVersion(), new Date() - ), - threats.getThreats() - ); - } catch (IOException ex) { - throw new IllegalStateException("Cannot write threat model report to the file [" + params.get("out") + "]", ex); + for (String threatModelsParam : threatModelsFilesOnlyParams) { + Map singleValueParams = ConsoleUtil.copySingleValueParamsWithDefinedArg(multipleValueParams, + "threatModel", threatModelsParam); + + ThreatRulesProvider rulesProvider = getRulesProvider(singleValueParams); + Mitigator mitigator = getMitigator(singleValueParams); + + ThreatEngine threatEngine = getThreatEngine(rulesProvider, mitigator); + + ThreatModelProvider threatModelProvider = getThreatModel(singleValueParams); + ThreatsCollection threats = threatEngine.generateThreats(threatModelProvider.getModel()); + + modelThreats.put(threatModelsParam, threats.getThreats()); + + try { + getThreatsReporter(singleValueParams).publish( + new ReportHeader( + threats.getName(), threats.getVersion(), new Date() + ), + threats.getThreats() + ); + } catch (IOException ex) { + throw new IllegalStateException("Cannot write threat model report to the path [" + singleValueParams.get("out") + "]", ex); + } } - checkQualityGate(params, threats.getThreats()); + checkQualityGate(multipleValueParams, modelThreats); } } diff --git a/src/main/java/com/github/rusakovichma/tictaac/provider/reader/MitigationsFilter.java b/src/main/java/com/github/rusakovichma/tictaac/provider/reader/MitigationsFilter.java new file mode 100644 index 0000000..192a745 --- /dev/null +++ b/src/main/java/com/github/rusakovichma/tictaac/provider/reader/MitigationsFilter.java @@ -0,0 +1,18 @@ +package com.github.rusakovichma.tictaac.provider.reader; + +import com.github.rusakovichma.tictaac.util.FileUtil; + +import java.io.File; +import java.io.FileFilter; + +public class MitigationsFilter implements FileFilter { + + @Override + public boolean accept(File mitigationsFile) { + if (!mitigationsFile.getName().toLowerCase().endsWith(".yml")) { + return false; + } + return FileUtil.findString(mitigationsFile, "mitigated:"); + } + +} diff --git a/src/main/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilter.java b/src/main/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilter.java new file mode 100644 index 0000000..3cfab02 --- /dev/null +++ b/src/main/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilter.java @@ -0,0 +1,18 @@ +package com.github.rusakovichma.tictaac.provider.reader; + +import com.github.rusakovichma.tictaac.util.FileUtil; + +import java.io.File; +import java.io.FileFilter; + +public class ThreatModelFilter implements FileFilter { + + @Override + public boolean accept(File modelFile) { + if (!modelFile.getName().toLowerCase().endsWith(".yml")) { + return false; + } + return FileUtil.findString(modelFile, "elements:") + && FileUtil.findString(modelFile, "data-flows:"); + } +} diff --git a/src/main/java/com/github/rusakovichma/tictaac/reporter/FileStreamThreatsReporter.java b/src/main/java/com/github/rusakovichma/tictaac/reporter/FileStreamThreatsReporter.java index bae81ac..957d385 100644 --- a/src/main/java/com/github/rusakovichma/tictaac/reporter/FileStreamThreatsReporter.java +++ b/src/main/java/com/github/rusakovichma/tictaac/reporter/FileStreamThreatsReporter.java @@ -23,14 +23,12 @@ public class FileStreamThreatsReporter extends StreamThreatsReporter { - private static final String REPORT_NAME = "threat-model-report"; - - public FileStreamThreatsReporter(String reportOut, ReportFormat reportFormat) + public FileStreamThreatsReporter(String reportOut, String reportName, ReportFormat reportFormat) throws FileNotFoundException { super(new FileOutputStream(new File( new StringBuilder(reportOut) .append(File.separator) - .append(REPORT_NAME) + .append(reportName) .append(".") .append(reportFormat.name()) .toString())), diff --git a/src/main/java/com/github/rusakovichma/tictaac/util/ConsoleUtil.java b/src/main/java/com/github/rusakovichma/tictaac/util/ConsoleUtil.java index 83f8b9f..4d15f56 100644 --- a/src/main/java/com/github/rusakovichma/tictaac/util/ConsoleUtil.java +++ b/src/main/java/com/github/rusakovichma/tictaac/util/ConsoleUtil.java @@ -33,7 +33,7 @@ private ConsoleUtil() { private static class ConsoleParam { private String key; - private String value; + private List values = new ArrayList<>(); public ConsoleParam(String key) { this.key = key; @@ -47,12 +47,12 @@ public void setKey(String key) { this.key = key; } - public String getValue() { - return value; + public List getValues() { + return values; } - public void setValue(String value) { - this.value = value; + public void addValue(String value) { + this.values.add(value); } @Override @@ -60,16 +60,16 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ConsoleParam that = (ConsoleParam) o; - return Objects.equals(key, that.key) && Objects.equals(value, that.value); + return Objects.equals(key, that.key) && Objects.equals(values, that.values); } @Override public int hashCode() { - return Objects.hash(key, value); + return Objects.hash(key, values); } } - public static Map getParamsMap(String[] args) { + public static Map> getParamsMap(String[] args) { Stack params = new Stack<>(); if (args != null && args.length != 0) { for (int i = 0; i < args.length; i++) { @@ -79,7 +79,7 @@ public static Map getParamsMap(String[] args) { .replaceFirst("--", ""))); } else { if (!params.empty()) { - params.peek().setValue( + params.peek().addValue( args[i].trim().replaceAll("\"", "") .replaceAll("'", "")); } @@ -87,17 +87,17 @@ public static Map getParamsMap(String[] args) { } } - Map paramsMap = new HashMap<>(); + Map> paramsMap = new HashMap<>(); while (!params.empty()) { ConsoleParam param = params.pop(); - paramsMap.put(param.getKey(), param.getValue()); + paramsMap.put(param.getKey(), param.getValues()); } return paramsMap; } - public static boolean hasOnlyAllowed(Map params) { - for (Map.Entry entry : params.entrySet()) { + public static boolean hasOnlyAllowed(Map> params) { + for (Map.Entry> entry : params.entrySet()) { if (!PARAMS_WHITELIST.stream() .anyMatch(entry.getKey()::equalsIgnoreCase)) { return false; @@ -106,4 +106,16 @@ public static boolean hasOnlyAllowed(Map params) { return true; } + public static Map copySingleValueParamsWithDefinedArg(Map> params, + String paramName, String paramValue) { + Map singleValueParams = new HashMap<>(); + for (Map.Entry> entry : params.entrySet()) { + if (entry.getValue() != null) { + String value = paramName.equalsIgnoreCase(entry.getKey()) ? paramValue : entry.getValue().get(0); + singleValueParams.put(entry.getKey(), value); + } + } + return singleValueParams; + } + } diff --git a/src/main/java/com/github/rusakovichma/tictaac/util/FileUtil.java b/src/main/java/com/github/rusakovichma/tictaac/util/FileUtil.java index 8bd97b5..6447ce3 100644 --- a/src/main/java/com/github/rusakovichma/tictaac/util/FileUtil.java +++ b/src/main/java/com/github/rusakovichma/tictaac/util/FileUtil.java @@ -17,12 +17,14 @@ */ package com.github.rusakovichma.tictaac.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.nio.charset.Charset; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; @@ -44,4 +46,65 @@ public static InputStream fileToInputStream(String filePath) return new FileInputStream(file); } + public static boolean findString(File file, String string) { + try { + try (Stream lines = Files.lines(file.toPath(), Charset.defaultCharset())) { + return (lines.filter(line -> line.contains(string)) + .findFirst() + .get()) != null; + } + } catch (Exception ex) { + return false; + } + } + + public static List extractFiles(List paths, FileFilter filter) { + if (paths == null || paths.isEmpty()) { + return Collections.EMPTY_LIST; + } + + List extractedFiles = new ArrayList<>(); + + for (String path : paths) { + File file = new File(path); + if (file.exists()) { + if (file.isFile()) { + extractedFiles.add(path); + } else { + File[] filesInFolder = (filter != null) + ? file.listFiles(filter) : file.listFiles(); + if (filesInFolder != null && filesInFolder.length != 0) { + for (File fileInFolder : filesInFolder) { + extractedFiles.add(fileInFolder.getAbsolutePath()); + } + } + } + } + } + + return extractedFiles; + } + + public static String getFilenameWithoutExtensionFromPath(String filePath) { + if (filePath == null) return null; + + Path path = Paths.get(filePath); + String fileName = path.getFileName().toString(); + + int extPosition = fileName.lastIndexOf("."); + if (extPosition == -1) return fileName; + + return fileName.substring(0, extPosition); + } + + public static String getParentFolderFromFilePath(String filePath) { + if (filePath == null) return null; + + Path path = Paths.get(filePath); + String fileName = path.getFileName().toString(); + + return filePath.replaceAll(fileName, ""); + } + + } diff --git a/src/main/resources/version b/src/main/resources/version index 033a30f..e56cace 100644 --- a/src/main/resources/version +++ b/src/main/resources/version @@ -1 +1 @@ -Version: 1.1.4 \ No newline at end of file +Version: 1.2.3 \ No newline at end of file diff --git a/src/test/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilterTest.java b/src/test/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilterTest.java new file mode 100644 index 0000000..3c0468c --- /dev/null +++ b/src/test/java/com/github/rusakovichma/tictaac/provider/reader/ThreatModelFilterTest.java @@ -0,0 +1,18 @@ +package com.github.rusakovichma.tictaac.provider.reader; + +import org.junit.jupiter.api.Test; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.*; + +class ThreatModelFilterTest { + + @Test + void accept() { + File dir = new File("src/test/resources"); + File[] modelFiles = dir.listFiles(new ThreatModelFilter()); + + assertTrue(modelFiles.length == 5); + } +} \ No newline at end of file diff --git a/src/test/java/com/github/rusakovichma/tictaac/util/ConsoleUtilTest.java b/src/test/java/com/github/rusakovichma/tictaac/util/ConsoleUtilTest.java index 0d234a0..f68be20 100644 --- a/src/test/java/com/github/rusakovichma/tictaac/util/ConsoleUtilTest.java +++ b/src/test/java/com/github/rusakovichma/tictaac/util/ConsoleUtilTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; @@ -15,7 +16,7 @@ void getParams() { "--threatsLibraryAccessUsername", "username", "--threatsLibraryAccessPassword", "pass123456", "--mitigations", "\"${WORKSPACE}/mitigations.yml\"", "--outFormat", "html", "--out", "${WORKSPACE}/reports"}; - Map paramsMap = ConsoleUtil.getParamsMap(params); + Map> paramsMap = ConsoleUtil.getParamsMap(params); assertTrue(paramsMap.size() == 8); } @@ -26,7 +27,7 @@ void getParamsWhitelistPass() { "--threatsLibraryAccessUsername", "username", "--threatsLibraryAccessPassword", "pass123456", "--mitigations", "\"${WORKSPACE}/mitigations.yml\"", "--outFormat", "html", "--out", "${WORKSPACE}/reports"}; - Map paramsMap = ConsoleUtil.getParamsMap(params); + Map> paramsMap = ConsoleUtil.getParamsMap(params); assertTrue(ConsoleUtil.hasOnlyAllowed(paramsMap)); } @@ -37,7 +38,33 @@ void getParamsWhitelistNotPassed() { "--threatsLibraryAccessUsername", "username", "--threatsLibraryAccessPassword", "pass123456", "--mitigations", "\"${WORKSPACE}/mitigations.yml\"", "--outFormat", "html", "--out", "${WORKSPACE}/reports"}; - Map paramsMap = ConsoleUtil.getParamsMap(params); + Map> paramsMap = ConsoleUtil.getParamsMap(params); assertFalse(ConsoleUtil.hasOnlyAllowed(paramsMap)); } + + @Test + void getParamsWithMultipleValues() { + String[] params = {"--threatModel", "${WORKSPACE}/threat-model.yml", "${WORKSPACE}/threat-model-two.yml", "threat-model-three.yml", + "--failOnThreatRisk", "High", "--threatsLibrary", "https://my-site.com/my-threats-library.yml", + "--threatsLibraryAccessUsername", "username", "--threatsLibraryAccessPassword", "pass123456", + "--mitigations", "\"${WORKSPACE}/mitigations.yml\"", "--outFormat", "html", "--out", "${WORKSPACE}/reports"}; + + Map> paramsMap = ConsoleUtil.getParamsMap(params); + assertTrue(paramsMap.get("threatModel").size() == 3); + } + + @Test + void copySingleValueParamsWithDefinedArg() { + String[] params = {"--threatModel", "${WORKSPACE}/threat-model.yml", "${WORKSPACE}/threat-model-two.yml", "threat-model-three.yml", + "--failOnThreatRisk", "High", "--threatsLibrary", "https://my-site.com/my-threats-library.yml", + "--threatsLibraryAccessUsername", "username", "--threatsLibraryAccessPassword", "pass123456", + "--mitigations", "\"${WORKSPACE}/mitigations.yml\"", "--outFormat", "html", "--out", "${WORKSPACE}/reports"}; + + Map> paramsMap = ConsoleUtil.getParamsMap(params); + Map singleValueMap = ConsoleUtil.copySingleValueParamsWithDefinedArg(paramsMap, + "threatModel", "threat-model-three.yml"); + assertTrue(singleValueMap.size() == 8); + assertTrue(singleValueMap.get("threatModel").equals("threat-model-three.yml")); + + } } \ No newline at end of file diff --git a/src/test/java/com/github/rusakovichma/tictaac/util/FileUtilTest.java b/src/test/java/com/github/rusakovichma/tictaac/util/FileUtilTest.java index 16c23ae..2adc53f 100644 --- a/src/test/java/com/github/rusakovichma/tictaac/util/FileUtilTest.java +++ b/src/test/java/com/github/rusakovichma/tictaac/util/FileUtilTest.java @@ -1,8 +1,11 @@ package com.github.rusakovichma.tictaac.util; +import com.github.rusakovichma.tictaac.provider.reader.ThreatModelFilter; import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.*; @@ -14,4 +17,27 @@ void readLineByLine() throws IOException { Consumer lineReader = string -> assertTrue(!string.isEmpty()); FileUtil.readLineByLine("src/test/resources/threat-model-test.yml", lineReader); } + + @Test + void extractFiles() throws IOException { + List paths = new ArrayList<>(); + + paths.add("src/test/resources/threat-model-test.yml"); + paths.add("src/test/resources/"); + + List threatModels = FileUtil.extractFiles(paths, new ThreatModelFilter()); + assertEquals(6, threatModels.size()); + } + + @Test + void getFilenameWithoutExtensionFromPath() { + String filename = FileUtil.getFilenameWithoutExtensionFromPath("src/test/resources/threat-model-test.yml"); + assertEquals("threat-model-test", filename); + } + + @Test + void getParentFolderFromFilePath() { + String parent = FileUtil.getParentFolderFromFilePath("src/test/resources/threat-model-test.yml"); + assertEquals("src/test/resources/", parent); + } } \ No newline at end of file