Skip to content

Commit

Permalink
Merge pull request #248 from snyk/feat/add-login-button
Browse files Browse the repository at this point in the history
feat: add login button to plugin welcome page [IDE-798]
  • Loading branch information
andrewrobinsonhodges-snyk authored Jan 7, 2025
2 parents 7d48ade + 6fa083b commit 6f72711
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 53 deletions.
4 changes: 1 addition & 3 deletions plugin/OSGI-INF/l10n/bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,4 @@ tooltip.showNetNewIssues=Show Only Net New Issues
scanWorkspace.name=snykWorkspaceScan
scanWorkspace.label=Snyk Test Workspace

snyk.trust.dialog.warning.text=When scanning project files for vulnerabilities, Snyk may automatically execute code such as invoking the package manager to get dependency information.<br><br>You should only scan projects you trust.<br><br>


snyk.panel.auth.trust.warning.text=When scanning project files, Snyk may automatically execute code such as invoking the package manager to get dependency information.<br/>You should only scan projects you trust. <a href="https://docs.snyk.io/ide-tools/eclipse-plugin/folder-trust">More info</a>
7 changes: 1 addition & 6 deletions plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
Expand Down Expand Up @@ -68,11 +67,7 @@ protected IStatus run(IProgressMonitor monitor) {
Preferences prefs = Preferences.getInstance();
if (prefs.getAuthToken().isBlank() && !prefs.isTest()) {
monitor.subTask("Starting Snyk Wizard to configure initial settings...");
SnykWizard wizard = new SnykWizard();
WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
wizard);
dialog.setBlockOnOpen(true);
dialog.open();
SnykWizard.createAndLaunch();
}
});
monitor.done();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public String getNonce() {

public String getNoDescriptionHtml() {
String snykWarningText = Platform.getResourceString(Platform.getBundle("io.snyk.eclipse.plugin"),
"%snyk.trust.dialog.warning.text");
"snyk.panel.auth.trust.warning.text");

Bundle bundle = Platform.getBundle("io.snyk.eclipse.plugin");
String base64Image = ResourceUtils.getBase64Image(bundle, "logo_snyk.png");
Expand Down Expand Up @@ -107,8 +107,9 @@ public String replaceCssVariables(String html) {
// Replace CSS variables with actual color values
html = html.replace("var(--text-color)", getColorAsHex("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR", "#000000"));
html = html.replace("var(--background-color)", getColorAsHex("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END", "#FFFFFF"));
html = html.replace("var(--code-background-color)", getColorAsHex("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", "#F0F0F0"));
html = html.replace("var(--circle-color)", getColorAsHex("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", "#F0F0F0"));
html = html.replace("var(--code-background-color)", getColorAsHex("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", "#F0F0F0"));
html = html.replace("var(--button-color)", getColorAsHex("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", "#F0F0F0"));
html = html.replace("var(--circle-color)", getColorAsHex("org.eclipse.ui.workbench.INACTIVE_TAB_BG_START", "#F0F0F0"));

html = html.replace("var(--border-color)", getColorAsHex("org.eclipse.ui.workbench.ACTIVE_TAB_OUTER_KEYLINE_COLOR", "#CCCCCC"));
html = html.replace("var(--link-color)", getColorAsHex("ACTIVE_HYPERLINK_COLOR", "#0000FF"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,133 @@ public static StaticPageHtmlProvider getInstance() {
return instance;
}

public String getInitHtml() {
String snykWarningText = Platform.getResourceString(Platform.getBundle("io.snyk.eclipse.plugin"),
"%snyk.trust.dialog.warning.text");

Bundle bundle = Platform.getBundle("io.snyk.eclipse.plugin");
String base64Image = ResourceUtils.getBase64Image(bundle, "logo_snyk.png");

var html = """
<!DOCTYPE html>
<html lang="en">
private String head = """
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snyk for Eclipse</title>
<style>
html {
height:100%;
}
body {
font-family: var(--default-font);
font-family: var(--default-font);
background-color: var(--background-color);
color: var(--text-color);
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.status {
text-align: center;
}
.welcome-text {
width: 520px;
}
.agreement-text {
font-size: smaller;
display: inline-block;
width: 350px;
}
.logo {
margin-right: 20px;
}
a {
color: var(--link-color)
}
div {
padding: 20px
}
a {
color: var(--link-color);
}
div {
padding: 20px;
}
button {
text-align: center;
text-decoration: none;
background-color: var(--button-color);
display: inline-block;
border-color: var(--border-color);
border-style: solid;
border-radius: 5px;
font-family: inherit;
font-size: inherit;
color: inherit;
}
</style>
</head>
""";

public String getScanningHtml() {
var html = """
<!DOCTYPE html>
<html lang="en">
%s
<body>
<div class="container">
<p>
Scanning project for vulnerabilities...<br/>
<a class="stop_scan" onclick="window.stopScan();">Stop Scanning</a>
</p>
</div>
</body>
</html>
""".formatted(head);
return replaceCssVariables(html);
}

public String getDefaultHtml() {
var html = """
<!DOCTYPE html>
<html lang="en">
%s
<body>
<div class="container">
<p>
Select an issue and start improving your project.
</p>
</div>
</body>
</html>
""".formatted(head);
return replaceCssVariables(html);
}

public String getInitHtml() {
String snykWarningText = Platform.getResourceString(Platform.getBundle("io.snyk.eclipse.plugin"),
"%snyk.panel.auth.trust.warning.text");

Bundle bundle = Platform.getBundle("io.snyk.eclipse.plugin");
String base64Image = ResourceUtils.getBase64Image(bundle, "logo_snyk.png");

var html = """
<!DOCTYPE html>
<html lang="en">
%s
<body>
<div class="container">
<img src='data:image/png;base64,%s' alt='Snyk Logo'>
<div>
<p><strong>Welcome to Snyk for Eclipse</strong></p>
<div class="welcome-text">
<p><strong>Welcome to Snyk for Eclipse!</strong></p>
<ol>
<li align="left">Authenticate to Snyk.io</li>
<li align="left">Analyze code for issues and vulnerabilities</li>
<li align="left">Improve your code and upgrade dependencies</li>
</ol>
<p>%s</p>
By connecting your account with Snyk, you agree to<br>
the Snyk <a href="https://snyk.io/policies/privacy/">Privacy Policy</a>,
and the Snyk <a href="https://snyk.io/policies/terms-of-service/">Terms of Service</a>.
<button type="button" onclick="window.initiateLogin()">Trust project and scan</button>
<p class="agreement-text">
By connecting your account with Snyk, you agree to
the Snyk <a href="https://snyk.io/policies/privacy/">Privacy Policy</a>,
and the Snyk <a href="https://snyk.io/policies/terms-of-service/">Terms of Service</a>.
</p>
</div>
</div>
</body>
</html>
""".formatted(base64Image, snykWarningText);
""".formatted(head, base64Image, snykWarningText);
return replaceCssVariables(html);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.CommandException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.jface.viewers.TreeNode;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4j.Location;
Expand All @@ -18,13 +23,18 @@
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;

import com.google.gson.Gson;

import io.snyk.eclipse.plugin.html.BaseHtmlProvider;
import io.snyk.eclipse.plugin.html.HtmlProviderFactory;
import io.snyk.eclipse.plugin.html.StaticPageHtmlProvider;
import io.snyk.eclipse.plugin.preferences.Preferences;
import io.snyk.eclipse.plugin.utils.SnykLogger;
import io.snyk.eclipse.plugin.views.snyktoolview.handlers.IHandlerCommands;
import io.snyk.eclipse.plugin.wizards.SnykWizard;

@SuppressWarnings("restriction")
public class BrowserHandler {
Expand Down Expand Up @@ -66,6 +76,28 @@ public Object function(Object[] arguments) {
}
};

new BrowserFunction(browser, "initiateLogin") {
@Override
public Object function(Object[] arguments) {
SnykWizard.createAndLaunch();
return null;
}
};

new BrowserFunction(browser, "stopScan") {
@Override
public Object function(Object[] arguments) {
IHandlerService handlerService =
(IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
try {
handlerService.executeCommand(IHandlerCommands.STOP_SCAN, null);
} catch (CommandException e) {
SnykLogger.logError(e);
}
return null;
}
};

browser.addLocationListener(new LocationListener() {
@Override
public void changing(LocationEvent event) {
Expand All @@ -89,7 +121,8 @@ public void completed(ProgressEvent event) {
}
}
});
initBrowserText();

setDefaultBrowserText();
}

private record ErrorMessage(String error, String path) {
Expand All @@ -99,10 +132,12 @@ public CompletableFuture<Void> updateBrowserContent(TreeNode node) {
// Generate HTML content based on the selected node
var htmlProvider = getHtmlProvider(node);
initScript = htmlProvider.getInitScript();
boolean shouldShowDefaultMessage = true;
if (node instanceof ProductTreeNode) {
var ptn = (ProductTreeNode) node;
String errorJson = ptn.getErrorMessage();
if (errorJson != null && !errorJson.isBlank()) {
shouldShowDefaultMessage = false;
var error = new Gson().fromJson(errorJson, ErrorMessage.class);
String errorHtml = htmlProvider.getErrorHtml(error.error, error.path);
Display.getDefault().syncExec(() -> {
Expand All @@ -111,8 +146,12 @@ public CompletableFuture<Void> updateBrowserContent(TreeNode node) {
}
}

if (!(node instanceof IssueTreeNode))
if (!(node instanceof IssueTreeNode)) {
if (shouldShowDefaultMessage) {
setDefaultBrowserText();
}
return CompletableFuture.completedFuture(null);
}

return CompletableFuture.supplyAsync(() -> {
return generateHtmlContent(node);
Expand All @@ -127,7 +166,6 @@ public CompletableFuture<Void> updateBrowserContent(TreeNode node) {
browser.setText(browserContent);
});
});

}

private BaseHtmlProvider getHtmlProvider(TreeNode node) {
Expand Down Expand Up @@ -155,7 +193,16 @@ public String generateHtmlContent(String text) {
return "<html><body<p>" + text + "</p></body></html>";
}

public void initBrowserText() {
browser.setText(StaticPageHtmlProvider.getInstance().getInitHtml());
public void setDefaultBrowserText() {
// If we are not authenticated, show the welcome page, else show the issue placeholder.
if (Preferences.getInstance().getAuthToken().isBlank()) {
browser.setText(StaticPageHtmlProvider.getInstance().getInitHtml());
} else {
browser.setText(StaticPageHtmlProvider.getInstance().getDefaultHtml());
}
}

public void setScanningBrowserText() {
browser.setText(StaticPageHtmlProvider.getInstance().getScanningHtml());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ public interface ISnykToolView {
*/
abstract void refreshTree();

/**
* Refreshes the browser
*/
abstract void refreshBrowser(String status);

/**
* Returns the tree root
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.snyk.eclipse.plugin.views.snyktoolview;

import static io.snyk.eclipse.plugin.domain.ProductConstants.SCAN_STATE_IN_PROGRESS;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
Expand Down Expand Up @@ -305,6 +307,17 @@ public void refreshTree() {
});
}

@Override
public void refreshBrowser(String status) {
Display.getDefault().asyncExec(() -> {
if (status != null && status.equals(SCAN_STATE_IN_PROGRESS)) {
this.browserHandler.setScanningBrowserText();
} else {
this.browserHandler.setDefaultBrowserText();
}
});
};

@Override
public void resetNode(BaseTreeNode node) {
if (node != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

import io.snyk.eclipse.plugin.SnykStartup;
import io.snyk.eclipse.plugin.utils.ResourceUtils;
Expand Down Expand Up @@ -92,4 +94,11 @@ protected IStatus run(IProgressMonitor monitor) {
}.schedule();
return true;
}

public static void createAndLaunch() {
SnykWizard wizard = new SnykWizard();
WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), wizard);
dialog.setBlockOnOpen(true);
dialog.open();
}
}
Loading

0 comments on commit 6f72711

Please sign in to comment.