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.io.OsmApi;
008import org.openstreetmap.josm.spi.preferences.Config;
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 apiUrl the API URL. Must not be null.
082     * @return the parameters
083     */
084    public static OAuthParameters createFromApiUrl(String apiUrl) {
085        OAuthParameters parameters = createDefault(apiUrl);
086        return new OAuthParameters(
087                Config.getPref().get("oauth.settings.consumer-key", parameters.getConsumerKey()),
088                Config.getPref().get("oauth.settings.consumer-secret", parameters.getConsumerSecret()),
089                Config.getPref().get("oauth.settings.request-token-url", parameters.getRequestTokenUrl()),
090                Config.getPref().get("oauth.settings.access-token-url", parameters.getAccessTokenUrl()),
091                Config.getPref().get("oauth.settings.authorise-url", parameters.getAuthoriseUrl()),
092                Config.getPref().get("oauth.settings.osm-login-url", parameters.getOsmLoginUrl()),
093                Config.getPref().get("oauth.settings.osm-logout-url", parameters.getOsmLogoutUrl()));
094    }
095
096    /**
097     * Remembers the current values in the preferences.
098     */
099    public void rememberPreferences() {
100        Config.getPref().put("oauth.settings.consumer-key", getConsumerKey());
101        Config.getPref().put("oauth.settings.consumer-secret", getConsumerSecret());
102        Config.getPref().put("oauth.settings.request-token-url", getRequestTokenUrl());
103        Config.getPref().put("oauth.settings.access-token-url", getAccessTokenUrl());
104        Config.getPref().put("oauth.settings.authorise-url", getAuthoriseUrl());
105        Config.getPref().put("oauth.settings.osm-login-url", getOsmLoginUrl());
106        Config.getPref().put("oauth.settings.osm-logout-url", getOsmLogoutUrl());
107    }
108
109    private final String consumerKey;
110    private final String consumerSecret;
111    private final String requestTokenUrl;
112    private final String accessTokenUrl;
113    private final String authoriseUrl;
114    private final String osmLoginUrl;
115    private final String osmLogoutUrl;
116
117    /**
118     * Constructs a new {@code OAuthParameters}.
119     * @param consumerKey consumer key
120     * @param consumerSecret consumer secret
121     * @param requestTokenUrl request token URL
122     * @param accessTokenUrl access token URL
123     * @param authoriseUrl authorise URL
124     * @param osmLoginUrl the OSM login URL (for automatic mode)
125     * @param osmLogoutUrl the OSM logout URL (for automatic mode)
126     * @see #createDefault
127     * @see #createFromApiUrl
128     * @since 9220
129     */
130    public OAuthParameters(String consumerKey, String consumerSecret,
131                           String requestTokenUrl, String accessTokenUrl, String authoriseUrl, String osmLoginUrl, String osmLogoutUrl) {
132        this.consumerKey = consumerKey;
133        this.consumerSecret = consumerSecret;
134        this.requestTokenUrl = requestTokenUrl;
135        this.accessTokenUrl = accessTokenUrl;
136        this.authoriseUrl = authoriseUrl;
137        this.osmLoginUrl = osmLoginUrl;
138        this.osmLogoutUrl = osmLogoutUrl;
139    }
140
141    /**
142     * Creates a clone of the parameters in <code>other</code>.
143     *
144     * @param other the other parameters. Must not be null.
145     * @throws IllegalArgumentException if other is null
146     */
147    public OAuthParameters(OAuthParameters other) {
148        CheckParameterUtil.ensureParameterNotNull(other, "other");
149        this.consumerKey = other.consumerKey;
150        this.consumerSecret = other.consumerSecret;
151        this.accessTokenUrl = other.accessTokenUrl;
152        this.requestTokenUrl = other.requestTokenUrl;
153        this.authoriseUrl = other.authoriseUrl;
154        this.osmLoginUrl = other.osmLoginUrl;
155        this.osmLogoutUrl = other.osmLogoutUrl;
156    }
157
158    /**
159     * Gets the consumer key.
160     * @return The consumer key
161     */
162    public String getConsumerKey() {
163        return consumerKey;
164    }
165
166    /**
167     * Gets the consumer secret.
168     * @return The consumer secret
169     */
170    public String getConsumerSecret() {
171        return consumerSecret;
172    }
173
174    /**
175     * Gets the request token URL.
176     * @return The request token URL
177     */
178    public String getRequestTokenUrl() {
179        return requestTokenUrl;
180    }
181
182    /**
183     * Gets the access token URL.
184     * @return The access token URL
185     */
186    public String getAccessTokenUrl() {
187        return accessTokenUrl;
188    }
189
190    /**
191     * Gets the authorise URL.
192     * @return The authorise URL
193     */
194    public String getAuthoriseUrl() {
195        return authoriseUrl;
196    }
197
198    /**
199     * Gets the URL used to login users on the website (for automatic mode).
200     * @return The URL used to login users
201     */
202    public String getOsmLoginUrl() {
203        return osmLoginUrl;
204    }
205
206    /**
207     * Gets the URL used to logout users on the website (for automatic mode).
208     * @return The URL used to logout users
209     */
210    public String getOsmLogoutUrl() {
211        return osmLogoutUrl;
212    }
213
214    /**
215     * Builds an {@link OAuthConsumer} based on these parameters.
216     *
217     * @return the consumer
218     */
219    public OAuthConsumer buildConsumer() {
220        return new SignpostAdapters.OAuthConsumer(consumerKey, consumerSecret);
221    }
222
223    /**
224     * Builds an {@link OAuthProvider} based on these parameters and a OAuth consumer <code>consumer</code>.
225     *
226     * @param consumer the consumer. Must not be null.
227     * @return the provider
228     * @throws IllegalArgumentException if consumer is null
229     */
230    public OAuthProvider buildProvider(OAuthConsumer consumer) {
231        CheckParameterUtil.ensureParameterNotNull(consumer, "consumer");
232        return new SignpostAdapters.OAuthProvider(
233                requestTokenUrl,
234                accessTokenUrl,
235                authoriseUrl
236        );
237    }
238
239    @Override
240    public boolean equals(Object o) {
241        if (this == o) return true;
242        if (o == null || getClass() != o.getClass()) return false;
243        OAuthParameters that = (OAuthParameters) o;
244        return Objects.equals(consumerKey, that.consumerKey) &&
245                Objects.equals(consumerSecret, that.consumerSecret) &&
246                Objects.equals(requestTokenUrl, that.requestTokenUrl) &&
247                Objects.equals(accessTokenUrl, that.accessTokenUrl) &&
248                Objects.equals(authoriseUrl, that.authoriseUrl) &&
249                Objects.equals(osmLoginUrl, that.osmLoginUrl) &&
250                Objects.equals(osmLogoutUrl, that.osmLogoutUrl);
251    }
252
253    @Override
254    public int hashCode() {
255        return Objects.hash(consumerKey, consumerSecret, requestTokenUrl, accessTokenUrl, authoriseUrl, osmLoginUrl, osmLogoutUrl);
256    }
257}