diff --git a/build.gradle b/build.gradle index faaed309..31bc9933 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ repositories { dependencies { implementation 'net.portswigger.burp.extensions:montoya-api:1.0.0' implementation 'org.swinglabs:swingx:1.6.1' - implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:8501f80f05' + implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:07e3e02b' implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.15.2' implementation 'org.apache.httpcomponents:httpclient:4.5.13' implementation 'org.apache.commons:commons-text:1.10.0' diff --git a/src/main/java/com/nccgroup/loggerplusplus/filter/tag/Tag.java b/src/main/java/com/nccgroup/loggerplusplus/filter/tag/Tag.java index 5f5e8c14..d21c2eb5 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/filter/tag/Tag.java +++ b/src/main/java/com/nccgroup/loggerplusplus/filter/tag/Tag.java @@ -140,6 +140,6 @@ public boolean shouldRetest() { @Override public String toString() { - return "ColorFilter[" + (this.filter != null ? this.filter.toString() : "") + "]"; + return this.getName(); } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java index df693ac2..fa3071c0 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java @@ -533,7 +533,7 @@ public Object getValueByKey(LogEntryField columnName) { case REQUEST_TOOL: return tool.toolName(); case TAGS: - return this.matchingTags.stream().map(Tag::getName).collect(Collectors.toList()); + return this.matchingTags.stream().collect(Collectors.toList()); case URL: return this.urlString; case PATH: diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java index e7a1750f..a666d3ab 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java @@ -13,10 +13,13 @@ package com.nccgroup.loggerplusplus.logview.logtable; import com.coreyd97.BurpExtenderUtilities.Preferences; +import com.nccgroup.loggerplusplus.logentry.LogEntryField; import com.nccgroup.loggerplusplus.util.Globals; import com.nccgroup.loggerplusplus.LoggerPlusPlus; +import com.nccgroup.loggerplusplus.util.userinterface.renderer.TagRenderer; import javax.swing.event.TableColumnModelEvent; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.TableColumn; import java.util.*; @@ -47,6 +50,11 @@ public LogTableColumnModel(LogTableController controller) { } } + Optional tagColumn = this.allColumns.stream().filter(logTableColumn -> logTableColumn.getName().equals("Tags")).findFirst(); + if((boolean) preferences.getSetting(Globals.PREF_TABLE_PILL_STYLE) && tagColumn.isPresent()){ + tagColumn.get().setCellRenderer(new TagRenderer()); + } + initialize(); } @@ -167,7 +175,7 @@ public void hideColumn(LogTableColumn column){ } } - public Enumeration getAllColumns() { - return Collections.enumeration(this.allColumns); + public List getAllColumns() { + return this.allColumns; } } diff --git a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java index b1b84cc7..e37a3c65 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java +++ b/src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java @@ -62,10 +62,8 @@ public void actionPerformed(ActionEvent e) { item = new JMenuItem("Make all visible"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Enumeration columnEnumeration = logTable.getColumnModel().getAllColumns(); - while (columnEnumeration.hasMoreElements()) { - LogTableColumn logTableColumn = columnEnumeration.nextElement(); - logTable.getColumnModel().showColumn(logTableColumn); + for (LogTableColumn column : logTable.getColumnModel().getAllColumns()) { + logTable.getColumnModel().showColumn(column); } logTableController.getLogTableColumnModel().saveLayout(); } @@ -74,9 +72,8 @@ public void actionPerformed(ActionEvent e) { Map groupMenus = new HashMap<>(); - Enumeration columnEnumeration = logTable.getColumnModel().getAllColumns(); - while (columnEnumeration.hasMoreElements()) { - LogTableColumn logTableColumn = columnEnumeration.nextElement(); + for (LogTableColumn logTableColumn : logTable.getColumnModel().getAllColumns()) { + FieldGroup group = logTableColumn.getIdentifier().getFieldGroup(); if (!groupMenus.containsKey(group)) { groupMenus.put(group, new JMenu(group.getLabel())); diff --git a/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java b/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java index dfb678e2..442ed444 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java +++ b/src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java @@ -16,7 +16,6 @@ import com.nccgroup.loggerplusplus.logentry.LogEntrySerializer; import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn; import com.nccgroup.loggerplusplus.util.Globals; -import lombok.extern.java.Log; import lombok.extern.log4j.Log4j2; import org.apache.logging.log4j.Level; @@ -78,6 +77,7 @@ protected void registerSettings() { prefs.registerSetting(PREF_LOG_EXTENSIONS, Boolean.class, true); prefs.registerSetting(PREF_LOG_TARGET_TAB, Boolean.class, true); prefs.registerSetting(PREF_MAX_RESP_SIZE, Integer.class, 10); //Default 10MB + prefs.registerSetting(PREF_TABLE_PILL_STYLE, Boolean.class, true); prefs.registerSetting(PREF_COLOR_FILTERS, new TypeToken>() { }.getType(), defaultColorFilters); prefs.registerSetting(PREF_TAG_FILTERS, new TypeToken>() { diff --git a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java index 3965fdd4..bcc8fed7 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java @@ -24,15 +24,17 @@ import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter; import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter; import com.nccgroup.loggerplusplus.imports.LoggerImport; +import com.nccgroup.loggerplusplus.logentry.LogEntryField; +import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn; +import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumnModel; import com.nccgroup.loggerplusplus.util.MoreHelp; +import com.nccgroup.loggerplusplus.util.userinterface.renderer.TagRenderer; import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; import java.awt.*; import java.awt.event.ActionEvent; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; import static com.nccgroup.loggerplusplus.util.Globals.*; @@ -208,6 +210,21 @@ public void actionPerformed(ActionEvent e) { ((SpinnerNumberModel) maxResponseSize.getModel()).setMaximum(1000000); ((SpinnerNumberModel) maxResponseSize.getModel()).setStepSize(1); + JCheckBox tagStyle = otherPanel.addPreferenceComponent(preferences, PREF_TABLE_PILL_STYLE, "Display matching tags as pill components"); + + preferences.addSettingListener((source, settingName, newValue) -> { + if(Objects.equals(settingName, PREF_TABLE_PILL_STYLE)){ + LogTableColumnModel columnModel = LoggerPlusPlus.instance.getLogViewController().getLogViewPanel().getLogTable().getColumnModel(); + Optional column = columnModel.getAllColumns().stream().filter(logTableColumn -> logTableColumn.getIdentifier() == LogEntryField.TAGS).findFirst(); + if(column.isEmpty()) return; + if((boolean) newValue) { + column.get().setCellRenderer(new TagRenderer()); + }else{ + column.get().setCellRenderer(new DefaultTableCellRenderer()); + } + } + }); + ComponentGroup savedFilterSharing = new ComponentGroup(Orientation.VERTICAL, "Saved Filter Sharing"); savedFilterSharing.add(new JButton(new AbstractAction("Import Saved Filters") { @Override diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java b/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java index 8ff26039..e7d069db 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java +++ b/src/main/java/com/nccgroup/loggerplusplus/util/Globals.java @@ -75,6 +75,7 @@ public class Globals { public static final String PREF_SAVED_FIELD_SELECTIONS = "savedFieldSelections"; public static final String PREF_COLUMNS_VERSION = "columnsVersion"; public static final String PREF_MAX_RESP_SIZE = "maxRespBodySize"; + public static final String PREF_TABLE_PILL_STYLE = "tagsStyle"; public enum ElasticAuthType {ApiKey, Basic, None} diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTable.java b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTable.java index 50440a36..747c4db3 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTable.java +++ b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTable.java @@ -2,7 +2,9 @@ import com.nccgroup.loggerplusplus.filter.tag.Tag; import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController; +import com.nccgroup.loggerplusplus.util.userinterface.ColorEditor; import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer; +import com.nccgroup.loggerplusplus.util.userinterface.renderer.ColorRenderer; import com.nccgroup.loggerplusplus.util.userinterface.renderer.FilterRenderer; import javax.swing.*; @@ -28,7 +30,11 @@ public class TagTable extends JTable { ((JComponent) this.getDefaultRenderer(JButton.class)).setOpaque(true); this.getColumnModel().getColumn(1).setCellRenderer(new FilterRenderer()); - this.getColumnModel().getColumn(3).setCellRenderer(new ButtonRenderer()); + this.getColumnModel().getColumn(2).setCellRenderer(new ColorRenderer(true)); + this.getColumnModel().getColumn(2).setCellEditor(new ColorEditor()); + this.getColumnModel().getColumn(3).setCellRenderer(new ColorRenderer(true)); + this.getColumnModel().getColumn(3).setCellEditor(new ColorEditor()); + this.getColumnModel().getColumn(5).setCellRenderer(new ButtonRenderer()); this.setDragEnabled(true); diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTableModel.java b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTableModel.java index c1d64bd0..df67bb0d 100644 --- a/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTableModel.java +++ b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTableModel.java @@ -7,7 +7,9 @@ import javax.swing.*; import javax.swing.table.AbstractTableModel; +import java.awt.*; import java.util.*; +import java.util.List; /** * Created by corey on 19/07/17. @@ -16,7 +18,7 @@ public class TagTableModel extends AbstractTableModel { private final Map rowUUIDs = new HashMap(); private final Map tags; - private final String[] columnNames = {"Tag", "LogFilter", "Enabled", ""}; + private final String[] columnNames = {"Tag", "LogFilter", "Foreground Color", "Background Color", "Enabled", ""}; private final JButton removeButton = new JButton("Remove"); private final FilterLibraryController filterLibraryController; @@ -55,8 +57,12 @@ public Object getValueAt(int row, int col) { case 1: return (tags.get(rowUid).getFilterString() == null ? "" : tags.get(rowUid).getFilterString()); case 2: - return tags.get(rowUid).isEnabled(); + return (tags.get(rowUid).getForegroundColor() == null ? Color.BLACK : tags.get(rowUid).getForegroundColor()); case 3: + return (tags.get(rowUid).getBackgroundColor() == null ? Color.WHITE : tags.get(rowUid).getBackgroundColor()); + case 4: + return tags.get(rowUid).isEnabled(); + case 5: return removeButton; default: return false; @@ -92,6 +98,12 @@ public void setValueAt(Object value, int row, int col) { break; } case 2: + tag.setForegroundColor((Color) value); + break; + case 3: + tag.setBackgroundColor((Color) value); + break; + case 4: tag.setEnabled((Boolean) value); break; default: @@ -106,8 +118,11 @@ public void setValueAt(Object value, int row, int col) { public Class getColumnClass(int columnIndex) { switch (columnIndex) { case 2: - return Boolean.class; case 3: + return Color.class; + case 4: + return Boolean.class; + case 5: return JButton.class; default: return String.class; @@ -116,7 +131,7 @@ public Class getColumnClass(int columnIndex) { @Override public boolean isCellEditable(int row, int col) { - return col != 3; + return col != 5; } public void addTag(Tag tag) { @@ -128,7 +143,7 @@ public void addTag(Tag tag) { } public void onClick(int row, int column) { - if (row != -1 && row < tags.size() && column == 3) { + if (row != -1 && row < tags.size() && column == 5) { synchronized (rowUUIDs) { Tag removedFilter = tags.get(rowUUIDs.get((short) row)); filterLibraryController.removeTag(removedFilter); diff --git a/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/renderer/TagRenderer.java b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/renderer/TagRenderer.java new file mode 100644 index 00000000..4becad10 --- /dev/null +++ b/src/main/java/com/nccgroup/loggerplusplus/util/userinterface/renderer/TagRenderer.java @@ -0,0 +1,36 @@ +package com.nccgroup.loggerplusplus.util.userinterface.renderer; + +import com.nccgroup.loggerplusplus.filter.tag.Tag; +import org.jdesktop.swingx.HorizontalLayout; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; + +/** + * Created by corey on 22/08/17. + */ +public class TagRenderer implements TableCellRenderer { + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JPanel tagWrapper = new JPanel(); + tagWrapper.setLayout(new HorizontalLayout(2)); + tagWrapper.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); + + if(value instanceof Collection){ + for (Object o : ((Collection) value).toArray()) { + JButton c = new JButton(((Tag) o).getName()); + c.putClientProperty("JButton.buttonType", "roundRect"); + c.setMargin(new Insets(7,4,7,4)); + c.setBackground(((Tag) o).getBackgroundColor()); + c.setForeground(((Tag) o).getForegroundColor()); + tagWrapper.add(c); + } + } + + return tagWrapper; + } +}