Skip to content

Commit fdee698

Browse files
[google_sign_in] Implement clearAuthorizationToken (#10024)
Platform interface portion of #9846 Part of flutter/flutter#173924 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 4f06c73 commit fdee698

File tree

26 files changed

+204
-20
lines changed

26 files changed

+204
-20
lines changed

packages/google_sign_in/google_sign_in_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 7.1.0
2+
3+
* Adds support for the `clearAuthorizationToken` method.
4+
15
## 7.0.5
26

37
* Adds support for `hostedDomain` when authenticating.

packages/google_sign_in/google_sign_in_android/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ dependencies {
7070
implementation 'androidx.credentials:credentials:1.5.0'
7171
implementation 'androidx.credentials:credentials-play-services-auth:1.5.0'
7272
implementation 'com.google.android.libraries.identity.googleid:googleid:1.1.1'
73-
implementation 'com.google.android.gms:play-services-auth:21.3.0'
73+
implementation 'com.google.android.gms:play-services-auth:21.4.0'
7474
testImplementation 'junit:junit:4.13.2'
7575
testImplementation 'org.mockito:mockito-inline:5.2.0'
7676
}

packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.android.gms.auth.api.identity.AuthorizationClient;
3333
import com.google.android.gms.auth.api.identity.AuthorizationRequest;
3434
import com.google.android.gms.auth.api.identity.AuthorizationResult;
35+
import com.google.android.gms.auth.api.identity.ClearTokenRequest;
3536
import com.google.android.gms.auth.api.identity.Identity;
3637
import com.google.android.gms.common.api.ApiException;
3738
import com.google.android.gms.common.api.Scope;
@@ -219,7 +220,7 @@ public void getCredential(
219220
return;
220221
}
221222

222-
// getCredentialAsync requires an acitivity context, not an application context, per
223+
// getCredentialAsync requires an activity context, not an application context, per
223224
// the API docs.
224225
Activity activity = getActivity();
225226
if (activity == null) {
@@ -337,17 +338,31 @@ public void clearCredentialState(@NonNull Function1<? super Result<Unit>, Unit>
337338
new CredentialManagerCallback<>() {
338339
@Override
339340
public void onResult(Void result) {
340-
ResultUtilsKt.completeWithClearCredentialStateSuccess(callback);
341+
ResultUtilsKt.completeWithUnitSuccess(callback);
341342
}
342343

343344
@Override
344345
public void onError(@NonNull ClearCredentialException e) {
345-
ResultUtilsKt.completeWithClearCredentialStateError(
346+
ResultUtilsKt.completeWithUnitError(
346347
callback, new FlutterError("Clear Failed", e.getMessage(), null));
347348
}
348349
});
349350
}
350351

352+
@Override
353+
public void clearAuthorizationToken(
354+
@NonNull String token, @NonNull Function1<? super Result<Unit>, Unit> callback) {
355+
authorizationClientFactory
356+
.create(context)
357+
.clearToken(ClearTokenRequest.builder().setToken(token).build())
358+
.addOnSuccessListener(unused -> ResultUtilsKt.completeWithUnitSuccess(callback))
359+
.addOnFailureListener(
360+
e ->
361+
ResultUtilsKt.completeWithUnitError(
362+
callback,
363+
new FlutterError("clearAuthorizationToken failed", e.getMessage(), null)));
364+
}
365+
351366
@Override
352367
public void authorize(
353368
@NonNull PlatformAuthorizationRequest params,

packages/google_sign_in/google_sign_in_android/android/src/main/kotlin/io/flutter/plugins/googlesignin/Messages.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ interface GoogleSignInApi {
606606
)
607607
/** Clears CredentialManager credential state. */
608608
fun clearCredentialState(callback: (Result<Unit>) -> Unit)
609+
/** Clears the authorization cache for the given token. */
610+
fun clearAuthorizationToken(token: String, callback: (Result<Unit>) -> Unit)
609611
/** Requests authorization tokens via AuthorizationClient. */
610612
fun authorize(
611613
params: PlatformAuthorizationRequest,
@@ -692,6 +694,29 @@ interface GoogleSignInApi {
692694
channel.setMessageHandler(null)
693695
}
694696
}
697+
run {
698+
val channel =
699+
BasicMessageChannel<Any?>(
700+
binaryMessenger,
701+
"dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.clearAuthorizationToken$separatedMessageChannelSuffix",
702+
codec)
703+
if (api != null) {
704+
channel.setMessageHandler { message, reply ->
705+
val args = message as List<Any?>
706+
val tokenArg = args[0] as String
707+
api.clearAuthorizationToken(tokenArg) { result: Result<Unit> ->
708+
val error = result.exceptionOrNull()
709+
if (error != null) {
710+
reply.reply(MessagesPigeonUtils.wrapError(error))
711+
} else {
712+
reply.reply(MessagesPigeonUtils.wrapResult(null))
713+
}
714+
}
715+
}
716+
} else {
717+
channel.setMessageHandler(null)
718+
}
719+
}
695720
run {
696721
val channel =
697722
BasicMessageChannel<Any?>(

packages/google_sign_in/google_sign_in_android/android/src/main/kotlin/io/flutter/plugins/googlesignin/ResultUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ fun completeWithGetCredentialFailure(
1818
callback(Result.success(failure))
1919
}
2020

21-
fun completeWithClearCredentialStateSuccess(callback: (Result<Unit>) -> Unit) {
21+
fun completeWithUnitSuccess(callback: (Result<Unit>) -> Unit) {
2222
callback(Result.success(Unit))
2323
}
2424

25-
fun completeWithClearCredentialStateError(callback: (Result<Unit>) -> Unit, failure: FlutterError) {
25+
fun completeWithUnitError(callback: (Result<Unit>) -> Unit, failure: FlutterError) {
2626
callback(Result.failure(failure))
2727
}
2828

packages/google_sign_in/google_sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.google.android.gms.auth.api.identity.AuthorizationClient;
4141
import com.google.android.gms.auth.api.identity.AuthorizationRequest;
4242
import com.google.android.gms.auth.api.identity.AuthorizationResult;
43+
import com.google.android.gms.auth.api.identity.ClearTokenRequest;
4344
import com.google.android.gms.common.api.ApiException;
4445
import com.google.android.gms.common.api.Status;
4546
import com.google.android.gms.tasks.OnSuccessListener;
@@ -71,6 +72,7 @@ public class GoogleSignInTest {
7172
@Mock CustomCredential mockGenericCredential;
7273
@Mock GoogleIdTokenCredential mockGoogleCredential;
7374
@Mock Task<AuthorizationResult> mockAuthorizationTask;
75+
@Mock Task<Void> mockClearTokenTask;
7476

7577
private GoogleSignInPlugin flutterPlugin;
7678
// Technically this is not the plugin, but in practice almost all of the functionality is in this
@@ -88,6 +90,8 @@ public void setUp() {
8890
.thenReturn(GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL);
8991
when(mockAuthorizationTask.addOnSuccessListener(any())).thenReturn(mockAuthorizationTask);
9092
when(mockAuthorizationTask.addOnFailureListener(any())).thenReturn(mockAuthorizationTask);
93+
when(mockClearTokenTask.addOnSuccessListener(any())).thenReturn(mockClearTokenTask);
94+
when(mockClearTokenTask.addOnFailureListener(any())).thenReturn(mockClearTokenTask);
9195
when(mockAuthorizationIntent.getIntentSender()).thenReturn(mockAuthorizationIntentSender);
9296
when(mockActivityPluginBinding.getActivity()).thenReturn(mockActivity);
9397

@@ -1144,4 +1148,29 @@ public void clearCredentialState_reportsFailure() {
11441148

11451149
callbackCaptor.getValue().onError(mock(ClearCredentialException.class));
11461150
}
1151+
1152+
@Test
1153+
public void clearAuthorizationToken_callsClient() {
1154+
final String testToken = "testToken";
1155+
when(mockAuthorizationClient.clearToken(any())).thenReturn(mockClearTokenTask);
1156+
plugin.clearAuthorizationToken(
1157+
testToken,
1158+
ResultCompat.asCompatCallback(
1159+
reply -> {
1160+
return null;
1161+
}));
1162+
1163+
ArgumentCaptor<ClearTokenRequest> authRequestCaptor =
1164+
ArgumentCaptor.forClass(ClearTokenRequest.class);
1165+
verify(mockAuthorizationClient).clearToken(authRequestCaptor.capture());
1166+
1167+
@SuppressWarnings("unchecked")
1168+
ArgumentCaptor<OnSuccessListener<Void>> callbackCaptor =
1169+
ArgumentCaptor.forClass(OnSuccessListener.class);
1170+
verify(mockClearTokenTask).addOnSuccessListener(callbackCaptor.capture());
1171+
callbackCaptor.getValue().onSuccess(null);
1172+
1173+
ClearTokenRequest request = authRequestCaptor.getValue();
1174+
assertEquals(testToken, request.getToken());
1175+
}
11471176
}

packages/google_sign_in/google_sign_in_android/example/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dependencies:
1616
# The example app is bundled with the plugin so we use a path dependency on
1717
# the parent directory to use the current plugin's version.
1818
path: ../
19-
google_sign_in_platform_interface: ^3.0.0
19+
google_sign_in_platform_interface: ^3.1.0
2020
http: ">=0.13.0 <2.0.0"
2121

2222
dev_dependencies:

packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class GoogleSignInAndroid extends GoogleSignInPlatform {
2727
GoogleSignInPlatform.instance = GoogleSignInAndroid();
2828
}
2929

30+
@override
31+
Future<void> clearAuthorizationToken(ClearAuthorizationTokenParams params) {
32+
return _hostApi.clearAuthorizationToken(params.accessToken);
33+
}
34+
3035
@override
3136
Future<void> init(InitParameters params) async {
3237
_hostedDomain = params.hostedDomain;

packages/google_sign_in/google_sign_in_android/lib/src/messages.g.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,34 @@ class GoogleSignInApi {
713713
}
714714
}
715715

716+
/// Clears the authorization cache for the given token.
717+
Future<void> clearAuthorizationToken(String token) async {
718+
final String pigeonVar_channelName =
719+
'dev.flutter.pigeon.google_sign_in_android.GoogleSignInApi.clearAuthorizationToken$pigeonVar_messageChannelSuffix';
720+
final BasicMessageChannel<Object?> pigeonVar_channel =
721+
BasicMessageChannel<Object?>(
722+
pigeonVar_channelName,
723+
pigeonChannelCodec,
724+
binaryMessenger: pigeonVar_binaryMessenger,
725+
);
726+
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
727+
<Object?>[token],
728+
);
729+
final List<Object?>? pigeonVar_replyList =
730+
await pigeonVar_sendFuture as List<Object?>?;
731+
if (pigeonVar_replyList == null) {
732+
throw _createConnectionError(pigeonVar_channelName);
733+
} else if (pigeonVar_replyList.length > 1) {
734+
throw PlatformException(
735+
code: pigeonVar_replyList[0]! as String,
736+
message: pigeonVar_replyList[1] as String?,
737+
details: pigeonVar_replyList[2],
738+
);
739+
} else {
740+
return;
741+
}
742+
}
743+
716744
/// Requests authorization tokens via AuthorizationClient.
717745
Future<AuthorizeResult> authorize(
718746
PlatformAuthorizationRequest params, {

packages/google_sign_in/google_sign_in_android/pigeons/messages.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ abstract class GoogleSignInApi {
196196
@async
197197
void clearCredentialState();
198198

199+
/// Clears the authorization cache for the given token.
200+
@async
201+
void clearAuthorizationToken(String token);
202+
199203
/// Requests authorization tokens via AuthorizationClient.
200204
@async
201205
AuthorizeResult authorize(

0 commit comments

Comments
 (0)