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