Use google-auth-library-java

pull/935/head
Alex Baker 6 years ago
parent 1e04d578cf
commit 73c2cd1dca

@ -188,6 +188,7 @@ dependencies {
implementation("com.google.apis:google-api-services-tasks:v1-rev20190628-1.30.8") implementation("com.google.apis:google-api-services-tasks:v1-rev20190628-1.30.8")
implementation("com.google.apis:google-api-services-drive:v3-rev20191108-1.30.8") implementation("com.google.apis:google-api-services-drive:v3-rev20191108-1.30.8")
implementation("com.google.api-client:google-api-client-android:1.30.8") implementation("com.google.api-client:google-api-client-android:1.30.8")
implementation("com.google.auth:google-auth-library-oauth2-http:0.20.0")
implementation("androidx.work:work-runtime:${Versions.work}") implementation("androidx.work:work-runtime:${Versions.work}")
implementation("com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.0") implementation("com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.0")
implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:4.6.0") implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:4.6.0")

@ -1,21 +0,0 @@
package org.tasks;
import com.google.api.client.http.HttpExecuteInterceptor;
import com.google.api.client.http.HttpRequest;
import java.io.IOException;
public class ChainedHttpExecuteInterceptor implements HttpExecuteInterceptor {
private final HttpExecuteInterceptor[] interceptors;
ChainedHttpExecuteInterceptor(HttpExecuteInterceptor... interceptors) {
this.interceptors = interceptors;
}
@Override
public void intercept(HttpRequest request) throws IOException {
for (HttpExecuteInterceptor interceptor : interceptors) {
interceptor.intercept(request);
}
}
}

@ -32,7 +32,7 @@ public class DebugNetworkInterceptor {
FlipperHttpInterceptor<T> interceptor = FlipperHttpInterceptor<T> interceptor =
new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass); new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass);
request request
.setInterceptor(new ChainedHttpExecuteInterceptor(request.getInterceptor(), interceptor)) .setInterceptor(interceptor)
.setResponseInterceptor(interceptor) .setResponseInterceptor(interceptor)
.execute(); .execute();
return interceptor.getResponse(); return interceptor.getResponse();

