From 2c535800aae8ac2c2cb536fbf49bd50a6da2eb7b Mon Sep 17 00:00:00 2001 From: hmmachadocx Date: Thu, 18 Nov 2021 15:42:11 +0000 Subject: [PATCH 1/4] AST-6024 - Eclipse - Add option to filter - Severity - Status - State - Refactored code to uncouple utils methods and actions from the main logic --- .../checkmarx/eclipse/utils/PluginUtils.java | 68 +++++ .../eclipse/views/CheckmarxView.java | 232 +++--------------- .../views/actions/ActionAbortScanResults.java | 40 +++ .../views/actions/ActionClearSelection.java | 109 ++++++++ .../views/actions/ActionGetScanResults.java | 76 ++++++ .../actions/ActionOpenPreferencesPage.java | 46 ++++ .../eclipse/views/actions/CxBaseAction.java | 36 +++ .../eclipse/views/actions/ToolBarActions.java | 82 +++++++ 8 files changed, 489 insertions(+), 200 deletions(-) create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java new file mode 100644 index 00000000..4c449d3b --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java @@ -0,0 +1,68 @@ +package com.checkmarx.eclipse.utils; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import org.eclipse.jface.viewers.ComboViewer; + +public class PluginUtils { + + private static final String PARAM_TIMESTAMP_PATTERN = "yyyy-MM-dd | HH:mm:ss"; + private static final String PARAM_SCAN_ID_VALID_FORMAT = "[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[0-9a-f]{12}"; + + + /** + * Converts a String timestamp to a specific format + * + * @param timestamp + * @return + */ + public static String convertStringTimeStamp(String timestamp) { + + String parsedDate = null; + + try { + + Instant instant = Instant.parse(timestamp); + + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PARAM_TIMESTAMP_PATTERN).withZone(ZoneId.systemDefault()); + parsedDate = dateTimeFormatter.format(instant); + } catch (Exception e) { + System.out.println(e); + return timestamp; + } + + return parsedDate; + } + + /** + * Validate scan id format + * + * @param scanId + * @return + */ + public static boolean validateScanIdFormat(String scanId) { + return scanId.matches(PARAM_SCAN_ID_VALID_FORMAT); + } + + /** + * Enables a combo viewer + * + * @param comboviewer + * @param enable + */ + public static void enableComboViewer(ComboViewer comboviewer, boolean enable){ + comboviewer.getCombo().setEnabled(enable); + } + + /** + * Set combo viewer placeholder + * + * @param comboViewer + * @param text + */ + public static void setTextForComboViewer(ComboViewer comboViewer , String text) { + comboViewer.getCombo().setText(text); + } +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java index 5afd2b60..c06c86d8 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java @@ -1,8 +1,5 @@ package com.checkmarx.eclipse.views; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -20,7 +17,6 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.viewers.ArrayContentProvider; @@ -54,7 +50,6 @@ import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.ViewPart; @@ -64,6 +59,9 @@ import com.checkmarx.ast.scan.Scan; import com.checkmarx.eclipse.Activator; import com.checkmarx.eclipse.utils.PluginConstants; +import com.checkmarx.eclipse.utils.PluginUtils; +import com.checkmarx.eclipse.views.actions.ActionOpenPreferencesPage; +import com.checkmarx.eclipse.views.actions.ToolBarActions; import com.checkmarx.eclipse.views.provider.ColumnProvider; import com.checkmarx.eclipse.views.provider.TreeContentProvider; @@ -87,20 +85,15 @@ public class CheckmarxView extends ViewPart { public static final Image INFO_SEVERITY = Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui/icons/full/obj16/info_tsk.png").createImage(); - IWorkbench workbench; - private TreeViewer viewer; private ComboViewer scanIdComboViewer, projectComboViewer; private StringFieldEditor scanIdField; - private Action getScanResultsAction, openPrefPageAction, abortGetResultsAction, clearSelectionAction, refreshProjectListAction; private DisplayModel rootModel; private Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); private static final String RUNNING = "Retrieving the results for the scan id: %s ."; - private static final String ABORTING = "Aborting the retrieval of results..."; - private static final String INIT_MESSAGE = "Paste a scanId and hit play to fetch the results."; private static final String PROJECT_COMBO_VIEWER_TEXT = "Select project"; private static final String SCAN_COMBO_VIEWER_TEXT = "Select scan id"; @@ -120,7 +113,8 @@ public class CheckmarxView extends ViewPart { private Composite topComposite; private Composite resultInfoCompositePanel , attackVectorCompositePanel; private Composite leftCompositePanel; - + + private ToolBarActions toolBarActions; public CheckmarxView() { super(); @@ -140,7 +134,6 @@ public void dispose() { @Override public void createPartControl(Composite parent) { createViewer(parent); - createActions(); createToolbar(); createContextMenu(); @@ -157,118 +150,17 @@ private void createContextMenu() { } private void fillContextMenu(IMenuManager manager) { -// ITreeSelection selection = viewer.getStructuredSelection(); -// DisplayModel selected = (DisplayModel)selection.getFirstElement(); - manager.add(openPrefPageAction); + Action openPreferencesPageAction = new ActionOpenPreferencesPage(rootModel, viewer, alreadyRunning, scanIdField, shell).createAction(); + manager.add(openPreferencesPageAction); } private void createToolbar() { IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); - toolBarManager.add(clearSelectionAction); - // toolBarManager.add(refreshProjectListAction); - toolBarManager.add(getScanResultsAction); - toolBarManager.add(abortGetResultsAction); + toolBarActions = new ToolBarActions(rootModel, viewer, alreadyRunning, scanIdField, resultInfoCompositePanel, attackVectorCompositePanel, leftCompositePanel, scanIdComboViewer, projectComboViewer); - } - - private void createActions() { - getScanResultsAction = new Action() { - @Override - public void run() { - if (alreadyRunning) - return; - String scanId = scanIdField.getStringValue(); - if (!validateScanIdFormat(scanId)) { - showMessage("Incorrect scanId format."); - return; - } - - showMessage(String.format(RUNNING, scanId)); - - getScanResultsAction.setEnabled(false); - abortGetResultsAction.setEnabled(true); - - - CompletableFuture.runAsync(() -> { - alreadyRunning = true; - List scanResults = DataProvider.INSTANCE.getResultsForScanId(scanId); - - rootModel.children.clear(); - rootModel.children.addAll(scanResults); - viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - getScanResultsAction.setEnabled(true); - alreadyRunning = false; - - - }); - - } - }; - - getScanResultsAction.setText("Scan Results"); - getScanResultsAction.setToolTipText("Get results for the scan id."); - getScanResultsAction.setImageDescriptor( - Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui.browser/icons/clcl16/nav_go.png")); - - openPrefPageAction = new Action() { - - @Override - public void run() { - PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn(shell, - "com.checkmarx.eclipse.properties.preferencespage", null, null); - if (pref != null) - pref.open(); - } - }; - - openPrefPageAction.setText("Preferences"); - - abortGetResultsAction = new Action() { - @Override - public void run() { - showMessage(ABORTING); - DataProvider.abort.set(true); - abortGetResultsAction.setEnabled(false); - } - }; - abortGetResultsAction.setImageDescriptor( - Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui.browser/icons/clcl16/nav_stop.png")); - abortGetResultsAction.setEnabled(false); - - - clearSelectionAction = new Action() { - @Override - public void run() { - - clearSelectionFromTheViewers(); - } - }; - clearSelectionAction.setImageDescriptor( - Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui/icons/full/etool16/delete.png")); - clearSelectionAction.setText("Clear Selection"); - clearSelectionAction.setToolTipText("Clear the selected scanId and the results view."); - -// refreshProjectListAction = new Action() { -// @Override -// public void run() { -// List projectList = DataProvider.INSTANCE.getProjectList(); -// projectComboViewer.setInput(projectList); -// projectComboViewer.refresh(); -// } -// }; -// refreshProjectListAction.setImageDescriptor( -// Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui.browser/icons/clcl16/nav_refresh.png")); -// refreshProjectListAction.setText("Refresh Projects"); -// refreshProjectListAction.setToolTipText("Reload/Refresh the projects list."); - - } - - private boolean validateScanIdFormat(String scanId) { - - if (scanId.matches("[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[0-9a-f]{12}")) { - return true; + for(Action action : toolBarActions.getToolBarActions()) { + toolBarManager.add(action); } - return false; } @Override @@ -278,9 +170,6 @@ public void setFocus() { private void createViewer(Composite parent) { - - - GridLayout parentLayout = new GridLayout(); parentLayout.numColumns = 1; parentLayout.horizontalSpacing = 0; @@ -289,8 +178,6 @@ private void createViewer(Composite parent) { parentLayout.marginWidth = 0; parent.setLayout(parentLayout); - - //Top Bar Composite Panel topComposite = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); @@ -301,19 +188,12 @@ private void createViewer(Composite parent) { topGridData.horizontalAlignment = GridData.FILL; topGridData.verticalAlignment = GridData.FILL; topGridData.grabExcessHorizontalSpace = true; - //topGridData.grabExcessVerticalSpace = true; topComposite.setLayoutData(topGridData); createProjectListComboBox(topComposite); createScanIdComboBox(topComposite); - //Bottom Panel Composite bottomComposite = new Composite(parent, SWT.BORDER); -// GridLayout bottomLayout = new GridLayout(); -// bottomLayout.numColumns = 3; -// bottomLayout.makeColumnsEqualWidth = true; -// bottomLayout.horizontalSpacing = 0; -// bottomLayout.verticalSpacing = 0; GridData bottomGridData = new GridData(); bottomGridData.horizontalAlignment = GridData.FILL; @@ -325,8 +205,6 @@ private void createViewer(Composite parent) { bottomComposite.setLayout(bottomLayout); bottomComposite.setLayoutData(bottomGridData); - - leftCompositePanel = new Composite(bottomComposite, SWT.BORDER); GridLayout leftCompositeLayout = new GridLayout(); leftCompositeLayout.numColumns = 1; @@ -343,15 +221,13 @@ private void createViewer(Composite parent) { scanIdField.getTextControl(leftCompositePanel).addListener(SWT.DefaultSelection, new Listener() { public void handleEvent(Event event) { - getScanResultsAction.run(); + toolBarActions.getScanResultsAction().run(); } }); scanIdField.getTextControl(leftCompositePanel).setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); - - viewer = new TreeViewer(leftCompositePanel, - SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + viewer = new TreeViewer(leftCompositePanel, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); ColumnViewerToolTipSupport.enableFor(viewer); createColumns(); @@ -359,7 +235,6 @@ public void handleEvent(Event event) { viewer.getTree().setLinesVisible(true); viewer.setContentProvider(new TreeContentProvider()); - // viewer.setLabelProvider(); getSite().setSelectionProvider(viewer); // define layout for the viewer @@ -376,7 +251,6 @@ public void handleEvent(Event event) { configureTreeItemSelectionChangeEvent(viewer); // SECTION 2 - // Setting the BOLD Font for Labels Display display = parent.getShell().getDisplay(); FontData systemFontData = display.getSystemFont().getFontData()[0]; @@ -429,11 +303,8 @@ public void handleEvent(Event event) { attackVectorLabel.setFont(boldFont); attackVectorLabel.setText("Attack Vector:"); - resultInfoCompositePanel.setVisible(false); attackVectorCompositePanel.setVisible(false); - - } private void createProjectListComboBox(Composite parent) @@ -468,8 +339,8 @@ public void selectionChanged(SelectionChangedEvent event) { if (selection.size() > 0){ - enableComboViewer(scanIdComboViewer, false); - setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); + PluginUtils.enableComboViewer(scanIdComboViewer, false); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); scanIdComboViewer.getCombo().update(); @@ -480,14 +351,14 @@ public void selectionChanged(SelectionChangedEvent event) { if(scanList.isEmpty()) { scanIdComboViewer.setInput(scanList); - setTextForComboViewer(scanIdComboViewer, "No scans available."); - enableComboViewer(scanIdComboViewer, true); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "No scans available."); + PluginUtils.enableComboViewer(scanIdComboViewer, true); } else { scanIdComboViewer.setInput(scanList); - setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); - enableComboViewer(scanIdComboViewer, true); + PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(scanIdComboViewer, true); } @@ -496,12 +367,11 @@ public void selectionChanged(SelectionChangedEvent event) { } }); - setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); + PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); } - private void createScanIdComboBox(Composite parent) - { + private void createScanIdComboBox(Composite parent){ scanIdComboViewer = new ComboViewer(parent, SWT.DROP_DOWN); scanIdComboViewer.setContentProvider(ArrayContentProvider.getInstance()); @@ -511,7 +381,7 @@ private void createScanIdComboBox(Composite parent) public String getText(Object element) { if (element instanceof Scan) { Scan scan = (Scan) element; - String updatedAtDate = convertStringTimeStamp(scan.getUpdatedAt()); + String updatedAtDate = PluginUtils.convertStringTimeStamp(scan.getUpdatedAt()); String itemLabel = scan.getID() + " ( " + scan.getStatus() + ", " + updatedAtDate + " )"; return itemLabel ; } @@ -533,7 +403,7 @@ public void selectionChanged(SelectionChangedEvent event) { /// Using async approach so that message can be displayed in the tree while getting the scans list showMessage(String.format(RUNNING, selectedScan.getID())); - getScanResultsAction.setEnabled(false); + toolBarActions.getScanResultsAction().setEnabled(false); CompletableFuture.runAsync(() -> { alreadyRunning = true; @@ -542,55 +412,25 @@ public void selectionChanged(SelectionChangedEvent event) { rootModel.children.clear(); rootModel.children.addAll(scanResults); viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - getScanResultsAction.setEnabled(true); + toolBarActions.getScanResultsAction().setEnabled(true); alreadyRunning = false; }); //end - - -// List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); -// rootModel.children.clear(); -// rootModel.children.addAll(scanResults); -// viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - - } } }); - - - setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); + PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); GridData gridData = new GridData(); gridData.widthHint = 510; scanIdComboViewer.getCombo().setLayoutData(gridData); - enableComboViewer(scanIdComboViewer, false); - + PluginUtils.enableComboViewer(scanIdComboViewer, false); } - private String convertStringTimeStamp(String timestamp) { - - String parsedDate = null; - - try - { - - Instant instant = Instant.parse(timestamp); - - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd | HH:mm:ss").withZone(ZoneId.systemDefault()); - parsedDate = dateTimeFormatter.format(instant); - } - catch(Exception e) - { - System.out.println(e); - } - - return parsedDate; - } private void configureTreeItemSelectionChangeEvent(TreeViewer viewer) { @@ -851,10 +691,10 @@ private void clearResultsTreeViewer() { } private void clearScanIdComboViewer() { - enableComboViewer(scanIdComboViewer, false); + PluginUtils.enableComboViewer(scanIdComboViewer, false); scanIdComboViewer.refresh(); scanIdComboViewer.setInput(Collections.EMPTY_LIST); - setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); + PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); scanIdComboViewer.getCombo().update(); @@ -862,27 +702,19 @@ private void clearScanIdComboViewer() { private void clearProjectComboViewer() { projectComboViewer.setInput(Collections.EMPTY_LIST); - setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); + PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); } - private void setTextForComboViewer(ComboViewer comboViewer , String text) { - comboViewer.getCombo().setText(text); - } private void reloadProjectComboViewer() { - enableComboViewer(projectComboViewer, false); - setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); + PluginUtils.enableComboViewer(projectComboViewer, false); + PluginUtils.setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); projectComboViewer.getCombo().update(); List projectList = DataProvider.INSTANCE.getProjectList(); projectComboViewer.setInput(projectList); projectComboViewer.refresh(); - setTextForComboViewer(projectComboViewer ,PROJECT_COMBO_VIEWER_TEXT); - enableComboViewer(projectComboViewer, true); - - } + PluginUtils.setTextForComboViewer(projectComboViewer ,PROJECT_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(projectComboViewer, true); - private void enableComboViewer(ComboViewer comboviewer, boolean enable) - { - comboviewer.getCombo().setEnabled(enable); } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java new file mode 100644 index 00000000..a22300e0 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java @@ -0,0 +1,40 @@ +package com.checkmarx.eclipse.views.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.TreeViewer; + +import com.checkmarx.eclipse.Activator; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.DisplayModel; + +public class ActionAbortScanResults extends CxBaseAction { + + private static final String MSG_ABORTING_RETRIEVAL_SCAN_RESULTS = "Aborting the retrieval of results..."; + private static final String ACTION_ABORT_SCAN_RESULTS_TOOLTIP = "Abort the retrieval of results"; + private static final String ACTION_ABORT_SCAN_RESULTS_ICON_PATH = "platform:/plugin/org.eclipse.ui.browser/icons/clcl16/nav_stop.png"; + + public ActionAbortScanResults(DisplayModel rootModel, TreeViewer resultsTree) { + super(rootModel, resultsTree); + } + + /** + * Creates a JFace action to abort the retrieving of scan results + */ + public Action createAction() { + Action abortScanResultsAction = new Action() { + @Override + public void run() { + showMessage(MSG_ABORTING_RETRIEVAL_SCAN_RESULTS); + DataProvider.abort.set(true); + this.setEnabled(false); + } + }; + + abortScanResultsAction.setToolTipText(ACTION_ABORT_SCAN_RESULTS_TOOLTIP); + abortScanResultsAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_ABORT_SCAN_RESULTS_ICON_PATH)); + abortScanResultsAction.setEnabled(false); + + return abortScanResultsAction; + } + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java new file mode 100644 index 00000000..2e924662 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java @@ -0,0 +1,109 @@ +package com.checkmarx.eclipse.views.actions; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; + +import com.checkmarx.ast.project.Project; +import com.checkmarx.eclipse.Activator; +import com.checkmarx.eclipse.utils.PluginUtils; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.DisplayModel; + +public class ActionClearSelection extends CxBaseAction { + + private static final String ACTION_CLEAR_SELECTION_TOOLTIP = "Clear the selected scanId and the results view."; + private static final String ACTION_CLEAR_SELECTION_ICON_PATH = "platform:/plugin/org.eclipse.ui/icons/full/etool16/delete.png"; + + private static final String PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT = "Select scan id"; + private static final String PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT = "Select project"; + + private Composite resultInfoCompositePanel; + private Composite attackVectorCompositePanel; + private Composite leftCompositePanel; + + private ComboViewer scanIdComboViewer; + private ComboViewer projectComboViewer; + + public ActionClearSelection(DisplayModel rootModel, TreeViewer resultsTree, Composite resultInfoCompositePanel, Composite attackVectorCompositePanel, Composite leftCompositePanel, ComboViewer scanIdComboViewer, ComboViewer projectComboViewer) { + + super(rootModel, resultsTree); + + this.resultInfoCompositePanel = resultInfoCompositePanel; + this.attackVectorCompositePanel = attackVectorCompositePanel; + this.leftCompositePanel = leftCompositePanel; + this.scanIdComboViewer = scanIdComboViewer; + this.projectComboViewer = projectComboViewer; + } + + /** + * Creates a JFace action to clear selection + */ + public Action createAction() { + Action clearSelectionAction = new Action() { + @Override + public void run() { + resultInfoCompositePanel.setVisible(false); + attackVectorCompositePanel.setVisible(false); + + clearResultsTreeViewer(); + leftCompositePanel.layout(); + + clearScanIdComboViewer(); + clearProjectComboViewer(); + reloadProjectComboViewer(); + } + }; + + clearSelectionAction.setToolTipText(ACTION_CLEAR_SELECTION_TOOLTIP); + clearSelectionAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_CLEAR_SELECTION_ICON_PATH)); + + return clearSelectionAction; + } + + /** + * Clears Results' tree + */ + private void clearResultsTreeViewer() { + rootModel.children.clear(); + resultsTree.refresh(); + } + + /** + * Clears Scans' combobox + */ + private void clearScanIdComboViewer() { + PluginUtils.enableComboViewer(scanIdComboViewer, false); + scanIdComboViewer.refresh(); + scanIdComboViewer.setInput(Collections.EMPTY_LIST); + PluginUtils.setTextForComboViewer(scanIdComboViewer, PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT); + scanIdComboViewer.getCombo().update(); + } + + /** + * Clears Projects' combobox + */ + private void clearProjectComboViewer() { + projectComboViewer.setInput(Collections.EMPTY_LIST); + PluginUtils.setTextForComboViewer(projectComboViewer, PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); + } + + /** + * Reloads Projects' combobox + */ + private void reloadProjectComboViewer() { + PluginUtils.enableComboViewer(projectComboViewer, false); + PluginUtils.setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); + projectComboViewer.getCombo().update(); + List projectList = DataProvider.INSTANCE.getProjectList(); + projectComboViewer.setInput(projectList); + projectComboViewer.refresh(); + PluginUtils.setTextForComboViewer(projectComboViewer ,PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(projectComboViewer, true); + } + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java new file mode 100644 index 00000000..77988b1f --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java @@ -0,0 +1,76 @@ +package com.checkmarx.eclipse.views.actions; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.viewers.TreeViewer; + +import com.checkmarx.eclipse.Activator; +import com.checkmarx.eclipse.utils.PluginUtils; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.DisplayModel; + +public class ActionGetScanResults extends CxBaseAction { + + private static final String ACTION_SCAN_RESULTS_TOOLTIP = "Get results for the scan id."; + private static final String ACTION_SCAN_RESULTS_ICON_PATH = "platform:/plugin/org.eclipse.ui.browser/icons/clcl16/nav_go.png"; + + private static final String MSG_RETRIEVING_RESULTS = "Retrieving the results for the scan id: %s ."; + + private Action abortScanResultsAction; + + private boolean alreadyRunning = false; + private StringFieldEditor scanIdField; + + public ActionGetScanResults(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, Action abortScanResultsAction) { + + super(rootModel, resultsTree); + + this.abortScanResultsAction = abortScanResultsAction; + this.alreadyRunning = alreadyRunning; + this.scanIdField = scanIdField; + } + + /** + * Creates a JFace action to get scan results + */ + public Action createAction() { + Action getScanResultsAction = new Action() { + @Override + public void run() { + if (alreadyRunning) + return; + String scanId = scanIdField.getStringValue(); + if (!PluginUtils.validateScanIdFormat(scanId)) { + showMessage("Incorrect scanId format."); + return; + } + + showMessage(String.format(MSG_RETRIEVING_RESULTS, scanId)); + + this.setEnabled(false); + abortScanResultsAction.setEnabled(true); + + CompletableFuture.runAsync(() -> { + alreadyRunning = true; + List scanResults = DataProvider.INSTANCE.getResultsForScanId(scanId); + + rootModel.children.clear(); + rootModel.children.addAll(scanResults); + resultsTree.getTree().getDisplay().asyncExec(() -> resultsTree.refresh()); + this.setEnabled(true); + alreadyRunning = false; + }); + + } + }; + + getScanResultsAction.setToolTipText(ACTION_SCAN_RESULTS_TOOLTIP); + getScanResultsAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_SCAN_RESULTS_ICON_PATH)); + + return getScanResultsAction; + } + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java new file mode 100644 index 00000000..24f200bd --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java @@ -0,0 +1,46 @@ +package com.checkmarx.eclipse.views.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.PreferencesUtil; + +import com.checkmarx.eclipse.views.DisplayModel; + +public class ActionOpenPreferencesPage extends CxBaseAction { + + private static final String PREFERENCE_PAGE_ID = "com.checkmarx.eclipse.properties.preferencespage"; + private static final String LABEL_PREFERENCES = "Preferences"; + + private Shell shell; + + public ActionOpenPreferencesPage(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, Shell shell) { + + super(rootModel, resultsTree); + + this.shell = shell; + } + + /** + * Creates a JFace action to open the preference page + */ + public Action createAction() { + Action openPreferencesPageAction = new Action() { + @Override + public void run() { + PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn(shell, PREFERENCE_PAGE_ID, null, null); + + if (pref != null) { + pref.open(); + } + } + }; + + openPreferencesPageAction.setText(LABEL_PREFERENCES); + + return openPreferencesPageAction; + } + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java new file mode 100644 index 00000000..6bfd67ed --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java @@ -0,0 +1,36 @@ +package com.checkmarx.eclipse.views.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.TreeViewer; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.DisplayModel; + +public abstract class CxBaseAction { + + public DisplayModel rootModel; + public TreeViewer resultsTree; + + public CxBaseAction(DisplayModel rootModel, TreeViewer resultsTree) { + this.rootModel = rootModel; + this.resultsTree = resultsTree; + } + + /** + * Create a JFace action + * + * @return + */ + public abstract Action createAction(); + + /** + * Add a message to the tree + * + * @param message + */ + public void showMessage(String message) { + rootModel.children.clear(); + rootModel.children.add(DataProvider.INSTANCE.message(message)); + resultsTree.refresh(); + } + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java new file mode 100644 index 00000000..9825bece --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java @@ -0,0 +1,82 @@ +package com.checkmarx.eclipse.views.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; + +import com.checkmarx.eclipse.views.DisplayModel; + +public class ToolBarActions { + + private List toolBarActions = new ArrayList(); + + private DisplayModel rootModel; + private TreeViewer resultsTree; + private StringFieldEditor scanIdField; + private boolean alreadyRunning = false; + + private Composite resultInfoPanel; + private Composite attackVectorPanel; + private Composite leftPanel; + + private ComboViewer scanIdComboViewer; + private ComboViewer projectComboViewer; + + private Action scanResultsAction; + private Action clearSelectionAction; + private Action abortScanResultsAction; + + public ToolBarActions(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, + Composite resultInfoPanel, Composite attackVectorPanel, Composite leftPanel, + ComboViewer scanIdComboViewer, ComboViewer projectComboViewer) { + + this.rootModel = rootModel; + this.resultsTree = resultsTree; + this.alreadyRunning = alreadyRunning; + this.scanIdField = scanIdField; + this.resultInfoPanel = resultInfoPanel; + this.attackVectorPanel = attackVectorPanel; + this.leftPanel = leftPanel; + this.scanIdComboViewer = scanIdComboViewer; + this.projectComboViewer = projectComboViewer; + + createActions(); + } + + /** + * Create all tool bar actions + */ + private void createActions() { + + clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); + abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); + scanResultsAction = new ActionGetScanResults(rootModel, resultsTree, alreadyRunning, scanIdField, abortScanResultsAction).createAction(); + + toolBarActions.add(clearSelectionAction); + toolBarActions.add(scanResultsAction); + toolBarActions.add(abortScanResultsAction); + } + + /** + * Gets all tool bar actions + * + * @return + */ + public List getToolBarActions() { + return this.toolBarActions; + } + + /** + * Gets scan results action + * + * @return + */ + public Action getScanResultsAction() { + return scanResultsAction; + } +} From 5eaf24ac3b23b761173a08a5509cc7cc0c298a72 Mon Sep 17 00:00:00 2001 From: hmmachadocx Date: Fri, 19 Nov 2021 10:48:50 +0000 Subject: [PATCH 2/4] AST-6024 - Eclipse - Add option to filter - Severity - Status - State - Fixed UI tests by putting scan id field's placeholder back; - Create ToolBarActionsBuilder to easily construct ToolBarActions; - Code refactoring --- .../eclipse/views/CheckmarxView.java | 217 ++++++------------ .../eclipse/views/actions/ToolBarActions.java | 103 +++++++-- 2 files changed, 157 insertions(+), 163 deletions(-) diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java index c06c86d8..89bcd476 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java @@ -1,7 +1,6 @@ package com.checkmarx.eclipse.views; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -18,7 +17,6 @@ import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.preference.StringFieldEditor; -import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ComboViewer; @@ -72,19 +70,16 @@ public class CheckmarxView extends ViewPart { */ public static final String ID = "com.checkmarx.eclipse.views.CheckmarxView"; - public static final Image CRITICAL_SEVERITY = Activator.getImageDescriptor("/icons/severity-critical.png") - .createImage(); + public static final Image CRITICAL_SEVERITY = Activator.getImageDescriptor("/icons/severity-critical.png").createImage(); public static final Image HIGH_SEVERITY = Activator.getImageDescriptor("/icons/severity-high.png").createImage(); - public static final Image MEDIUM_SEVERITY = Activator.getImageDescriptor("/icons/severity-medium.png") - .createImage(); + public static final Image MEDIUM_SEVERITY = Activator.getImageDescriptor("/icons/severity-medium.png").createImage(); public static final Image LOW_SEVERITY = Activator.getImageDescriptor("/icons/severity-low.png").createImage(); public static final Image INFO_SEVERITY = Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui/icons/full/obj16/info_tsk.png").createImage(); - IWorkbench workbench; private TreeViewer viewer; @@ -97,12 +92,8 @@ public class CheckmarxView extends ViewPart { private static final String PROJECT_COMBO_VIEWER_TEXT = "Select project"; private static final String SCAN_COMBO_VIEWER_TEXT = "Select scan id"; - private boolean alreadyRunning = false; - private IPropertyChangeListener stringChangeListener; - - Font boldFont; private Text typeValueText; private Text severityValueText; @@ -120,7 +111,7 @@ public CheckmarxView() { super(); // DisplayModel init = new DisplayModel.DisplayModelBuilder("Paste a scanId and hit play to fetch the results.").build(); - rootModel = new DisplayModel.DisplayModelBuilder("").build(); + rootModel = new DisplayModel.DisplayModelBuilder("Paste a scanId and hit play to fetch the results.").build(); // rootModel.children.add(init); } @@ -136,9 +127,8 @@ public void createPartControl(Composite parent) { createViewer(parent); createToolbar(); createContextMenu(); - } - + private void createContextMenu() { MenuManager menuManager = new MenuManager("#PopupMenu"); menuManager.setRemoveAllWhenShown(true); @@ -154,9 +144,23 @@ private void fillContextMenu(IMenuManager manager) { manager.add(openPreferencesPageAction); } + /** + * Creates the Checkmarx plugin tool bar with all actions + */ private void createToolbar() { - IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); - toolBarActions = new ToolBarActions(rootModel, viewer, alreadyRunning, scanIdField, resultInfoCompositePanel, attackVectorCompositePanel, leftCompositePanel, scanIdComboViewer, projectComboViewer); + IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); + + toolBarActions = new ToolBarActions.ToolBarActionsBuilder() + .rootModel(rootModel) + .resultsTree(viewer) + .alreadyRunning(alreadyRunning) + .scanIdField(scanIdField) + .resultInfoPanel(resultInfoCompositePanel) + .attackVectorPanel(attackVectorCompositePanel) + .leftPanel(attackVectorCompositePanel) + .scanIdComboViewer(scanIdComboViewer) + .projectComboViewer(projectComboViewer) + .build(); for(Action action : toolBarActions.getToolBarActions()) { toolBarManager.add(action); @@ -330,45 +334,35 @@ public String getText(Object element) { } }); - projectComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - if (selection.size() > 0){ - - PluginUtils.enableComboViewer(scanIdComboViewer, false); - PluginUtils.setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); - scanIdComboViewer.getCombo().update(); - - - Project selectedProject = ((Project)selection.getFirstElement()); - - List scanList = DataProvider.INSTANCE.getScanListOfProject(selectedProject.getID()); - - if(scanList.isEmpty()) - { - scanIdComboViewer.setInput(scanList); - PluginUtils.setTextForComboViewer(scanIdComboViewer, "No scans available."); - PluginUtils.enableComboViewer(scanIdComboViewer, true); - } - else - { - scanIdComboViewer.setInput(scanList); - PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); - PluginUtils.enableComboViewer(scanIdComboViewer, true); - } - - - - } + if (selection.size() > 0) { + + PluginUtils.enableComboViewer(scanIdComboViewer, false); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); + scanIdComboViewer.getCombo().update(); + + Project selectedProject = ((Project) selection.getFirstElement()); + + List scanList = DataProvider.INSTANCE.getScanListOfProject(selectedProject.getID()); + + if (scanList.isEmpty()) { + scanIdComboViewer.setInput(scanList); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "No scans available."); + PluginUtils.enableComboViewer(scanIdComboViewer, true); + } else { + scanIdComboViewer.setInput(scanList); + PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(scanIdComboViewer, true); + } + } } }); PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); - } private void createScanIdComboBox(Composite parent){ @@ -391,36 +385,34 @@ public String getText(Object element) { scanIdComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); - - if (selection.size() > 0){ - - Scan selectedScan = ((Scan)selection.getFirstElement()); - - /// Using async approach so that message can be displayed in the tree while getting the scans list - showMessage(String.format(RUNNING, selectedScan.getID())); - - toolBarActions.getScanResultsAction().setEnabled(false); - - CompletableFuture.runAsync(() -> { - alreadyRunning = true; - List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); - - rootModel.children.clear(); - rootModel.children.addAll(scanResults); - viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - toolBarActions.getScanResultsAction().setEnabled(true); - alreadyRunning = false; - + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - }); - - //end - } - } + if (selection.size() > 0) { + + Scan selectedScan = ((Scan) selection.getFirstElement()); + + /// Using async approach so that message can be displayed in the tree while + /// getting the scans list + showMessage(String.format(RUNNING, selectedScan.getID())); + + toolBarActions.getScanResultsAction().setEnabled(false); + + CompletableFuture.runAsync(() -> { + alreadyRunning = true; + List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); + + rootModel.children.clear(); + rootModel.children.addAll(scanResults); + viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); + toolBarActions.getScanResultsAction().setEnabled(true); + alreadyRunning = false; + }); + + // end + } + } }); PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); @@ -431,7 +423,6 @@ public void selectionChanged(SelectionChangedEvent event) { PluginUtils.enableComboViewer(scanIdComboViewer, false); } - private void configureTreeItemSelectionChangeEvent(TreeViewer viewer) { viewer.addSelectionChangedListener(new ISelectionChangedListener() { @@ -484,8 +475,6 @@ public void selectionChanged(SelectionChangedEvent event) { } - - private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { clearAttackVectorSection(attackVectorCompositePanel); @@ -518,11 +507,11 @@ private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { } } + if (selectedItem.getType().equalsIgnoreCase(PluginConstants.KICS_INFRASTRUCTURE)) { } - if (selectedItem.getType().equalsIgnoreCase(PluginConstants.SAST)) { String queryName = selectedItem.getResult().getData().getQueryName(); @@ -531,19 +520,13 @@ private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { List nodesList = selectedItem.getResult().getData().getNodes(); if (nodesList != null && nodesList.size() > 0) { - for (Node node : nodesList) { String nodeName = node.getName(); String markerDescription = groupName+"_"+queryName+"_"+ nodeName; - // attackVectorValueText = new Text(attackVectorCompositePanel, SWT.READ_ONLY); - // attackVectorValueText.setText(node.getFileName() + "[" + node.getLine() + "," - // + node.getColumn() + "]"); - Link attackVectorValueLinkText = new Link(attackVectorCompositePanel, SWT.NONE); - String text = "" + node.getFileName() + "[" + node.getLine() + "," + node.getColumn() + "]" - + ""; + String text = "" + node.getFileName() + "[" + node.getLine() + "," + node.getColumn() + "]" + ""; attackVectorValueLinkText.setText(text); attackVectorValueLinkText.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { @@ -558,18 +541,16 @@ public void handleEvent(Event event) { if (attackVectorValueLinkText != null) { attackVectorValueLinkText.setText("Not Available."); } - } } - } private void clearAttackVectorSection(Composite attackVectorCompositePanel) { for (Control child : attackVectorCompositePanel.getChildren()) { - if(!(child instanceof Label)) - child.dispose(); + if (!(child instanceof Label)) + child.dispose(); } } @@ -594,12 +575,9 @@ private void openTheSelectedFile(String fileName, Integer lineNumber, String mar e.printStackTrace(); } } - } - } - private List findFileInWorkspace(final String fileName) { final List foundFiles = new ArrayList(); try { @@ -661,60 +639,9 @@ private Image findSeverityImage(DisplayModel model) { return null; } - public void showMessage(String message) { rootModel.children.clear(); rootModel.children.add(DataProvider.INSTANCE.message(message)); viewer.refresh(); - // monitorActions.forEach(act -> act.setEnabled(true)); - } - - private void clearSelectionFromTheViewers() { - resultInfoCompositePanel.setVisible(false); - attackVectorCompositePanel.setVisible(false); - - - - clearResultsTreeViewer(); - leftCompositePanel.layout(); - - clearScanIdComboViewer(); - clearProjectComboViewer(); - reloadProjectComboViewer(); - - - } - - private void clearResultsTreeViewer() { - rootModel.children.clear(); - viewer.refresh(); - } - - private void clearScanIdComboViewer() { - PluginUtils.enableComboViewer(scanIdComboViewer, false); - scanIdComboViewer.refresh(); - scanIdComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); - scanIdComboViewer.getCombo().update(); - - - } - - private void clearProjectComboViewer() { - projectComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); - } - - - private void reloadProjectComboViewer() { - PluginUtils.enableComboViewer(projectComboViewer, false); - PluginUtils.setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); - projectComboViewer.getCombo().update(); - List projectList = DataProvider.INSTANCE.getProjectList(); - projectComboViewer.setInput(projectList); - projectComboViewer.refresh(); - PluginUtils.setTextForComboViewer(projectComboViewer ,PROJECT_COMBO_VIEWER_TEXT); - PluginUtils.enableComboViewer(projectComboViewer, true); - } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java index 9825bece..b86d778c 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java @@ -28,22 +28,17 @@ public class ToolBarActions { private ComboViewer projectComboViewer; private Action scanResultsAction; - private Action clearSelectionAction; - private Action abortScanResultsAction; - - public ToolBarActions(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, - Composite resultInfoPanel, Composite attackVectorPanel, Composite leftPanel, - ComboViewer scanIdComboViewer, ComboViewer projectComboViewer) { - - this.rootModel = rootModel; - this.resultsTree = resultsTree; - this.alreadyRunning = alreadyRunning; - this.scanIdField = scanIdField; - this.resultInfoPanel = resultInfoPanel; - this.attackVectorPanel = attackVectorPanel; - this.leftPanel = leftPanel; - this.scanIdComboViewer = scanIdComboViewer; - this.projectComboViewer = projectComboViewer; + + public ToolBarActions(ToolBarActionsBuilder toolBarActionsBuilder) { + this.rootModel = toolBarActionsBuilder.rootModel; + this.resultsTree = toolBarActionsBuilder.resultsTree; + this.alreadyRunning = toolBarActionsBuilder.alreadyRunning; + this.scanIdField = toolBarActionsBuilder.scanIdField; + this.resultInfoPanel = toolBarActionsBuilder.resultInfoPanel; + this.attackVectorPanel = toolBarActionsBuilder.attackVectorPanel; + this.leftPanel = toolBarActionsBuilder.leftPanel; + this.scanIdComboViewer = toolBarActionsBuilder.scanIdComboViewer; + this.projectComboViewer = toolBarActionsBuilder.projectComboViewer; createActions(); } @@ -53,8 +48,8 @@ public ToolBarActions(DisplayModel rootModel, TreeViewer resultsTree, boolean al */ private void createActions() { - clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); - abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); + Action clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); + Action abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); scanResultsAction = new ActionGetScanResults(rootModel, resultsTree, alreadyRunning, scanIdField, abortScanResultsAction).createAction(); toolBarActions.add(clearSelectionAction); @@ -79,4 +74,76 @@ public List getToolBarActions() { public Action getScanResultsAction() { return scanResultsAction; } + + /** + * Builder Class to construct a ToolBarActions + * + * @author HugoMa + * + */ + public static class ToolBarActionsBuilder { + + private DisplayModel rootModel; + private TreeViewer resultsTree; + private StringFieldEditor scanIdField; + private boolean alreadyRunning = false; + + private Composite resultInfoPanel; + private Composite attackVectorPanel; + private Composite leftPanel; + + private ComboViewer scanIdComboViewer; + private ComboViewer projectComboViewer; + + public ToolBarActionsBuilder() {} + + public ToolBarActionsBuilder rootModel(DisplayModel rootModel) { + this.rootModel = rootModel; + return this; + } + + public ToolBarActionsBuilder resultsTree(TreeViewer resultsTree) { + this.resultsTree = resultsTree; + return this; + } + + public ToolBarActionsBuilder scanIdField(StringFieldEditor scanIdField) { + this.scanIdField = scanIdField; + return this; + } + + public ToolBarActionsBuilder alreadyRunning(boolean alreadyRunning) { + this.alreadyRunning = alreadyRunning; + return this; + } + + public ToolBarActionsBuilder resultInfoPanel(Composite resultInfoPanel) { + this.resultInfoPanel = resultInfoPanel; + return this; + } + + public ToolBarActionsBuilder attackVectorPanel(Composite attackVectorPanel) { + this.attackVectorPanel = attackVectorPanel; + return this; + } + + public ToolBarActionsBuilder leftPanel(Composite leftPanel) { + this.leftPanel = leftPanel; + return this; + } + + public ToolBarActionsBuilder scanIdComboViewer(ComboViewer scanIdComboViewer) { + this.scanIdComboViewer = scanIdComboViewer; + return this; + } + + public ToolBarActionsBuilder projectComboViewer(ComboViewer projectComboViewer) { + this.projectComboViewer = projectComboViewer; + return this; + } + + public ToolBarActions build() { + return new ToolBarActions(this); + } + } } From 7ceee7de947fb0096e64afcb024ca52b48ab2fe3 Mon Sep 17 00:00:00 2001 From: hmmachadocx Date: Fri, 19 Nov 2021 10:48:50 +0000 Subject: [PATCH 3/4] AST-6024 - Eclipse - Add option to filter - Severity - Status - State - Fixed UI tests by adding initial placeholder to the tree; --- .../ast/eclipse/plugin/tests/ui/TestUI.java | 5 +- .../eclipse/utils/PluginConstants.java | 1 + .../eclipse/views/CheckmarxView.java | 222 ++++++------------ .../eclipse/views/actions/ToolBarActions.java | 103 ++++++-- 4 files changed, 164 insertions(+), 167 deletions(-) diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java index e7b1848d..f5d0f242 100644 --- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java +++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java @@ -11,6 +11,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import com.checkmarx.eclipse.utils.PluginConstants; + import checkmarx.ast.eclipse.plugin.tests.common.Environment; @RunWith(SWTBotJunit4ClassRunner.class) @@ -20,7 +22,6 @@ public class TestUI extends BaseUITest { private static final String ERROR_SERVER_URL_NOT_SET = "Error: Checkmarx server URL is not set"; private static final String INFO_SCAN_RETRIVING_RESULTS = "Retrieving the results for the scan id: " + Environment.SCAN_ID + " ."; - private static final String INFO_TYPE_SCAN_TO_GET_RESULTS = "Paste a scanId and hit play to fetch the results."; private static final String INFO_SUCCESSFUL_CONNECTION = "Connection successfull !"; @@ -96,7 +97,7 @@ public void testEnd2End() throws TimeoutException { preventWidgetWasNullInCIEnvironment(); assertEquals("The tree must contain one row with an info message", _bot.tree().rowCount(), 1); - assertEquals("", INFO_TYPE_SCAN_TO_GET_RESULTS, _bot.tree().cell(0, COLUMN_TITLE)); + assertEquals("", PluginConstants.SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER, _bot.tree().cell(0, COLUMN_TITLE)); // Test incorrect Scan ID format _bot.textWithLabel(LABEL_SCAN_ID).setText("invalid-scan-id"); diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java index ef3fb78d..ba432a51 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java @@ -4,4 +4,5 @@ public class PluginConstants { public static final String SAST = "sast"; public static final String SCA_DEPENDENCY = "dependency"; public static final String KICS_INFRASTRUCTURE = "infrastructure"; + public static final String SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER = "Paste a scan id and hit play to fetch results."; } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java index c06c86d8..c3b4c54f 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java @@ -1,7 +1,6 @@ package com.checkmarx.eclipse.views; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -18,7 +17,6 @@ import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.preference.StringFieldEditor; -import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ComboViewer; @@ -72,19 +70,16 @@ public class CheckmarxView extends ViewPart { */ public static final String ID = "com.checkmarx.eclipse.views.CheckmarxView"; - public static final Image CRITICAL_SEVERITY = Activator.getImageDescriptor("/icons/severity-critical.png") - .createImage(); + public static final Image CRITICAL_SEVERITY = Activator.getImageDescriptor("/icons/severity-critical.png").createImage(); public static final Image HIGH_SEVERITY = Activator.getImageDescriptor("/icons/severity-high.png").createImage(); - public static final Image MEDIUM_SEVERITY = Activator.getImageDescriptor("/icons/severity-medium.png") - .createImage(); + public static final Image MEDIUM_SEVERITY = Activator.getImageDescriptor("/icons/severity-medium.png").createImage(); public static final Image LOW_SEVERITY = Activator.getImageDescriptor("/icons/severity-low.png").createImage(); public static final Image INFO_SEVERITY = Activator.getImageDescriptor("platform:/plugin/org.eclipse.ui/icons/full/obj16/info_tsk.png").createImage(); - IWorkbench workbench; private TreeViewer viewer; @@ -97,12 +92,8 @@ public class CheckmarxView extends ViewPart { private static final String PROJECT_COMBO_VIEWER_TEXT = "Select project"; private static final String SCAN_COMBO_VIEWER_TEXT = "Select scan id"; - private boolean alreadyRunning = false; - private IPropertyChangeListener stringChangeListener; - - Font boldFont; private Text typeValueText; private Text severityValueText; @@ -119,10 +110,7 @@ public class CheckmarxView extends ViewPart { public CheckmarxView() { super(); - // DisplayModel init = new DisplayModel.DisplayModelBuilder("Paste a scanId and hit play to fetch the results.").build(); rootModel = new DisplayModel.DisplayModelBuilder("").build(); - // rootModel.children.add(init); - } @Override @@ -136,9 +124,8 @@ public void createPartControl(Composite parent) { createViewer(parent); createToolbar(); createContextMenu(); - } - + private void createContextMenu() { MenuManager menuManager = new MenuManager("#PopupMenu"); menuManager.setRemoveAllWhenShown(true); @@ -154,9 +141,23 @@ private void fillContextMenu(IMenuManager manager) { manager.add(openPreferencesPageAction); } + /** + * Creates the Checkmarx plugin tool bar with all actions + */ private void createToolbar() { - IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); - toolBarActions = new ToolBarActions(rootModel, viewer, alreadyRunning, scanIdField, resultInfoCompositePanel, attackVectorCompositePanel, leftCompositePanel, scanIdComboViewer, projectComboViewer); + IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); + + toolBarActions = new ToolBarActions.ToolBarActionsBuilder() + .rootModel(rootModel) + .resultsTree(viewer) + .alreadyRunning(alreadyRunning) + .scanIdField(scanIdField) + .resultInfoPanel(resultInfoCompositePanel) + .attackVectorPanel(attackVectorCompositePanel) + .leftPanel(attackVectorCompositePanel) + .scanIdComboViewer(scanIdComboViewer) + .projectComboViewer(projectComboViewer) + .build(); for(Action action : toolBarActions.getToolBarActions()) { toolBarManager.add(action); @@ -228,6 +229,10 @@ public void handleEvent(Event event) { scanIdField.getTextControl(leftCompositePanel).setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); viewer = new TreeViewer(leftCompositePanel, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); + + // Display initial message + showMessage(PluginConstants.SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER); + ColumnViewerToolTipSupport.enableFor(viewer); createColumns(); @@ -330,45 +335,35 @@ public String getText(Object element) { } }); - projectComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - if (selection.size() > 0){ - - PluginUtils.enableComboViewer(scanIdComboViewer, false); - PluginUtils.setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); - scanIdComboViewer.getCombo().update(); - - - Project selectedProject = ((Project)selection.getFirstElement()); - - List scanList = DataProvider.INSTANCE.getScanListOfProject(selectedProject.getID()); - - if(scanList.isEmpty()) - { - scanIdComboViewer.setInput(scanList); - PluginUtils.setTextForComboViewer(scanIdComboViewer, "No scans available."); - PluginUtils.enableComboViewer(scanIdComboViewer, true); - } - else - { - scanIdComboViewer.setInput(scanList); - PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); - PluginUtils.enableComboViewer(scanIdComboViewer, true); - } - - - - } + if (selection.size() > 0) { + + PluginUtils.enableComboViewer(scanIdComboViewer, false); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "Getting scans for the project..."); + scanIdComboViewer.getCombo().update(); + + Project selectedProject = ((Project) selection.getFirstElement()); + + List scanList = DataProvider.INSTANCE.getScanListOfProject(selectedProject.getID()); + + if (scanList.isEmpty()) { + scanIdComboViewer.setInput(scanList); + PluginUtils.setTextForComboViewer(scanIdComboViewer, "No scans available."); + PluginUtils.enableComboViewer(scanIdComboViewer, true); + } else { + scanIdComboViewer.setInput(scanList); + PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(scanIdComboViewer, true); + } + } } }); PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); - } private void createScanIdComboBox(Composite parent){ @@ -391,36 +386,34 @@ public String getText(Object element) { scanIdComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); - - if (selection.size() > 0){ - - Scan selectedScan = ((Scan)selection.getFirstElement()); - - /// Using async approach so that message can be displayed in the tree while getting the scans list - showMessage(String.format(RUNNING, selectedScan.getID())); - - toolBarActions.getScanResultsAction().setEnabled(false); - - CompletableFuture.runAsync(() -> { - alreadyRunning = true; - List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); - - rootModel.children.clear(); - rootModel.children.addAll(scanResults); - viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - toolBarActions.getScanResultsAction().setEnabled(true); - alreadyRunning = false; - + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - }); - - //end - } - } + if (selection.size() > 0) { + + Scan selectedScan = ((Scan) selection.getFirstElement()); + + /// Using async approach so that message can be displayed in the tree while + /// getting the scans list + showMessage(String.format(RUNNING, selectedScan.getID())); + + toolBarActions.getScanResultsAction().setEnabled(false); + + CompletableFuture.runAsync(() -> { + alreadyRunning = true; + List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); + + rootModel.children.clear(); + rootModel.children.addAll(scanResults); + viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); + toolBarActions.getScanResultsAction().setEnabled(true); + alreadyRunning = false; + }); + + // end + } + } }); PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); @@ -431,7 +424,6 @@ public void selectionChanged(SelectionChangedEvent event) { PluginUtils.enableComboViewer(scanIdComboViewer, false); } - private void configureTreeItemSelectionChangeEvent(TreeViewer viewer) { viewer.addSelectionChangedListener(new ISelectionChangedListener() { @@ -484,8 +476,6 @@ public void selectionChanged(SelectionChangedEvent event) { } - - private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { clearAttackVectorSection(attackVectorCompositePanel); @@ -518,11 +508,11 @@ private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { } } + if (selectedItem.getType().equalsIgnoreCase(PluginConstants.KICS_INFRASTRUCTURE)) { } - if (selectedItem.getType().equalsIgnoreCase(PluginConstants.SAST)) { String queryName = selectedItem.getResult().getData().getQueryName(); @@ -531,19 +521,13 @@ private void updateAttackVectorForSelectedTreeItem(DisplayModel selectedItem) { List nodesList = selectedItem.getResult().getData().getNodes(); if (nodesList != null && nodesList.size() > 0) { - for (Node node : nodesList) { String nodeName = node.getName(); String markerDescription = groupName+"_"+queryName+"_"+ nodeName; - // attackVectorValueText = new Text(attackVectorCompositePanel, SWT.READ_ONLY); - // attackVectorValueText.setText(node.getFileName() + "[" + node.getLine() + "," - // + node.getColumn() + "]"); - Link attackVectorValueLinkText = new Link(attackVectorCompositePanel, SWT.NONE); - String text = "" + node.getFileName() + "[" + node.getLine() + "," + node.getColumn() + "]" - + ""; + String text = "" + node.getFileName() + "[" + node.getLine() + "," + node.getColumn() + "]" + ""; attackVectorValueLinkText.setText(text); attackVectorValueLinkText.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { @@ -558,18 +542,16 @@ public void handleEvent(Event event) { if (attackVectorValueLinkText != null) { attackVectorValueLinkText.setText("Not Available."); } - } } - } private void clearAttackVectorSection(Composite attackVectorCompositePanel) { for (Control child : attackVectorCompositePanel.getChildren()) { - if(!(child instanceof Label)) - child.dispose(); + if (!(child instanceof Label)) + child.dispose(); } } @@ -594,12 +576,9 @@ private void openTheSelectedFile(String fileName, Integer lineNumber, String mar e.printStackTrace(); } } - } - } - private List findFileInWorkspace(final String fileName) { final List foundFiles = new ArrayList(); try { @@ -661,60 +640,9 @@ private Image findSeverityImage(DisplayModel model) { return null; } - public void showMessage(String message) { rootModel.children.clear(); rootModel.children.add(DataProvider.INSTANCE.message(message)); viewer.refresh(); - // monitorActions.forEach(act -> act.setEnabled(true)); - } - - private void clearSelectionFromTheViewers() { - resultInfoCompositePanel.setVisible(false); - attackVectorCompositePanel.setVisible(false); - - - - clearResultsTreeViewer(); - leftCompositePanel.layout(); - - clearScanIdComboViewer(); - clearProjectComboViewer(); - reloadProjectComboViewer(); - - - } - - private void clearResultsTreeViewer() { - rootModel.children.clear(); - viewer.refresh(); - } - - private void clearScanIdComboViewer() { - PluginUtils.enableComboViewer(scanIdComboViewer, false); - scanIdComboViewer.refresh(); - scanIdComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(scanIdComboViewer, SCAN_COMBO_VIEWER_TEXT); - scanIdComboViewer.getCombo().update(); - - - } - - private void clearProjectComboViewer() { - projectComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWER_TEXT); - } - - - private void reloadProjectComboViewer() { - PluginUtils.enableComboViewer(projectComboViewer, false); - PluginUtils.setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); - projectComboViewer.getCombo().update(); - List projectList = DataProvider.INSTANCE.getProjectList(); - projectComboViewer.setInput(projectList); - projectComboViewer.refresh(); - PluginUtils.setTextForComboViewer(projectComboViewer ,PROJECT_COMBO_VIEWER_TEXT); - PluginUtils.enableComboViewer(projectComboViewer, true); - } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java index 9825bece..b86d778c 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java @@ -28,22 +28,17 @@ public class ToolBarActions { private ComboViewer projectComboViewer; private Action scanResultsAction; - private Action clearSelectionAction; - private Action abortScanResultsAction; - - public ToolBarActions(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, - Composite resultInfoPanel, Composite attackVectorPanel, Composite leftPanel, - ComboViewer scanIdComboViewer, ComboViewer projectComboViewer) { - - this.rootModel = rootModel; - this.resultsTree = resultsTree; - this.alreadyRunning = alreadyRunning; - this.scanIdField = scanIdField; - this.resultInfoPanel = resultInfoPanel; - this.attackVectorPanel = attackVectorPanel; - this.leftPanel = leftPanel; - this.scanIdComboViewer = scanIdComboViewer; - this.projectComboViewer = projectComboViewer; + + public ToolBarActions(ToolBarActionsBuilder toolBarActionsBuilder) { + this.rootModel = toolBarActionsBuilder.rootModel; + this.resultsTree = toolBarActionsBuilder.resultsTree; + this.alreadyRunning = toolBarActionsBuilder.alreadyRunning; + this.scanIdField = toolBarActionsBuilder.scanIdField; + this.resultInfoPanel = toolBarActionsBuilder.resultInfoPanel; + this.attackVectorPanel = toolBarActionsBuilder.attackVectorPanel; + this.leftPanel = toolBarActionsBuilder.leftPanel; + this.scanIdComboViewer = toolBarActionsBuilder.scanIdComboViewer; + this.projectComboViewer = toolBarActionsBuilder.projectComboViewer; createActions(); } @@ -53,8 +48,8 @@ public ToolBarActions(DisplayModel rootModel, TreeViewer resultsTree, boolean al */ private void createActions() { - clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); - abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); + Action clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); + Action abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); scanResultsAction = new ActionGetScanResults(rootModel, resultsTree, alreadyRunning, scanIdField, abortScanResultsAction).createAction(); toolBarActions.add(clearSelectionAction); @@ -79,4 +74,76 @@ public List getToolBarActions() { public Action getScanResultsAction() { return scanResultsAction; } + + /** + * Builder Class to construct a ToolBarActions + * + * @author HugoMa + * + */ + public static class ToolBarActionsBuilder { + + private DisplayModel rootModel; + private TreeViewer resultsTree; + private StringFieldEditor scanIdField; + private boolean alreadyRunning = false; + + private Composite resultInfoPanel; + private Composite attackVectorPanel; + private Composite leftPanel; + + private ComboViewer scanIdComboViewer; + private ComboViewer projectComboViewer; + + public ToolBarActionsBuilder() {} + + public ToolBarActionsBuilder rootModel(DisplayModel rootModel) { + this.rootModel = rootModel; + return this; + } + + public ToolBarActionsBuilder resultsTree(TreeViewer resultsTree) { + this.resultsTree = resultsTree; + return this; + } + + public ToolBarActionsBuilder scanIdField(StringFieldEditor scanIdField) { + this.scanIdField = scanIdField; + return this; + } + + public ToolBarActionsBuilder alreadyRunning(boolean alreadyRunning) { + this.alreadyRunning = alreadyRunning; + return this; + } + + public ToolBarActionsBuilder resultInfoPanel(Composite resultInfoPanel) { + this.resultInfoPanel = resultInfoPanel; + return this; + } + + public ToolBarActionsBuilder attackVectorPanel(Composite attackVectorPanel) { + this.attackVectorPanel = attackVectorPanel; + return this; + } + + public ToolBarActionsBuilder leftPanel(Composite leftPanel) { + this.leftPanel = leftPanel; + return this; + } + + public ToolBarActionsBuilder scanIdComboViewer(ComboViewer scanIdComboViewer) { + this.scanIdComboViewer = scanIdComboViewer; + return this; + } + + public ToolBarActionsBuilder projectComboViewer(ComboViewer projectComboViewer) { + this.projectComboViewer = projectComboViewer; + return this; + } + + public ToolBarActions build() { + return new ToolBarActions(this); + } + } } From 35bb50a4ba4fae3d0eb1e3db24178c53639acad8 Mon Sep 17 00:00:00 2001 From: hmmachadocx Date: Wed, 24 Nov 2021 09:30:35 +0000 Subject: [PATCH 4/4] AST-6024 - Eclipse - Add option to filter - Severity - Status - State - Added severity filters and group by options to the eclipse plugin --- .../ast/eclipse/plugin/tests/ui/TestUI.java | 197 +++++++- .../META-INF/MANIFEST.MF | 3 +- .../eclipse/utils/PluginConstants.java | 1 - .../checkmarx/eclipse/utils/PluginUtils.java | 24 + .../eclipse/views/CheckmarxView.java | 153 +++++- .../checkmarx/eclipse/views/DataProvider.java | 445 +++++++++++------- .../views/PluginListenerDefinition.java | 30 ++ .../eclipse/views/PluginListenerType.java | 9 + .../views/actions/ActionAbortScanResults.java | 1 + .../views/actions/ActionClearSelection.java | 82 +--- .../views/actions/ActionGetScanResults.java | 18 +- .../eclipse/views/actions/ActionName.java | 15 + .../actions/ActionOpenPreferencesPage.java | 1 + .../eclipse/views/actions/CxBaseAction.java | 2 +- .../eclipse/views/actions/ToolBarActions.java | 142 ++++-- .../eclipse/views/filters/ActionFilters.java | 83 ++++ .../eclipse/views/filters/FilterState.java | 73 +++ .../eclipse/views/filters/Severity.java | 15 + 18 files changed, 965 insertions(+), 329 deletions(-) create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerDefinition.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerType.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionName.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/ActionFilters.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/FilterState.java create mode 100644 checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/Severity.java diff --git a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java index f5d0f242..4b430839 100644 --- a/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java +++ b/checkmarx-ast-eclipse-plugin-tests/src/test/java/checkmarx/ast/eclipse/plugin/tests/ui/TestUI.java @@ -3,27 +3,44 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; import org.eclipse.swtbot.eclipse.finder.waits.Conditions; import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton; import org.junit.Test; import org.junit.runner.RunWith; -import com.checkmarx.eclipse.utils.PluginConstants; +import com.checkmarx.eclipse.views.actions.ActionName; +import com.checkmarx.eclipse.views.actions.ToolBarActions; +import com.checkmarx.eclipse.views.filters.Severity; import checkmarx.ast.eclipse.plugin.tests.common.Environment; @RunWith(SWTBotJunit4ClassRunner.class) public class TestUI extends BaseUITest { - + private static final String ERROR_INCORRECT_SCAN_ID_FORMAT = "Incorrect scanId format."; private static final String ERROR_SERVER_URL_NOT_SET = "Error: Checkmarx server URL is not set"; private static final String INFO_SCAN_RETRIVING_RESULTS = "Retrieving the results for the scan id: " + Environment.SCAN_ID + " ."; private static final String INFO_SUCCESSFUL_CONNECTION = "Connection successfull !"; + + private static final String ASSERT_FILTER_ACTIONS_IN_TOOLBAR = "All filter actions must be in the tool bar"; + private static final String ASSERT_GROUP_BY_ACTIONS_IN_TOOLBAR = "All group by actions must be in the tool bar"; + private static final String ASSERT_TREE_CONSTAIN_HIGH_MEDIUM = "Results must contain results grouped by High and Medium"; + private static final String ASSERT_TREE_CONSTAIN_HIGH_MEDIUM_LOW = "Results must contain results grouped by High, Medium and Low"; + private static final String ASSERT_TREE_CONSTAIN_HIGH_MEDIUM_LOW_INFO = "Results must contain results grouped by High, Medium, Low and Info"; + private static final String ASSERT_TREE_WITH_NO_ISSUES = "The tree mustn't have results once we are grouping by severity and no severity is selected"; + private static final String ASSERT_GROUP_BY_QUERY_NAME = "Parent name must be equals to child name once it is grouped by query name"; + private static final String ASSERT_NO_CHINDREN = "One group by severity and group by query name are not selected, this node shouldn't have children"; + private static final String ASSERT_GROUP_BY_SEVERITY_NOT_SELECTED = "Engine child should not be HIGH, MEDIUM, LOW or INFO once the group by severity is not enabled"; private static boolean _cxSettingsDefined = false; @@ -88,6 +105,146 @@ public void testMissingSetCheckmarxServerUrl() { @Test public void testEnd2End() throws TimeoutException { + // Set credentials, test connection and add checkmarx plugin + setUpCheckmarxPlugin(); + + String firstNodeName = _bot.tree().cell(0, COLUMN_TITLE); + String secondNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).getText(); + String thirdNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).expand().getNode(0).getText(); + + // Expand nodes until the first vulnerability + _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).expandNode(thirdNodeName).getNode(0).select(); + + sleep(1000); + + // Close Checkmarx AST Scan view + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).close(); + } + + @Test + public void testFilterButtonsAndGroupByActionsInToolBar() throws TimeoutException { + + // Add Checkmarx AST Plugin + addCheckmarxPlugin(); + + List toolbarButtons = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons(); + List toolBarButtonsNames = toolbarButtons.stream().map(btn -> btn.getToolTipText().toUpperCase()).collect(Collectors.toList()); + List filterActions = Arrays.asList(ActionName.HIGH.name(), ActionName.MEDIUM.name(), ActionName.LOW.name(), ActionName.INFO.name()); + + // Assert all filter actions are present in the tool bar + assertTrue(ASSERT_FILTER_ACTIONS_IN_TOOLBAR, toolBarButtonsNames.containsAll(filterActions)); + + List groupByActions = Arrays.asList(ToolBarActions.GROUP_BY_SEVERITY, ToolBarActions.GROUP_BY_QUERY_NAME); + List toolBarGroupByActions = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).viewMenu().menu(ToolBarActions.MENU_GROUP_BY).menuItems(); + + // Assert all group by actions are present in the tool bar + assertTrue(ASSERT_GROUP_BY_ACTIONS_IN_TOOLBAR, toolBarGroupByActions.containsAll(groupByActions)); + + // Close Checkmarx AST Scan view + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).close(); + } + + @Test + public void testFilteringAndGroupingResults() throws TimeoutException { + + // Set credentials, test connection and add checkmarx plugin + setUpCheckmarxPlugin(); + + ArrayList currentActiveFilters = new ArrayList<>(Arrays.asList(Severity.HIGH.name(), Severity.MEDIUM.name())); + + // Checks that tree contains High and Medium results + assertTrue(ASSERT_TREE_CONSTAIN_HIGH_MEDIUM, expandTreeUntilFirstEngineAndGetCurrentSeverities().containsAll(currentActiveFilters)); + + // Click to include Low severity + clickSeverityFilter(ActionName.LOW.name()); + currentActiveFilters.add(Severity.LOW.name()); + + // Checks that tree contains High, Medium and Low results + assertTrue(ASSERT_TREE_CONSTAIN_HIGH_MEDIUM_LOW, expandTreeUntilFirstEngineAndGetCurrentSeverities().containsAll(currentActiveFilters)); + + // Click to include Info severity + clickSeverityFilter(ActionName.INFO.name()); + currentActiveFilters.add(Severity.INFO.name()); + + // Checks that tree contains High, Medium, Low and Info results + assertTrue(ASSERT_TREE_CONSTAIN_HIGH_MEDIUM_LOW_INFO, expandTreeUntilFirstEngineAndGetCurrentSeverities().containsAll(currentActiveFilters)); + + // Get all filter buttons individually + SWTBotToolbarButton filterHighBtn = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons().stream().filter(btn -> btn.getToolTipText().toUpperCase().equals(ActionName.HIGH.name())).findFirst().get(); + SWTBotToolbarButton filterMediumBtn = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons().stream().filter(btn -> btn.getToolTipText().toUpperCase().equals(ActionName.MEDIUM.name())).findFirst().get(); + SWTBotToolbarButton filterLowBtn = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons().stream().filter(btn -> btn.getToolTipText().toUpperCase().equals(ActionName.LOW.name())).findFirst().get(); + SWTBotToolbarButton filterInfoBtn = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons().stream().filter(btn -> btn.getToolTipText().toUpperCase().equals(ActionName.INFO.name())).findFirst().get(); + + // Click to remove all filters + filterHighBtn.click(); + filterMediumBtn.click(); + filterLowBtn.click(); + filterInfoBtn.click(); + + // Asserts that no issues are visible in the tree once we are grouping by Severity and no severity is selected + assertEquals(ASSERT_TREE_WITH_NO_ISSUES, _bot.tree().cell(0, COLUMN_TITLE), Environment.SCAN_ID + " (0 Issues)"); + + // Click to include High severity + clickSeverityFilter(ActionName.HIGH.name()); + currentActiveFilters.add(Severity.HIGH.name()); + + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).viewMenu().menu(ToolBarActions.MENU_GROUP_BY).menu(ToolBarActions.GROUP_BY_QUERY_NAME).click(); + + sleep(1000); + + String firstNodeName = _bot.tree().cell(0, COLUMN_TITLE); + String secondNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).getText(); + String thirdNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).expand().getNode(0).getText(); + + // Expand nodes until the first vulnerability + String groupByQueryNameParent = _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).expandNode(thirdNodeName).getNode(0).getText(); + String groupByQueryNameChild = _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).expandNode(thirdNodeName).getNode(0).expand().getNode(0).getText(); + + // Select the first vulnerability + _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).expandNode(thirdNodeName).getNode(0).expand().getNode(0).select(); + + // Asserts that the vulnerability has the same name as the parent node which means it is grouped by query name + assertTrue(ASSERT_GROUP_BY_QUERY_NAME, groupByQueryNameParent.split("\\(")[0].trim().equals(groupByQueryNameChild)); + + // Remove either group by severity and query name + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).viewMenu().menu(ToolBarActions.MENU_GROUP_BY).menu(ToolBarActions.GROUP_BY_QUERY_NAME).click(); + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).viewMenu().menu(ToolBarActions.MENU_GROUP_BY).menu(ToolBarActions.GROUP_BY_SEVERITY).click(); + + sleep(1000); + + firstNodeName = _bot.tree().cell(0, COLUMN_TITLE); + secondNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).getText(); + _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName); + + sleep(1000); + + // Get's the first engine child + String firstEngineChild = _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).getNode(0).getText(); + + // Checks if it starts by HIGH, MEDIUM, LOW or INFO + boolean engineChildDontStartWithHIGH = !firstEngineChild.startsWith(ActionName.HIGH.name()); + boolean engineChildDontStartWithMEDIUM = !firstEngineChild.startsWith(ActionName.MEDIUM.name()); + boolean engineChildDontStartWithLOW = !firstEngineChild.startsWith(ActionName.LOW.name()); + boolean engineChildDontStartWithINFO = !firstEngineChild.startsWith(ActionName.INFO.name()); + + // Asserts group by options are not enabled + assertTrue(ASSERT_NO_CHINDREN, _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).getNode(0).getNodes().isEmpty()); + assertTrue(ASSERT_GROUP_BY_SEVERITY_NOT_SELECTED, engineChildDontStartWithHIGH && engineChildDontStartWithMEDIUM && engineChildDontStartWithLOW && engineChildDontStartWithINFO); + + // Close Checkmarx AST Scan view + _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).close(); + } + + /** + * Set up checkmarx plugin + * + * -> Set credentials + * -> Test connection + * -> Add checkmarx plugin + * + * @throws TimeoutException + */ + private void setUpCheckmarxPlugin() throws TimeoutException{ // Test Connection testSuccessfulConnection(); @@ -96,9 +253,8 @@ public void testEnd2End() throws TimeoutException { preventWidgetWasNullInCIEnvironment(); - assertEquals("The tree must contain one row with an info message", _bot.tree().rowCount(), 1); - assertEquals("", PluginConstants.SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER, _bot.tree().cell(0, COLUMN_TITLE)); - + sleep(1000); + // Test incorrect Scan ID format _bot.textWithLabel(LABEL_SCAN_ID).setText("invalid-scan-id"); _bot.textWithLabel(LABEL_SCAN_ID).pressShortcut(Keystrokes.LF); @@ -108,8 +264,6 @@ public void testEnd2End() throws TimeoutException { assertEquals("The tree must contain one row with an error message", _bot.tree().rowCount(), 1); assertEquals("An incorrect scanId format message must be displayed", ERROR_INCORRECT_SCAN_ID_FORMAT, _bot.tree().cell(0, COLUMN_TITLE)); - sleep(1000); - // type a valid and existing Scan ID typeValidScanID(); @@ -119,21 +273,33 @@ public void testEnd2End() throws TimeoutException { waitWhileTreeNodeEqualsTo(INFO_SCAN_RETRIVING_RESULTS); assertTrue("The plugin should retrieve results", _bot.tree().cell(0, COLUMN_TITLE).startsWith(Environment.SCAN_ID)); - + } + + /** + * Click on a severity filter + * + * @param actionName + */ + private void clickSeverityFilter(String actionName) { + SWTBotToolbarButton filterLowBtn = _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).getToolbarButtons().stream().filter(btn -> btn.getToolTipText().toUpperCase().equals(actionName)).findFirst().get(); + filterLowBtn.click(); + } + + /** + * Expands the tree until the first engine and picks the list of available severities + * + * @return + */ + private List expandTreeUntilFirstEngineAndGetCurrentSeverities() { String firstNodeName = _bot.tree().cell(0, COLUMN_TITLE); String secondNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).getText(); - String thirdNodeName = _bot.tree().getTreeItem(firstNodeName).expand().getNode(0).expand().getNode(0).getText(); - - // Expand nodes until the first vulnerability - _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName).expandNode(thirdNodeName).getNode(0).select(); + _bot.tree().expandNode(firstNodeName).expandNode(secondNodeName); sleep(1000); - // Close Checkmarx AST Scan view - _bot.viewByTitle(VIEW_CHECKMARX_AST_SCAN).close(); + return _bot.tree().getTreeItem(_bot.tree().cell(0, COLUMN_TITLE)).expand().getNode(0).getNodes().stream().map(node -> node.split("\\(")[0].trim()).collect(Collectors.toList()); } - /** * Test successful connection */ @@ -254,6 +420,5 @@ private static void waitWhileTreeNodeEqualsTo(String nodeText) throws TimeoutExc if (retryIdx == 10) { throw new TimeoutException("Timeout after 5000ms. Scan results should be retrieved"); } - } } diff --git a/checkmarx-ast-eclipse-plugin/META-INF/MANIFEST.MF b/checkmarx-ast-eclipse-plugin/META-INF/MANIFEST.MF index b1fc6db5..89082fc6 100644 --- a/checkmarx-ast-eclipse-plugin/META-INF/MANIFEST.MF +++ b/checkmarx-ast-eclipse-plugin/META-INF/MANIFEST.MF @@ -7,7 +7,8 @@ Bundle-Vendor: Checkmarx Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime;bundle-version="3.22.0", org.eclipse.jdt.core;bundle-version="3.26.0", - org.eclipse.ui.ide;bundle-version="3.18.300" + org.eclipse.ui.ide;bundle-version="3.18.300", + com.google.guava Automatic-Module-Name: com.checkmarx.eclipse Bundle-RequiredExecutionEnvironment: JavaSE-11 Import-Package: org.eclipse.core.resources diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java index ba432a51..ef3fb78d 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginConstants.java @@ -4,5 +4,4 @@ public class PluginConstants { public static final String SAST = "sast"; public static final String SCA_DEPENDENCY = "dependency"; public static final String KICS_INFRASTRUCTURE = "infrastructure"; - public static final String SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER = "Paste a scan id and hit play to fetch results."; } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java index 4c449d3b..a8ac5e96 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/utils/PluginUtils.java @@ -3,9 +3,15 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.List; +import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.ComboViewer; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.actions.ActionName; +import com.checkmarx.eclipse.views.filters.FilterState; + public class PluginUtils { private static final String PARAM_TIMESTAMP_PATTERN = "yyyy-MM-dd | HH:mm:ss"; @@ -65,4 +71,22 @@ public static void enableComboViewer(ComboViewer comboviewer, boolean enable){ public static void setTextForComboViewer(ComboViewer comboViewer , String text) { comboViewer.getCombo().setText(text); } + + /** + * Enable/Disable filter actions + * + * @param filterActions + */ + public static void updateFiltersEnabledAndCheckedState(List filterActions) { + + for(Action action : filterActions) { + + // avoid to disable group by severity and group by query name actions + if(!action.getId().equals(ActionName.GROUP_BY_SEVERITY.name()) && !action.getId().equals(ActionName.GROUP_BY_QUERY_NAME.name())) { + action.setEnabled(DataProvider.getInstance().getCurrentScanId() != null); + } + + action.setChecked(FilterState.isSeverityEnabled(action.getId())); + } + } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java index 625efe5c..85075045 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/CheckmarxView.java @@ -1,6 +1,7 @@ package com.checkmarx.eclipse.views; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -16,6 +17,7 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; @@ -45,6 +47,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.IActionBars; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; @@ -58,12 +61,20 @@ import com.checkmarx.eclipse.Activator; import com.checkmarx.eclipse.utils.PluginConstants; import com.checkmarx.eclipse.utils.PluginUtils; +import com.checkmarx.eclipse.views.actions.ActionName; import com.checkmarx.eclipse.views.actions.ActionOpenPreferencesPage; import com.checkmarx.eclipse.views.actions.ToolBarActions; +import com.checkmarx.eclipse.views.filters.FilterState; import com.checkmarx.eclipse.views.provider.ColumnProvider; import com.checkmarx.eclipse.views.provider.TreeContentProvider; +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; public class CheckmarxView extends ViewPart { + + private static final String PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT = "Select scan id"; + private static final String PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT = "Select project"; + private static final String PROJECT_COMBO_VIEWERGETTING_PROJECTS = "Getting the projects from AST server..."; /** * The ID of the view as specified by the extension. @@ -106,7 +117,9 @@ public class CheckmarxView extends ViewPart { private Composite leftCompositePanel; private ToolBarActions toolBarActions; - + + private EventBus pluginEventBus; + public CheckmarxView() { super(); @@ -117,6 +130,7 @@ public CheckmarxView() { public void dispose() { super.dispose(); boldFont.dispose(); + pluginEventBus.unregister(this); } @Override @@ -145,22 +159,29 @@ private void fillContextMenu(IMenuManager manager) { * Creates the Checkmarx plugin tool bar with all actions */ private void createToolbar() { - IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); + + IActionBars actionBars = getViewSite().getActionBars(); + IToolBarManager toolBarManager = actionBars.getToolBarManager(); + + pluginEventBus = new EventBus(); + pluginEventBus.register(this); toolBarActions = new ToolBarActions.ToolBarActionsBuilder() + .actionBars(actionBars) .rootModel(rootModel) .resultsTree(viewer) .alreadyRunning(alreadyRunning) .scanIdField(scanIdField) - .resultInfoPanel(resultInfoCompositePanel) - .attackVectorPanel(attackVectorCompositePanel) - .leftPanel(attackVectorCompositePanel) - .scanIdComboViewer(scanIdComboViewer) - .projectComboViewer(projectComboViewer) + .pluginEventBus(pluginEventBus) .build(); - + for(Action action : toolBarActions.getToolBarActions()) { toolBarManager.add(action); + + // Add divider + if(action.getId() != null && action.getId().equals(ActionName.INFO.name())) { + toolBarManager.add(new Separator("\t")); + } } } @@ -230,9 +251,6 @@ public void handleEvent(Event event) { viewer = new TreeViewer(leftCompositePanel, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); - // Display initial message - showMessage(PluginConstants.SCAN_RESULTS_TREE_INITIAL_PLACEHOLDER); - ColumnViewerToolTipSupport.enableFor(viewer); createColumns(); @@ -314,7 +332,7 @@ public void handleEvent(Event event) { private void createProjectListComboBox(Composite parent) { - List projectList = DataProvider.INSTANCE.getProjectList(); + List projectList = DataProvider.getInstance().getProjectList(); projectComboViewer = new ComboViewer(parent, SWT.DROP_DOWN); projectComboViewer.setContentProvider(ArrayContentProvider.getInstance()); @@ -348,7 +366,7 @@ public void selectionChanged(SelectionChangedEvent event) { Project selectedProject = ((Project) selection.getFirstElement()); - List scanList = DataProvider.INSTANCE.getScanListOfProject(selectedProject.getID()); + List scanList = DataProvider.getInstance().getScanListOfProject(selectedProject.getID()); if (scanList.isEmpty()) { scanIdComboViewer.setInput(scanList); @@ -402,13 +420,7 @@ public void selectionChanged(SelectionChangedEvent event) { CompletableFuture.runAsync(() -> { alreadyRunning = true; - List scanResults = DataProvider.INSTANCE.getResultsForScanId(selectedScan.getID()); - - rootModel.children.clear(); - rootModel.children.addAll(scanResults); - viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); - toolBarActions.getScanResultsAction().setEnabled(true); - alreadyRunning = false; + updateResultsTree(DataProvider.getInstance().getResultsForScanId(selectedScan.getID())); }); // end @@ -642,7 +654,106 @@ private Image findSeverityImage(DisplayModel model) { public void showMessage(String message) { rootModel.children.clear(); - rootModel.children.add(DataProvider.INSTANCE.message(message)); + rootModel.children.add(DataProvider.getInstance().message(message)); viewer.refresh(); } + + @Subscribe + private void listener(PluginListenerDefinition definition) { + + switch(definition.getListenerType()) { + case FILTER_CHANGED: + case GET_RESULTS: + updateResultsTree(definition.getResutls()); + break; + case CLEAN_AND_REFRESH: + clearAndRefreshPlugin(); + break; + } + } + + /** + * Update results tree + * + * @param results + */ + private void updateResultsTree(List results) { + + rootModel.children.clear(); + rootModel.children.addAll(results); + viewer.getTree().getDisplay().asyncExec(() -> viewer.refresh()); + toolBarActions.getScanResultsAction().setEnabled(true); + alreadyRunning = false; + + PluginUtils.updateFiltersEnabledAndCheckedState(toolBarActions.getFilterActions()); + } + + /** + * Clear all plugin fields and reload projects + */ + private void clearAndRefreshPlugin() { + + resultInfoCompositePanel.setVisible(false); + attackVectorCompositePanel.setVisible(false); + + clearResultsTreeViewer(); + leftCompositePanel.layout(); + + clearScanIdComboViewer(); + clearProjectComboViewer(); + reloadProjectComboViewer(); + + resetFiltersState(); + } + + /** + * Clears Results' tree + */ + private void clearResultsTreeViewer() { + rootModel.children.clear(); + viewer.refresh(); + } + + /** + * Clears Scans' combobox + */ + private void clearScanIdComboViewer() { + PluginUtils.enableComboViewer(scanIdComboViewer, false); + scanIdComboViewer.refresh(); + scanIdComboViewer.setInput(Collections.EMPTY_LIST); + PluginUtils.setTextForComboViewer(scanIdComboViewer, PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT); + scanIdComboViewer.getCombo().update(); + } + + /** + * Clears Projects' combobox + */ + private void clearProjectComboViewer() { + projectComboViewer.setInput(Collections.EMPTY_LIST); + PluginUtils.setTextForComboViewer(projectComboViewer, PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); + } + + /** + * Reloads Projects' combobox + */ + private void reloadProjectComboViewer() { + PluginUtils.enableComboViewer(projectComboViewer, false); + PluginUtils.setTextForComboViewer(projectComboViewer, PROJECT_COMBO_VIEWERGETTING_PROJECTS); + projectComboViewer.getCombo().update(); + List projectList = DataProvider.getInstance().getProjectList(); + projectComboViewer.setInput(projectList); + projectComboViewer.refresh(); + PluginUtils.setTextForComboViewer(projectComboViewer ,PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); + PluginUtils.enableComboViewer(projectComboViewer, true); + } + + /** + * Reset filters + */ + private void resetFiltersState() { + DataProvider.getInstance().setCurrentScanId(null); + DataProvider.getInstance().setCurrentResults(null); + FilterState.resetFilters(); + PluginUtils.updateFiltersEnabledAndCheckedState(toolBarActions.getFilterActions()); + } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/DataProvider.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/DataProvider.java index 57c822d0..f8857f1c 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/DataProvider.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/DataProvider.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -10,7 +11,6 @@ import java.util.stream.Collectors; import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; @@ -27,22 +27,54 @@ import com.checkmarx.eclipse.properties.Preferences; import com.checkmarx.eclipse.runner.Authenticator; import com.checkmarx.eclipse.utils.PluginConstants; +import com.checkmarx.eclipse.views.filters.FilterState; public class DataProvider { + + private static final String SAST_TREE_NAME = "SAST (%d)"; + private static final String SCA_TREE_NAME = "SCA (%d)"; + private static final String KICS_TREE_NAME = "KICS (%d)"; + private static final String RESULTS_TREE_NAME = "%s (%d Issues)"; private static final Bundle BUNDLE = FrameworkUtil.getBundle(DataProvider.class); private static final ILog LOG = Platform.getLog(BUNDLE); - - public static final DataProvider INSTANCE = new DataProvider(); + + public static DataProvider _dataProvider = null; public static final AtomicBoolean abort = new AtomicBoolean(false); + + private Results currentResults; + private String currentScanId; + + /** + * Singleton data provider instance + * + * @return + */ + public static final DataProvider getInstance() { + + if(_dataProvider == null) { + _dataProvider = new DataProvider(); + } + + return _dataProvider; + } - private List scanTypes = new ArrayList(); - private List severityTypes = new ArrayList(); + public String getCurrentScanId() { + return currentScanId; + } - private Integer sastCount = 0; - private Integer scaCount = 0; - private Integer kicsCount = 0; + public void setCurrentScanId(String currentScanId) { + this.currentScanId = currentScanId; + } + + public Results getCurrentResults() { + return currentResults; + } + + public void setCurrentResults(Results currentResults) { + this.currentResults = currentResults; + } public DisplayModel message(String message) { DisplayModel messageModel = new DisplayModel.DisplayModelBuilder(message).build(); @@ -137,20 +169,21 @@ public List getResultsForScanId(String scanId) { Results scanResults = null; Logger log = LoggerFactory.getLogger(Authenticator.class.getName()); + + setCurrentScanId(scanId); try { - CxConfig config = CxConfig.builder().baseUri(Preferences.getServerUrl()).tenant(Preferences.getTenant()) - .apiKey(Preferences.getApiKey()).additionalParameters("").build(); + CxConfig config = CxConfig.builder().baseUri(Preferences.getServerUrl()).tenant(Preferences.getTenant()).apiKey(Preferences.getApiKey()).additionalParameters("").build(); CxWrapper wrapper = new CxWrapper(config, log); String validationResult = wrapper.authValidate(); - - System.out.println("Authentication Status :" + validationResult); - System.out.println("Fetching the results for scanId :" + scanId); + System.out.println("Authentication Status: " + validationResult); + System.out.println("Fetching the results for scanId: " + scanId); scanResults = wrapper.results(UUID.fromString(scanId)); - System.out.println("Scan results :" + scanResults.getTotalCount()); + setCurrentResults(scanResults); + System.out.println("Scan results: " + scanResults.getTotalCount()); } catch (Exception e) { return error(e); @@ -160,161 +193,162 @@ public List getResultsForScanId(String scanId) { } private List processResults(Results scanResults, String scanId) { + + if(scanResults == null || scanResults.getResults() == null || scanResults.getResults().isEmpty()) { + return Collections.emptyList(); + } - DisplayModel projectModel; List resultsList = scanResults.getResults(); // transform all the results at once to avoid multiple transformation steps - List allResultsTransformed = resultsList.stream().map(resultItem -> transform(resultItem)) - .collect(Collectors.toList()); - - // Divide all the results as per the scanner type - Map> filteredResultsByScannerType = filterResultsByScannerTypeV2( - allResultsTransformed); - - // Divide the results for each scanner as per the severity - Map> sastResultsMap = new HashMap<>(); - Map> scaResultsMap = new HashMap<>(); - Map> kicsResultsMap = new HashMap<>(); + List allResultsTransformed = resultsList.stream().map(resultItem -> transform(resultItem)).collect(Collectors.toList()); - if (filteredResultsByScannerType.containsKey(PluginConstants.SAST)) { - List sastList = filteredResultsByScannerType.get(PluginConstants.SAST); - sastResultsMap = filterResultsBySeverityV2(sastList); - } - if (filteredResultsByScannerType.containsKey(PluginConstants.SCA_DEPENDENCY)) { - List scaList = filteredResultsByScannerType.get(PluginConstants.SCA_DEPENDENCY); - scaResultsMap = filterResultsBySeverityV2(scaList); - } - if (filteredResultsByScannerType.containsKey(PluginConstants.KICS_INFRASTRUCTURE)) { - List kicsList = filteredResultsByScannerType.get(PluginConstants.KICS_INFRASTRUCTURE); - kicsResultsMap = filterResultsBySeverityV2(kicsList); - } + // Divide all the results by scanner type + Map> filteredResultsByScannerType = filterResultsByScannerTypeV2(allResultsTransformed); - // Creating a parent node for each scanner - // SAST - sastCount = 0; - List sastParentModelList = new ArrayList(); - for (Map.Entry> mapEntry : sastResultsMap.entrySet()) { - - List listForEachSeverity = mapEntry.getValue(); - sastCount = sastCount + listForEachSeverity.size(); + // build results based on selected filters + return buildResults(scanId, filteredResultsByScannerType); + } + + /** + * Build results to be displayed in the tree + * + * @param scanId + * @param filteredResultsByScannerType + * @return + */ + private List buildResults(String scanId, Map> filteredResultsByScannerType){ + + if(FilterState.groupBySeverity) { + // Divide the results for each scanner as per the severity + Map> sastResultsMap = new HashMap<>(); + Map> scaResultsMap = new HashMap<>(); + Map> kicsResultsMap = new HashMap<>(); + + if (filteredResultsByScannerType.containsKey(PluginConstants.SAST)) { + List sastList = filteredResultsByScannerType.get(PluginConstants.SAST); + sastResultsMap = filterResultsBySeverityV2(sastList); + + if(FilterState.groupByQueryName && !sastResultsMap.isEmpty()) { + filterResultsByQueryName(sastResultsMap); + } + } - DisplayModel sastSeverityParentModel = new DisplayModel.DisplayModelBuilder(mapEntry.getKey() + " (" + listForEachSeverity.size() + ")").setChildren(listForEachSeverity) - .build(); + if (filteredResultsByScannerType.containsKey(PluginConstants.SCA_DEPENDENCY)) { + List scaList = filteredResultsByScannerType.get(PluginConstants.SCA_DEPENDENCY); + scaResultsMap = filterResultsBySeverityV2(scaList); + + if(FilterState.groupByQueryName && !scaResultsMap.isEmpty()) { + filterResultsByQueryName(scaResultsMap); + } + } - sastParentModelList.add(sastSeverityParentModel); - - } - // SCA - scaCount = 0; - List scaParentModelList = new ArrayList(); - for (Map.Entry> mapEntry : scaResultsMap.entrySet()) { + if (filteredResultsByScannerType.containsKey(PluginConstants.KICS_INFRASTRUCTURE)) { + List kicsList = filteredResultsByScannerType.get(PluginConstants.KICS_INFRASTRUCTURE); + kicsResultsMap = filterResultsBySeverityV2(kicsList); + + if(FilterState.groupByQueryName && !kicsResultsMap.isEmpty()) { + filterResultsByQueryName(kicsResultsMap); + } + } - List listForEachSeverity = mapEntry.getValue(); - scaCount = scaCount + listForEachSeverity.size(); + // Parent node for SAST + Map> sastParentModelList = createParentNodeByScanner(sastResultsMap); + Integer sastCount = sastParentModelList.keySet().stream().findFirst().get(); + List sastChildren = sastParentModelList.get(sastCount); - DisplayModel scaSeverityParentModel = new DisplayModel.DisplayModelBuilder(mapEntry.getKey() + " (" + listForEachSeverity.size() + ")").setChildren(listForEachSeverity) - .build(); - scaParentModelList.add(scaSeverityParentModel); + // Parent node for SCA + Map> scaParentModelList = createParentNodeByScanner(scaResultsMap); + Integer scaCount = scaParentModelList.keySet().stream().findFirst().get(); + List scaChildren = scaParentModelList.get(scaCount); + // Parent node for KICS + Map> kicsParentModelList = createParentNodeByScanner(kicsResultsMap); + Integer kicsCount = kicsParentModelList.keySet().stream().findFirst().get(); + List kicsChildren = kicsParentModelList.get(kicsCount); + + return addResults(scanId, sastCount, sastChildren, scaCount, scaChildren, kicsCount, kicsChildren); + + }else if(FilterState.groupByQueryName) { + filterResultsByQueryName(filteredResultsByScannerType); } - - // kics - kicsCount = 0; - List kicsParentModelList = new ArrayList(); - for (Map.Entry> mapEntry : kicsResultsMap.entrySet()) { - - List listForEachSeverity = mapEntry.getValue(); - kicsCount = kicsCount + listForEachSeverity.size(); - DisplayModel kicsSeverityParentModel = new DisplayModel.DisplayModelBuilder(mapEntry.getKey() + " (" + listForEachSeverity.size() + ")").setChildren(listForEachSeverity) - .build(); - kicsParentModelList.add(kicsSeverityParentModel); - - } + boolean constainsSASTResults = filteredResultsByScannerType.containsKey(PluginConstants.SAST) && filteredResultsByScannerType.get(PluginConstants.SAST).size() > 0; + List sastResults = constainsSASTResults ? filteredResultsByScannerType.get(PluginConstants.SAST) : Collections.emptyList(); + int sastCount = constainsSASTResults ? getParentCounter(sastResults) : 0; + + boolean constainsSCAResults = filteredResultsByScannerType.containsKey(PluginConstants.SCA_DEPENDENCY) && filteredResultsByScannerType.get(PluginConstants.SCA_DEPENDENCY).size() > 0; + List scaResults = constainsSCAResults ? filteredResultsByScannerType.get(PluginConstants.SCA_DEPENDENCY) : Collections.emptyList(); + int scaCount = constainsSCAResults ? getParentCounter(scaResults) : 0; + + boolean constainsKICKSResults = filteredResultsByScannerType.containsKey(PluginConstants.KICS_INFRASTRUCTURE) && filteredResultsByScannerType.get(PluginConstants.KICS_INFRASTRUCTURE).size() > 0; + List kicsResults = constainsKICKSResults ? filteredResultsByScannerType.get(PluginConstants.KICS_INFRASTRUCTURE) : Collections.emptyList(); + int kicsCount = constainsKICKSResults ? getParentCounter(kicsResults) : 0; + return addResults(scanId, sastCount, sastResults, scaCount, scaResults, kicsCount, kicsResults); + } + + /** + * Evaluates if each engine has results and adds it to the final map + * + * @param scanId + * @param sastCount + * @param sastChildren + * @param scaCount + * @param scaChildren + * @param kicsCount + * @param kicsChildren + * @return + */ + private List addResults(String scanId, Integer sastCount, List sastChildren, Integer scaCount, List scaChildren, Integer kicsCount, List kicsChildren) { + List returnList = new ArrayList<>(); List results = new ArrayList<>(); - if (sastParentModelList.size() > 0) { - + + if (sastCount > 0) { - DisplayModel sastModel = new DisplayModel.DisplayModelBuilder("SAST" + " (" + sastCount + ")").setChildren(sastParentModelList).build(); + DisplayModel sastModel = new DisplayModel.DisplayModelBuilder(String.format(SAST_TREE_NAME, sastCount)).setChildren(sastChildren).build(); results.add(sastModel); } - if (scaParentModelList.size() > 0) { - DisplayModel scaModel = new DisplayModel.DisplayModelBuilder("SCA" + " (" + scaCount + ")").setChildren(scaParentModelList).build(); + if (scaCount > 0) { + + DisplayModel scaModel = new DisplayModel.DisplayModelBuilder(String.format(SCA_TREE_NAME, scaCount)).setChildren(scaChildren).build(); results.add(scaModel); } - if (kicsParentModelList.size() > 0) { - DisplayModel kicsModel = new DisplayModel.DisplayModelBuilder("KICS" + " (" + kicsCount + ")").setChildren(kicsParentModelList).build(); + if (kicsCount > 0) { + + DisplayModel kicsModel = new DisplayModel.DisplayModelBuilder(String.format(KICS_TREE_NAME, kicsCount)).setChildren(kicsChildren).build(); results.add(kicsModel); } - -// for (Map.Entry mapEntry : treeItemMap.entrySet()) { -// DisplayModel parentDisplayItem = new DisplayModel().builder().name((String) mapEntry.getKey()).children((List) mapEntry.getValue()).build(); -// results.add(parentDisplayItem); -// } - - projectModel = new DisplayModel.DisplayModelBuilder(scanId + " (" + scanResults.getTotalCount() + " Issues)").setChildren(results).build(); - - List returnList = new ArrayList<>(); + + int totalCount = sastCount + scaCount + kicsCount; + DisplayModel projectModel = new DisplayModel.DisplayModelBuilder(String.format(RESULTS_TREE_NAME, scanId, totalCount)).setChildren(results).build(); + returnList.add(projectModel); return returnList; } + /** + * Creates a Display Model which represents each result + * + * @param resultItem + * @return + */ private DisplayModel transform(Result resultItem) { - String displayName; - if ((resultItem.getType()).equals(PluginConstants.SCA_DEPENDENCY)) { - displayName = resultItem.getSimilarityId(); - } else { - displayName = (resultItem.getData()).getQueryName(); - } - - - return new DisplayModel.DisplayModelBuilder(displayName).setSeverity(resultItem.getSeverity()).setType(resultItem.getType()) - .setResult(resultItem).build(); - -// return DisplayModel.builder().name(displayName).state(resultItem.getState()).status(resultItem.getStatus()) -// .severity(resultItem.getSeverity()).type(resultItem.getType()).description(description).nodes(nodesList).build(); + String displayName = resultItem.getType().equals(PluginConstants.SCA_DEPENDENCY) ? resultItem.getSimilarityId() : resultItem.getData().getQueryName(); + + return new DisplayModel.DisplayModelBuilder(displayName).setSeverity(resultItem.getSeverity()).setType(resultItem.getType()).setResult(resultItem).build(); } -// private List filterResultsByScannerType(List resultList, String scannerType) { -// -// List filteredResults = new ArrayList<>(); -// -// for (CxResult cxResult : resultList) { -// -// if (cxResult.getType().equalsIgnoreCase(scannerType)) { -// filteredResults.add(cxResult); -// } -// } -// return filteredResults; -// } - -// private Map> filterResultsByScannerType(List resultList) { -// -// Map> filteredMap = new HashMap<>(); -// -// for (CxResult cxResult : resultList) { -// -// String scanType = cxResult.getType(); -// -// if (filteredMap.containsKey(scanType)) { -// List mapResultList = filteredMap.get(scanType); -// mapResultList.add(cxResult); -// } else { -// List mapResultList = new ArrayList<>(); -// mapResultList.add(cxResult); -// filteredMap.put(scanType, mapResultList); -// } -// -// } -// return filteredMap; -// } - + /** + * Group results by scanner type + * + * @param allResultsTransformed + * @return + */ private Map> filterResultsByScannerTypeV2(List allResultsTransformed) { Map> filteredMap = new HashMap<>(); @@ -336,37 +370,132 @@ private Map> filterResultsByScannerTypeV2(List filterResultsBySeverity(List resultList, String severity) { -// -// List filteredResult = new ArrayList<>(); -// -// for (CxResult cxResult : resultList) { -// -// if (cxResult.getSeverity().equalsIgnoreCase(severity)) { -// filteredResult.add(cxResult); -// } -// } -// return filteredResult; -// } - + /** + * Group results by Severity + * + * @param resultList + * @return + */ private Map> filterResultsBySeverityV2(List resultList) { - Map> filteredMap = new HashMap<>(); + Map> filteredMapBySeverity = new HashMap<>(); for (DisplayModel result : resultList) { String severityType = result.getSeverity(); + + if(FilterState.isSeverityEnabled(severityType)) { + if (filteredMapBySeverity.containsKey(severityType)) { + List mapResultList = filteredMapBySeverity.get(severityType); + mapResultList.add(result); + } else { + List mapResultList = new ArrayList<>(); + mapResultList.add(result); + filteredMapBySeverity.put(severityType, mapResultList); + } + } + } + + return filteredMapBySeverity; + } + + /** + * Group results by query name + * + * @param results + */ + private void filterResultsByQueryName(Map> results) { + + for (Map.Entry> entry : results.entrySet()) { + + String severityOrScannerType = entry.getKey(); + List vulnerabilities = entry.getValue(); + + Map> filteredByQueryName = new HashMap<>(); - if (filteredMap.containsKey(severityType)) { - List mapResultList = filteredMap.get(severityType); - mapResultList.add(result); - } else { - List mapResultList = new ArrayList<>(); - mapResultList.add(result); - filteredMap.put(severityType, mapResultList); + for (DisplayModel result : vulnerabilities) { + + String queryName = result.getName(); + + if (filteredByQueryName.containsKey(queryName)) { + List mapResultList = filteredByQueryName.get(queryName); + mapResultList.add(result); + } else { + List mapResultList = new ArrayList<>(); + mapResultList.add(result); + filteredByQueryName.put(queryName, mapResultList); + } } + + Map> parentModelList = createParentNodeByScanner(filteredByQueryName); + Integer sastCount = parentModelList.keySet().stream().findFirst().get(); + List children = parentModelList.get(sastCount); + results.put(severityOrScannerType, children); + } + } + + /** + * Creates parent node for each scanner + * + * @param map + * @return + */ + private Map> createParentNodeByScanner(Map> map){ + + Map> result = new HashMap<>(); + List resultList = new ArrayList<>(); + int counter = 0; + + for (Map.Entry> mapEntry : map.entrySet()) { + int childCounter = 0; + List listForEachSeverity = mapEntry.getValue(); + + // When grouped by query name we need to count children + for(DisplayModel dm : listForEachSeverity) { + if(dm.getChildren() != null && dm.getChildren().size() > 0) { + childCounter = childCounter + dm.getChildren().size(); + } + } + + counter += childCounter == 0 ? listForEachSeverity.size() : childCounter; + + int parentCounter = childCounter > 0 ? childCounter : listForEachSeverity.size(); + DisplayModel parentModel = new DisplayModel.DisplayModelBuilder(mapEntry.getKey() + " (" + parentCounter + ")").setChildren(listForEachSeverity).build(); + + resultList.add(parentModel); } - return filteredMap; + + result.put(counter, resultList); + + return result; + } + + /** + * Counts the number of results evaluating if the model has children or not + * + * @param results + * @return + */ + private int getParentCounter(List results) { + + int counter = 0; + + for (DisplayModel dm : results) { + if (dm.getChildren() != null && !dm.getChildren().isEmpty()) { + counter += dm.getChildren().size(); + } + } + + return counter > 0 ? counter : results.size(); + } + + /** + * Filter results based on current filter + * + * @return + */ + public List filterResults(){ + return processResults(getCurrentResults(), getCurrentScanId()); } } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerDefinition.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerDefinition.java new file mode 100644 index 00000000..30383a19 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerDefinition.java @@ -0,0 +1,30 @@ +package com.checkmarx.eclipse.views; + +import java.util.List; + +public class PluginListenerDefinition { + + private PluginListenerType listenerType; + private List resutls; + + public PluginListenerDefinition(PluginListenerType listenerType, List results) { + this.listenerType = listenerType; + this.resutls = results; + } + + public PluginListenerType getListenerType() { + return listenerType; + } + + public void setListenerType(PluginListenerType listenerType) { + this.listenerType = listenerType; + } + + public List getResutls() { + return resutls; + } + + public void setResutls(List resutls) { + this.resutls = resutls; + } +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerType.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerType.java new file mode 100644 index 00000000..a77d73e8 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/PluginListenerType.java @@ -0,0 +1,9 @@ +package com.checkmarx.eclipse.views; + +public enum PluginListenerType { + + GET_RESULTS, + FILTER_CHANGED, + CLEAN_AND_REFRESH, + +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java index a22300e0..968b54f2 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionAbortScanResults.java @@ -30,6 +30,7 @@ public void run() { } }; + abortScanResultsAction.setId(ActionName.ABORT_RESULTS.name()); abortScanResultsAction.setToolTipText(ACTION_ABORT_SCAN_RESULTS_TOOLTIP); abortScanResultsAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_ABORT_SCAN_RESULTS_ICON_PATH)); abortScanResultsAction.setEnabled(false); diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java index 2e924662..d3c0858b 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionClearSelection.java @@ -1,43 +1,29 @@ package com.checkmarx.eclipse.views.actions; + import java.util.Collections; -import java.util.List; import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.widgets.Composite; -import com.checkmarx.ast.project.Project; import com.checkmarx.eclipse.Activator; -import com.checkmarx.eclipse.utils.PluginUtils; -import com.checkmarx.eclipse.views.DataProvider; import com.checkmarx.eclipse.views.DisplayModel; +import com.checkmarx.eclipse.views.PluginListenerType; +import com.checkmarx.eclipse.views.PluginListenerDefinition; +import com.google.common.eventbus.EventBus; public class ActionClearSelection extends CxBaseAction { private static final String ACTION_CLEAR_SELECTION_TOOLTIP = "Clear the selected scanId and the results view."; - private static final String ACTION_CLEAR_SELECTION_ICON_PATH = "platform:/plugin/org.eclipse.ui/icons/full/etool16/delete.png"; - - private static final String PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT = "Select scan id"; - private static final String PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT = "Select project"; - - private Composite resultInfoCompositePanel; - private Composite attackVectorCompositePanel; - private Composite leftCompositePanel; + private static final String ACTION_CLEAR_SELECTION_ICON_PATH = "platform:/plugin/org.eclipse.ui.views.log/icons/elcl16/refresh.png"; - private ComboViewer scanIdComboViewer; - private ComboViewer projectComboViewer; + private EventBus pluginEventBus; - public ActionClearSelection(DisplayModel rootModel, TreeViewer resultsTree, Composite resultInfoCompositePanel, Composite attackVectorCompositePanel, Composite leftCompositePanel, ComboViewer scanIdComboViewer, ComboViewer projectComboViewer) { + public ActionClearSelection(DisplayModel rootModel, TreeViewer resultsTree, EventBus pluginEventBus) { super(rootModel, resultsTree); - this.resultInfoCompositePanel = resultInfoCompositePanel; - this.attackVectorCompositePanel = attackVectorCompositePanel; - this.leftCompositePanel = leftCompositePanel; - this.scanIdComboViewer = scanIdComboViewer; - this.projectComboViewer = projectComboViewer; + this.pluginEventBus = pluginEventBus; } /** @@ -47,63 +33,15 @@ public Action createAction() { Action clearSelectionAction = new Action() { @Override public void run() { - resultInfoCompositePanel.setVisible(false); - attackVectorCompositePanel.setVisible(false); - - clearResultsTreeViewer(); - leftCompositePanel.layout(); - - clearScanIdComboViewer(); - clearProjectComboViewer(); - reloadProjectComboViewer(); + pluginEventBus.post(new PluginListenerDefinition(PluginListenerType.CLEAN_AND_REFRESH, Collections.emptyList())); } }; + clearSelectionAction.setId(ActionName.CLEAN_AND_REFRESH.name()); clearSelectionAction.setToolTipText(ACTION_CLEAR_SELECTION_TOOLTIP); clearSelectionAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_CLEAR_SELECTION_ICON_PATH)); return clearSelectionAction; } - /** - * Clears Results' tree - */ - private void clearResultsTreeViewer() { - rootModel.children.clear(); - resultsTree.refresh(); - } - - /** - * Clears Scans' combobox - */ - private void clearScanIdComboViewer() { - PluginUtils.enableComboViewer(scanIdComboViewer, false); - scanIdComboViewer.refresh(); - scanIdComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(scanIdComboViewer, PLACEHOLDER_SCAN_COMBO_VIEWER_TEXT); - scanIdComboViewer.getCombo().update(); - } - - /** - * Clears Projects' combobox - */ - private void clearProjectComboViewer() { - projectComboViewer.setInput(Collections.EMPTY_LIST); - PluginUtils.setTextForComboViewer(projectComboViewer, PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); - } - - /** - * Reloads Projects' combobox - */ - private void reloadProjectComboViewer() { - PluginUtils.enableComboViewer(projectComboViewer, false); - PluginUtils.setTextForComboViewer(projectComboViewer, "Getting the projects from AST server..."); - projectComboViewer.getCombo().update(); - List projectList = DataProvider.INSTANCE.getProjectList(); - projectComboViewer.setInput(projectList); - projectComboViewer.refresh(); - PluginUtils.setTextForComboViewer(projectComboViewer ,PLACEHOLDER_PROJECT_COMBO_VIEWER_TEXT); - PluginUtils.enableComboViewer(projectComboViewer, true); - } - } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java index 77988b1f..dbd9d70e 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionGetScanResults.java @@ -1,6 +1,5 @@ package com.checkmarx.eclipse.views.actions; -import java.util.List; import java.util.concurrent.CompletableFuture; import org.eclipse.jface.action.Action; @@ -11,6 +10,9 @@ import com.checkmarx.eclipse.utils.PluginUtils; import com.checkmarx.eclipse.views.DataProvider; import com.checkmarx.eclipse.views.DisplayModel; +import com.checkmarx.eclipse.views.PluginListenerType; +import com.checkmarx.eclipse.views.PluginListenerDefinition; +import com.google.common.eventbus.EventBus; public class ActionGetScanResults extends CxBaseAction { @@ -23,14 +25,16 @@ public class ActionGetScanResults extends CxBaseAction { private boolean alreadyRunning = false; private StringFieldEditor scanIdField; + private EventBus pluginEventBus; - public ActionGetScanResults(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, Action abortScanResultsAction) { + public ActionGetScanResults(DisplayModel rootModel, TreeViewer resultsTree, boolean alreadyRunning, StringFieldEditor scanIdField, Action abortScanResultsAction, EventBus pluginEventBus) { super(rootModel, resultsTree); this.abortScanResultsAction = abortScanResultsAction; this.alreadyRunning = alreadyRunning; this.scanIdField = scanIdField; + this.pluginEventBus = pluginEventBus; } /** @@ -55,18 +59,12 @@ public void run() { CompletableFuture.runAsync(() -> { alreadyRunning = true; - List scanResults = DataProvider.INSTANCE.getResultsForScanId(scanId); - - rootModel.children.clear(); - rootModel.children.addAll(scanResults); - resultsTree.getTree().getDisplay().asyncExec(() -> resultsTree.refresh()); - this.setEnabled(true); - alreadyRunning = false; + pluginEventBus.post(new PluginListenerDefinition(PluginListenerType.GET_RESULTS, DataProvider.getInstance().getResultsForScanId(scanId))); }); - } }; + getScanResultsAction.setId(ActionName.GET_RESULTS.name()); getScanResultsAction.setToolTipText(ACTION_SCAN_RESULTS_TOOLTIP); getScanResultsAction.setImageDescriptor(Activator.getImageDescriptor(ACTION_SCAN_RESULTS_ICON_PATH)); diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionName.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionName.java new file mode 100644 index 00000000..ae252b93 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionName.java @@ -0,0 +1,15 @@ +package com.checkmarx.eclipse.views.actions; + +public enum ActionName { + + HIGH, + MEDIUM, + LOW, + INFO, + GET_RESULTS, + ABORT_RESULTS, + CLEAN_AND_REFRESH, + PREFERENCES, + GROUP_BY_SEVERITY, + GROUP_BY_QUERY_NAME +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java index 24f200bd..a8206d93 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ActionOpenPreferencesPage.java @@ -38,6 +38,7 @@ public void run() { } }; + openPreferencesPageAction.setId(ActionName.PREFERENCES.name()); openPreferencesPageAction.setText(LABEL_PREFERENCES); return openPreferencesPageAction; diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java index 6bfd67ed..e3214a94 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/CxBaseAction.java @@ -29,7 +29,7 @@ public CxBaseAction(DisplayModel rootModel, TreeViewer resultsTree) { */ public void showMessage(String message) { rootModel.children.clear(); - rootModel.children.add(DataProvider.INSTANCE.message(message)); + rootModel.children.add(DataProvider.getInstance().message(message)); resultsTree.refresh(); } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java index b86d778c..e7592cd7 100644 --- a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/actions/ToolBarActions.java @@ -4,41 +4,51 @@ import java.util.List; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.preference.StringFieldEditor; -import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import com.checkmarx.eclipse.views.DataProvider; import com.checkmarx.eclipse.views.DisplayModel; +import com.checkmarx.eclipse.views.PluginListenerDefinition; +import com.checkmarx.eclipse.views.PluginListenerType; +import com.checkmarx.eclipse.views.filters.ActionFilters; +import com.checkmarx.eclipse.views.filters.FilterState; +import com.checkmarx.eclipse.views.filters.Severity; +import com.google.common.eventbus.EventBus; public class ToolBarActions { + + public static final String MENU_GROUP_BY = "Group By"; + public static final String GROUP_BY_SEVERITY = "Severity"; + public static final String GROUP_BY_QUERY_NAME = "Query Name"; private List toolBarActions = new ArrayList(); + + private IActionBars actionBars; private DisplayModel rootModel; private TreeViewer resultsTree; private StringFieldEditor scanIdField; private boolean alreadyRunning = false; - - private Composite resultInfoPanel; - private Composite attackVectorPanel; - private Composite leftPanel; - - private ComboViewer scanIdComboViewer; - private ComboViewer projectComboViewer; + + private EventBus pluginEventBus; private Action scanResultsAction; + private Action groupBySeverityAction; + private Action groupByQueryNameAction; + private List filterActions; - public ToolBarActions(ToolBarActionsBuilder toolBarActionsBuilder) { + private ToolBarActions(ToolBarActionsBuilder toolBarActionsBuilder) { + this.actionBars = toolBarActionsBuilder.actionBars; this.rootModel = toolBarActionsBuilder.rootModel; this.resultsTree = toolBarActionsBuilder.resultsTree; this.alreadyRunning = toolBarActionsBuilder.alreadyRunning; this.scanIdField = toolBarActionsBuilder.scanIdField; - this.resultInfoPanel = toolBarActionsBuilder.resultInfoPanel; - this.attackVectorPanel = toolBarActionsBuilder.attackVectorPanel; - this.leftPanel = toolBarActionsBuilder.leftPanel; - this.scanIdComboViewer = toolBarActionsBuilder.scanIdComboViewer; - this.projectComboViewer = toolBarActionsBuilder.projectComboViewer; + this.pluginEventBus = toolBarActionsBuilder.pluginEventBus; createActions(); } @@ -48,17 +58,60 @@ public ToolBarActions(ToolBarActionsBuilder toolBarActionsBuilder) { */ private void createActions() { - Action clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, resultInfoPanel, attackVectorPanel, leftPanel, scanIdComboViewer, projectComboViewer).createAction(); - Action abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); - scanResultsAction = new ActionGetScanResults(rootModel, resultsTree, alreadyRunning, scanIdField, abortScanResultsAction).createAction(); + filterActions = new ActionFilters(pluginEventBus).createFilterActions(); + Action clearSelectionAction = new ActionClearSelection(rootModel, resultsTree, pluginEventBus).createAction(); + Action abortScanResultsAction = new ActionAbortScanResults(rootModel, resultsTree).createAction(); + scanResultsAction = new ActionGetScanResults(rootModel, resultsTree, alreadyRunning, scanIdField, abortScanResultsAction, pluginEventBus).createAction(); + + toolBarActions.addAll(filterActions); toolBarActions.add(clearSelectionAction); toolBarActions.add(scanResultsAction); toolBarActions.add(abortScanResultsAction); + + createGroupByActions(); } /** - * Gets all tool bar actions + * Create Group By actions (Severity & Query Name) + */ + private void createGroupByActions() { + groupBySeverityAction = new Action(GROUP_BY_SEVERITY, IAction.AS_CHECK_BOX) { + @Override + public void run() { + FilterState.setState(Severity.GROUP_BY_SEVERITY); + pluginEventBus.post(new PluginListenerDefinition(PluginListenerType.FILTER_CHANGED, DataProvider.getInstance().filterResults())); + } + }; + + groupBySeverityAction.setId(ActionName.GROUP_BY_SEVERITY.name()); + groupBySeverityAction.setChecked(FilterState.groupBySeverity); + + groupByQueryNameAction = new Action(GROUP_BY_QUERY_NAME, IAction.AS_CHECK_BOX) { + @Override + public void run() { + FilterState.setState(Severity.GROUP_BY_QUERY_NAME); + pluginEventBus.post(new PluginListenerDefinition(PluginListenerType.FILTER_CHANGED, DataProvider.getInstance().filterResults())); + } + }; + + groupByQueryNameAction.setId(ActionName.GROUP_BY_QUERY_NAME.name()); + groupByQueryNameAction.setChecked(FilterState.groupByQueryName); + + filterActions.add(groupBySeverityAction); + filterActions.add(groupByQueryNameAction); + + IMenuManager dropDownMenu = actionBars.getMenuManager(); + MenuManager subMenu = new MenuManager(MENU_GROUP_BY, MENU_GROUP_BY); + subMenu.add(groupBySeverityAction); + subMenu.add(groupByQueryNameAction); + dropDownMenu.add(subMenu); + + actionBars.updateActionBars(); + } + + /** + * Get all tool bar actions * * @return */ @@ -67,7 +120,7 @@ public List getToolBarActions() { } /** - * Gets scan results action + * Get scan results action * * @return */ @@ -75,6 +128,15 @@ public Action getScanResultsAction() { return scanResultsAction; } + /** + * Get all filter actions + * + * @return + */ + public List getFilterActions() { + return filterActions; + } + /** * Builder Class to construct a ToolBarActions * @@ -83,20 +145,22 @@ public Action getScanResultsAction() { */ public static class ToolBarActionsBuilder { + private IActionBars actionBars; + private DisplayModel rootModel; private TreeViewer resultsTree; private StringFieldEditor scanIdField; private boolean alreadyRunning = false; - - private Composite resultInfoPanel; - private Composite attackVectorPanel; - private Composite leftPanel; - - private ComboViewer scanIdComboViewer; - private ComboViewer projectComboViewer; + + private EventBus pluginEventBus; public ToolBarActionsBuilder() {} + public ToolBarActionsBuilder actionBars(IActionBars actionBars) { + this.actionBars = actionBars; + return this; + } + public ToolBarActionsBuilder rootModel(DisplayModel rootModel) { this.rootModel = rootModel; return this; @@ -117,28 +181,8 @@ public ToolBarActionsBuilder alreadyRunning(boolean alreadyRunning) { return this; } - public ToolBarActionsBuilder resultInfoPanel(Composite resultInfoPanel) { - this.resultInfoPanel = resultInfoPanel; - return this; - } - - public ToolBarActionsBuilder attackVectorPanel(Composite attackVectorPanel) { - this.attackVectorPanel = attackVectorPanel; - return this; - } - - public ToolBarActionsBuilder leftPanel(Composite leftPanel) { - this.leftPanel = leftPanel; - return this; - } - - public ToolBarActionsBuilder scanIdComboViewer(ComboViewer scanIdComboViewer) { - this.scanIdComboViewer = scanIdComboViewer; - return this; - } - - public ToolBarActionsBuilder projectComboViewer(ComboViewer projectComboViewer) { - this.projectComboViewer = projectComboViewer; + public ToolBarActionsBuilder pluginEventBus(EventBus pluginEventBus) { + this.pluginEventBus = pluginEventBus; return this; } diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/ActionFilters.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/ActionFilters.java new file mode 100644 index 00000000..aa25cf61 --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/ActionFilters.java @@ -0,0 +1,83 @@ +package com.checkmarx.eclipse.views.filters; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.action.Action; + +import com.checkmarx.eclipse.Activator; +import com.checkmarx.eclipse.views.DataProvider; +import com.checkmarx.eclipse.views.PluginListenerType; +import com.checkmarx.eclipse.views.PluginListenerDefinition; +import com.checkmarx.eclipse.views.actions.ActionName; +import com.google.common.eventbus.EventBus; + +public class ActionFilters { + + private static final String ACTION_FILTER_HIGH_TOOLTIP = "High"; + private static final String ACTION_FILTER_HIGH_ICON_PATH = "/icons/severity-high.png"; + + private static final String ACTION_FILTER_MEDIUM_TOOLTIP = "Medium"; + private static final String ACTION_FILTER_MEDIUM_ICON_PATH = "/icons/severity-medium.png"; + + private static final String ACTION_FILTER_LOW_TOOLTIP = "Low"; + private static final String ACTION_FILTER_LOW_ICON_PATH = "/icons/severity-low.png"; + + private static final String ACTION_FILTER_INFO_TOOLTIP = "Info"; + private static final String ACTION_FILTER_INFO_ICON_PATH = "platform:/plugin/org.eclipse.ui/icons/full/obj16/info_tsk.png"; + + private EventBus pluginEventBus; + + public ActionFilters(EventBus pluginEventBus) { + this.pluginEventBus = pluginEventBus; + } + + /** + * Creates a JFace actions to severity filters + * + * @return + */ + public List createFilterActions(){ + + List filters = new ArrayList<>(); + + Action filterHighAction = createFilterAction(ACTION_FILTER_HIGH_TOOLTIP, ACTION_FILTER_HIGH_ICON_PATH, Severity.HIGH, ActionName.HIGH); + Action filterMediumAction = createFilterAction(ACTION_FILTER_MEDIUM_TOOLTIP, ACTION_FILTER_MEDIUM_ICON_PATH, Severity.MEDIUM, ActionName.MEDIUM); + Action filterLowAction = createFilterAction(ACTION_FILTER_LOW_TOOLTIP, ACTION_FILTER_LOW_ICON_PATH, Severity.LOW, ActionName.LOW); + Action filterInfoAction = createFilterAction(ACTION_FILTER_INFO_TOOLTIP, ACTION_FILTER_INFO_ICON_PATH, Severity.INFO, ActionName.INFO); + + filters.add(filterHighAction); + filters.add(filterMediumAction); + filters.add(filterLowAction); + filters.add(filterInfoAction); + + return filters; + } + + /** + * Creates a filter action + * + * @param tooltip + * @param imagePath + * @param severity + * @param actionName + * @return + */ + private Action createFilterAction(String tooltip, String imagePath, Severity severity, ActionName actionName) { + Action filterAction = new Action() { + @Override + public void run() { + FilterState.setState(severity); + pluginEventBus.post(new PluginListenerDefinition(PluginListenerType.FILTER_CHANGED, DataProvider.getInstance().filterResults())); + } + }; + + filterAction.setId(actionName.name()); + filterAction.setToolTipText(tooltip); + filterAction.setImageDescriptor(Activator.getImageDescriptor(imagePath)); + filterAction.setEnabled(DataProvider.getInstance().getCurrentScanId() != null); + filterAction.setChecked(FilterState.isSeverityEnabled(severity.name())); + + return filterAction; + } +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/FilterState.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/FilterState.java new file mode 100644 index 00000000..085c9c2c --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/FilterState.java @@ -0,0 +1,73 @@ +package com.checkmarx.eclipse.views.filters; + + +public class FilterState { + + public static boolean high = true; + public static boolean medium = true; + public static boolean low = false; + public static boolean info = false; + public static boolean groupBySeverity = true; + public static boolean groupByQueryName = false; + + /** + * Change severity state + * + * @param severity + */ + public static void setState(Severity severity) { + + switch(severity) { + case HIGH: + high = !high; + break; + case MEDIUM: + medium = !medium; + break; + case LOW: + low = !low; + break; + case INFO: + info = !info; + break; + case GROUP_BY_SEVERITY: + groupBySeverity = !groupBySeverity; + break; + case GROUP_BY_QUERY_NAME: + groupByQueryName = !groupByQueryName; + break; + } + } + + /** + * Checks whether a severity is enabled + * + * @param severity + * @return + */ + public static boolean isSeverityEnabled(String severity) { + + switch(Severity.getSeverity(severity)) { + case HIGH: return high; + case MEDIUM: return medium; + case LOW: return low; + case INFO: return info; + case GROUP_BY_SEVERITY: return groupBySeverity; + case GROUP_BY_QUERY_NAME: return groupByQueryName; + } + + return false; + } + + /** + * Reset filters state + */ + public static void resetFilters() { + high = true; + medium = true; + low = false; + info = false; + groupBySeverity = true; + groupByQueryName = false; + } +} diff --git a/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/Severity.java b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/Severity.java new file mode 100644 index 00000000..6683df8e --- /dev/null +++ b/checkmarx-ast-eclipse-plugin/src/com/checkmarx/eclipse/views/filters/Severity.java @@ -0,0 +1,15 @@ +package com.checkmarx.eclipse.views.filters; + +public enum Severity { + + HIGH, + MEDIUM, + LOW, + INFO, + GROUP_BY_SEVERITY, + GROUP_BY_QUERY_NAME; + + public static Severity getSeverity(String severity) { + return Severity.valueOf(severity); + } +}