001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.oauth;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.io.IOException;
008
009import javax.swing.JOptionPane;
010
011import org.openstreetmap.josm.data.oauth.OAuthParameters;
012import org.openstreetmap.josm.data.oauth.OAuthToken;
013import org.openstreetmap.josm.gui.HelpAwareOptionPane;
014import org.openstreetmap.josm.gui.PleaseWaitRunnable;
015import org.openstreetmap.josm.gui.help.HelpUtil;
016import org.openstreetmap.josm.gui.util.GuiHelper;
017import org.openstreetmap.josm.io.OsmTransferCanceledException;
018import org.openstreetmap.josm.io.OsmTransferException;
019import org.openstreetmap.josm.tools.CheckParameterUtil;
020import org.openstreetmap.josm.tools.Logging;
021import org.xml.sax.SAXException;
022
023/**
024 * Asynchronous task for retrieving an Access Token.
025 *
026 */
027public class RetrieveAccessTokenTask extends PleaseWaitRunnable {
028
029    private boolean canceled;
030    private OAuthToken accessToken;
031    private final OAuthParameters parameters;
032    private OsmOAuthAuthorizationClient client;
033    private final OAuthToken requestToken;
034    private final Component parent;
035
036    /**
037     * Creates the task
038     *
039     * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog
040     * is displayed
041     * @param parameters the OAuth parameters. Must not be null.
042     * @param requestToken the request token for which an Access Token is retrieved. Must not be null.
043     * @throws IllegalArgumentException if parameters is null.
044     * @throws IllegalArgumentException if requestToken is null.
045     */
046    public RetrieveAccessTokenTask(Component parent, OAuthParameters parameters, OAuthToken requestToken) {
047        super(parent, tr("Retrieving OAuth Access Token..."), false /* don't ignore exceptions */);
048        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
049        CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");
050        this.parameters = parameters;
051        this.requestToken = requestToken;
052        this.parent = parent;
053    }
054
055    @Override
056    protected void cancel() {
057        canceled = true;
058        synchronized (this) {
059            if (client != null) {
060                client.cancel();
061            }
062        }
063    }
064
065    @Override
066    protected void finish() { /* not used in this task */}
067
068    protected void alertRetrievingAccessTokenFailed() {
069        HelpAwareOptionPane.showOptionDialog(
070                parent,
071                tr(
072                        "<html>Retrieving an OAuth Access Token from ''{0}'' failed.</html>",
073                        parameters.getAccessTokenUrl()
074                ),
075                tr("Request Failed"),
076                JOptionPane.ERROR_MESSAGE,
077                HelpUtil.ht("/OAuth#NotAuthorizedException")
078        );
079    }
080
081    @Override
082    protected void realRun() throws SAXException, IOException, OsmTransferException {
083        try {
084            synchronized (this) {
085                client = new OsmOAuthAuthorizationClient(parameters, requestToken);
086            }
087            accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false));
088        } catch (OsmTransferCanceledException e) {
089            Logging.trace(e);
090            return;
091        } catch (final OsmOAuthAuthorizationException e) {
092            Logging.error(e);
093            GuiHelper.runInEDT(this::alertRetrievingAccessTokenFailed);
094            accessToken = null;
095        } finally {
096            synchronized (this) {
097                client = null;
098            }
099        }
100    }
101
102    /**
103     * Replies true if the task was canceled.
104     *
105     * @return {@code true} if user aborted operation
106     */
107    public boolean isCanceled() {
108        return canceled;
109    }
110
111    /**
112     * Replies the retrieved Access Token. null, if something went wrong.
113     *
114     * @return the retrieved Access Token
115     */
116    public OAuthToken getAccessToken() {
117        return accessToken;
118    }
119}