Use google-auth-library-java

pull/935/head
Alex Baker 5 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-drive:v3-rev20191108-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("com.mapbox.mapboxsdk:mapbox-android-sdk:7.3.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 =
new FlipperHttpInterceptor<>(getNetworkPlugin(context), responseClass);
request
.setInterceptor(new ChainedHttpExecuteInterceptor(request.getInterceptor(), interceptor))
.setInterceptor(interceptor)
.setResponseInterceptor(interceptor)
.execute();
return interceptor.getResponse();

@ -2,7 +2,6 @@ package com.todoroo.astrid.gtasks.api;
import android.content.Context;
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.HttpResponseException;
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.TaskList;
import com.google.api.services.tasks.model.TaskLists;
import com.google.common.base.Strings;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
@ -33,55 +30,46 @@ import timber.log.Timber;
public class GtasksInvoker {
private final Context context;
private final GoogleAccountManager googleAccountManager;
private final Preferences preferences;
private final DebugNetworkInterceptor interceptor;
@Nullable private final GoogleCredential credential;
private final String account;
private final Tasks service;
private final HttpCredentialsAdapter credentialsAdapter;
@Inject
public GtasksInvoker(
@ForApplication Context context,
GoogleAccountManager googleAccountManager,
HttpCredentialsAdapter credentialsAdapter,
Preferences preferences,
DebugNetworkInterceptor interceptor) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.credentialsAdapter = credentialsAdapter;
this.preferences = preferences;
this.interceptor = interceptor;
account = null;
service = null;
credential = null;
}
private GtasksInvoker(
Context context,
GoogleAccountManager googleAccountManager,
HttpCredentialsAdapter credentialsAdapter,
Preferences preferences,
DebugNetworkInterceptor interceptor,
String account) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.credentialsAdapter = credentialsAdapter;
this.preferences = preferences;
this.interceptor = interceptor;
this.account = account;
credential = new GoogleCredential();
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))
.build();
}
public GtasksInvoker forAccount(String account) {
return new GtasksInvoker(context, googleAccountManager, preferences, interceptor, account);
}
private void checkToken() {
if (credential != null && Strings.isNullOrEmpty(credential.getAccessToken())) {
credential.setAccessToken(googleAccountManager.getAccessToken(account, TasksScopes.TASKS));
}
return new GtasksInvoker(context, credentialsAdapter, preferences, interceptor, account);
}
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)
throws IOException {
checkToken();
credentialsAdapter.checkToken(account, TasksScopes.TASKS);
T response;
try {
HttpRequest httpRequest = request.buildHttpRequest();
@ -172,8 +160,7 @@ public class GtasksInvoker {
}
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) {
googleAccountManager.invalidateToken(credential.getAccessToken());
credential.setAccessToken(null);
credentialsAdapter.invalidateToken();
return execute(request, true);
} else if (e.getStatusCode() == 404) {
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.net.Uri;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
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.DriveScopes;
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.util.Collections;
import java.util.List;
@ -24,7 +23,6 @@ import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor;
import org.tasks.R;
import org.tasks.files.FileHelper;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
@ -35,35 +33,27 @@ public class DriveInvoker {
private final Context context;
private final Preferences preferences;
private final GoogleAccountManager googleAccountManager;
private final DebugNetworkInterceptor interceptor;
private final Drive service;
private final GoogleCredential credential = new GoogleCredential();
private final HttpCredentialsAdapter credentialsAdapter;
@Inject
public DriveInvoker(
@ForApplication Context context,
Preferences preferences,
GoogleAccountManager googleAccountManager,
HttpCredentialsAdapter credentialsAdapter,
DebugNetworkInterceptor interceptor) {
this.context = context;
this.preferences = preferences;
this.googleAccountManager = googleAccountManager;
this.credentialsAdapter = credentialsAdapter;
this.interceptor = interceptor;
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))
.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 {
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 {
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);
T response;
try {
@ -123,8 +114,7 @@ public class DriveInvoker {
}
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) {
googleAccountManager.invalidateToken(credential.getAccessToken());
credential.setAccessToken(null);
credentialsAdapter.invalidateToken();
return execute(request, true);
} else {
throw e;

Loading…
Cancel
Save