Skip to content

Commit

Permalink
See #23804: Try to detect common failures with OpenBrowser.displayUrl
Browse files Browse the repository at this point in the history
In #23804, the user indicated that the web browser did not open, so they were
unable to go through the automatic authentication flow. This attempts to work
around that problem by detecting caught exceptions and showing the user a dialog
that will allow them to copy the authorization URL.

git-svn-id: https://josm.openstreetmap.de/svn/trunk@19141 0c6e7542-c601-0410-84e7-c038aed88b3b
  • Loading branch information
taylor.smock committed Jul 15, 2024
1 parent 000f61e commit 497eb82
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion src/org/openstreetmap/josm/data/oauth/OAuth20Authorization.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import static org.openstreetmap.josm.tools.I18n.tr;

import java.awt.Dimension;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
Expand All @@ -16,6 +17,13 @@
import java.util.UUID;
import java.util.function.Consumer;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
import org.openstreetmap.josm.gui.util.GuiHelper;
import org.openstreetmap.josm.gui.widgets.HtmlPanel;
import org.openstreetmap.josm.io.remotecontrol.handler.AuthorizationHandler;
import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler;
import org.openstreetmap.josm.tools.HttpClient;
Expand Down Expand Up @@ -55,7 +63,36 @@ public void authorize(IOAuthParameters parameters, Consumer<Optional<IOAuthToken
String url = parameters.getAuthorizationUrl(state, scopes)
+ "&code_challenge_method=S256&code_challenge=" + s256CodeChallenge;
AuthorizationHandler.addAuthorizationConsumer(state, new OAuth20AuthorizationHandler(state, codeVerifier, parameters, consumer));
OpenBrowser.displayUrl(url);
GuiHelper.runInEDT(() -> showUrlOpenFailure(url, OpenBrowser.displayUrl(url)));
}

/**
* Show a message if a URL fails to open
* @param url The URL that failed to open
* @param error The message indicating why the URL failed to open; if {@code null}, no message is shown.
*/
private static void showUrlOpenFailure(String url, String error) {
if (error != null) {
final HtmlPanel textField = new HtmlPanel("<html><body>"
+ tr("The web browser failed to open with the following error: \"{0}\".<br>\n"
+ "Please open the following url:<br>\n"
+ "<a href=\"{1}\">{1}</a><br>\n"
+ "Should we copy the URL to the clipboard?", error, url)
+ "</body></html>");
textField.enableClickableHyperlinks();
final JScrollPane scrollPane = new JScrollPane(textField);
// Ensure that the scroll pane doesn't extend too much or too little.
// For now, assume that the user hasn't made the main JOSM frame beyond monitors.
scrollPane.setPreferredSize(new Dimension(Math.min(textField.getPreferredSize().width + 32,
MainApplication.getMainFrame().getWidth() - 240 /* warning image + buffer */),
textField.getPreferredSize().height + scrollPane.getHorizontalScrollBar().getPreferredSize().height * 2));
GuiHelper.prepareResizeableOptionPane(scrollPane, scrollPane.getPreferredSize());
int answer = JOptionPane.showConfirmDialog(MainApplication.getMainFrame(), scrollPane, tr("Failed to open browser"),
JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE);
if (answer == JOptionPane.YES_OPTION) {
ClipboardUtils.copyString(url);
}
}
}

private static class OAuth20AuthorizationHandler implements AuthorizationHandler.AuthorizationConsumer {
Expand Down

0 comments on commit 497eb82

Please sign in to comment.