From 04d34125c0e4ff440d12ed6301fb786b71103c7b Mon Sep 17 00:00:00 2001 From: Adrian Frajham Date: Thu, 9 Jan 2025 18:45:53 +0100 Subject: [PATCH] IDE-280 Update google login API IDE-280 Fix google login API implementation IDE-280 Add authorization with backend server IDE-280 Fix empty scope --- build.gradle | 4 +- catroid/build.gradle | 17 +- catroid/proguard-project.txt | 6 + .../transfers/GoogleExchangeCodeTask.java | 1 + .../catroid/transfers/GoogleLoginHandler.java | 202 +++++++++++++----- .../transfers/GoogleVerifyUserTask.java | 84 ++++++++ .../catrobat/catroid/ui/SignInActivity.java | 14 +- .../login/OAuthUsernameDialogFragment.java | 2 +- .../org/catrobat/catroid/utils/Utils.java | 13 +- 9 files changed, 268 insertions(+), 75 deletions(-) create mode 100644 catroid/src/main/java/org/catrobat/catroid/transfers/GoogleVerifyUserTask.java diff --git a/build.gradle b/build.gradle index 3aa1f847ae2..e17c1f95ae4 100644 --- a/build.gradle +++ b/build.gradle @@ -24,9 +24,9 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.6.21' + ext.kotlin_version = '1.8.22' ext.koin_version = '2.1.6' - ext.lifecycle_version = '2.2.0' + ext.lifecycle_version = '2.5.0' ext.jacoco_core_version = '0.8.7' repositories { google() diff --git a/catroid/build.gradle b/catroid/build.gradle index 2a48bc34023..53e3d46d036 100644 --- a/catroid/build.gradle +++ b/catroid/build.gradle @@ -29,7 +29,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.google.gms:google-services:4.3.10' + classpath 'com.google.gms:google-services:4.4.2' } } @@ -200,7 +200,9 @@ android { excludes += ['lib/mips/*', 'lib/armeabi/*'] } resources { - excludes += ['LICENSE.txt', 'META-INF/LICENSE.md', 'META-INF/INDEX.LIST', 'lib/mips/*', 'lib/armeabi/*'] + excludes += ['LICENSE.txt', 'META-INF/DEPENDENCIES', 'META-INF/LICENSE.md', + 'META-INF/INDEX.LIST', + 'lib/mips/*', 'lib/armeabi/*'] } } @@ -381,6 +383,9 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.mediarouter:mediarouter:1.1.0' implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.credentials:credentials:1.3.0' + implementation 'androidx.credentials:credentials-play-services-auth:1.3.0' + implementation 'com.google.android.libraries.identity.googleid:googleid:1.1.1' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.browser:browser:1.2.0' implementation 'androidx.core:core-ktx:1.3.2' @@ -409,7 +414,6 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.11.0' // Lifecycle - implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" @@ -439,6 +443,11 @@ dependencies { exclude group: 'xmlpull' } + // Client + implementation 'com.google.api-client:google-api-client:2.7.0' + implementation 'com.google.oauth-client:google-oauth-client:1.37.0' + implementation 'com.google.http-client:google-http-client-jackson2:1.42.0' + // Catblocks implementation "androidx.webkit:webkit:1.2.0" @@ -482,7 +491,7 @@ dependencies { natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a" natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-arm64-v8a" - implementation "com.google.android.gms:play-services-auth:17.0.0" + implementation "com.google.android.gms:play-services-auth:20.6.0" androidTestImplementation('tools.fastlane:screengrab:2.1.1') { // https://issuetracker.google.com/issues/123060356 diff --git a/catroid/proguard-project.txt b/catroid/proguard-project.txt index fb84b55e877..a2f1cc453df 100644 --- a/catroid/proguard-project.txt +++ b/catroid/proguard-project.txt @@ -52,3 +52,9 @@ public static int d(...); public static int e(...); } + +# Credentials Manager +-if class androidx.credentials.CredentialManager +-keep class androidx.credentials.playservices.** { + *; +} diff --git a/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleExchangeCodeTask.java b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleExchangeCodeTask.java index cd661ff3107..841b55f1b88 100644 --- a/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleExchangeCodeTask.java +++ b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleExchangeCodeTask.java @@ -25,6 +25,7 @@ import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; +import android.content.Intent; import android.os.AsyncTask; import android.util.Log; diff --git a/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleLoginHandler.java b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleLoginHandler.java index b628f34392f..a28ee57d27d 100644 --- a/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleLoginHandler.java +++ b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleLoginHandler.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2025 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -23,82 +23,132 @@ package org.catrobat.catroid.transfers; +import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.CancellationSignal; import android.preference.PreferenceManager; +import android.util.Log; -import com.google.android.gms.auth.api.signin.GoogleSignInAccount; -import com.google.android.gms.auth.api.signin.GoogleSignInClient; -import com.google.android.gms.auth.api.signin.GoogleSignInOptions; -import com.google.android.gms.tasks.Task; +import com.google.android.gms.auth.api.identity.AuthorizationClient; +import com.google.android.gms.auth.api.identity.AuthorizationRequest; +import com.google.android.gms.auth.api.identity.AuthorizationResult; +import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.ApiException; +import com.google.android.gms.common.api.Scope; +import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption; +import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential; import org.catrobat.catroid.R; import org.catrobat.catroid.common.Constants; +import org.catrobat.catroid.ui.BaseActivity; import org.catrobat.catroid.ui.recyclerview.dialog.login.OAuthUsernameDialogFragment; import org.catrobat.catroid.ui.recyclerview.dialog.login.SignInCompleteListener; import org.catrobat.catroid.utils.DeviceSettingsProvider; import org.catrobat.catroid.utils.ToastUtil; -import androidx.appcompat.app.AppCompatActivity; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.Executor; -import static com.google.android.gms.auth.api.signin.GoogleSignIn.getClient; -import static com.google.android.gms.auth.api.signin.GoogleSignIn.getSignedInAccountFromIntent; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; +import androidx.credentials.Credential; +import androidx.credentials.CredentialManager; +import androidx.credentials.CredentialManagerCallback; +import androidx.credentials.GetCredentialRequest; +import androidx.credentials.GetCredentialResponse; +import androidx.credentials.exceptions.GetCredentialException; import static org.catrobat.catroid.web.ServerAuthenticationConstants.GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID; -public class GoogleLoginHandler implements CheckOAuthTokenTask.OnCheckOAuthTokenCompleteListener, - GoogleLogInTask.OnGoogleServerLogInCompleteListener, +public class GoogleLoginHandler extends BaseActivity implements GoogleLogInTask.OnGoogleServerLogInCompleteListener, CheckEmailAvailableTask.OnCheckEmailAvailableCompleteListener, + CheckOAuthTokenTask.OnCheckOAuthTokenCompleteListener, + GoogleVerifyUserTask.OnGoogleVerifyUserCompleteListener, GoogleExchangeCodeTask.OnGoogleExchangeCodeCompleteListener { + public static final int REQUEST_CODE_GOOGLE_AUTHORIZATION = 111; + private AppCompatActivity activity; - public static final int REQUEST_CODE_GOOGLE_SIGNIN = 100; - private GoogleSignInClient googleSignInClient; @SuppressWarnings("RestrictedApi") public GoogleLoginHandler(AppCompatActivity activity) { this.activity = activity; - - GoogleSignInOptions googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) - .requestEmail() - .requestIdToken(GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID) - .build(); - googleSignInClient = getClient(this.activity, googleSignInOptions); } - public GoogleSignInClient getGoogleSignInClient() { - return googleSignInClient; - } + public void signInWithGoogle() { + CredentialManager credentialManager = CredentialManager.create(activity); - @SuppressWarnings("RestrictedApi") - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_CODE_GOOGLE_SIGNIN) { - Task task = getSignedInAccountFromIntent(data); - if (task.isSuccessful()) { - onGoogleLogInComplete(task.getResult()); - } else { - ToastUtil.showError(activity, - String.format(activity.getString(R.string.error_google_plus_sign_in), task.getException().getLocalizedMessage().replace(":", ""))); + StringBuilder hashedNonce = new StringBuilder(); + try { + String rawNonce = UUID.randomUUID().toString(); + byte[] bytes = rawNonce.getBytes(); + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] digest = md.digest(bytes); + + for (byte b : digest) { + hashedNonce.append(String.format("%02x", b)); } + } catch (Exception e) { + Log.i("Google", "Creating nonce has failed."); + e.printStackTrace(); } + + GetSignInWithGoogleOption googleSignInOption = + new GetSignInWithGoogleOption.Builder(GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID) + .setNonce(hashedNonce.toString()) + .build(); + GetCredentialRequest credentialRequest = new GetCredentialRequest.Builder() + .addCredentialOption(googleSignInOption) + .build(); + Executor executor = ContextCompat.getMainExecutor(activity); + CancellationSignal cancellationSignal = new CancellationSignal(); + GoogleLoginHandler googleLoginHandler = this; + credentialManager.getCredentialAsync( + activity, + credentialRequest, + cancellationSignal, + executor, + new CredentialManagerCallback() { + @Override + public void onResult(GetCredentialResponse getCredentialResponse) { + Credential credential = getCredentialResponse.getCredential(); + GoogleIdTokenCredential tokenCredential = + GoogleIdTokenCredential.createFrom(credential.getData()); + + GoogleVerifyUserTask googleVerifyUserTask = new GoogleVerifyUserTask(tokenCredential); + googleVerifyUserTask.setOnGoogleVerifyUserCompleteListener(googleLoginHandler); + googleVerifyUserTask.execute(); + } + + @Override + public void onError(@NonNull GetCredentialException e) { + ToastUtil.showError(activity, + String.format(activity.getString(R.string.error_google_plus_sign_in), e.getLocalizedMessage().replace(":", ""))); + e.printStackTrace(); + } + } + ); } - public void onGoogleLogInComplete(GoogleSignInAccount account) { + @Override + public void onGoogleVerifyUserComplete(GoogleIdTokenCredential account, String googleEmail) { String id = account.getId(); String personName = account.getDisplayName(); - String email = account.getEmail(); String locale = DeviceSettingsProvider.getUserCountryCode(); String idToken = account.getIdToken(); - String code = account.getServerAuthCode(); PreferenceManager.getDefaultSharedPreferences(activity).edit() .putString(Constants.GOOGLE_ID, id) .putString(Constants.GOOGLE_USERNAME, personName) - .putString(Constants.GOOGLE_EMAIL, email) + .putString(Constants.GOOGLE_EMAIL, googleEmail) .putString(Constants.GOOGLE_LOCALE, locale) .putString(Constants.GOOGLE_ID_TOKEN, idToken) - .putString(Constants.GOOGLE_EXCHANGE_CODE, code) .apply(); CheckOAuthTokenTask checkOAuthTokenTask = new CheckOAuthTokenTask(activity, id, Constants.GOOGLE_PLUS); @@ -125,23 +175,62 @@ public void onCheckOAuthTokenComplete(Boolean tokenAvailable, String provider) { } } - @Override - public void onGoogleServerLogInComplete() { - Bundle bundle = new Bundle(); - bundle.putString(Constants.CURRENT_OAUTH_PROVIDER, Constants.GOOGLE_PLUS); - ((SignInCompleteListener) activity).onLoginSuccessful(bundle); - } - @Override public void onCheckEmailAvailableComplete(Boolean emailAvailable, String provider) { if (emailAvailable) { - exchangeGoogleAuthorizationCode(); + authorizeGoogleUser(); } else { showOauthUserNameDialog(Constants.GOOGLE_PLUS); } } - public void exchangeGoogleAuthorizationCode() { + public void authorizeGoogleUser() { + AuthorizationRequest authorizationRequest = new AuthorizationRequest.Builder() + .requestOfflineAccess(GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID) + .setRequestedScopes(List.of( + new Scope("https://www.googleapis.com/auth/userinfo.email") // Request email scope + )) + .build(); + + AuthorizationClient authorizationClient = Identity.getAuthorizationClient(activity); + authorizationClient.authorize(authorizationRequest).addOnSuccessListener(authorizationResult -> { + if (authorizationResult.hasResolution()) { + try { + authorizationResult.getPendingIntent().send(REQUEST_CODE_GOOGLE_AUTHORIZATION); + } catch (Exception e) { + Log.e("Google", "Failed to start authorization UI: " + e.getLocalizedMessage()); + } + } else { + PreferenceManager.getDefaultSharedPreferences(activity).edit() + .putString(Constants.GOOGLE_EXCHANGE_CODE, authorizationResult.getServerAuthCode()) + .apply(); + exchangeGoogleServerAuthCode(); + } + }).addOnFailureListener(e -> Log.e("Google", "Authorization failed", e)); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_CODE_GOOGLE_AUTHORIZATION && resultCode == Activity.RESULT_OK) { + AuthorizationClient authorizationClient = Identity.getAuthorizationClient(this); + AuthorizationResult authorizationResult; + + try { + authorizationResult = authorizationClient.getAuthorizationResultFromIntent(data); + } catch (ApiException e) { + throw new RuntimeException(e); + } + + PreferenceManager.getDefaultSharedPreferences(activity).edit() + .putString(Constants.GOOGLE_EXCHANGE_CODE, authorizationResult.getServerAuthCode()) + .apply(); + exchangeGoogleServerAuthCode(); + } + } + + private void exchangeGoogleServerAuthCode() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity); GoogleExchangeCodeTask googleExchangeCodeTask = new GoogleExchangeCodeTask(activity, sharedPreferences.getString(Constants.GOOGLE_EXCHANGE_CODE, Constants.NO_GOOGLE_EXCHANGE_CODE), @@ -154,15 +243,6 @@ public void exchangeGoogleAuthorizationCode() { googleExchangeCodeTask.execute(); } - private void showOauthUserNameDialog(String provider) { - OAuthUsernameDialogFragment dialog = new OAuthUsernameDialogFragment(); - Bundle bundle = new Bundle(); - bundle.putString(Constants.CURRENT_OAUTH_PROVIDER, provider); - dialog.setArguments(bundle); - dialog.setSignInCompleteListener((SignInCompleteListener) activity); - dialog.show(activity.getSupportFragmentManager(), OAuthUsernameDialogFragment.TAG); - } - @Override public void onGoogleExchangeCodeComplete() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity); @@ -174,4 +254,20 @@ public void onGoogleExchangeCodeComplete() { googleLogInTask.setOnGoogleServerLogInCompleteListener(this); googleLogInTask.execute(); } + + @Override + public void onGoogleServerLogInComplete() { + Bundle bundle = new Bundle(); + bundle.putString(Constants.CURRENT_OAUTH_PROVIDER, Constants.GOOGLE_PLUS); + ((SignInCompleteListener) activity).onLoginSuccessful(bundle); + } + + private void showOauthUserNameDialog(String provider) { + OAuthUsernameDialogFragment dialog = new OAuthUsernameDialogFragment(); + Bundle bundle = new Bundle(); + bundle.putString(Constants.CURRENT_OAUTH_PROVIDER, provider); + dialog.setArguments(bundle); + dialog.setSignInCompleteListener((SignInCompleteListener) activity); + dialog.show(activity.getSupportFragmentManager(), OAuthUsernameDialogFragment.TAG); + } } diff --git a/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleVerifyUserTask.java b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleVerifyUserTask.java new file mode 100644 index 00000000000..4137d7be13b --- /dev/null +++ b/catroid/src/main/java/org/catrobat/catroid/transfers/GoogleVerifyUserTask.java @@ -0,0 +1,84 @@ +/* + * Catroid: An on-device visual programming system for Android devices + * Copyright (C) 2010-2025 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * An additional term exception under section 7 of the GNU Affero + * General Public License, version 3, is available at + * http://developer.catrobat.org/license_additional_term + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.catrobat.catroid.transfers; + +import android.os.AsyncTask; +import android.util.Log; + +import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.gson.GsonFactory; + +import java.util.List; + +import static org.catrobat.catroid.web.ServerAuthenticationConstants.GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID; + +public class GoogleVerifyUserTask extends AsyncTask { + private static final String TAG = GoogleVerifyUserTask.class.getSimpleName(); + + private GoogleIdTokenCredential account; + private String email; + + private OnGoogleVerifyUserCompleteListener onGoogleVerifyUserCompleteListener; + + public GoogleVerifyUserTask(GoogleIdTokenCredential account) { + this.account = account; + } + + public void setOnGoogleVerifyUserCompleteListener(OnGoogleVerifyUserCompleteListener listener) { + onGoogleVerifyUserCompleteListener = listener; + } + + @Override + protected Boolean doInBackground(String... params) { + try { + HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); + GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(httpTransport, new GsonFactory()) + .setAudience(List.of(GOOGLE_LOGIN_CATROWEB_SERVER_CLIENT_ID)) + .build(); + GoogleIdToken googleIdToken = verifier.verify(account.getIdToken()); + email = googleIdToken.getPayload().getEmail(); + return true; + } catch (Exception e) { + Log.e("Google", "Google account verification failed: ", e); + } + return false; + } + + @Override + protected void onPostExecute(Boolean success) { + super.onPostExecute(success); + + if (onGoogleVerifyUserCompleteListener != null) { + onGoogleVerifyUserCompleteListener.onGoogleVerifyUserComplete(account, email); + } + } + + public interface OnGoogleVerifyUserCompleteListener { + void onGoogleVerifyUserComplete(GoogleIdTokenCredential account, String googleEmail); + } +} diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/SignInActivity.java b/catroid/src/main/java/org/catrobat/catroid/ui/SignInActivity.java index b231d4d62b3..6bbbf92cfca 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/SignInActivity.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/SignInActivity.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2025 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify @@ -24,6 +24,7 @@ package org.catrobat.catroid.ui; import android.content.Intent; + import android.os.Bundle; import android.text.Html; import android.text.method.LinkMovementMethod; @@ -38,8 +39,6 @@ import org.catrobat.catroid.ui.recyclerview.dialog.login.SignInCompleteListener; import org.catrobat.catroid.utils.Utils; -import static org.catrobat.catroid.transfers.GoogleLoginHandler.REQUEST_CODE_GOOGLE_SIGNIN; - public class SignInActivity extends BaseActivity implements SignInCompleteListener { public static final String LOGIN_SUCCESSFUL = "LOGIN_SUCCESSFUL"; @@ -83,20 +82,13 @@ private void onButtonClickForRealThisTime(View view) { registrationDialog.show(getSupportFragmentManager(), RegistrationDialogFragment.TAG); break; case R.id.sign_in_google_login_button: - startActivityForResult(googleLoginHandler.getGoogleSignInClient().getSignInIntent(), REQUEST_CODE_GOOGLE_SIGNIN); + googleLoginHandler.signInWithGoogle(); break; default: break; } } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - googleLoginHandler.onActivityResult(requestCode, resultCode, data); - - super.onActivityResult(requestCode, resultCode, data); - } - @Override public void onLoginSuccessful(Bundle bundle) { Intent intent = new Intent(); diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/dialog/login/OAuthUsernameDialogFragment.java b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/dialog/login/OAuthUsernameDialogFragment.java index 2728bdbdafe..1fc5c180ef9 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/dialog/login/OAuthUsernameDialogFragment.java +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/dialog/login/OAuthUsernameDialogFragment.java @@ -1,6 +1,6 @@ /* * Catroid: An on-device visual programming system for Android devices - * Copyright (C) 2010-2022 The Catrobat Team + * Copyright (C) 2010-2025 The Catrobat Team * () * * This program is free software: you can redistribute it and/or modify diff --git a/catroid/src/main/java/org/catrobat/catroid/utils/Utils.java b/catroid/src/main/java/org/catrobat/catroid/utils/Utils.java index 0834baba8d6..b3a8afe375c 100644 --- a/catroid/src/main/java/org/catrobat/catroid/utils/Utils.java +++ b/catroid/src/main/java/org/catrobat/catroid/utils/Utils.java @@ -40,6 +40,7 @@ import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import com.google.android.gms.auth.GoogleAuthUtil; import com.google.common.base.Splitter; import com.huawei.hms.mlsdk.asr.MLAsrConstants; @@ -53,7 +54,6 @@ import org.catrobat.catroid.formulaeditor.SensorHandler; import org.catrobat.catroid.io.StorageOperations; import org.catrobat.catroid.io.XstreamSerializer; -import org.catrobat.catroid.transfers.GoogleLoginHandler; import org.catrobat.catroid.ui.WebViewActivity; import org.catrobat.catroid.web.WebConnectionException; import org.json.JSONException; @@ -74,7 +74,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import androidx.appcompat.app.AppCompatActivity; import androidx.exifinterface.media.ExifInterface; import okhttp3.Response; @@ -479,8 +478,14 @@ public static void invalidateLoginTokenIfUserRestricted(Context context) { public static void logoutUser(Context context) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); - GoogleLoginHandler googleLoginHandler = new GoogleLoginHandler((AppCompatActivity) context); - googleLoginHandler.getGoogleSignInClient().signOut(); + + String token = sharedPreferences.getString(Constants.TOKEN, Constants.NO_TOKEN); + try { + GoogleAuthUtil.clearToken(context, token); + } catch (Exception e) { + Log.i("Google", "Logging out failed."); + } + sharedPreferences.edit() .putString(Constants.TOKEN, Constants.NO_TOKEN) .putString(Constants.USERNAME, Constants.NO_USERNAME)