Java tutorial
/******************************************************************************* * Copyright (c) 2017 Contrast Security. * All rights reserved. * * This program and the accompanying materials are made available under * the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License. * * The terms of the GNU GPL version 3 which accompanies this distribution * and is available at https://www.gnu.org/licenses/gpl-3.0.en.html * * Contributors: * Contrast Security - initial API and implementation *******************************************************************************/ package com.contrastsecurity.ide.eclipse.ui.internal.model; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.resource.ColorRegistry; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import com.contrastsecurity.exceptions.UnauthorizedException; import com.contrastsecurity.ide.eclipse.core.Constants; import com.contrastsecurity.ide.eclipse.core.extended.BaseResponse; import com.contrastsecurity.ide.eclipse.core.extended.EventResource; import com.contrastsecurity.ide.eclipse.core.extended.EventSummaryResource; import com.contrastsecurity.ide.eclipse.core.extended.ExtendedContrastSDK; import com.contrastsecurity.ide.eclipse.core.extended.HttpRequest; import com.contrastsecurity.ide.eclipse.core.extended.HttpRequestResource; import com.contrastsecurity.ide.eclipse.core.extended.RecommendationResource; import com.contrastsecurity.ide.eclipse.core.extended.StoryResource; import com.contrastsecurity.ide.eclipse.core.extended.TagsResource; import com.contrastsecurity.ide.eclipse.core.extended.TagsServersResource; import com.contrastsecurity.ide.eclipse.core.extended.TraceStatusRequest; import com.contrastsecurity.ide.eclipse.ui.ContrastUIActivator; import com.contrastsecurity.ide.eclipse.ui.internal.views.MarkStatusDialog; import com.contrastsecurity.ide.eclipse.ui.cache.ContrastCache; import com.contrastsecurity.ide.eclipse.ui.cache.Key; import com.contrastsecurity.ide.eclipse.ui.internal.views.TagDialog; import com.contrastsecurity.ide.eclipse.ui.internal.views.VulnerabilitiesView; import com.contrastsecurity.ide.eclipse.ui.util.SystemUtils; import com.contrastsecurity.ide.eclipse.ui.util.UIElementUtils; import com.contrastsecurity.models.Trace; public class VulnerabilityDetailsPage extends AbstractPage { private Label severityLabel; private Label nameLabel; private Button externalLinkButton; private Button markAsButton; private Button tagButton; private Trace trace; private OverviewTab overviewTab; private RecommendationTab recommendationTab; private EventsTab eventsTab; private HttpRequestTab httpRequestTab; private HttpRequestResource httpRequest; private EventSummaryResource eventSummaryResource; private CTabFolder folder; private CTabItem eventsTabItem; private CTabItem httpRequestTabItem; private TagsResource traceTagsResource; private TagsResource orgTagsResource; private ContrastCache contrastCache = ContrastUIActivator.getContrastCache(); public VulnerabilityDetailsPage(final Composite parent, final int style, final VulnerabilitiesView vulnerabilitiesView) { super(parent, style, vulnerabilitiesView); setLayout(new GridLayout()); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); setLayoutData(gd); UIElementUtils.createLogoLabel(this, ContrastUIActivator.getImage("/icons/contrastLogo.png")); Composite comboComposite = new Composite(this, SWT.NONE); comboComposite.setLayout(new GridLayout(6, false)); gd = new GridData(SWT.FILL, SWT.FILL, true, false); comboComposite.setLayoutData(gd); severityLabel = UIElementUtils.createLabel(comboComposite, ""); nameLabel = UIElementUtils.createLabel(comboComposite, ""); externalLinkButton = UIElementUtils.createButton(comboComposite, ContrastUIActivator.getImage("/icons/externalLink.png")); externalLinkButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { try { vulnerabilitiesView.openTraceInBrowser(trace); } catch (PartInitException | MalformedURLException e1) { ContrastUIActivator.log(e1); } } }); tagButton = UIElementUtils.createButton(comboComposite, ContrastUIActivator.getImage("/icons/tag.png")); tagButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { TagDialog tagDialog = new TagDialog(getShell(), traceTagsResource, orgTagsResource); tagDialog.create(); tagDialog.open(); List<String> newTraceTags = tagDialog.getNewTraceTags(); if (newTraceTags != null) { Key key = new Key(ContrastUIActivator.getOrgUuid(), trace.getUuid()); Key keyForOrg = new Key(ContrastUIActivator.getOrgUuid(), null); boolean tagsChanged = false; // remove tags if necessary for (String tag : traceTagsResource.getTags()) { if (!newTraceTags.contains(tag)) { try { getSdk().deleteTag(ContrastUIActivator.getOrgUuid(), trace.getUuid(), tag); if (!tagsChanged) { tagsChanged = true; } } catch (IOException | UnauthorizedException e1) { e1.printStackTrace(); } } } // add tags if necessary List<String> tagsToAdd = new ArrayList<>(); for (String tag : newTraceTags) { if (!traceTagsResource.getTags().contains(tag)) { tagsToAdd.add((tag)); } } if (!tagsToAdd.isEmpty()) { List<String> tracesId = new ArrayList<>(); tracesId.add(trace.getUuid()); TagsServersResource tagsServersResource = new TagsServersResource(tagsToAdd, tracesId); try { getSdk().putTags(ContrastUIActivator.getOrgUuid(), tagsServersResource); if (!tagsChanged) { tagsChanged = true; } } catch (IOException | UnauthorizedException e1) { e1.printStackTrace(); } } if (tagsChanged) { contrastCache.getTagsResources().remove(key); contrastCache.getTagsResources().remove(keyForOrg); try { traceTagsResource = getTags(key); orgTagsResource = getTags(keyForOrg); } catch (IOException | UnauthorizedException e1) { e1.printStackTrace(); } } } } }); if (SystemUtils.isMacOS()) markAsButton = UIElementUtils.createButton(comboComposite, "Mark as", 130); else markAsButton = UIElementUtils.createButton(comboComposite, "Mark as", 100); markAsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { showMarkStatusDialog(comboComposite); } }); Button backLink = new Button(comboComposite, SWT.NONE); gd = new GridData(SWT.END, SWT.FILL, true, false); backLink.setLayoutData(gd); backLink.setText("Back To Results"); backLink.addMouseListener(new MouseListener() { @Override public void mouseUp(MouseEvent e) { getVulnerabilitiesView().showVulnerabilityPage(); } @Override public void mouseDown(MouseEvent e) { } @Override public void mouseDoubleClick(MouseEvent e) { } }); folder = createTabFolder(this); CTabItem overviewTabItem = new CTabItem(folder, SWT.NONE); overviewTabItem.setText("Overview"); overviewTab = new OverviewTab(folder, SWT.NONE); overviewTabItem.setControl(overviewTab); CTabItem recommendationTabItem = new CTabItem(folder, SWT.NONE); recommendationTabItem.setText("How to Fix"); recommendationTab = new RecommendationTab(folder, SWT.NONE); recommendationTabItem.setControl(recommendationTab); folder.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { if (e.item == httpRequestTabItem) { if (trace != null && httpRequestTab.getHttpRequest() == null) { HttpRequestResource httpRequest = null; try { httpRequest = getSdk().getHttpRequest(ContrastUIActivator.getOrgUuid(), trace.getUuid()); httpRequestTab.setHttpRequest(httpRequest); } catch (UnauthorizedException e1) { ContrastUIActivator.log(e1); } catch (IOException e1) { ContrastUIActivator.logInfo("Trace doesn't have http request"); httpRequest = new HttpRequestResource(); HttpRequest req = new HttpRequest(); req.setFormattedText("There isn't http request"); httpRequest.setHttpRequest(req); setHttpRequest(httpRequest); } } } else if (e.item == eventsTabItem) { if (trace != null && eventsTab.getEventSummary() == null) { EventSummaryResource eventSummary = null; try { eventSummary = getSdk().getEventSummary(ContrastUIActivator.getOrgUuid(), trace.getUuid()); eventsTab.setEventSummary(eventSummary); } catch (UnauthorizedException e1) { ContrastUIActivator.log(e1); } catch (IOException e1) { ContrastUIActivator.logInfo("Trace doesn't have event summary"); // FIXME // eventSummary = new EventSummaryResource(); } } } } @Override public void widgetDefaultSelected(SelectionEvent e) { } }); } protected ExtendedContrastSDK getSdk() { return getVulnerabilitiesView().getSdk(); } private void showMarkStatusDialog(Composite composite) { final MarkStatusDialog dialog = new MarkStatusDialog(getShell(), trace.getUuid()); dialog.setBlockOnOpen(true); if (dialog.open() != Dialog.OK) return; final TraceStatusRequest request = dialog.getTraceStatusRequest(); final String status = dialog.getSelectedStatus(); BusyIndicator.showWhile(getDisplay(), new Runnable() { @Override public void run() { if (markStatus(request)) markAsButton.setText(status); } }); } public void createAdditionalTabs() { disposeTab(eventsTabItem); disposeTab(httpRequestTabItem); eventsTabItem = null; httpRequestTabItem = null; List<EventResource> events = eventSummaryResource.getEvents(); if (events != null && events.size() > 0) { eventsTabItem = new CTabItem(folder, SWT.NONE); eventsTabItem.setText("Events"); eventsTab = new EventsTab(folder, SWT.NONE); eventsTabItem.setControl(eventsTab); eventsTab.setEventSummary(eventSummaryResource); } if (httpRequest != null && httpRequest.getHttpRequest() != null && httpRequest.getHttpRequest().getFormattedText() != null) { httpRequestTabItem = new CTabItem(folder, SWT.NONE); httpRequestTabItem.setText("HTTP Request"); httpRequestTab = new HttpRequestTab(folder, SWT.NONE); httpRequestTabItem.setControl(httpRequestTab); httpRequestTab.setHttpRequest(httpRequest); } setDefaultSelection(); } private void disposeTab(CTabItem tab) { if (tab != null && !tab.isDisposed()) { Control control = tab.getControl(); if (control != null) { control.dispose(); } tab.dispose(); } } private CTabFolder createTabFolder(Composite parent) { CTabFolder folder = new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.FLAT); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); folder.setLayoutData(gd); ColorRegistry reg = JFaceResources.getColorRegistry(); Color c1 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), c2 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END"); folder.setSelectionBackground(new Color[] { c1, c2 }, new int[] { 100 }, true); folder.setSelectionForeground(reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); folder.setSimple(PlatformUI.getPreferenceStore() .getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS)); folder.setBorderVisible(true); folder.setFont(parent.getFont()); return folder; } public Label getSeverityLabel() { return severityLabel; } public Label getNameLabel() { return nameLabel; } public Button getExternalLinkLabel() { return externalLinkButton; } public Trace getTrace() { return trace; } public void setTrace(Trace trace) { this.trace = trace; if (trace != null) { getNameLabel().setText(trace.getTitle() == null ? Constants.BLANK : trace.getTitle()); getSeverityLabel().setImage(ContrastUIActivator.getSeverityImage(trace)); } else { getNameLabel().setText("?"); getSeverityLabel().setImage(null); } httpRequest = null; eventSummaryResource = null; getParent().layout(true, true); getParent().redraw(); } public void setStory(StoryResource story) { overviewTab.setStory(story); } public void setRecommendationResource(RecommendationResource recommendationResource) { recommendationTab.setRecommendationResource(recommendationResource); } public HttpRequestResource getHttpRequest() { return httpRequest; } public void setHttpRequest(HttpRequestResource httpRequest) { this.httpRequest = httpRequest; } public void setVulnerabilityStatus(String status) { markAsButton.setText(status); } /** * Sets the default tab that user should see when entering this view. */ public void setDefaultSelection() { setDefaultSelection(VulnerabilityDetailsTab.OVERVIEW); } /** * Sets the default tab that user should see when entering this view. If the tab specified * was not added to the view, then first one will be showed instead. * @param tab The tab that this user should see when entering this view. */ public void setDefaultSelection(VulnerabilityDetailsTab tab) { if (folder.getItemCount() > 1) folder.setSelection(tab.ordinal()); else folder.setSelection(0); } public EventSummaryResource getEventSummaryResource() { return eventSummaryResource; } public void setEventSummaryResource(EventSummaryResource eventSummaryResource) { this.eventSummaryResource = eventSummaryResource; } public void setTraceTagsResource(TagsResource traceTagsResource) { this.traceTagsResource = traceTagsResource; } public void setOrgTagsResource(TagsResource orgTagsResource) { this.orgTagsResource = orgTagsResource; } //==================== Requests ==================== private TagsResource getTags(Key key) throws IOException, UnauthorizedException { TagsResource tagsResource = contrastCache.getTagsResources().get(key); if (tagsResource == null) { if (key.getTraceId() != null) { tagsResource = getSdk().getTagsByTrace(key.getOrgUuid(), key.getTraceId()); } else { tagsResource = getSdk().getTagsByOrg(key.getOrgUuid()); } contrastCache.getTagsResources().put(key, tagsResource); } return tagsResource; } private boolean markStatus(TraceStatusRequest request) { try { BaseResponse response = getSdk().markStatus(ContrastUIActivator.getOrgUuid(), request); return response.getSuccess(); } catch (UnauthorizedException e1) { ContrastUIActivator.log(e1); UIElementUtils.ShowErrorMessage(getShell(), "You don't have authority to perform this operation."); } catch (IOException e1) { ContrastUIActivator.log(e1); UIElementUtils.ShowErrorMessage(getShell(), "Request failed. If error persists, contact support."); } return false; } }