001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.oauth;
003
004import java.util.Objects;
005
006import org.openstreetmap.josm.spi.preferences.Config;
007import org.openstreetmap.josm.spi.preferences.IUrls;
008import org.openstreetmap.josm.tools.CheckParameterUtil;
009import org.openstreetmap.josm.tools.Utils;
010
011import oauth.signpost.OAuthConsumer;
012import oauth.signpost.OAuthProvider;
013
014/**
015 * This class manages an immutable set of OAuth parameters.
016 * @since 2747
017 */
018public class OAuthParameters {
019
020    /**
021     * The default JOSM OAuth consumer key (created by user josmeditor).
022     */
023    public static final String DEFAULT_JOSM_CONSUMER_KEY = "F7zPYlVCqE2BUH9Hr4SsWZSOnrKjpug1EgqkbsSb";
024    /**
025     * The default JOSM OAuth consumer secret (created by user josmeditor).
026     */
027    public static final String DEFAULT_JOSM_CONSUMER_SECRET = "rIkjpPcBNkMQxrqzcOvOC4RRuYupYr7k8mfP13H5";
028
029    /**
030     * Replies a set of default parameters for a consumer accessing the standard OSM server
031     * at {@link IUrls#getDefaultOsmApiUrl}.
032     *
033     * @return a set of default parameters
034     */
035    public static OAuthParameters createDefault() {
036        return createDefault(null);
037    }
038
039    /**
040     * Replies a set of default parameters for a consumer accessing an OSM server
041     * at the given API url. URL parameters are only set if the URL equals {@link IUrls#getDefaultOsmApiUrl}
042     * or references the domain "dev.openstreetmap.org", otherwise they may be <code>null</code>.
043     *
044     * @param apiUrl The API URL for which the OAuth default parameters are created. If null or empty, the default OSM API url is used.
045     * @return a set of default parameters for the given {@code apiUrl}
046     * @since 5422
047     */
048    public static OAuthParameters createDefault(String apiUrl) {
049        final String consumerKey;
050        final String consumerSecret;
051        final String serverUrl;
052
053        if (!Utils.isValidUrl(apiUrl)) {
054            apiUrl = null;
055        }
056
057        if (apiUrl != null && !Config.getUrls().getDefaultOsmApiUrl().equals(apiUrl)) {
058            consumerKey = ""; // a custom consumer key is required
059            consumerSecret = ""; // a custom consumer secret is requireds
060            serverUrl = apiUrl.replaceAll("/api$", "");
061        } else {
062            consumerKey = DEFAULT_JOSM_CONSUMER_KEY;
063            consumerSecret = DEFAULT_JOSM_CONSUMER_SECRET;
064            serverUrl = Config.getUrls().getOSMWebsite();
065        }
066
067        return new OAuthParameters(
068                consumerKey,
069                consumerSecret,
070                serverUrl + "/oauth/request_token",
071                serverUrl + "/oauth/access_token",
072                serverUrl + "/oauth/authorize",
073                serverUrl + "/login",
074                serverUrl + "/logout");
075    }
076
077    /**
078     * Replies a set of parameters as defined in the preferences.
079     *
080     * @param apiUrl the API URL. Must not be null.
081     * @return the parameters
082     */
083    public static OAuthParameters createFromApiUrl(String apiUrl) {
084        OAuthParameters parameters = createDefault(apiUrl);
085        return new OAuthParameters(
086                Config.getPref().get("oauth.settings.consumer-key", parameters.getConsumerKey()),
087                Config.getPref().get("oauth.settings.consumer-secret", parameters.getConsumerSecret()),
088                Config.getPref().get("oauth.settings.request-token-url", parameters.getRequestTokenUrl()),
089                Config.getPref().get("oauth.settings.access-token-url", parameters.getAccessTokenUrl()),
090                Config.getPref().get("oauth.settings.authorise-url", parameters.getAuthoriseUrl()),
091                Config.getPref().get("oauth.settings.osm-login-url", parameters.getOsmLoginUrl()),
092                Config.getPref().get("oauth.settings.osm-logout-url", parameters.getOsmLogoutUrl()));
093    }
094
095    /**
096     * Remembers the current values in the preferences.
097     */
098    public void rememberPreferences() {
099        Config.getPref().put("oauth.settings.consumer-key", getConsumerKey());
100        Config.getPref().put("oauth.settings.consumer-secret", getConsumerSecret());
101        Config.getPref().put("oauth.settings.request-token-url", getRequestTokenUrl());
102        Config.getPref().put("oauth.settings.access-token-url", getAccessTokenUrl());
103        Config.getPref().put("oauth.settings.authorise-url", getAuthoriseUrl());
104        Config.getPref().put("oauth.settings.osm-login-url", getOsmLoginUrl());
105        Config.getPref().put("oauth.settings.osm-logout-url", getOsmLogoutUrl());
106    }
107
108    private final String consumerKey;
109    private final String consumerSecret;
110    private final String requestTokenUrl;
111    private final String accessTokenUrl;
112    private final String authoriseUrl;
113    private final String osmLoginUrl;
114    private final String osmLogoutUrl;
115
116    /**
117     * Constructs a new {@code OAuthParameters}.
118     * @param consumerKey consumer key
119     * @param consumerSecret consumer secret
120     * @param requestTokenUrl request token URL
121     * @param accessTokenUrl access token URL
122     * @param authoriseUrl authorise URL
123     * @param osmLoginUrl the OSM login URL (for automatic mode)
124     * @param osmLogoutUrl the OSM logout URL (for automatic mode)
125     * @see #createDefault
126     * @see #createFromApiUrl
127     * @since 9220
128     */
129    public OAuthParameters(String consumerKey, String consumerSecret,
130                           String requestTokenUrl, String accessTokenUrl, String authoriseUrl, String osmLoginUrl, String osmLogoutUrl) {
131        this.consumerKey = consumerKey;
132        this.consumerSecret = consumerSecret;
133        this.requestTokenUrl = requestTokenUrl;
134        this.accessTokenUrl = accessTokenUrl;
135        this.authoriseUrl = authoriseUrl;
136        this.osmLoginUrl = osmLoginUrl;
137        this.osmLogoutUrl = osmLogoutUrl;
138    }
139
140    /**
141     * Creates a clone of the parameters in <code>other</code>.
142     *
143     * @param other the other parameters. Must not be null.
144     * @throws IllegalArgumentException if other is null
145     */
146    public OAuthParameters(OAuthParameters other) {
147        CheckParameterUtil.ensureParameterNotNull(other, "other");
148        this.consumerKey = other.consumerKey;
149        this.consumerSecret = other.consumerSecret;
150        this.accessTokenUrl = other.accessTokenUrl;
151        this.requestTokenUrl = other.requestTokenUrl;
152        this.authoriseUrl = other.authoriseUrl;
153        this.osmLoginUrl = other.osmLoginUrl;
154        this.osmLogoutUrl = other.osmLogoutUrl;
155    }
156
157    /**
158     * Gets the consumer key.
159     * @return The consumer key
160     */
161    public String getConsumerKey() {
162        return consumerKey;
163    }
164
165    /**
166     * Gets the consumer secret.
167     * @return The consumer secret
168     */
169    public String getConsumerSecret() {
170        return consumerSecret;
171    }
172
173    /**
174     * Gets the request token URL.
175     * @return The request token URL
176     */
177    public String getRequestTokenUrl() {
178        return requestTokenUrl;
179    }
180
181    /**
182     * Gets the access token URL.
183     * @return The access token URL
184     */
185    public String getAccessTokenUrl() {
186        return accessTokenUrl;
187    }
188
189    /**
190     * Gets the authorise URL.
191     * @return The authorise URL
192     */
193    public String getAuthoriseUrl() {
194        return authoriseUrl;
195    }
196
197    /**
198     * Gets the URL used to login users on the website (for automatic mode).
199     * @return The URL used to login users
200     */
201    public String getOsmLoginUrl() {
202        return osmLoginUrl;
203    }
204
205    /**
206     * Gets the URL used to logout users on the website (for automatic mode).
207     * @return The URL used to logout users
208     */
209    public String getOsmLogoutUrl() {
210        return osmLogoutUrl;
211    }
212
213    /**
214     * Builds an {@link OAuthConsumer} based on these parameters.
215     *
216     * @return the consumer
217     */
218    public OAuthConsumer buildConsumer() {
219        return new SignpostAdapters.OAuthConsumer(consumerKey, consumerSecret);
220    }
221
222    /**
223     * Builds an {@link OAuthProvider} based on these parameters and a OAuth consumer <code>consumer</code>.
224     *
225     * @param consumer the consumer. Must not be null.
226     * @return the provider
227     * @throws IllegalArgumentException if consumer is null
228     */
229    public OAuthProvider buildProvider(OAuthConsumer consumer) {
230        CheckParameterUtil.ensureParameterNotNull(consumer, "consumer");
231        return new SignpostAdapters.OAuthProvider(
232                requestTokenUrl,
233                accessTokenUrl,
234                authoriseUrl
235        );
236    }
237
238    @Override
239    public boolean equals(Object o) {
240        if (this == o) return true;
241        if (o == null || getClass() != o.getClass()) return false;
242        OAuthParameters that = (OAuthParameters) o;
243        return Objects.equals(consumerKey, that.consumerKey) &&
244                Objects.equals(consumerSecret, that.consumerSecret) &&
245                Objects.equals(requestTokenUrl, that.requestTokenUrl) &&
246                Objects.equals(accessTokenUrl, that.accessTokenUrl) &&
247                Objects.equals(authoriseUrl, that.authoriseUrl) &&
248                Objects.equals(osmLoginUrl, that.osmLoginUrl) &&
249                Objects.equals(osmLogoutUrl, that.osmLogoutUrl);
250    }
251
252    @Override
253    public int hashCode() {
254        return Objects.hash(consumerKey, consumerSecret, requestTokenUrl, accessTokenUrl, authoriseUrl, osmLoginUrl, osmLogoutUrl);
255    }
256}