All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zaproxy.zap.view.messagelocation.AbstractMessageLocationsPanel Maven / Gradle / Ivy

Go to download

The Zed Attack Proxy (ZAP) is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications. It is designed to be used by people with a wide range of security experience and as such is ideal for developers and functional testers who are new to penetration testing. ZAP provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually.

There is a newer version: 2.15.0
Show newest version
/*
 * Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2015 The ZAP Development Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.zaproxy.zap.view.messagelocation;

import java.awt.Component;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.SortOrder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import org.jdesktop.swingx.JXTable;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.httppanel.ComponentChangedEvent;
import org.zaproxy.zap.extension.httppanel.MessagePanelEventListener;
import org.zaproxy.zap.extension.httppanel.MessageViewSelectedEvent;
import org.zaproxy.zap.extension.httppanel.view.HttpPanelView;
import org.zaproxy.zap.model.MessageLocation;
import org.zaproxy.zap.view.AbstractMultipleOptionsBaseTablePanel;

/**
 * An {@code AbstractMultipleOptionsBaseTablePanel} that allows to manage highlights and message
 * locations.
 *
 * @param  the type that contains the details of the highlight and message location
 * @param  the type of the table model that contains the elements with the details
 * @since 2.4.0
 * @see MessageLocationTableEntry
 * @see MessageLocationsTableModel
 */
