Skip to content

Commit

Permalink
fix: add auth token query parameter to HTTP requests of webview assets
Browse files Browse the repository at this point in the history
  • Loading branch information
jansorg authored and ahtrotta committed Jan 30, 2024
1 parent 989dc3c commit d8ee3e0
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import appland.AppMapBundle;
import appland.utils.GsonUtils;
import appland.webviews.webserver.AppMapWebview;
import appland.webviews.webserver.WebviewAuthTokenRequestHandler;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditor;
Expand Down Expand Up @@ -178,6 +178,8 @@ protected boolean isWebViewReady() {
private void setupJCEF() {
// open links to https://appmap.io in the external browser
contentPanel.getJBCefClient().addRequestHandler(new OpenExternalLinksHandler(), contentPanel.getCefBrowser());
// add auth tokens to our localhost requests
contentPanel.getJBCefClient().addRequestHandler(new WebviewAuthTokenRequestHandler(), contentPanel.getCefBrowser());

contentPanel.setErrorPage(new DefaultWebviewErrorPage(navigating));
contentPanel.getJBCefClient().addDisplayHandler(new ConsoleInitMessageHandler(this::initWebviewApplication), contentPanel.getCefBrowser());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public enum AppMapWebview {
return "http://localhost:" + BuiltInServerOptions.getInstance().getEffectiveBuiltInServerPort();
}

public static @NotNull String getBaseUrlWithPath() {
return getBaseUrl() + APPMAP_SERVER_BASE_PATH;
}

private final @NotNull String webviewAssetsDirectoryName;

/**
Expand All @@ -39,6 +43,6 @@ public enum AppMapWebview {
* @return HTTP URL of the IDE's built-in webserver for this webview's index.html file.
*/
public @NotNull String getIndexHtmlUrl() {
return getBaseUrl() + APPMAP_SERVER_BASE_PATH + "/" + webviewAssetsDirectoryName + "/index.html";
return getBaseUrlWithPath() + "/" + webviewAssetsDirectoryName + "/index.html";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package appland.webviews.webserver;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Urls;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.handler.CefRequestHandlerAdapter;
import org.cef.handler.CefResourceRequestHandler;
import org.cef.handler.CefResourceRequestHandlerAdapter;
import org.cef.misc.BoolRef;
import org.cef.network.CefRequest;
import org.jetbrains.builtInWebServer.BuiltInWebServerKt;
import org.jetbrains.ide.BuiltInServerManager;

/**
* Adds auth tokens to requests to webview resources to bypass any filtering of the built-in webserver.
* Without auth tokens the IDE's built-in webserver only accepts URLs prefixed with a project name.
*/
public final class WebviewAuthTokenRequestHandler extends CefRequestHandlerAdapter {
@Override
public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser,
CefFrame frame,
CefRequest request,
boolean isNavigation,
boolean isDownload,
String requestInitiator,
BoolRef disableDefaultHandling) {

if (isUnsignedWebViewRequest(request)) {
return new CefResourceRequestHandlerAdapter() {
@Override
public boolean onBeforeResourceLoad(CefBrowser browser, CefFrame frame, CefRequest request) {
var url = Urls.parseEncoded(request.getURL());
if (url != null) {
request.setURL(BuiltInServerManager.getInstance().addAuthToken(url).toExternalForm());
}

// false to continue with the request
return false;
}
};
}

// fallback to default handling of JCEF
return null;
}

/**
* @return true if the request is for a webview asset, but not yet signed with an auth token
*/
private static boolean isUnsignedWebViewRequest(CefRequest request) {
var url = Urls.parseEncoded(request.getURL());
var params = StringUtil.defaultIfEmpty(url != null ? url.getParameters() : null, "");
return request.getURL().startsWith(AppMapWebview.getBaseUrlWithPath())
&& !params.contains("?" + BuiltInWebServerKt.TOKEN_PARAM_NAME + "=")
&& !params.contains("&" + BuiltInWebServerKt.TOKEN_PARAM_NAME + "=");
}
}

0 comments on commit d8ee3e0

Please sign in to comment.