From 9a9eedbd46e44cf316b8df7ecf7a340a0bdc357c Mon Sep 17 00:00:00 2001 From: Lorenzo Coppi Date: Mon, 4 Mar 2024 16:56:06 +0100 Subject: [PATCH 01/13] wip: document sections & add TODOs --- README.md | 40 +++++++++++++++++++ .../com/cys4/sensitivediscoverer/Utils.java | 7 ++++ .../model/RegexEntityTest.java | 8 +++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebb3228..d843f28 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ * [Manual install](#manual-install) * [Usage](#usage) * [Importing Lists](#importing-lists) + * [Importing Lists - Advanced](#importing-lists---advanced) * [How to compile from source code](#how-to-compile-from-source-code) * [Using Maven from CLI](#using-maven-from-cli) * [About us](#about-us) @@ -132,6 +133,45 @@ Both `CSV` and `JSON` files with their respective extensions are supported. Regexes must be compliant with the Java's Regexes Style. If in doubt, use [regex101](https://regex101.com/) with the `Java 8` flavour to test regexes. +### Importing Lists - Advanced + +In the lists it's also possible to specify the sections that the regexes should match. If no section is specified, by default `all` sections are used. + +Each HTTP item composed of a request and a response is divided into the following matchable sections: + +- `req_url`: Request URL; +- `req_headers`: Request headers without the request line (first line); +- `req_body`: Request body; +- `res_headers`: Response headers without the status line (first line); +- `res_body`: Response body; + +The following sections groups are also available to make things easier and more readable: + +- `req`: req_url + req_headers + req_body +- `res`: res_headers + res_body +- `all`: req + res + +To specify the sections to match use the following format: + +- For **CSV** files, add a `sections` column and for each row add the list of sections to be matched as a string with sections delimited by the character `|`: + + ```csv + "description","regex","sections" + "Google e-mail","\w+@gmail.com","req|res_body" + ``` + +- For **JSON** files, add a `sections` field containing the array of sections to be matched as strings: + + ```json + [ + { + "description": "Google e-mail", + "regex": "\\w+@gmail.com", + "sections": [ "req", "res_body" ] + } + ] + ``` + ## How to compile from source code ### Using Maven from CLI diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index e989193..ddb1a78 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -213,17 +213,24 @@ public static void saveListToJSON(List regexEntities) { Utils.saveToFile("json", List.of(gson.toJson(lines, tListEntries))); } + // todo: separate this function from the file-chooser GUI modal in Utils.linesFromFile to allow for testing. public static void openListFromCSV(RegexListContext ctx) { StringBuilder alreadyAddedMsg = new StringBuilder(); List lines = Utils.linesFromFile("csv"); if (Objects.isNull(lines)) return; + //todo: Allow files without the header line. + + //todo: if first line is not the header line, then don't skip it. + // for each line after the first (Headers Line) lines.subList(1, lines.size()).forEach(line -> { Matcher matcher = RegexEntity.checkRegexEntityFromCSV(line); if (!matcher.find()) return; + //todo: when sections are not specified it should still parse the regex and set the sections to all + String description = matcher.group(1).replaceAll("\"\"", "\""); String regex = matcher.group(2).replaceAll("\"\"", "\""); List sections = List.of(matcher.group(3).replaceAll("\"\"", "\"").split("\\|")); diff --git a/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java b/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java index 1bc4480..4543d24 100644 --- a/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java +++ b/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java @@ -51,14 +51,18 @@ void testActiveFlag() { assertThat(entity.isActive()).isTrue(); } + //TODO add a test that checks regex are imported correctly + + //TODO add a test that checks CSV files without the header line are imported correctly + @Test void checkRegexEntityFromCSV() { - Matcher csvMatcher = RegexEntity.checkRegexEntityFromCSV("\"description\",\"regex\",\"SECTION_1,SECTION_2\""); + Matcher csvMatcher = RegexEntity.checkRegexEntityFromCSV("\"description\",\"regex\",\"SECTION_1|SECTION_2\""); assertThat(csvMatcher.find()).isTrue(); assertThat(csvMatcher.groupCount()).isEqualTo(3); assertThat(csvMatcher.group(1)).isEqualTo("description"); assertThat(csvMatcher.group(2)).isEqualTo("regex"); - assertThat(csvMatcher.group(3)).isEqualTo("SECTION_1,SECTION_2"); + assertThat(csvMatcher.group(3)).isEqualTo("SECTION_1|SECTION_2"); } @Test From c5b8ba033f18bc6fc969d4603904b5cba177c382 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Thu, 14 Mar 2024 14:06:40 +0100 Subject: [PATCH 02/13] Fix: import/export regex list --- .../sensitivediscoverer/RegexListViewer.java | 42 +++---- .../com/cys4/sensitivediscoverer/Utils.java | 104 ++++++++++++------ .../model/RegexEntity.java | 3 +- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index bc0ed78..eba631b 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -253,20 +253,12 @@ private JMenuItem createListSaveMenuItem(List regexEntities) { JMenuItem menuItem = new JMenuItem(getLocaleString("options-list-save")); String[] options = {"JSON", "CSV"}; menuItem.addActionListener(actionEvent -> { - int dialog = JOptionPane.showOptionDialog( - null, - getLocaleString("options-list-save-formatDialogMessage"), - getLocaleString("options-list-save-formatDialogTitle"), - JOptionPane.DEFAULT_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - null - ); - if ("JSON".equals(options[dialog])) { - Utils.saveListToJSON(regexEntities); - } else if ("CSV".equals(options[dialog])) { - Utils.saveListToCSV(regexEntities); + + String fileName = Utils.selectFile(options, getLocaleString("utils-saveToFile-exportFile")); + if (fileName.toUpperCase().endsWith("JSON")) { + Utils.saveListToJSON(fileName, regexEntities); + } else if (fileName.toUpperCase().endsWith("CSV")) { + Utils.saveListToCSV(fileName, regexEntities); } }); @@ -279,21 +271,15 @@ private JMenuItem createListOpenMenuItem(RegexListContext ctx, String[] options = {"JSON", "CSV"}; JMenuItem menuItem = new JMenuItem(getLocaleString("options-list-open")); menuItem.addActionListener(actionEvent -> { - int dialog = JOptionPane.showOptionDialog( - null, - getLocaleString("options-list-open-formatDialogMessage"), - getLocaleString("options-list-open-formatDialogTitle"), - JOptionPane.DEFAULT_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - null - ); - if ("JSON".equals(options[dialog])) { - Utils.openListFromJSON(ctx); - } else if ("CSV".equals(options[dialog])) { - Utils.openListFromCSV(ctx); + + String fileName = Utils.selectFile(options, getLocaleString("utils-linesFromFile-importFile")); + + if (fileName.toUpperCase().endsWith("JSON")) { + Utils.openListFromJSON(fileName, ctx); + } else if (fileName.toUpperCase().endsWith("CSV")) { + Utils.openListFromCSV(fileName, ctx); } + tableModel.fireTableDataChanged(); tabPaneOptions.validate(); tabPaneOptions.repaint(); diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index ddb1a78..676b94a 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -18,6 +18,7 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.*; import java.util.regex.Matcher; @@ -86,26 +87,37 @@ public static void saveToFile(String extensionName, List lines) { /** * Open JFileChooser to get lines from a file * - * @param extensionName the extension to filter files - * @return The lines from the file, or null if there was an error + * @param extensionNames the extensions to filter files + * @param title the window title + * @return The filename, or null if there was an error */ - public static List linesFromFile(String extensionName) { + public static String selectFile(String[] extensionNames, String title) { JFrame parentFrame = new JFrame(); JFileChooser fileChooser = new JFileChooser(); - FileNameExtensionFilter filter = new FileNameExtensionFilter("." + extensionName, extensionName); - fileChooser.setFileFilter(filter); - fileChooser.setDialogTitle(getLocaleString("utils-linesFromFile-importFile")); + for (String extensionName : extensionNames) { + FileNameExtensionFilter filter = new FileNameExtensionFilter("." + extensionName, extensionName); + fileChooser.addChoosableFileFilter(filter); + } + + fileChooser.setDialogTitle(title); + + int userSelection = title.toLowerCase().contains("import") ? + fileChooser.showOpenDialog(parentFrame) : + fileChooser.showSaveDialog(parentFrame); - int userSelection = fileChooser.showOpenDialog(parentFrame); if (userSelection != JFileChooser.APPROVE_OPTION) return null; - File selectedFile = fileChooser.getSelectedFile(); - try { - return Files.readAllLines(selectedFile.toPath()); - } catch (IOException e) { - e.printStackTrace(); - return null; + String exportFilePath = fileChooser.getSelectedFile().getAbsolutePath(); + + String selectedExt = fileChooser.getFileFilter().getDescription().toLowerCase(); + if (selectedExt.equals("all files")) + return exportFilePath; + + if (!exportFilePath.toLowerCase().endsWith(selectedExt)) { + exportFilePath += selectedExt; } + + return exportFilePath; } /** @@ -177,7 +189,7 @@ public static InputStream getResourceAsStream(String name) { return Utils.class.getClassLoader().getResourceAsStream(name); } - public static void saveListToCSV(List regexEntities) { + public static void saveListToCSV(String csvFile, List regexEntities) { List lines = new ArrayList<>(); lines.add("\"description\",\"regex\",\"sections\""); @@ -190,10 +202,16 @@ public static void saveListToCSV(List regexEntities) { lines.add(String.format("\"%s\",\"%s\",\"%s\"", description, regex, sections)); }); - Utils.saveToFile("csv", lines); + try { + PrintWriter pwt = new PrintWriter(csvFile, StandardCharsets.UTF_8); + lines.forEach(pwt::println); + pwt.close(); + } catch (Exception e) { + e.printStackTrace(); + } } - public static void saveListToJSON(List regexEntities) { + public static void saveListToJSON(String jsonFile, List regexEntities) { List lines = new ArrayList<>(); regexEntities.forEach(regexEntity -> { @@ -210,36 +228,48 @@ public static void saveListToJSON(List regexEntities) { Gson gson = builder.create(); Type tListEntries = (new TypeToken>() { }).getType(); - Utils.saveToFile("json", List.of(gson.toJson(lines, tListEntries))); + + try { + PrintWriter pwt = new PrintWriter(jsonFile, StandardCharsets.UTF_8); + List.of(gson.toJson(lines, tListEntries)).forEach(pwt::println); + pwt.close(); + } catch (Exception e) { + e.printStackTrace(); + } } - // todo: separate this function from the file-chooser GUI modal in Utils.linesFromFile to allow for testing. - public static void openListFromCSV(RegexListContext ctx) { + public static void openListFromCSV(String csvFile, RegexListContext ctx) { StringBuilder alreadyAddedMsg = new StringBuilder(); + List lines; + try { + lines = Files.readAllLines(Path.of(csvFile)); + } catch (IOException e) { + e.printStackTrace(); + return; + } - List lines = Utils.linesFromFile("csv"); - if (Objects.isNull(lines)) return; - - //todo: Allow files without the header line. - - //todo: if first line is not the header line, then don't skip it. + //Skip header line if present + int startRow = (lines.get(0).contains("\"description\",\"regex\"")) ? 1 : 0; - // for each line after the first (Headers Line) - lines.subList(1, lines.size()).forEach(line -> { + // for each line + lines.subList(startRow, lines.size()).forEach(line -> { Matcher matcher = RegexEntity.checkRegexEntityFromCSV(line); - if (!matcher.find()) return; - //todo: when sections are not specified it should still parse the regex and set the sections to all + if (!matcher.find()) + return; + + //load sections if presents, otherwise set all sections + boolean hasSections = !(matcher.group(3) == null || matcher.group(3).isBlank()); String description = matcher.group(1).replaceAll("\"\"", "\""); String regex = matcher.group(2).replaceAll("\"\"", "\""); - List sections = List.of(matcher.group(3).replaceAll("\"\"", "\"").split("\\|")); + List sections = hasSections ? List.of(matcher.group(3).replaceAll("\"\"", "\"").split("\\|")) : null; RegexEntity newRegexEntity = new RegexEntity( description, regex, true, - ProxyItemSection.deserializeSections(sections) + hasSections ? ProxyItemSection.deserializeSections(sections) : ProxyItemSection.ALL ); if (!ctx.getRegexEntities().contains(newRegexEntity)) { @@ -255,12 +285,16 @@ public static void openListFromCSV(RegexListContext ctx) { alreadyAddedMsg.toString()); } - public static void openListFromJSON(RegexListContext ctx) { + public static void openListFromJSON(String jsonFile, RegexListContext ctx) { Gson gson = new Gson(); StringBuilder alreadyAddedMsg = new StringBuilder(); - - List lines = Utils.linesFromFile("json"); - if (Objects.isNull(lines)) return; + List lines; + try { + lines = Files.readAllLines(Path.of(jsonFile)); + } catch (IOException e) { + e.printStackTrace(); + return; + } Type tArrayListRegexEntity = new TypeToken>() { }.getType(); diff --git a/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java b/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java index af40caf..85d0704 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java +++ b/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java @@ -23,6 +23,7 @@ public class RegexEntity { private final EnumSet sections; private final List tests; private boolean active; + public RegexEntity(String description, String regex) throws IllegalArgumentException { this(description, regex, true, ProxyItemSection.getDefault(), null); } @@ -63,7 +64,7 @@ public RegexEntity(RegexEntity entity) throws IllegalArgumentException { */ public static Matcher checkRegexEntityFromCSV(String input) { return Pattern - .compile("^\\s*[\"'](.*?)[\"']\\s*,\\s*[\"'](.+?)[\"']\\s*,\\s*[\"'](.+?)[\"']\\s*$") + .compile("^[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*,[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*(?:,[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*)?$") .matcher(input); } From 39083292bec1da88441083da61ddf78e29556103 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Thu, 14 Mar 2024 14:30:09 +0100 Subject: [PATCH 03/13] Add: test import regex without sections --- .../model/RegexEntityTest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java b/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java index 4543d24..26c8f41 100644 --- a/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java +++ b/src/test/java/com/cys4/sensitivediscoverer/model/RegexEntityTest.java @@ -1,11 +1,14 @@ package com.cys4.sensitivediscoverer.model; +import com.cys4.sensitivediscoverer.Utils; +import com.cys4.sensitivediscoverer.tab.LoggerTab; import org.junit.jupiter.api.Test; import java.util.EnumSet; import java.util.regex.Matcher; import static org.assertj.core.api.Assertions.*; +import com.cys4.sensitivediscoverer.tab.LoggerTab; class RegexEntityTest { @@ -51,9 +54,15 @@ void testActiveFlag() { assertThat(entity.isActive()).isTrue(); } - //TODO add a test that checks regex are imported correctly - - //TODO add a test that checks CSV files without the header line are imported correctly + @Test + void checkRegexEntityFromCSVNoSections() { + Matcher csvMatcher = RegexEntity.checkRegexEntityFromCSV("\"description\",\"regex\""); + assertThat(csvMatcher.find()).isTrue(); + assertThat(csvMatcher.groupCount()).isEqualTo(3); + assertThat(csvMatcher.group(1)).isEqualTo("description"); + assertThat(csvMatcher.group(2)).isEqualTo("regex"); + assertThat(csvMatcher.group(3)).isNullOrEmpty(); + } @Test void checkRegexEntityFromCSV() { From af152bd4edc81cd4ac335fbb6f8f1091dc386083 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 14:19:44 +0100 Subject: [PATCH 04/13] Fix: RegexEntity.checkRegexEntityFromCSV: regex without escaping the backslashes --- .../java/com/cys4/sensitivediscoverer/model/RegexEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java b/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java index 85d0704..2345784 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java +++ b/src/main/java/com/cys4/sensitivediscoverer/model/RegexEntity.java @@ -58,13 +58,13 @@ public RegexEntity(RegexEntity entity) throws IllegalArgumentException { /** * Checks if the input is in the format: `"Description","Regex","Sections"` - * + * Matches also if sections are not present, in this case group(3) is null * @param input Text string to check against the format * @return If the input was in the correct format, a Matcher object where group(1) = description, group(2) = regex, group(3) = sections */ public static Matcher checkRegexEntityFromCSV(String input) { return Pattern - .compile("^[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*,[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*(?:,[\\t ]*[\\\"'](.+?)[\\\"'][\\t ]*)?$") + .compile("^[\t ]*[\"'](.+?)[\"'][\t ]*,[\t ]*[\"'](.+?)[\"'][\t ]*(?:,[\t ]*[\"'](.+?)[\"'][\t ]*)?$") .matcher(input); } From 700cba55a5a8a57b9bb0c638ea4c73b4d2ea4e3d Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 14:31:48 +0100 Subject: [PATCH 05/13] Fix: remove unreferenced keys from TextUI_en_US.properties --- src/main/resources/TextUI_en_US.properties | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/resources/TextUI_en_US.properties b/src/main/resources/TextUI_en_US.properties index 99cf880..bad9fe8 100644 --- a/src/main/resources/TextUI_en_US.properties +++ b/src/main/resources/TextUI_en_US.properties @@ -44,13 +44,9 @@ options-list-clear=Clear list options-list-clear-message=Delete ALL the regex in the list? options-list-clear-title=Clear list? options-list-open=Open list... -options-list-open-formatDialogMessage=Choose the import format -options-list-open-formatDialogTitle=Import regex list options-list-open-alreadyPresentWarn=These regexes are already present options-list-open-alreadyPresentTitle=Regexes alert options-list-save=Save list... -options-list-save-formatDialogMessage=Choose the export format -options-list-save-formatDialogTitle=Export regex list options-list-new=New regex options-list-new-dialogTitle=Add a regular expression options-list-delete=Delete selected From 11dbc39e0f1af478b1a23715c4baa4f95b149072 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 14:37:28 +0100 Subject: [PATCH 06/13] Fix: handle if filename is null --- .../java/com/cys4/sensitivediscoverer/RegexListViewer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index eba631b..cb2f814 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -16,6 +16,7 @@ import javax.swing.border.TitledBorder; import java.awt.*; import java.util.List; +import java.util.Objects; import java.util.function.Supplier; import static com.cys4.sensitivediscoverer.Messages.getLocaleString; @@ -255,6 +256,9 @@ private JMenuItem createListSaveMenuItem(List regexEntities) { menuItem.addActionListener(actionEvent -> { String fileName = Utils.selectFile(options, getLocaleString("utils-saveToFile-exportFile")); + + if (Objects.isNull(fileName)) return; + if (fileName.toUpperCase().endsWith("JSON")) { Utils.saveListToJSON(fileName, regexEntities); } else if (fileName.toUpperCase().endsWith("CSV")) { From 77261bc295b2d7e95d6ab552ae49805535d0f583 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 14:38:34 +0100 Subject: [PATCH 07/13] Fix: handle if filename is null --- src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index cb2f814..5ffeae0 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -278,6 +278,8 @@ private JMenuItem createListOpenMenuItem(RegexListContext ctx, String fileName = Utils.selectFile(options, getLocaleString("utils-linesFromFile-importFile")); + if (Objects.isNull(fileName)) return; + if (fileName.toUpperCase().endsWith("JSON")) { Utils.openListFromJSON(fileName, ctx); } else if (fileName.toUpperCase().endsWith("CSV")) { From edb7e3f4356aeefeecc768fca3022be703469c71 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 14:51:11 +0100 Subject: [PATCH 08/13] Fix: change array to collection for extensionNames --- .../com/cys4/sensitivediscoverer/RegexListViewer.java | 5 +++-- src/main/java/com/cys4/sensitivediscoverer/Utils.java | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index 5ffeae0..c305274 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -15,6 +15,7 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.function.Supplier; @@ -252,7 +253,7 @@ private JMenuItem createNewRegexMenuItem(RegexListContext ctx, private JMenuItem createListSaveMenuItem(List regexEntities) { JMenuItem menuItem = new JMenuItem(getLocaleString("options-list-save")); - String[] options = {"JSON", "CSV"}; + List options = Arrays.asList("JSON", "CSV"); menuItem.addActionListener(actionEvent -> { String fileName = Utils.selectFile(options, getLocaleString("utils-saveToFile-exportFile")); @@ -272,7 +273,7 @@ private JMenuItem createListSaveMenuItem(List regexEntities) { private JMenuItem createListOpenMenuItem(RegexListContext ctx, JPanel tabPaneOptions, RegexListViewerTableModel tableModel) { - String[] options = {"JSON", "CSV"}; + List options = Arrays.asList("JSON", "CSV"); JMenuItem menuItem = new JMenuItem(getLocaleString("options-list-open")); menuItem.addActionListener(actionEvent -> { diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index 676b94a..05652b7 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -91,13 +91,14 @@ public static void saveToFile(String extensionName, List lines) { * @param title the window title * @return The filename, or null if there was an error */ - public static String selectFile(String[] extensionNames, String title) { + public static String selectFile(List extensionNames, String title) { JFrame parentFrame = new JFrame(); JFileChooser fileChooser = new JFileChooser(); - for (String extensionName : extensionNames) { - FileNameExtensionFilter filter = new FileNameExtensionFilter("." + extensionName, extensionName); - fileChooser.addChoosableFileFilter(filter); - } + + extensionNames.stream() + .map(extensionName -> new FileNameExtensionFilter("." + extensionName, extensionName)) + .forEachOrdered(fileChooser::addChoosableFileFilter); + fileChooser.setDialogTitle(title); From 8e9961783913a8ddcab48a231cab456f726b6738 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 15:02:50 +0100 Subject: [PATCH 09/13] Fix: add an argument to the function selectFile to distinguish between open or save a file --- .../sensitivediscoverer/RegexListViewer.java | 4 ++-- .../java/com/cys4/sensitivediscoverer/Utils.java | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index c305274..d77ad63 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -256,7 +256,7 @@ private JMenuItem createListSaveMenuItem(List regexEntities) { List options = Arrays.asList("JSON", "CSV"); menuItem.addActionListener(actionEvent -> { - String fileName = Utils.selectFile(options, getLocaleString("utils-saveToFile-exportFile")); + String fileName = Utils.selectFile(options, false); if (Objects.isNull(fileName)) return; @@ -277,7 +277,7 @@ private JMenuItem createListOpenMenuItem(RegexListContext ctx, JMenuItem menuItem = new JMenuItem(getLocaleString("options-list-open")); menuItem.addActionListener(actionEvent -> { - String fileName = Utils.selectFile(options, getLocaleString("utils-linesFromFile-importFile")); + String fileName = Utils.selectFile(options, true); if (Objects.isNull(fileName)) return; diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index 05652b7..e40485d 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -85,24 +85,28 @@ public static void saveToFile(String extensionName, List lines) { } /** - * Open JFileChooser to get lines from a file + * Open JFileChooser to get a file name * * @param extensionNames the extensions to filter files - * @param title the window title + * @param openFile Set to true if the file should be opened, false if it should be saved * @return The filename, or null if there was an error */ - public static String selectFile(List extensionNames, String title) { + public static String selectFile(List extensionNames, boolean openFile) { JFrame parentFrame = new JFrame(); JFileChooser fileChooser = new JFileChooser(); + //add supported extensions extensionNames.stream() .map(extensionName -> new FileNameExtensionFilter("." + extensionName, extensionName)) .forEachOrdered(fileChooser::addChoosableFileFilter); + //set window title to Open or Save + fileChooser.setDialogTitle(getLocaleString(openFile? + getLocaleString("utils-linesFromFile-importFile") + : "utils-saveToFile-exportFile")); - fileChooser.setDialogTitle(title); - - int userSelection = title.toLowerCase().contains("import") ? + //show the Open or Save window + int userSelection = openFile ? fileChooser.showOpenDialog(parentFrame) : fileChooser.showSaveDialog(parentFrame); From 99568187aa04e96e0dd4e62a19097a1e7951cc90 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 15:34:14 +0100 Subject: [PATCH 10/13] Fix: remove AllFileFilter in selectFile window --- src/main/java/com/cys4/sensitivediscoverer/Utils.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index e40485d..9564da4 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -95,6 +95,8 @@ public static String selectFile(List extensionNames, boolean openFile) { JFrame parentFrame = new JFrame(); JFileChooser fileChooser = new JFileChooser(); + fileChooser.setAcceptAllFileFilterUsed(false); + //add supported extensions extensionNames.stream() .map(extensionName -> new FileNameExtensionFilter("." + extensionName, extensionName)) @@ -115,14 +117,8 @@ public static String selectFile(List extensionNames, boolean openFile) { String exportFilePath = fileChooser.getSelectedFile().getAbsolutePath(); String selectedExt = fileChooser.getFileFilter().getDescription().toLowerCase(); - if (selectedExt.equals("all files")) - return exportFilePath; - - if (!exportFilePath.toLowerCase().endsWith(selectedExt)) { - exportFilePath += selectedExt; - } - return exportFilePath; + return exportFilePath.toLowerCase().endsWith(selectedExt) ? exportFilePath : exportFilePath+selectedExt; } /** From b8a9750c9611a2853e970c1b5c82fb15cc413faa Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 15:39:19 +0100 Subject: [PATCH 11/13] Fix: add writeLinesToFile function --- .../com/cys4/sensitivediscoverer/Utils.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index 9564da4..dd3be4e 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -190,6 +190,16 @@ public static InputStream getResourceAsStream(String name) { return Utils.class.getClassLoader().getResourceAsStream(name); } + private static void writeLinesToFile(String fileName, List lines) { + try { + PrintWriter pwt = new PrintWriter(fileName, StandardCharsets.UTF_8); + lines.forEach(pwt::println); + pwt.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + public static void saveListToCSV(String csvFile, List regexEntities) { List lines = new ArrayList<>(); @@ -203,13 +213,7 @@ public static void saveListToCSV(String csvFile, List regexEntities lines.add(String.format("\"%s\",\"%s\",\"%s\"", description, regex, sections)); }); - try { - PrintWriter pwt = new PrintWriter(csvFile, StandardCharsets.UTF_8); - lines.forEach(pwt::println); - pwt.close(); - } catch (Exception e) { - e.printStackTrace(); - } + writeLinesToFile(csvFile, lines); } public static void saveListToJSON(String jsonFile, List regexEntities) { @@ -230,13 +234,8 @@ public static void saveListToJSON(String jsonFile, List regexEntiti Type tListEntries = (new TypeToken>() { }).getType(); - try { - PrintWriter pwt = new PrintWriter(jsonFile, StandardCharsets.UTF_8); - List.of(gson.toJson(lines, tListEntries)).forEach(pwt::println); - pwt.close(); - } catch (Exception e) { - e.printStackTrace(); - } + writeLinesToFile(jsonFile, List.of(gson.toJson(lines, tListEntries))); + } public static void openListFromCSV(String csvFile, RegexListContext ctx) { From 80879f958033a586bfcf39557a1cca38fa4ec061 Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 16:06:53 +0100 Subject: [PATCH 12/13] Fix: code optimization --- .../com/cys4/sensitivediscoverer/RegexListViewer.java | 5 ----- src/main/java/com/cys4/sensitivediscoverer/Utils.java | 11 +++++------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java index d77ad63..dbfd048 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java +++ b/src/main/java/com/cys4/sensitivediscoverer/RegexListViewer.java @@ -17,7 +17,6 @@ import java.awt.*; import java.util.Arrays; import java.util.List; -import java.util.Objects; import java.util.function.Supplier; import static com.cys4.sensitivediscoverer.Messages.getLocaleString; @@ -258,8 +257,6 @@ private JMenuItem createListSaveMenuItem(List regexEntities) { String fileName = Utils.selectFile(options, false); - if (Objects.isNull(fileName)) return; - if (fileName.toUpperCase().endsWith("JSON")) { Utils.saveListToJSON(fileName, regexEntities); } else if (fileName.toUpperCase().endsWith("CSV")) { @@ -279,8 +276,6 @@ private JMenuItem createListOpenMenuItem(RegexListContext ctx, String fileName = Utils.selectFile(options, true); - if (Objects.isNull(fileName)) return; - if (fileName.toUpperCase().endsWith("JSON")) { Utils.openListFromJSON(fileName, ctx); } else if (fileName.toUpperCase().endsWith("CSV")) { diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index dd3be4e..2c879a8 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -88,7 +88,7 @@ public static void saveToFile(String extensionName, List lines) { * Open JFileChooser to get a file name * * @param extensionNames the extensions to filter files - * @param openFile Set to true if the file should be opened, false if it should be saved + * @param openFile Set to true if the file should be opened, false if it should be saved * @return The filename, or null if there was an error */ public static String selectFile(List extensionNames, boolean openFile) { @@ -103,8 +103,8 @@ public static String selectFile(List extensionNames, boolean openFile) { .forEachOrdered(fileChooser::addChoosableFileFilter); //set window title to Open or Save - fileChooser.setDialogTitle(getLocaleString(openFile? - getLocaleString("utils-linesFromFile-importFile") + fileChooser.setDialogTitle(getLocaleString(openFile ? + "utils-linesFromFile-importFile" : "utils-saveToFile-exportFile")); //show the Open or Save window @@ -112,13 +112,13 @@ public static String selectFile(List extensionNames, boolean openFile) { fileChooser.showOpenDialog(parentFrame) : fileChooser.showSaveDialog(parentFrame); - if (userSelection != JFileChooser.APPROVE_OPTION) return null; + if (userSelection != JFileChooser.APPROVE_OPTION) return ""; String exportFilePath = fileChooser.getSelectedFile().getAbsolutePath(); String selectedExt = fileChooser.getFileFilter().getDescription().toLowerCase(); - return exportFilePath.toLowerCase().endsWith(selectedExt) ? exportFilePath : exportFilePath+selectedExt; + return exportFilePath.toLowerCase().endsWith(selectedExt) ? exportFilePath : exportFilePath + selectedExt; } /** @@ -235,7 +235,6 @@ public static void saveListToJSON(String jsonFile, List regexEntiti }).getType(); writeLinesToFile(jsonFile, List.of(gson.toJson(lines, tListEntries))); - } public static void openListFromCSV(String csvFile, RegexListContext ctx) { From df49ea3b38726b44ac4ee9318e8864d8a7f6bfea Mon Sep 17 00:00:00 2001 From: davidebresaola Date: Wed, 20 Mar 2024 17:27:21 +0100 Subject: [PATCH 13/13] Fix: code optimization export Logs --- .../com/cys4/sensitivediscoverer/Utils.java | 33 ++++++++++--------- .../sensitivediscoverer/tab/LoggerTab.java | 11 +++++-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/cys4/sensitivediscoverer/Utils.java b/src/main/java/com/cys4/sensitivediscoverer/Utils.java index 2c879a8..5967c89 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/Utils.java +++ b/src/main/java/com/cys4/sensitivediscoverer/Utils.java @@ -89,7 +89,7 @@ public static void saveToFile(String extensionName, List lines) { * * @param extensionNames the extensions to filter files * @param openFile Set to true if the file should be opened, false if it should be saved - * @return The filename, or null if there was an error + * @return The filename, or empty string if there was an error */ public static String selectFile(List extensionNames, boolean openFile) { JFrame parentFrame = new JFrame(); @@ -190,7 +190,7 @@ public static InputStream getResourceAsStream(String name) { return Utils.class.getClassLoader().getResourceAsStream(name); } - private static void writeLinesToFile(String fileName, List lines) { + public static void writeLinesToFile(String fileName, List lines) { try { PrintWriter pwt = new PrintWriter(fileName, StandardCharsets.UTF_8); lines.forEach(pwt::println); @@ -200,6 +200,15 @@ private static void writeLinesToFile(String fileName, List lines) { } } + private static List readLinesFromFile(String fileName) { + try { + return Files.readAllLines(Path.of(fileName)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + public static void saveListToCSV(String csvFile, List regexEntities) { List lines = new ArrayList<>(); @@ -239,13 +248,9 @@ public static void saveListToJSON(String jsonFile, List regexEntiti public static void openListFromCSV(String csvFile, RegexListContext ctx) { StringBuilder alreadyAddedMsg = new StringBuilder(); - List lines; - try { - lines = Files.readAllLines(Path.of(csvFile)); - } catch (IOException e) { - e.printStackTrace(); - return; - } + + List lines = readLinesFromFile(csvFile); + if (Objects.isNull(lines)) return; //Skip header line if present int startRow = (lines.get(0).contains("\"description\",\"regex\"")) ? 1 : 0; @@ -287,13 +292,9 @@ public static void openListFromCSV(String csvFile, RegexListContext ctx) { public static void openListFromJSON(String jsonFile, RegexListContext ctx) { Gson gson = new Gson(); StringBuilder alreadyAddedMsg = new StringBuilder(); - List lines; - try { - lines = Files.readAllLines(Path.of(jsonFile)); - } catch (IOException e) { - e.printStackTrace(); - return; - } + + List lines = readLinesFromFile(jsonFile); + if (Objects.isNull(lines)) return; Type tArrayListRegexEntity = new TypeToken>() { }.getType(); diff --git a/src/main/java/com/cys4/sensitivediscoverer/tab/LoggerTab.java b/src/main/java/com/cys4/sensitivediscoverer/tab/LoggerTab.java index 2a5a999..08b4cfb 100644 --- a/src/main/java/com/cys4/sensitivediscoverer/tab/LoggerTab.java +++ b/src/main/java/com/cys4/sensitivediscoverer/tab/LoggerTab.java @@ -319,6 +319,9 @@ private JToggleButton createExportLogsButton() { JMenuItem itemToCSV = new JMenuItem(getLocaleString("common-toCSV")); itemToCSV.addActionListener(actionEvent -> { + String csvFile = Utils.selectFile(List.of("CSV"), false); + if (csvFile.isBlank()) return; + java.util.List lines = new ArrayList<>(); lines.add(String.format("\"%s\",\"%s\"", @@ -332,12 +335,15 @@ private JToggleButton createExportLogsButton() { lines.add(String.format("\"%s\",\"%s\"", url, matchEscaped)); } - Utils.saveToFile("csv", lines); + Utils.writeLinesToFile(csvFile, lines); }); menu.add(itemToCSV); JMenuItem itemToJSON = new JMenuItem(getLocaleString("common-toJSON")); itemToJSON.addActionListener(actionEvent -> { + String jsonFile = Utils.selectFile(List.of("JSON"), false); + if (jsonFile.isBlank()) return; + java.util.List lines = new ArrayList<>(); String prop1 = logsTableModel.getColumnNameFormatted(0); @@ -355,7 +361,8 @@ private JToggleButton createExportLogsButton() { Gson gson = builder.create(); Type tListEntries = new TypeToken>() { }.getType(); - Utils.saveToFile("json", List.of(gson.toJson(lines, tListEntries))); + + Utils.writeLinesToFile(jsonFile, List.of(gson.toJson(lines, tListEntries))); }); menu.add(itemToJSON);