Skip to content

Commit

Permalink
Add API Explore button to Quick Start
Browse files Browse the repository at this point in the history
Signed-off-by: ricekot <[email protected]>
  • Loading branch information
ricekot committed Jan 4, 2023
1 parent 323086c commit 0e7d859
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 6 deletions.
16 changes: 16 additions & 0 deletions addOns/quickstart/quickstart.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ zapAddOn {
}
}
}
register("org.zaproxy.zap.extension.quickstart.apiexplore.ExtensionApiExplore") {
classnames {
allowed.set(listOf("org.zaproxy.zap.extension.quickstart.apiexplore"))
}
dependencies {
addOns {
register("graphql") {
version.set(">= 0.13.0")
}
}
extensions {
register("org.zaproxy.zap.extension.quickstart.launch.ExtensionQuickStartLaunch")
}
}
}
}
dependencies {
addOns {
Expand All @@ -82,6 +97,7 @@ zapAddOn {

dependencies {
compileOnly(parent!!.childProjects.get("callhome")!!)
compileOnly(parent!!.childProjects.get("graphql")!!)
compileOnly(parent!!.childProjects.get("network")!!)
compileOnly(parent!!.childProjects.get("reports")!!)
compileOnly(parent!!.childProjects.get("selenium")!!)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public QuickStartPanel(ExtensionQuickStart extension) {
javax.swing.JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setHorizontalScrollBarPolicy(
javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane.setViewportView(panelContent);
showSubPanel(panelContent);

this.add(jScrollPane, BorderLayout.CENTER);

Expand Down Expand Up @@ -164,8 +164,16 @@ public void updateUI() {
}
}

public void showSubPanel(JPanel subPanel) {
jScrollPane.setViewportView(subPanel);
}

public void backToMainPanel() {
jScrollPane.setViewportView(panelContent);
showSubPanel(panelContent);
}

public JPanel getButtonPanel() {
return buttonPanel;
}

public AttackPanel getAttackPanel() {
Expand All @@ -186,7 +194,7 @@ private JButton getAttackButton() {
Constant.messages.getString("quickstart.top.button.tooltip.attack"));
attackButton.setPreferredSize(DisplayUtils.getScaledDimension(150, 120));

attackButton.addActionListener(e -> jScrollPane.setViewportView(getAttackPanel()));
attackButton.addActionListener(e -> showSubPanel(getAttackPanel()));
}
return attackButton;
}
Expand All @@ -211,7 +219,7 @@ private JButton getLearnMoreButton() {
learnMoreButton.setPreferredSize(DisplayUtils.getScaledDimension(150, 120));

learnMoreButton.addActionListener(
e -> jScrollPane.setViewportView(getLearnMorePanel()));
e -> showSubPanel(getLearnMorePanel()));
}
return learnMoreButton;
}
Expand All @@ -238,9 +246,9 @@ private JButton getExploreButton() {
exploreButton.addActionListener(
e -> {
if (explorePanel != null) {
jScrollPane.setViewportView(explorePanel);
showSubPanel(explorePanel);
} else {
jScrollPane.setViewportView(getDefaultExplorePanel());
showSubPanel(getDefaultExplorePanel());
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.zaproxy.zap.extension.quickstart.apiexplore;

import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.zaproxy.zap.extension.api.API;
import org.zaproxy.zap.extension.quickstart.ExtensionQuickStart;
import org.zaproxy.zap.extension.quickstart.QuickStartPanel;
import org.zaproxy.zap.extension.quickstart.QuickStartSubPanel;
import org.zaproxy.zap.extension.quickstart.launch.ExtensionQuickStartLaunch;
import org.zaproxy.zap.utils.DisplayUtils;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.FlowLayout;

public class ApiExplorePanel extends QuickStartSubPanel {

private static final long serialVersionUID = 1L;
private static final ImageIcon ICON = DisplayUtils.getScaledIcon(new ImageIcon(ApiExplorePanel.class.getResource("/org/zaproxy/zap/extension/quickstart/resources/api-explore_64px.png")));

private JButton graphiQlButton;

public ApiExplorePanel(ExtensionQuickStart extension, QuickStartPanel qsp) {
super(extension, qsp);
}

@Override
public String getTitleKey() {
return "quickstart.apiExplore.panel.title";
}

@Override
public ImageIcon getIcon() {
return ICON;
}

@Override
public JPanel getDescriptionPanel() {
return null;
}

@Override
public JPanel getContentPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(getBackground());
panel.add(getGraphiQlButton());
return panel;
}

private JButton getGraphiQlButton() {
if (graphiQlButton == null) {
graphiQlButton = new JButton();
graphiQlButton.setText(Constant.messages.getString("quickstart.graphiql.button.name"));
graphiQlButton.setIcon(DisplayUtils.getScaledIcon(getClass().getResource("/org/zaproxy/zap/extension/quickstart/resources/graphql_64px.png")));
graphiQlButton.setVerticalTextPosition(AbstractButton.BOTTOM);
graphiQlButton.setHorizontalTextPosition(AbstractButton.CENTER);
graphiQlButton.setToolTipText(Constant.messages.getString("quickstart.graphiql.button.tooltip"));
graphiQlButton.setPreferredSize(DisplayUtils.getScaledDimension(150, 120));
var extQuickStartLaunch = Control.getSingleton().getExtensionLoader().getExtension(ExtensionQuickStartLaunch.class);
graphiQlButton.addActionListener(e -> extQuickStartLaunch.launchBrowser(
"http://zap/graphiql?" + API.API_NONCE_PARAM + '=' + API.getInstance().getLongLivedNonce("/graphiql")
));
}
return graphiQlButton;
}

@Override
public JPanel getFooterPanel() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.zaproxy.zap.extension.quickstart.apiexplore;

import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.parosproxy.paros.extension.Extension;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.zaproxy.addon.graphql.ExtensionGraphQl;
import org.zaproxy.zap.extension.quickstart.ExtensionQuickStart;
import org.zaproxy.zap.extension.quickstart.launch.ExtensionQuickStartLaunch;
import org.zaproxy.zap.utils.DisplayUtils;

import javax.swing.AbstractButton;
import javax.swing.JButton;
import java.awt.Component;
import java.util.List;

public class ExtensionApiExplore extends ExtensionAdaptor {

private static final List<Class<? extends Extension>> DEPENDENCIES = List.of(ExtensionQuickStartLaunch.class, ExtensionGraphQl.class);

private ExtensionQuickStart extQuickStart;
private ApiExplorePanel apiExplorePanel;
private JButton apiExploreButton;

@Override
public String getUIName() {
return Constant.messages.getString("quickstart.apiExplore.extension.uiName");
}

@Override
public String getDescription() {
return Constant.messages.getString("quickstart.apiExplore.extension.desc");
}

@Override
public List<Class<? extends Extension>> getDependencies() {
return DEPENDENCIES;
}

@Override
public void hook(ExtensionHook extensionHook) {
super.hook(extensionHook);

if (hasView()) {
extQuickStart = Control.getSingleton().getExtensionLoader().getExtension(ExtensionQuickStart.class);
var buttonPanel = extQuickStart.getQuickStartPanel().getButtonPanel();
for (Component component : buttonPanel.getComponents()) {
if (component instanceof JButton) {
var button = (JButton) component;
if (Constant.messages.getString("quickstart.apiExplore.button.name").equals(button.getText())) {
buttonPanel.remove(button);
break;
}
}
}
var buttonCount = buttonPanel.getComponentCount();
buttonPanel.add(getApiExploreButton(), buttonCount - 1);
buttonPanel.revalidate();
buttonPanel.repaint();
}
}

private JButton getApiExploreButton() {
if (apiExploreButton == null) {
apiExploreButton = new JButton();
apiExploreButton.setText(Constant.messages.getString("quickstart.apiExplore.button.name"));
apiExploreButton.setIcon(getApiExplorePanel().getIcon());
apiExploreButton.setVerticalTextPosition(AbstractButton.BOTTOM);
apiExploreButton.setHorizontalTextPosition(AbstractButton.CENTER);
apiExploreButton.setToolTipText(
Constant.messages.getString("quickstart.apiExplore.button.tooltip"));
apiExploreButton.setPreferredSize(DisplayUtils.getScaledDimension(150, 120));
apiExploreButton.addActionListener(
e -> extQuickStart.getQuickStartPanel().showSubPanel(getApiExplorePanel()));
}
return apiExploreButton;
}

private ApiExplorePanel getApiExplorePanel() {
if (apiExplorePanel == null) {
apiExplorePanel = new ApiExplorePanel(extQuickStart, extQuickStart.getQuickStartPanel());
}
return apiExplorePanel;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;

import org.apache.commons.lang3.SystemUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
Expand Down Expand Up @@ -213,6 +217,10 @@ public ExtensionSelenium getExtSelenium() {
return Control.getSingleton().getExtensionLoader().getExtension(ExtensionSelenium.class);
}

public void launchBrowser(String url) {
launchBrowser(launchPanel.getSelectedBrowser(), url);
}

protected void launchBrowser(String browserName, String url) {
new Thread(
() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,13 @@ quickstart.top.button.tooltip.explore = Manually explore your application

quickstart.top.button.label.moreinfo = Learn More
quickstart.top.button.tooltip.moreinfo = Learn more about how you can use ZAP

quickstart.apiExplore.extension.uiName = Quick Start API Explore Menu
quickstart.apiExplore.extension.desc = Adds the API Explore Button to the Quick Start menu.
quickstart.apiExplore.panel.title = API Explore
quickstart.apiExplore.button.name = API Explore
quickstart.apiExplore.button.tooltip = Use proxied API IDEs to explore your application's API
quickstart.graphiql.desc = GraphiQL Integration
quickstart.graphiql.button.name = GraphQL IDE
quickstart.graphiql.button.tooltip = Launch GraphiQL IDE
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0e7d859

Please sign in to comment.