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