public abstract class AbstractMessageLocationsPanel<
                T extends MessageLocationTableEntry, S extends MessageLocationsTableModel>
        extends AbstractMultipleOptionsBaseTablePanel {

    private static final long serialVersionUID = -8990789229815588716L;

    private static final String REMOVE_DIALOG_TITLE =
            Constant.messages.getString("messagelocationspanel.dialog.remove.location.title");
    private static final String REMOVE_DIALOG_TEXT =
            Constant.messages.getString("messagelocationspanel.dialog.remove.location.text");

    private static final String REMOVE_DIALOG_CONFIRM_BUTTON_LABEL =
            Constant.messages.getString(
                    "messagelocationspanel.dialog.remove.location.button.confirm");
    private static final String REMOVE_DIALOG_CANCEL_BUTTON_LABEL =
            Constant.messages.getString(
                    "messagelocationspanel.dialog.remove.location.button.cancel");

    private static final String REMOVE_DIALOG_CHECKBOX_LABEL =
            Constant.messages.getString(
                    "messagelocationspanel.dialog.remove.location.checkbox.label");

    private MessageLocationProducerFocusListener addButtonFocusListenerEnabler;

    private SelectMessageLocationsPanel selectMessageLocationsPanel;

    private final Component parent;

    public AbstractMessageLocationsPanel(
            Component parent, SelectMessageLocationsPanel selectMessageLocationsPanel, S model) {
        this(parent, selectMessageLocationsPanel, model, false);
    }

    public AbstractMessageLocationsPanel(
            Component parent,
            SelectMessageLocationsPanel selectMessageLocationsPanel,
            S model,
            boolean allowModifications) {
        super(model, allowModifications);

        this.parent = parent;

        this.selectMessageLocationsPanel = selectMessageLocationsPanel;
        this.selectMessageLocationsPanel.addMessagePanelEventListener(
                createMessagePanelEventListener());

        getModel().addMessageLocationHighlightChangedListener(createHighlightChangedListener());

        addButton.setEnabled(false);
        addButton.setToolTipText(
                Constant.messages.getString("messagelocationspanel.add.location.tooltip"));
        addButtonFocusListenerEnabler = createFocusListener();

        getTable().setSortOrder(1, SortOrder.ASCENDING);
        getTable()
                .setDefaultRenderer(
                        MessageLocationHighlight.class,
                        new DefaultMessageLocationHighlightRenderer());

        getRemoveWithoutConfirmationCheckBox().setSelected(true);
    }

    protected MessagePanelEventListener createMessagePanelEventListener() {
        return new MessagePanelEventListener() {

            @Override
            public void componentChanged(ComponentChangedEvent event) {
                for (T entry : getModel().getElements()) {
                    MessageLocationHighlight highlight = entry.getHighlight();
                    if (highlight != null) {
                        MessageLocationHighlight highlightReference =
                                selectMessageLocationsPanel.highlight(
                                        entry.getLocation(), highlight);
                        entry.setHighlightReference(highlightReference);
                    }
                }
            }

            @Override
            public void viewSelected(MessageViewSelectedEvent event) {
                HttpPanelView view = event.getCurrentView();
                if (view instanceof MessageLocationHighlighter) {
                    MessageLocationHighlighter highlighter = (MessageLocationHighlighter) view;
                    for (T entry : getModel().getElements()) {
                        MessageLocationHighlight highlight = entry.getHighlight();
                        if (highlight != null) {
                            MessageLocationHighlight highlightReference =
                                    highlighter.highlight(entry.getLocation(), highlight);
                            entry.setHighlightReference(highlightReference);
                        }
                    }
                } else {
                    for (T entry : getModel().getElements()) {
                        entry.setHighlightReference(null);
                    }
                }
            }
        };
    }

    protected HighlightChangedListener createHighlightChangedListener() {
        return new MessageLocationsHighlightChangedListener();
    }

    @Override
    protected JXTable createTable() {
        MessageLocationsTable table = new MessageLocationsTable();
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.setColumnControlVisible(true);

        return table;
    }

    public MessageLocationProducerFocusListener getFocusListenerAddButtonEnabler() {
        return addButtonFocusListenerEnabler;
    }

    protected MessageLocationProducerFocusListener createFocusListener() {
        return new MessageLocationsFocusListener();
    }

    @Override
    public T showAddDialogue() {
        addButton.setEnabled(false);
        return addMessageLocationImpl(true, selectMessageLocationsPanel.getSelection());
    }

    public boolean addMessageLocation(MessageLocation messageLocation) {
        if (messageLocation == null) {
            throw new IllegalArgumentException("Parameter messageLocation must not be null.");
        }

        return addMessageLocationImpl(false, messageLocation) != null;
    }

    private T addMessageLocationImpl(boolean buttonAddedLocation, MessageLocation messageLocation) {
        for (T locationUI : getModel().getElements()) {
            if (locationUI.getLocation().overlaps(messageLocation)) {
                View.getSingleton()
                        .showWarningDialog(
                                Constant.messages.getString(
                                        "messagelocationspanel.add.location.warning.locations.overlap"));
                return null;
            }
        }

        MessageLocationHighlight highlight = null;
        MessageLocationHighlight highlightReference = null;
        MessageLocationHighlightsManager highlightsManager = selectMessageLocationsPanel.create();
        if (highlightsManager != null) {
            highlight = highlightsManager.getHighlight(messageLocation);
            highlightReference = selectMessageLocationsPanel.highlight(messageLocation, highlight);
        }

        T entry =
                createMessageLocationTableEntry(
                        buttonAddedLocation, messageLocation, highlight, highlightReference);
        if (entry == null) {
            if (highlightsManager != null) {
                selectMessageLocationsPanel.removeHighlight(messageLocation, highlightReference);
            }
            return null;
        }
        getModel().addElement(entry);

        int row = getTable().convertRowIndexToView(getModel().getRow(entry));
        getTable().setRowSelectionInterval(row, row);

        return null;
    }

    protected abstract T createMessageLocationTableEntry(
            boolean buttonAddedLocation,
            MessageLocation messageLocation,
            MessageLocationHighlight highlight,
            MessageLocationHighlight highlightReference);

    @Override
    public T showModifyDialogue(T e) {
        return null;
    }

    @Override
    public boolean showRemoveDialogue(T e) {
        if (!getRemoveWithoutConfirmationCheckBox().isSelected()) {
            if (!showRemoveDialogueImpl(e)) {
                return false;
            }
        }

        MessageLocationHighlight highlightReference = e.getHighlightReference();
        if (highlightReference != null) {
            selectMessageLocationsPanel.removeHighlight(e.getLocation(), highlightReference);
        }

        return true;
    }

    protected Component getParentOwner() {
        return parent;
    }

    protected boolean showRemoveDialogueImpl(T e) {
        JCheckBox removeWithoutConfirmationCheckBox = new JCheckBox(REMOVE_DIALOG_CHECKBOX_LABEL);
        Object[] messages = {REMOVE_DIALOG_TEXT, " ", removeWithoutConfirmationCheckBox};
        int option =
                JOptionPane.showOptionDialog(
                        View.getSingleton().getMainFrame(),
                        messages,
                        REMOVE_DIALOG_TITLE,
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        null,
                        new String[] {
                            REMOVE_DIALOG_CONFIRM_BUTTON_LABEL, REMOVE_DIALOG_CANCEL_BUTTON_LABEL
                        },
                        null);

        if (option == JOptionPane.OK_OPTION) {
            getRemoveWithoutConfirmationCheckBox()
                    .setSelected(removeWithoutConfirmationCheckBox.isSelected());
            return true;
        }

        return false;
    }

    @Override
    public boolean isRemoveWithoutConfirmation() {
        // Force base class to call the method showRemoveDialogue(T1) so the
        // state of the panels can be changed before deleting the entries
        return false;
    }

    public void reset() {
        for (T entry : getMultipleOptionsModel().getElements()) {
            MessageLocationHighlight highlightReference = entry.getHighlightReference();
            if (highlightReference != null) {
                selectMessageLocationsPanel.removeHighlight(
                        entry.getLocation(), highlightReference);
            }
        }
        getMultipleOptionsModel().clear();
    }

    @Override
    protected S getModel() {
        @SuppressWarnings("unchecked")
        // Safe cast it's the model that's set in the constructor (which can't be changed)
        S model = (S) super.getMultipleOptionsModel();
        return model;
    }

    private static class DefaultMessageLocationHighlightRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 427590735065539815L;

        @Override
        protected void setValue(Object value) {}
    }

    protected class MessageLocationsTable extends JXTable {

        private static final long serialVersionUID = -3277532157790764376L;

        @Override
        public TableCellEditor getCellEditor(int row, int column) {

            Class columnClass =
                    AbstractMessageLocationsPanel.this.getModel().getColumnClass(row, column);
            if (columnClass != null
                    && MessageLocationHighlight.class.isAssignableFrom(columnClass)) {

                @SuppressWarnings("unchecked")
                TableCellEditor editor =
                        MessageLocationHighlightRenderersEditors.getInstance()
                                .getEditor((Class) columnClass);
                if (editor != null) {
                    return editor;
                }
            }
            return super.getCellEditor(row, column);
        }

        @Override
        public TableCellRenderer getCellRenderer(int row, int column) {

            Class columnClass =
                    AbstractMessageLocationsPanel.this.getModel().getColumnClass(row, column);
            if (columnClass != null
                    && MessageLocationHighlight.class.isAssignableFrom(columnClass)) {

                @SuppressWarnings("unchecked")
                TableCellRenderer renderer =
                        MessageLocationHighlightRenderersEditors.getInstance()
                                .getRenderer(
                                        (Class) columnClass);
                if (renderer != null) {
                    return renderer;
                }
            }
            return super.getCellRenderer(row, column);
        }
    }

    protected class MessageLocationsHighlightChangedListener
            implements HighlightChangedListener {

        @Override
        public void highlightChanged(HighlightChangedEvent event) {
            T tableEntry = event.getEntry();

            MessageLocationHighlight highlightReference = event.getHighlightReference();
            if (highlightReference != null) {
                selectMessageLocationsPanel.removeHighlight(
                        tableEntry.getLocation(), event.getHighlightReference());
            }

            MessageLocationHighlight highlight = tableEntry.getHighlight();
            if (highlight != null) {
                highlightReference =
                        selectMessageLocationsPanel.highlight(
                                tableEntry.getLocation(), tableEntry.getHighlight());
                tableEntry.setHighlightReference(highlightReference);
            }
        };
    }

    protected class MessageLocationsFocusListener implements MessageLocationProducerFocusListener {

        @Override
        public void focusLost(MessageLocationProducerFocusEvent e) {
            if (e.getFocusEvent().getOppositeComponent() != addButton) {
                addButton.setEnabled(false);
            }
        }

        @Override
        public void focusGained(MessageLocationProducerFocusEvent e) {
            addButton.setEnabled(true);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy