package com.thebluealliance.androidclient.auth.google; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.auth.api.signin.GoogleSignInResult; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.OptionalPendingResult; import com.google.firebase.auth.AuthCredential; import com.thebluealliance.androidclient.TbaLogger; import com.thebluealliance.androidclient.accounts.AccountController; import com.thebluealliance.androidclient.auth.AuthProvider; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; import javax.inject.Inject; import javax.inject.Singleton; import rx.Observable; @Singleton public class GoogleAuthProvider implements AuthProvider, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks { private final Context mContext; private final AccountController mAccountController; private @Nullable GoogleApiClient mGoogleApiClient; private @Nullable GoogleSignInUser mCurrentUser; @Inject public GoogleAuthProvider(Context context, AccountController accountController) { mCurrentUser = null; mAccountController = accountController; mContext = context; } private void loadGoogleApiClient() { String clientId = mAccountController.getWebClientId(); if (clientId.isEmpty()) { // No client id set in tba.properties, can't continue TbaLogger.w("Oauth client ID not set, can't enable myTBA. See https://goo.gl/Swp5PC " + "for config details"); mGoogleApiClient = null; return; } GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .requestIdToken(clientId) .build(); mGoogleApiClient = new GoogleApiClient.Builder(mContext) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); } public AuthCredential getAuthCredential(String idToken) { return com.google.firebase.auth.GoogleAuthProvider.getCredential(idToken, null); } @Override public void onStart() { if (mGoogleApiClient != null && !mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } @Override public void onStop() { if (mGoogleApiClient != null && !mGoogleApiClient.isConnecting() && mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } @Override public boolean isUserSignedIn() { return mCurrentUser != null; } @Nullable @Override public GoogleSignInUser getCurrentUser() { return mCurrentUser; } @Nullable @Override public Intent buildSignInIntent() { if (mGoogleApiClient == null) { // Lazy load the API client, if needed loadGoogleApiClient(); } if (mGoogleApiClient != null) { return Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); } // If we still can't get the API client, just give up return null; } @Override public Observable<GoogleSignInUser> userFromSignInResult(int requestCode, int resultCode, Intent data) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); boolean success = result.isSuccess(); TbaLogger.d("Google Sign In Result: " + success); if (success) { mCurrentUser = new GoogleSignInUser(result.getSignInAccount()); } return Observable.just(mCurrentUser); } @WorkerThread public Observable<GoogleSignInUser> signInLegacyUser() { if (mGoogleApiClient == null) { TbaLogger.i("Lazy loading Google API Client for legacy sign in"); loadGoogleApiClient(); } if (mGoogleApiClient == null) { TbaLogger.i("Unable to get API Client for legacy sign in"); return Observable.empty(); } onStart(); OptionalPendingResult<GoogleSignInResult> optionalResult = Auth.GoogleSignInApi .silentSignIn(mGoogleApiClient); GoogleSignInResult result = optionalResult.await(); onStop(); if (result.isSuccess()) { return Observable.just(new GoogleSignInUser(result.getSignInAccount())); } else { TbaLogger.w("Unable to complete legacy sign in: " + result.getStatus().getStatusMessage()); } return Observable.empty(); } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { TbaLogger.w("Google API client connection failed"); TbaLogger.w(connectionResult.getErrorMessage()); } @Override public void onConnected(@Nullable Bundle bundle) { TbaLogger.d("Google API client connected"); } @Override public void onConnectionSuspended(int i) { } }