Skip to content

Commit

Permalink
quickstart: Add "API Explore" button
Browse files Browse the repository at this point in the history
Signed-off-by: ricekot <[email protected]>
  • Loading branch information
ricekot committed Feb 16, 2023
1 parent 409ba23 commit 9142bef
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 9 deletions.
2 changes: 1 addition & 1 deletion addOns/addOns.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ plugins {
eclipse
jacoco
id("org.rm3l.datanucleus-gradle-plugin") version "1.7.0" apply false
id("org.zaproxy.add-on") version "0.8.0" apply false
id("org.zaproxy.add-on") version "0.9.0" apply false
id("org.zaproxy.crowdin") version "0.3.1" apply false
id("me.champeau.gradle.japicmp") version "0.4.1" apply false
}
Expand Down
3 changes: 3 additions & 0 deletions addOns/quickstart/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased
### Added
- New "API Explore" button on home screen.

### Changed
- Maintenance changes.

Expand Down
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.14.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 @@ -210,8 +218,7 @@ private JButton getLearnMoreButton() {
Constant.messages.getString("quickstart.top.button.tooltip.moreinfo"));
learnMoreButton.setPreferredSize(DisplayUtils.getScaledDimension(150, 120));

learnMoreButton.addActionListener(
e -> jScrollPane.setViewportView(getLearnMorePanel()));
learnMoreButton.addActionListener(e -> showSubPanel(getLearnMorePanel()));
}
return learnMoreButton;
}
Expand All @@ -238,9 +245,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,119 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2023 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.extension.quickstart.apiexplore;

import java.awt.FlowLayout;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
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.QuickStartBackgroundPanel;
import org.zaproxy.zap.extension.quickstart.QuickStartHelper;
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 org.zaproxy.zap.view.LayoutHelper;

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() {
JPanel panel = new QuickStartBackgroundPanel();
panel.add(
QuickStartHelper.getWrappedLabel("quickstart.apiExplore.panel.message1"),
LayoutHelper.getGBC(0, 0, 2, 1.0D, DisplayUtils.getScaledInsets(5, 5, 5, 5)));
panel.add(
new JLabel(" "),
LayoutHelper.getGBC(
0, 1, 2, 1.0D, DisplayUtils.getScaledInsets(5, 5, 5, 5))); // Spacer
return panel;
}

@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,115 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2023 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.extension.quickstart.apiexplore;

import java.awt.Component;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.JButton;
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;

public class ExtensionApiExplore extends ExtensionAdaptor {

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

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()) {
var buttonPanel = getExtQuickStart().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 ->
getExtQuickStart()
.getQuickStartPanel()
.showSubPanel(getApiExplorePanel()));
}
return apiExploreButton;
}

private ApiExplorePanel getApiExplorePanel() {
if (apiExplorePanel == null) {
apiExplorePanel =
new ApiExplorePanel(
getExtQuickStart(), getExtQuickStart().getQuickStartPanel());
}
return apiExplorePanel;
}

private ExtensionQuickStart getExtQuickStart() {
return Control.getSingleton().getExtensionLoader().getExtension(ExtensionQuickStart.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,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 @@ -319,7 +319,7 @@ public void postInit() {
}
}

private String getSelectedBrowser() {
String getSelectedBrowser() {
return getBrowserComboBox().getSelectedItem().toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ <H3>Enable HUD</H3>
This option is enabled if the HUD add-on is installed.
If it is not available then you can download and install it for free from the ZAP Marketplace.

<H2>API Explore</H2>

The API Explore screen allows you to launch API IDEs in a proxied browser.
This screen is only visible if the following add-ons are installed:
<ul>
<li>graphql</li>
</ul>

<H2>Learn More</H2>

The Learn More screen provides links to local and online resources for you to learn more about ZAP.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,14 @@ 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.panel.message1 = This screen allows you to use proxied API IDEs to explore your application's API.
quickstart.apiExplore.button.name = API Explore
quickstart.apiExplore.button.tooltip = Use proxied API IDEs to explore your application's API

quickstart.graphiql.desc = GraphQL IDE Integration
quickstart.graphiql.button.name = GraphQL IDE
quickstart.graphiql.button.tooltip = Launch GraphQL 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 9142bef

Please sign in to comment.