@ -2,7 +2,6 @@ package com.todoroo.astrid.gtasks.api;
import android.content.Context; import android.content.Context;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponseException; import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.http.javanet.NetHttpTransport;
@ -14,12 +13,10 @@ import com.google.api.services.tasks.TasksScopes;
import com.google.api.services.tasks.model.Task; import com.google.api.services.tasks.model.Task;
import com.google.api.services.tasks.model.TaskList; import com.google.api.services.tasks.model.TaskList;
import com.google.api.services.tasks.model.TaskLists; import com.google.api.services.tasks.model.TaskLists;
import com.google.common.base.Strings;
import java.io.IOException; import java.io.IOException;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.BuildConfig; import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor; import org.tasks.DebugNetworkInterceptor;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import timber.log.Timber; import timber.log.Timber;
@ -33,55 +30,46 @@ import timber.log.Timber;
public class GtasksInvoker { public class GtasksInvoker {
private final Context context; private final Context context;
private final GoogleAccountManager googleAccountManager;
private final Preferences preferences; private final Preferences preferences;
private final DebugNetworkInterceptor interceptor; private final DebugNetworkInterceptor interceptor;
@Nullable private final GoogleCredential credential;
private final String account; private final String account;
private final Tasks service; private final Tasks service;
private final HttpCredentialsAdapter credentialsAdapter;
@Inject @Inject
public GtasksInvoker( public GtasksInvoker(
@ForApplication Context context, @ForApplication Context context,
GoogleAccountManager googleAccountManager, HttpCredentialsAdapter credentialsAdapter,
Preferences preferences, Preferences preferences,
DebugNetworkInterceptor interceptor) { DebugNetworkInterceptor interceptor) {
this.context = context; this.context = context;
this.googleAccountManager = googleAccountManager; this.credentialsAdapter = credentialsAdapter;
this.preferences = preferences; this.preferences = preferences;
this.interceptor = interceptor; this.interceptor = interceptor;
account = null; account = null;
service = null; service = null;
credential = null;
} }
private GtasksInvoker( private GtasksInvoker(
Context context, Context context,
GoogleAccountManager googleAccountManager, HttpCredentialsAdapter credentialsAdapter,
Preferences preferences, Preferences preferences,
DebugNetworkInterceptor interceptor, DebugNetworkInterceptor interceptor,
String account) { String account) {
this.context = context; this.context = context;
this.googleAccountManager = googleAccountManager; this.credentialsAdapter = credentialsAdapter;
this.preferences = preferences; this.preferences = preferences;
this.interceptor = interceptor; this.interceptor = interceptor;
this.account = account; this.account = account;
credential = new GoogleCredential();
service = service =
new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credential) new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credentialsAdapter)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME)) .setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build(); .build();
} }
public GtasksInvoker forAccount(String account) { public GtasksInvoker forAccount(String account) {
return new GtasksInvoker(context, googleAccountManager, preferences, interceptor, account); return new GtasksInvoker(context, credentialsAdapter, preferences, interceptor, account);
}
private void checkToken() {
if (credential != null && Strings.isNullOrEmpty(credential.getAccessToken())) {
credential.setAccessToken(googleAccountManager.getAccessToken(account, TasksScopes.TASKS));
}
} }
public @Nullable TaskLists allGtaskLists(@Nullable String pageToken) throws IOException { public @Nullable TaskLists allGtaskLists(@Nullable String pageToken) throws IOException {
@ -160,7 +148,7 @@ public class GtasksInvoker {
private synchronized @Nullable <T> T execute(TasksRequest<T> request, boolean retry) private synchronized @Nullable <T> T execute(TasksRequest<T> request, boolean retry)
throws IOException { throws IOException {
checkToken(); credentialsAdapter.checkToken(account, TasksScopes.TASKS);
T response; T response;
try { try {
HttpRequest httpRequest = request.buildHttpRequest(); HttpRequest httpRequest = request.buildHttpRequest();
@ -172,8 +160,7 @@ public class GtasksInvoker {
} }
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) { if (e.getStatusCode() == 401 && !retry) {
googleAccountManager.invalidateToken(credential.getAccessToken()); credentialsAdapter.invalidateToken();
credential.setAccessToken(null);
return execute(request, true); return execute(request, true);
} else if (e.getStatusCode() == 404) { } else if (e.getStatusCode() == 404) {
throw new HttpNotFoundException(e); throw new HttpNotFoundException(e);

@ -0,0 +1,76 @@
/*
* Copyright 2015, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.todoroo.astrid.gtasks.api
import com.google.api.client.http.HttpRequest
import com.google.api.client.http.HttpRequestInitializer
import com.google.auth.oauth2.AccessToken
import com.google.auth.oauth2.GoogleCredentials
import org.tasks.gtasks.GoogleAccountManager
import java.io.IOException
import java.net.URI
import java.util.*
import javax.inject.Inject
class HttpCredentialsAdapter @Inject constructor(private val googleAccountManager: GoogleAccountManager) : HttpRequestInitializer {
private var credentials: GoogleCredentials? = null
@Throws(IOException::class)
override fun initialize(request: HttpRequest) {
if (credentials == null || !credentials!!.hasRequestMetadata()) {
return
}
val requestHeaders = request.headers
var uri: URI? = null
if (request.url != null) {
uri = request.url.toURI()
}
val credentialHeaders = credentials!!.getRequestMetadata(uri) ?: return
for ((headerName, value) in credentialHeaders) {
val requestValues: MutableList<String> = ArrayList()
requestValues.addAll(value!!)
requestHeaders[headerName] = requestValues
}
}
fun checkToken(account: String?, scope: String) {
if (credentials == null) {
val token = googleAccountManager.getAccessToken(account, scope)
credentials = GoogleCredentials(AccessToken(token, null))
}
}
fun invalidateToken() {
googleAccountManager.invalidateToken(credentials?.accessToken?.tokenValue)
credentials = null
}
}

@ -4,7 +4,6 @@ import static com.todoroo.andlib.utility.DateUtilities.now;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException; import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.InputStreamContent; import com.google.api.client.http.InputStreamContent;
@ -15,7 +14,7 @@ import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveRequest; import com.google.api.services.drive.DriveRequest;
import com.google.api.services.drive.DriveScopes; import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.File;
import com.google.common.base.Strings; import com.todoroo.astrid.gtasks.api.HttpCredentialsAdapter;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -24,7 +23,6 @@ import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor; import org.tasks.DebugNetworkInterceptor;
import org.tasks.R; import org.tasks.R;
import org.tasks.files.FileHelper; import org.tasks.files.FileHelper;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ForApplication; import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import timber.log.Timber; import timber.log.Timber;
@ -35,35 +33,27 @@ public class DriveInvoker {
private final Context context; private final Context context;
private final Preferences preferences; private final Preferences preferences;
private final GoogleAccountManager googleAccountManager;
private final DebugNetworkInterceptor interceptor; private final DebugNetworkInterceptor interceptor;
private final Drive service; private final Drive service;
private final GoogleCredential credential = new GoogleCredential(); private final HttpCredentialsAdapter credentialsAdapter;
@Inject @Inject
public DriveInvoker( public DriveInvoker(
@ForApplication Context context, @ForApplication Context context,
Preferences preferences, Preferences preferences,
GoogleAccountManager googleAccountManager, HttpCredentialsAdapter credentialsAdapter,
DebugNetworkInterceptor interceptor) { DebugNetworkInterceptor interceptor) {
this.context = context; this.context = context;
this.preferences = preferences; this.preferences = preferences;
this.googleAccountManager = googleAccountManager; this.credentialsAdapter = credentialsAdapter;
this.interceptor = interceptor; this.interceptor = interceptor;
service = service =
new Drive.Builder(new NetHttpTransport(), new JacksonFactory(), credential) new Drive.Builder(new NetHttpTransport(), new JacksonFactory(), credentialsAdapter)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME)) .setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build(); .build();
} }
private void checkToken() {
if (Strings.isNullOrEmpty(credential.getAccessToken())) {
String account = preferences.getStringValue(R.string.p_google_drive_backup_account);
credential.setAccessToken(
googleAccountManager.getAccessToken(account, DriveScopes.DRIVE_FILE));
}
}
public File getFile(String folderId) throws IOException { public File getFile(String folderId) throws IOException {
return execute(service.files().get(folderId).setFields("id, trashed")); return execute(service.files().get(folderId).setFields("id, trashed"));
} }
@ -110,7 +100,8 @@ public class DriveInvoker {
} }
private synchronized <T> T execute(DriveRequest<T> request, boolean retry) throws IOException { private synchronized <T> T execute(DriveRequest<T> request, boolean retry) throws IOException {
checkToken(); String account = preferences.getStringValue(R.string.p_google_drive_backup_account);
credentialsAdapter.checkToken(account, DriveScopes.DRIVE_FILE);
Timber.d("%s request: %s", getCaller(), request); Timber.d("%s request: %s", getCaller(), request);
T response; T response;
try { try {
@ -123,8 +114,7 @@ public class DriveInvoker {
} }
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) { if (e.getStatusCode() == 401 && !retry) {
googleAccountManager.invalidateToken(credential.getAccessToken()); credentialsAdapter.invalidateToken();
credential.setAccessToken(null);
return execute(request, true); return execute(request, true);
} else { } else {
throw e; throw e;

Loading…
Cancel
Save