Merge pull request #9932 from osmandapp/issue_175_osmedit_use_oauth
Issue 175 osmedit use oauth
This commit is contained in:
commit
3e8f543942
16 changed files with 722 additions and 143 deletions
|
@ -104,6 +104,9 @@ dependencies {
|
||||||
implementation 'com.moparisthebest:junidecode:0.1.1'
|
implementation 'com.moparisthebest:junidecode:0.1.1'
|
||||||
implementation 'com.vividsolutions:jts-core:1.14.0'
|
implementation 'com.vividsolutions:jts-core:1.14.0'
|
||||||
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
||||||
|
implementation ('com.github.scribejava:scribejava-apis:7.1.1') {
|
||||||
|
exclude group: "com.fasterxml.jackson.core"
|
||||||
|
}
|
||||||
// turn off for now
|
// turn off for now
|
||||||
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
||||||
implementation 'net.sf.kxml:kxml2:2.1.8'
|
implementation 'net.sf.kxml:kxml2:2.1.8'
|
||||||
|
|
|
@ -1,30 +1,22 @@
|
||||||
package net.osmand.osm.io;
|
package net.osmand.osm.io;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import com.github.scribejava.core.model.OAuthRequest;
|
||||||
import java.io.BufferedReader;
|
import com.github.scribejava.core.model.Response;
|
||||||
import java.io.File;
|
import com.github.scribejava.core.model.Verb;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.Proxy;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.osm.oauth.OsmOAuthAuthorizationClient;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
public class NetworkUtils {
|
public class NetworkUtils {
|
||||||
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
||||||
|
private static final String GPX_UPLOAD_USER_AGENT = "OsmGPXUploadAgent";
|
||||||
private static Proxy proxy = null;
|
private static Proxy proxy = null;
|
||||||
|
|
||||||
public static String sendGetRequest(String urlText, String userNamePassword, StringBuilder responseBody){
|
public static String sendGetRequest(String urlText, String userNamePassword, StringBuilder responseBody){
|
||||||
|
@ -55,7 +47,6 @@ public class NetworkUtils {
|
||||||
responseBody.append("\n"); //$NON-NLS-1$
|
responseBody.append("\n"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
responseBody.append(s);
|
responseBody.append(s);
|
||||||
|
|
||||||
}
|
}
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
@ -65,9 +56,10 @@ public class NetworkUtils {
|
||||||
return e.getMessage();
|
return e.getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
|
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
|
||||||
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword, String formName, boolean gzip, Map<String, String> additionalMapData){
|
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword,
|
||||||
|
OsmOAuthAuthorizationClient client,
|
||||||
|
String formName, boolean gzip, Map<String, String> additionalMapData){
|
||||||
URL url;
|
URL url;
|
||||||
try {
|
try {
|
||||||
boolean firstPrm =!urlText.contains("?");
|
boolean firstPrm =!urlText.contains("?");
|
||||||
|
@ -77,34 +69,48 @@ public class NetworkUtils {
|
||||||
}
|
}
|
||||||
log.info("Start uploading file to " + urlText + " " +fileToUpload.getName());
|
log.info("Start uploading file to " + urlText + " " +fileToUpload.getName());
|
||||||
url = new URL(urlText);
|
url = new URL(urlText);
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn;
|
||||||
|
if (client != null && client.isValidToken()){
|
||||||
|
OAuthRequest req = new OAuthRequest(Verb.POST, urlText);
|
||||||
|
client.getService().signRequest(client.getAccessToken(), req);
|
||||||
|
req.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
||||||
|
try {
|
||||||
|
Response r = client.getHttpClient().execute(GPX_UPLOAD_USER_AGENT, req.getHeaders(), req.getVerb(),
|
||||||
|
req.getCompleteUrl(), fileToUpload);
|
||||||
|
if (r.getCode() != 200) {
|
||||||
|
return r.getBody();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
conn.setRequestMethod("POST");
|
conn.setRequestMethod("POST");
|
||||||
if(userNamePassword != null) {
|
if(userNamePassword != null) {
|
||||||
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
|
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
|
}
|
||||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
OutputStream ous = conn.getOutputStream();
|
OutputStream ous = conn.getOutputStream();
|
||||||
// for (String key : additionalMapData.keySet()) {
|
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||||
// ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
|
||||||
// ous.write(("content-disposition: form-data; name=\"" + key + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
// ous.write((additionalMapData.get(key) + "\r\n").getBytes());
|
|
||||||
// }
|
|
||||||
ous.write(("--" + BOUNDARY+"\r\n").getBytes());
|
|
||||||
String filename = fileToUpload.getName();
|
String filename = fileToUpload.getName();
|
||||||
if(gzip){
|
if (gzip) {
|
||||||
filename+=".gz";
|
filename += ".gz";
|
||||||
}
|
}
|
||||||
ous.write(("content-disposition: form-data; name=\""+formName+"\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||||
InputStream fis = new FileInputStream(fileToUpload);
|
InputStream fis = new FileInputStream(fileToUpload);
|
||||||
BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024);
|
BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024);
|
||||||
ous.flush();
|
ous.flush();
|
||||||
if(gzip){
|
if (gzip) {
|
||||||
GZIPOutputStream gous = new GZIPOutputStream(ous, 1024);
|
GZIPOutputStream gous = new GZIPOutputStream(ous, 1024);
|
||||||
Algorithms.streamCopy(bis, gous);
|
Algorithms.streamCopy(bis, gous);
|
||||||
gous.flush();
|
gous.flush();
|
||||||
|
@ -112,7 +118,6 @@ public class NetworkUtils {
|
||||||
} else {
|
} else {
|
||||||
Algorithms.streamCopy(bis, ous);
|
Algorithms.streamCopy(bis, ous);
|
||||||
}
|
}
|
||||||
|
|
||||||
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
ous.flush();
|
ous.flush();
|
||||||
Algorithms.closeStream(bis);
|
Algorithms.closeStream(bis);
|
||||||
|
@ -136,7 +141,6 @@ public class NetworkUtils {
|
||||||
responseBody.append("\n"); //$NON-NLS-1$
|
responseBody.append("\n"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
responseBody.append(s);
|
responseBody.append(s);
|
||||||
|
|
||||||
}
|
}
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
@ -157,7 +161,6 @@ public class NetworkUtils {
|
||||||
proxy = null;
|
proxy = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Proxy getProxy() {
|
public static Proxy getProxy() {
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
package net.osmand.osm.oauth;
|
||||||
|
|
||||||
|
import com.github.scribejava.core.exceptions.OAuthException;
|
||||||
|
import com.github.scribejava.core.httpclient.HttpClient;
|
||||||
|
import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig;
|
||||||
|
import com.github.scribejava.core.httpclient.jdk.JDKHttpFuture;
|
||||||
|
import com.github.scribejava.core.httpclient.multipart.MultipartPayload;
|
||||||
|
import com.github.scribejava.core.httpclient.multipart.MultipartUtils;
|
||||||
|
import com.github.scribejava.core.model.*;
|
||||||
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class OsmAndJDKHttpClient implements HttpClient {
|
||||||
|
private static final String BOUNDARY = "CowMooCowMooCowCowCow";
|
||||||
|
private final JDKHttpClientConfig config;
|
||||||
|
|
||||||
|
public OsmAndJDKHttpClient() {
|
||||||
|
this(JDKHttpClientConfig.defaultConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmAndJDKHttpClient(JDKHttpClientConfig clientConfig) {
|
||||||
|
config = clientConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
byte[] bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||||
|
|
||||||
|
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents, callback,
|
||||||
|
converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
MultipartPayload bodyContents, OAuthAsyncRequestCallback<T> callback,
|
||||||
|
OAuthRequest.ResponseConverter<T> converter) {
|
||||||
|
|
||||||
|
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, bodyContents, callback,
|
||||||
|
converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
String bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||||
|
|
||||||
|
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents, callback,
|
||||||
|
converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
File bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||||
|
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents, callback,
|
||||||
|
converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Future<T> doExecuteAsync(String userAgent, Map<String, String> headers, Verb httpVerb,
|
||||||
|
String completeUrl, BodyType bodyType, Object bodyContents, OAuthAsyncRequestCallback<T> callback,
|
||||||
|
OAuthRequest.ResponseConverter<T> converter) {
|
||||||
|
try {
|
||||||
|
final Response response = doExecute(userAgent, headers, httpVerb, completeUrl, bodyType, bodyContents);
|
||||||
|
@SuppressWarnings("unchecked") final T t = converter == null ? (T) response : converter.convert(response);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onCompleted(t);
|
||||||
|
}
|
||||||
|
return new JDKHttpFuture<>(t);
|
||||||
|
} catch (IOException | RuntimeException e) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onThrowable(e);
|
||||||
|
}
|
||||||
|
return new JDKHttpFuture<>(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
byte[] bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
MultipartPayload multipartPayloads) throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, multipartPayloads);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
String bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
File bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response doExecute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||||
|
BodyType bodyType, Object bodyContents) throws IOException {
|
||||||
|
final URL url = new URL(completeUrl);
|
||||||
|
final HttpURLConnection connection;
|
||||||
|
if (config.getProxy() == null) {
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
} else {
|
||||||
|
connection = (HttpURLConnection) url.openConnection(config.getProxy());
|
||||||
|
}
|
||||||
|
connection.setInstanceFollowRedirects(config.isFollowRedirects());
|
||||||
|
connection.setRequestMethod(httpVerb.name());
|
||||||
|
if (config.getConnectTimeout() != null) {
|
||||||
|
connection.setConnectTimeout(config.getConnectTimeout());
|
||||||
|
}
|
||||||
|
if (config.getReadTimeout() != null) {
|
||||||
|
connection.setReadTimeout(config.getReadTimeout());
|
||||||
|
}
|
||||||
|
addHeaders(connection, headers, userAgent);
|
||||||
|
if (httpVerb.isPermitBody()) {
|
||||||
|
bodyType.setBody(connection, bodyContents, httpVerb.isRequiresBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection.connect();
|
||||||
|
final int responseCode = connection.getResponseCode();
|
||||||
|
return new Response(responseCode, connection.getResponseMessage(), parseHeaders(connection),
|
||||||
|
responseCode >= 200 && responseCode < 400 ? connection.getInputStream()
|
||||||
|
: connection.getErrorStream());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new OAuthException("The IP address of a host could not be determined.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum BodyType {
|
||||||
|
BYTE_ARRAY {
|
||||||
|
@Override
|
||||||
|
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||||
|
addBody(connection, (byte[]) bodyContents, requiresBody);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
STREAM {
|
||||||
|
@Override
|
||||||
|
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||||
|
addBody(connection, (File) bodyContents, requiresBody);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MULTIPART {
|
||||||
|
@Override
|
||||||
|
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||||
|
addBody(connection, (MultipartPayload) bodyContents, requiresBody);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
STRING {
|
||||||
|
@Override
|
||||||
|
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||||
|
addBody(connection, ((String) bodyContents).getBytes(), requiresBody);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody)
|
||||||
|
throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> parseHeaders(HttpURLConnection conn) {
|
||||||
|
final Map<String, String> headers = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, List<String>> headerField : conn.getHeaderFields().entrySet()) {
|
||||||
|
final String key = headerField.getKey();
|
||||||
|
final String value = headerField.getValue().get(0);
|
||||||
|
if ("Content-Encoding".equalsIgnoreCase(key)) {
|
||||||
|
headers.put("Content-Encoding", value);
|
||||||
|
} else {
|
||||||
|
headers.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addHeaders(HttpURLConnection connection, Map<String, String> headers, String userAgent) {
|
||||||
|
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||||
|
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userAgent != null) {
|
||||||
|
connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addBody(HttpURLConnection connection, File file, boolean requiresBody) throws IOException {
|
||||||
|
if (requiresBody) {
|
||||||
|
String filename = file.getName();
|
||||||
|
String formName = "file";
|
||||||
|
InputStream stream = new FileInputStream(file);
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
connection.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
final OutputStream ous = connection.getOutputStream();
|
||||||
|
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||||
|
ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(stream, 20 * 1024);
|
||||||
|
ous.flush();
|
||||||
|
Algorithms.streamCopy(bis, ous);
|
||||||
|
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
ous.flush();
|
||||||
|
Algorithms.closeStream(bis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addBody(HttpURLConnection connection, byte[] content, boolean requiresBody) throws IOException {
|
||||||
|
final int contentLength = content.length;
|
||||||
|
if (requiresBody || contentLength > 0) {
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength);
|
||||||
|
if (contentLength > 0) {
|
||||||
|
outputStream.write(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addBody(HttpURLConnection connection, MultipartPayload multipartPayload, boolean requiresBody)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> header : multipartPayload.getHeaders().entrySet()) {
|
||||||
|
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresBody) {
|
||||||
|
final ByteArrayOutputStream os = MultipartUtils.getPayload(multipartPayload);
|
||||||
|
final int contentLength = os.size();
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength);
|
||||||
|
if (contentLength > 0) {
|
||||||
|
os.writeTo(outputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OutputStream prepareConnectionForBodyAndGetOutputStream(HttpURLConnection connection,
|
||||||
|
int contentLength) throws IOException {
|
||||||
|
connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(contentLength));
|
||||||
|
if (connection.getRequestProperty(CONTENT_TYPE) == null) {
|
||||||
|
connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
return connection.getOutputStream();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
// License: GPL. For details, see LICENSE file.
|
||||||
|
package net.osmand.osm.oauth;
|
||||||
|
|
||||||
|
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||||
|
import com.github.scribejava.core.builder.api.DefaultApi10a;
|
||||||
|
import com.github.scribejava.core.builder.api.OAuth1SignatureType;
|
||||||
|
import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig;
|
||||||
|
import com.github.scribejava.core.model.*;
|
||||||
|
import com.github.scribejava.core.oauth.OAuth10aService;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OAuth 1.0 authorization client.
|
||||||
|
*
|
||||||
|
* @since 2746
|
||||||
|
*/
|
||||||
|
public class OsmOAuthAuthorizationClient {
|
||||||
|
private OAuth1RequestToken requestToken;
|
||||||
|
private OAuth1AccessToken accessToken;
|
||||||
|
private final OAuth10aService service;
|
||||||
|
private final OsmAndJDKHttpClient httpClient;
|
||||||
|
public final static Log log = PlatformUtil.getLog(OsmOAuthAuthorizationClient.class);
|
||||||
|
|
||||||
|
public OsmOAuthAuthorizationClient(String key, String secret) {
|
||||||
|
httpClient = new OsmAndJDKHttpClient(JDKHttpClientConfig.defaultConfig());
|
||||||
|
service = new ServiceBuilder(key)
|
||||||
|
.apiSecret(secret)
|
||||||
|
.httpClient(httpClient)
|
||||||
|
.callback("osmand-oauth://example.com/oauth")
|
||||||
|
.build(new OsmApi());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class OsmApi extends DefaultApi10a {
|
||||||
|
@Override
|
||||||
|
public OAuth1SignatureType getSignatureType() {
|
||||||
|
return OAuth1SignatureType.QUERY_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRequestTokenEndpoint() {
|
||||||
|
return "https://www.openstreetmap.org/oauth/request_token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessTokenEndpoint() {
|
||||||
|
return "https://www.openstreetmap.org/oauth/access_token";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getAuthorizationBaseUrl() {
|
||||||
|
return "https://www.openstreetmap.org/oauth/authorize";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmAndJDKHttpClient getHttpClient() {
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth10aService getService() {
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessToken(OAuth1AccessToken accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth1AccessToken getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody)
|
||||||
|
throws InterruptedException, ExecutionException, IOException {
|
||||||
|
Verb verb = parseRequestMethod(requestMethod);
|
||||||
|
OAuthRequest req = new OAuthRequest(verb, url);
|
||||||
|
req.setPayload(requestBody);
|
||||||
|
return service.execute(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performGetRequest(String url, OAuthAsyncRequestCallback<Response> callback) {
|
||||||
|
if (accessToken == null) {
|
||||||
|
throw new IllegalStateException("Access token is null");
|
||||||
|
}
|
||||||
|
OAuthRequest req = new OAuthRequest(Verb.GET, url);
|
||||||
|
service.signRequest(accessToken, req);
|
||||||
|
service.execute(req, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response performRequest(String url, String method, String body)
|
||||||
|
throws InterruptedException, ExecutionException, IOException {
|
||||||
|
service.getApi().getSignatureType();
|
||||||
|
if (accessToken == null) {
|
||||||
|
throw new IllegalStateException("Access token is null");
|
||||||
|
}
|
||||||
|
Verb verbMethod = parseRequestMethod(method);
|
||||||
|
OAuthRequest req = new OAuthRequest(verbMethod, url);
|
||||||
|
req.setPayload(body);
|
||||||
|
service.signRequest(accessToken, req);
|
||||||
|
req.addHeader("Content-Type", "application/xml");
|
||||||
|
return service.execute(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth1RequestToken startOAuth() {
|
||||||
|
try {
|
||||||
|
requestToken = service.getRequestToken();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return requestToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth1AccessToken authorize(String oauthVerifier) {
|
||||||
|
try {
|
||||||
|
setAccessToken(service.getAccessToken(requestToken, oauthVerifier));
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValidToken() {
|
||||||
|
return !(accessToken == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Verb parseRequestMethod(String method) {
|
||||||
|
Verb m = Verb.GET;
|
||||||
|
if (method.equals("POST")) {
|
||||||
|
m = Verb.POST;
|
||||||
|
}
|
||||||
|
if (method.equals("PUT")) {
|
||||||
|
m = Verb.PUT;
|
||||||
|
}
|
||||||
|
if (method.equals("DELETE")) {
|
||||||
|
m = Verb.DELETE;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
|
@ -479,7 +479,16 @@
|
||||||
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation" />
|
||||||
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation" />
|
||||||
|
|
||||||
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:configChanges="keyboardHidden|orientation">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="osmand-oauth" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation" />
|
||||||
<activity android:name="net.osmand.plus.audionotes.SettingsAudioVideoActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.plus.audionotes.SettingsAudioVideoActivity" android:configChanges="keyboardHidden|orientation" />
|
||||||
<activity android:name="net.osmand.access.SettingsAccessibilityActivity" android:configChanges="keyboardHidden|orientation" />
|
<activity android:name="net.osmand.access.SettingsAccessibilityActivity" android:configChanges="keyboardHidden|orientation" />
|
||||||
|
|
|
@ -227,9 +227,13 @@ android {
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
|
buildConfigField "String", "OSM_OAUTH_CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\""
|
||||||
|
buildConfigField "String", "OSM_OAUTH_CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\""
|
||||||
signingConfig signingConfigs.development
|
signingConfig signingConfigs.development
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
|
buildConfigField "String", "OSM_OAUTH_CONSUMER_KEY", "\"Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y\""
|
||||||
|
buildConfigField "String", "OSM_OAUTH_CONSUMER_SECRET", "\"lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM\""
|
||||||
if (gradle.startParameter.taskNames.toString().contains("huawei")) {
|
if (gradle.startParameter.taskNames.toString().contains("huawei")) {
|
||||||
signingConfig signingConfigs.publishingHuawei
|
signingConfig signingConfigs.publishingHuawei
|
||||||
} else {
|
} else {
|
||||||
|
@ -532,6 +536,9 @@ dependencies {
|
||||||
implementation ("com.github.HITGIF:TextFieldBoxes:1.4.5"){
|
implementation ("com.github.HITGIF:TextFieldBoxes:1.4.5"){
|
||||||
exclude group: 'com.android.support'
|
exclude group: 'com.android.support'
|
||||||
}
|
}
|
||||||
|
implementation('com.github.scribejava:scribejava-apis:7.1.1'){
|
||||||
|
exclude group: "com.fasterxml.jackson.core"
|
||||||
|
}
|
||||||
implementation 'com.jaredrummler:colorpicker:1.1.0'
|
implementation 'com.jaredrummler:colorpicker:1.1.0'
|
||||||
|
|
||||||
freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300'
|
freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300'
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
Thx - Hardy
|
Thx - Hardy
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
<string name="osm_edit_logout_success">Logout successful</string>
|
||||||
|
<string name="clear_osm_token">Clear OpenStreetMap OAuth token</string>
|
||||||
|
<string name="perform_oauth_authorization">Log in via OAuth</string>
|
||||||
|
<string name="perform_oauth_authorization_description">Perform an OAuth Login to use osmedit features</string>
|
||||||
<string name="use_native_pt_desc">Switch to Java (safe) Public Transport routing calculation</string>
|
<string name="use_native_pt_desc">Switch to Java (safe) Public Transport routing calculation</string>
|
||||||
<string name="use_native_pt">Native Public Transport development</string>
|
<string name="use_native_pt">Native Public Transport development</string>
|
||||||
<string name="use_fast_recalculation_desc">Recalculates only the initial part of the route. Can be used for long trips.</string>
|
<string name="use_fast_recalculation_desc">Recalculates only the initial part of the route. Can be used for long trips.</string>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.app.Activity;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.TrafficStats;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.AsyncTask.Status;
|
import android.os.AsyncTask.Status;
|
||||||
|
@ -58,8 +59,8 @@ public class DownloadIndexesThread {
|
||||||
private ConcurrentLinkedQueue<IndexItem> indexItemDownloading = new ConcurrentLinkedQueue<IndexItem>();
|
private ConcurrentLinkedQueue<IndexItem> indexItemDownloading = new ConcurrentLinkedQueue<IndexItem>();
|
||||||
private IndexItem currentDownloadingItem = null;
|
private IndexItem currentDownloadingItem = null;
|
||||||
private int currentDownloadingItemProgress = 0;
|
private int currentDownloadingItemProgress = 0;
|
||||||
|
|
||||||
private DownloadResources indexes;
|
private DownloadResources indexes;
|
||||||
|
private static final int THREAD_ID = 10103;
|
||||||
|
|
||||||
public interface DownloadEvents {
|
public interface DownloadEvents {
|
||||||
|
|
||||||
|
@ -336,6 +337,7 @@ public class DownloadIndexesThread {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DownloadResources doInBackground(Void... params) {
|
protected DownloadResources doInBackground(Void... params) {
|
||||||
|
TrafficStats.setThreadStatsTag(THREAD_ID);
|
||||||
DownloadResources result = null;
|
DownloadResources result = null;
|
||||||
DownloadOsmandIndexesHelper.IndexFileList indexFileList = DownloadOsmandIndexesHelper.getIndexesList(ctx);
|
DownloadOsmandIndexesHelper.IndexFileList indexFileList = DownloadOsmandIndexesHelper.getIndexesList(ctx);
|
||||||
if (indexFileList != null) {
|
if (indexFileList != null) {
|
||||||
|
|
|
@ -2,10 +2,8 @@ package net.osmand.plus.osmedit;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
import net.osmand.data.PointDescription;
|
import net.osmand.data.PointDescription;
|
||||||
import net.osmand.osm.PoiType;
|
import net.osmand.osm.PoiType;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
|
@ -14,6 +12,7 @@ import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||||
import net.osmand.plus.osmedit.OsmPoint.Action;
|
import net.osmand.plus.osmedit.OsmPoint.Action;
|
||||||
import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment;
|
import net.osmand.plus.osmedit.dialogs.SendPoiDialogFragment;
|
||||||
|
import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter;
|
||||||
import net.osmand.plus.render.RenderingIcons;
|
import net.osmand.plus.render.RenderingIcons;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
@ -39,11 +38,18 @@ public class EditPOIMenuController extends MenuController {
|
||||||
public void buttonPressed() {
|
public void buttonPressed() {
|
||||||
MapActivity activity = getMapActivity();
|
MapActivity activity = getMapActivity();
|
||||||
if (plugin != null && activity != null) {
|
if (plugin != null && activity != null) {
|
||||||
|
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(activity.getMyApplication());
|
||||||
|
if (client.isValidToken()){
|
||||||
|
new SendPoiDialogFragment.SimpleProgressDialogPoiUploader(activity).
|
||||||
|
showProgressDialog(new OsmPoint[] { getOsmPoint() }, false, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
SendPoiDialogFragment sendPoiDialogFragment =
|
SendPoiDialogFragment sendPoiDialogFragment =
|
||||||
SendPoiDialogFragment.createInstance(new OsmPoint[]{getOsmPoint()}, SendPoiDialogFragment.PoiUploaderType.SIMPLE);
|
SendPoiDialogFragment.createInstance(new OsmPoint[]{getOsmPoint()}, SendPoiDialogFragment.PoiUploaderType.SIMPLE);
|
||||||
sendPoiDialogFragment.show(activity.getSupportFragmentManager(), SendPoiDialogFragment.TAG);
|
sendPoiDialogFragment.show(activity.getSupportFragmentManager(), SendPoiDialogFragment.TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
leftTitleButtonController.caption = mapActivity.getString(R.string.shared_string_upload);
|
leftTitleButtonController.caption = mapActivity.getString(R.string.shared_string_upload);
|
||||||
leftTitleButtonController.startIconId = R.drawable.ic_action_export;
|
leftTitleButtonController.startIconId = R.drawable.ic_action_export;
|
||||||
|
|
|
@ -2,7 +2,8 @@ package net.osmand.plus.osmedit;
|
||||||
|
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import com.github.scribejava.core.model.Response;
|
||||||
|
import gnu.trove.list.array.TLongArrayList;
|
||||||
import net.osmand.NativeLibrary;
|
import net.osmand.NativeLibrary;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.data.Amenity;
|
import net.osmand.data.Amenity;
|
||||||
|
@ -17,38 +18,29 @@ import net.osmand.osm.edit.Entity.EntityType;
|
||||||
import net.osmand.osm.edit.EntityInfo;
|
import net.osmand.osm.edit.EntityInfo;
|
||||||
import net.osmand.osm.edit.Node;
|
import net.osmand.osm.edit.Node;
|
||||||
import net.osmand.osm.edit.Way;
|
import net.osmand.osm.edit.Way;
|
||||||
import net.osmand.osm.io.Base64;
|
|
||||||
import net.osmand.osm.io.NetworkUtils;
|
import net.osmand.osm.io.NetworkUtils;
|
||||||
import net.osmand.osm.io.OsmBaseStorage;
|
import net.osmand.osm.io.OsmBaseStorage;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.Version;
|
import net.osmand.plus.Version;
|
||||||
|
import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter;
|
||||||
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import gnu.trove.list.array.TLongArrayList;
|
|
||||||
|
|
||||||
public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
||||||
|
|
||||||
|
@ -99,12 +91,16 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
||||||
private final static String URL_TO_UPLOAD_GPX = getSiteApi() + "api/0.6/gpx/create";
|
private final static String URL_TO_UPLOAD_GPX = getSiteApi() + "api/0.6/gpx/create";
|
||||||
|
|
||||||
public String uploadGPXFile(String tagstring, String description, String visibility, File f) {
|
public String uploadGPXFile(String tagstring, String description, String visibility, File f) {
|
||||||
|
OsmOAuthAuthorizationAdapter adapter = new OsmOAuthAuthorizationAdapter(ctx);
|
||||||
String url = URL_TO_UPLOAD_GPX;
|
String url = URL_TO_UPLOAD_GPX;
|
||||||
Map<String, String> additionalData = new LinkedHashMap<String, String>();
|
Map<String, String> additionalData = new LinkedHashMap<String, String>();
|
||||||
additionalData.put("description", description);
|
additionalData.put("description", description);
|
||||||
additionalData.put("tags", tagstring);
|
additionalData.put("tags", tagstring);
|
||||||
additionalData.put("visibility", visibility);
|
additionalData.put("visibility", visibility);
|
||||||
return NetworkUtils.uploadFile(url, f, settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(), "file",
|
return NetworkUtils.uploadFile(url, f,
|
||||||
|
settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(),
|
||||||
|
adapter.getClient(),
|
||||||
|
"file",
|
||||||
true, additionalData);
|
true, additionalData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,53 +108,15 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
||||||
boolean doAuthenticate) {
|
boolean doAuthenticate) {
|
||||||
log.info("Sending request " + url); //$NON-NLS-1$
|
log.info("Sending request " + url); //$NON-NLS-1$
|
||||||
try {
|
try {
|
||||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
if (doAuthenticate){
|
||||||
|
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx);
|
||||||
connection.setConnectTimeout(15000);
|
Response response = client.performRequest(url,requestMethod,requestBody);
|
||||||
connection.setRequestMethod(requestMethod);
|
return response.getBody();
|
||||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
|
|
||||||
StringBuilder responseBody = new StringBuilder();
|
|
||||||
if (doAuthenticate) {
|
|
||||||
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$
|
|
||||||
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
|
||||||
}
|
}
|
||||||
connection.setDoInput(true);
|
else {
|
||||||
if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx);
|
||||||
connection.setDoOutput(true);
|
Response response = client.performRequestWithoutAuth(url,requestMethod,requestBody);
|
||||||
connection.setRequestProperty("Content-type", "text/xml"); //$NON-NLS-1$ //$NON-NLS-2$
|
return response.getBody();
|
||||||
OutputStream out = connection.getOutputStream();
|
|
||||||
if (requestBody != null) {
|
|
||||||
BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"), 1024); //$NON-NLS-1$
|
|
||||||
bwr.write(requestBody);
|
|
||||||
bwr.flush();
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
connection.connect();
|
|
||||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
|
||||||
String msg = userOperation
|
|
||||||
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage(); //$NON-NLS-1$//$NON-NLS-2$
|
|
||||||
log.error(msg);
|
|
||||||
showWarning(msg);
|
|
||||||
} else {
|
|
||||||
log.info("Response : " + connection.getResponseMessage()); //$NON-NLS-1$
|
|
||||||
// populate return fields.
|
|
||||||
responseBody.setLength(0);
|
|
||||||
InputStream i = connection.getInputStream();
|
|
||||||
if (i != null) {
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
|
|
||||||
String s;
|
|
||||||
boolean f = true;
|
|
||||||
while ((s = in.readLine()) != null) {
|
|
||||||
if (!f) {
|
|
||||||
responseBody.append("\n"); //$NON-NLS-1$
|
|
||||||
} else {
|
|
||||||
f = false;
|
|
||||||
}
|
|
||||||
responseBody.append(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responseBody.toString();
|
|
||||||
}
|
}
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
|
||||||
|
@ -173,6 +131,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
||||||
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
||||||
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
||||||
|
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
|
||||||
|
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
|
||||||
|
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -208,10 +174,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
|
||||||
}
|
}
|
||||||
String response = sendRequest(
|
String response = sendRequest(
|
||||||
getSiteApi() + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), ctx.getString(R.string.opening_changeset), true); //$NON-NLS-1$ //$NON-NLS-2$
|
getSiteApi() + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), ctx.getString(R.string.opening_changeset), true); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
try {
|
||||||
if (response != null && response.length() > 0) {
|
if (response != null && response.length() > 0) {
|
||||||
|
log.debug(response);
|
||||||
id = Long.parseLong(response);
|
id = Long.parseLong(response);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ import net.osmand.PlatformUtil;
|
||||||
import net.osmand.osm.io.Base64;
|
import net.osmand.osm.io.Base64;
|
||||||
import net.osmand.osm.io.NetworkUtils;
|
import net.osmand.osm.io.NetworkUtils;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.Version;
|
import net.osmand.plus.Version;
|
||||||
import net.osmand.plus.osmedit.OsmPoint.Action;
|
import net.osmand.plus.osmedit.OsmPoint.Action;
|
||||||
|
import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter;
|
||||||
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -109,6 +109,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
|
||||||
|
|
||||||
private OsmBugResult editingPOI(String url, String requestMethod, String userOperation,
|
private OsmBugResult editingPOI(String url, String requestMethod, String userOperation,
|
||||||
boolean anonymous) {
|
boolean anonymous) {
|
||||||
|
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(app);
|
||||||
OsmBugResult r = new OsmBugResult();
|
OsmBugResult r = new OsmBugResult();
|
||||||
try {
|
try {
|
||||||
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
|
||||||
|
@ -118,9 +119,13 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
|
||||||
connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); //$NON-NLS-1$
|
connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); //$NON-NLS-1$
|
||||||
|
|
||||||
if (!anonymous) {
|
if (!anonymous) {
|
||||||
|
if (client.isValidToken()) {
|
||||||
|
connection.addRequestProperty("Authorization", "OAuth " + client.getClient().getAccessToken().getToken());
|
||||||
|
} else {
|
||||||
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$
|
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$
|
||||||
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
connection.setDoInput(true);
|
connection.setDoInput(true);
|
||||||
connection.connect();
|
connection.connect();
|
||||||
|
|
|
@ -13,11 +13,9 @@ import android.widget.ArrayAdapter;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.data.Amenity;
|
import net.osmand.data.Amenity;
|
||||||
|
@ -25,7 +23,7 @@ import net.osmand.data.MapObject;
|
||||||
import net.osmand.data.TransportStop;
|
import net.osmand.data.TransportStop;
|
||||||
import net.osmand.osm.PoiType;
|
import net.osmand.osm.PoiType;
|
||||||
import net.osmand.osm.edit.Entity;
|
import net.osmand.osm.edit.Entity;
|
||||||
import net.osmand.plus.ContextMenuAdapter;
|
import net.osmand.plus.*;
|
||||||
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
||||||
import net.osmand.plus.ContextMenuItem;
|
import net.osmand.plus.ContextMenuItem;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
@ -44,22 +42,16 @@ import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
||||||
import net.osmand.plus.myplaces.FavoritesActivity;
|
import net.osmand.plus.myplaces.FavoritesActivity;
|
||||||
import net.osmand.plus.osmedit.OsmPoint.Action;
|
import net.osmand.plus.osmedit.OsmPoint.Action;
|
||||||
import net.osmand.plus.quickaction.QuickActionType;
|
import net.osmand.plus.quickaction.QuickActionType;
|
||||||
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
|
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
|
||||||
import net.osmand.plus.views.OsmandMapTileView;
|
import net.osmand.plus.views.OsmandMapTileView;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_CREATE_POI;
|
import static net.osmand.aidlapi.OsmAndCustomizationConstants.*;
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_OSM_CHANGE;
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_OSM_NOTE;
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_MODIFY_POI;
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_OPEN_OSM_NOTE;
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_EDITS;
|
|
||||||
import static net.osmand.aidlapi.OsmAndCustomizationConstants.OSM_NOTES;
|
|
||||||
import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction;
|
import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction;
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,7 +457,8 @@ public class OsmEditingPlugin extends OsmandPlugin {
|
||||||
public boolean sendGPXFiles(final Activity la, AvailableGPXFragment f, final GpxInfo... info) {
|
public boolean sendGPXFiles(final Activity la, AvailableGPXFragment f, final GpxInfo... info) {
|
||||||
String name = settings.USER_NAME.get();
|
String name = settings.USER_NAME.get();
|
||||||
String pwd = settings.USER_PASSWORD.get();
|
String pwd = settings.USER_PASSWORD.get();
|
||||||
if (Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) {
|
String authToken = settings.USER_ACCESS_TOKEN.get();
|
||||||
|
if ((Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) && Algorithms.isEmpty(authToken)) {
|
||||||
Toast.makeText(la, R.string.validate_gpx_upload_name_pwd, Toast.LENGTH_LONG).show();
|
Toast.makeText(la, R.string.validate_gpx_upload_name_pwd, Toast.LENGTH_LONG).show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ package net.osmand.plus.osmedit;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.StrictMode;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.DialogPreference;
|
import android.preference.DialogPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
|
@ -12,22 +14,40 @@ import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import com.github.scribejava.core.model.OAuthAsyncRequestCallback;
|
||||||
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
|
import com.github.scribejava.core.model.Response;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.OsmandPlugin;
|
import net.osmand.plus.OsmandPlugin;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.activities.SettingsBaseActivity;
|
import net.osmand.plus.activities.SettingsBaseActivity;
|
||||||
|
import net.osmand.plus.osmedit.oauth.OsmOAuthAuthorizationAdapter;
|
||||||
|
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SettingsOsmEditingActivity extends SettingsBaseActivity {
|
public class SettingsOsmEditingActivity extends SettingsBaseActivity {
|
||||||
|
private OsmOAuthAuthorizationAdapter client;
|
||||||
|
private static final Log log = PlatformUtil.getLog(SettingsOsmEditingActivity.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
|
||||||
|
.detectDiskReads()
|
||||||
|
.detectDiskWrites()
|
||||||
|
.detectNetwork()
|
||||||
|
.penaltyLog()
|
||||||
|
.build());
|
||||||
|
|
||||||
((OsmandApplication) getApplication()).applyTheme(this);
|
((OsmandApplication) getApplication()).applyTheme(this);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
client = new OsmOAuthAuthorizationAdapter(getMyApplication());
|
||||||
|
|
||||||
getToolbar().setTitle(R.string.osm_settings);
|
getToolbar().setTitle(R.string.osm_settings);
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
PreferenceScreen grp = getPreferenceScreen();
|
PreferenceScreen grp = getPreferenceScreen();
|
||||||
|
@ -39,7 +59,7 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity {
|
||||||
R.string.offline_edition, R.string.offline_edition_descr);
|
R.string.offline_edition, R.string.offline_edition_descr);
|
||||||
grp.addPreference(poiEdit);
|
grp.addPreference(poiEdit);
|
||||||
|
|
||||||
Preference pref = new Preference(this);
|
final Preference pref = new Preference(this);
|
||||||
pref.setTitle(R.string.local_openstreetmap_settings);
|
pref.setTitle(R.string.local_openstreetmap_settings);
|
||||||
pref.setSummary(R.string.local_openstreetmap_settings_descr);
|
pref.setSummary(R.string.local_openstreetmap_settings_descr);
|
||||||
pref.setKey("local_openstreetmap_points");
|
pref.setKey("local_openstreetmap_points");
|
||||||
|
@ -56,6 +76,44 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grp.addPreference(pref);
|
grp.addPreference(pref);
|
||||||
|
|
||||||
|
final Preference prefOAuth = new Preference(this);
|
||||||
|
if (client.isValidToken()){
|
||||||
|
prefOAuth.setTitle(R.string.osm_authorization_success);
|
||||||
|
prefOAuth.setSummary(R.string.osm_authorization_success);
|
||||||
|
prefOAuth.setKey("local_openstreetmap_oauth_success");
|
||||||
|
final Preference prefClearToken = new Preference(this);
|
||||||
|
prefClearToken.setTitle(R.string.shared_string_logoff);
|
||||||
|
prefClearToken.setSummary(R.string.clear_osm_token);
|
||||||
|
prefClearToken.setKey("local_openstreetmap_oauth_clear");
|
||||||
|
prefClearToken.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
settings.USER_ACCESS_TOKEN.set("");
|
||||||
|
settings.USER_ACCESS_TOKEN_SECRET.set("");
|
||||||
|
client.resetToken();
|
||||||
|
Toast.makeText(SettingsOsmEditingActivity.this, R.string.osm_edit_logout_success, Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
startActivity(getIntent());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
grp.addPreference(prefClearToken);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefOAuth.setTitle(R.string.perform_oauth_authorization);
|
||||||
|
prefOAuth.setSummary(R.string.perform_oauth_authorization_description);
|
||||||
|
prefOAuth.setKey("local_openstreetmap_oauth_login");
|
||||||
|
prefOAuth.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
ViewGroup preferenceView = (ViewGroup)getListView().getChildAt(preference.getOrder());
|
||||||
|
client.startOAuth(preferenceView);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
grp.addPreference(prefOAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OsmLoginDataDialogPreference extends DialogPreference {
|
public class OsmLoginDataDialogPreference extends DialogPreference {
|
||||||
|
@ -116,4 +174,17 @@ public class SettingsOsmEditingActivity extends SettingsBaseActivity {
|
||||||
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
|
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
Uri uri = intent.getData();
|
||||||
|
System.out.println("URI=" + uri);
|
||||||
|
if (uri != null && uri.toString().startsWith("osmand-oauth")) {
|
||||||
|
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
|
||||||
|
client.authorize(oauthVerifier);
|
||||||
|
finish();
|
||||||
|
startActivity(getIntent());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package net.osmand.plus.osmedit;
|
package net.osmand.plus.osmedit;
|
||||||
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.net.TrafficStats;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
import net.osmand.osm.edit.Entity;
|
import net.osmand.osm.edit.Entity;
|
||||||
|
@ -24,6 +25,7 @@ public class UploadOpenstreetmapPointAsyncTask
|
||||||
private OsmEditingPlugin plugin;
|
private OsmEditingPlugin plugin;
|
||||||
private final boolean closeChangeSet;
|
private final boolean closeChangeSet;
|
||||||
private final boolean loadAnonymous;
|
private final boolean loadAnonymous;
|
||||||
|
private static final int THREAD_ID = 10102;
|
||||||
|
|
||||||
public UploadOpenstreetmapPointAsyncTask(ProgressDialogFragment progress,
|
public UploadOpenstreetmapPointAsyncTask(ProgressDialogFragment progress,
|
||||||
OsmEditsUploadListener listener,
|
OsmEditsUploadListener listener,
|
||||||
|
@ -43,6 +45,8 @@ public class UploadOpenstreetmapPointAsyncTask
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<OsmPoint, String> doInBackground(OsmPoint... points) {
|
protected Map<OsmPoint, String> doInBackground(OsmPoint... points) {
|
||||||
|
TrafficStats.setThreadStatsTag(THREAD_ID);
|
||||||
|
|
||||||
Map<OsmPoint, String> loadErrorsMap = new HashMap<>();
|
Map<OsmPoint, String> loadErrorsMap = new HashMap<>();
|
||||||
|
|
||||||
boolean uploaded = false;
|
boolean uploaded = false;
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package net.osmand.plus.osmedit.oauth;
|
||||||
|
|
||||||
|
import android.net.TrafficStats;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import com.github.scribejava.core.model.OAuth1AccessToken;
|
||||||
|
import com.github.scribejava.core.model.OAuth1RequestToken;
|
||||||
|
import com.github.scribejava.core.model.OAuthAsyncRequestCallback;
|
||||||
|
import com.github.scribejava.core.model.Response;
|
||||||
|
import net.osmand.osm.oauth.OsmOAuthAuthorizationClient;
|
||||||
|
import net.osmand.plus.BuildConfig;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public class OsmOAuthAuthorizationAdapter {
|
||||||
|
private OsmandApplication application;
|
||||||
|
private OsmOAuthAuthorizationClient client =
|
||||||
|
new OsmOAuthAuthorizationClient(BuildConfig.OSM_OAUTH_CONSUMER_KEY, BuildConfig.OSM_OAUTH_CONSUMER_SECRET);
|
||||||
|
private static final int THREAD_ID = 10101;
|
||||||
|
|
||||||
|
public OsmOAuthAuthorizationAdapter(OsmandApplication application) {
|
||||||
|
TrafficStats.setThreadStatsTag(THREAD_ID);
|
||||||
|
this.application = application;
|
||||||
|
restoreToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmOAuthAuthorizationClient getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValidToken() {
|
||||||
|
return client.isValidToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetToken() {
|
||||||
|
client.setAccessToken(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restoreToken() {
|
||||||
|
String token = application.getSettings().USER_ACCESS_TOKEN.get();
|
||||||
|
String tokenSecret = application.getSettings().USER_ACCESS_TOKEN_SECRET.get();
|
||||||
|
if (!(token.isEmpty() || tokenSecret.isEmpty())) {
|
||||||
|
client.setAccessToken(new OAuth1AccessToken(token, tokenSecret));
|
||||||
|
} else {
|
||||||
|
client.setAccessToken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startOAuth(ViewGroup rootLayout) {
|
||||||
|
OAuth1RequestToken requestToken = client.startOAuth();
|
||||||
|
loadWebView(rootLayout, client.getService().getAuthorizationUrl(requestToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveToken() {
|
||||||
|
OAuth1AccessToken accessToken = client.getAccessToken();
|
||||||
|
application.getSettings().USER_ACCESS_TOKEN.set(accessToken.getToken());
|
||||||
|
application.getSettings().USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadWebView(ViewGroup root, String url) {
|
||||||
|
WebView webView = new WebView(root.getContext());
|
||||||
|
webView.requestFocus(View.FOCUS_DOWN);
|
||||||
|
webView.loadUrl(url);
|
||||||
|
root.addView(webView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performGetRequest(String url, OAuthAsyncRequestCallback<Response> callback) {
|
||||||
|
client.performGetRequest(url, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response performRequest(String url, String method, String body)
|
||||||
|
throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return client.performRequest(url, method, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response performRequestWithoutAuth(String url, String method, String body)
|
||||||
|
throws InterruptedException, ExecutionException, IOException {
|
||||||
|
return client.performRequestWithoutAuth(url, method, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authorize(String oauthVerifier) {
|
||||||
|
client.authorize(oauthVerifier);
|
||||||
|
saveToken();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1125,6 +1125,12 @@ public class OsmandSettings {
|
||||||
public final OsmandPreference<String> USER_PASSWORD =
|
public final OsmandPreference<String> USER_PASSWORD =
|
||||||
new StringPreference(this, "user_password", "").makeGlobal();
|
new StringPreference(this, "user_password", "").makeGlobal();
|
||||||
|
|
||||||
|
public final OsmandPreference<String> USER_ACCESS_TOKEN =
|
||||||
|
new StringPreference("user_access_token", "").makeGlobal();
|
||||||
|
|
||||||
|
public final OsmandPreference<String> USER_ACCESS_TOKEN_SECRET =
|
||||||
|
new StringPreference("user_access_token_secret", "").makeGlobal();
|
||||||
|
|
||||||
// this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition
|
// this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition
|
||||||
public final OsmandPreference<Boolean> OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal();
|
public final OsmandPreference<Boolean> OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue