Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 6.2.1

* Fixes a bug that would cause `serverAuthorizationTokensForScopes` to
return null even when called for a user that had just authenticated.

## 6.2.0

* Adds support for the `clearAuthorizationToken` method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ class GoogleSignInIOS extends GoogleSignInPlatform {

String? _nonce;

/// The last server auth code returned when authenticating or adding scopes.
///
/// The SDK only returns an auth code when doing a new authentication or
/// when first adding new scopes; later calls to get refreshed tokens will not
/// provide the server auth code again. Because this plugin separates out
/// separate calls for authn, client authz, and server authz, the server auth
/// token needs to be cached when it was returned so that it can be returned
/// later in the session.
///
/// There is a small risk of returning an expired server auth token this way,
/// but the plugin docs are clear that clients should obtain the server auth
/// token immediately, and not rely on it continuing to be valid later.
String? _cachedServerAuthCode;

/// The user identifier for the cached server auth code, to ensure that a
/// cached code isn't returned across users.
String? _cachedServerAuthCodeUserId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache doesn't seem to be invalidated on logout?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! For signOut it's probably harmless since the grant should still be active, but it definitely shouldn't be returned after disconnect, and since I can't think of any reason someone should expect to get it after signOut I'll go ahead and clear it there.

Also added cache unit tests for both signOut and disconnect that would have caught this.


/// Registers this class as the default instance of [GoogleSignInPlatform].
static void registerWith() {
GoogleSignInPlatform.instance = GoogleSignInIOS();
Expand Down Expand Up @@ -70,7 +88,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
Future<AuthenticationResults> authenticate(
AuthenticateParameters params,
) async {
final SignInResult result = await _api.signIn(params.scopeHint, _nonce);
final SignInResult result = await _signIn(params.scopeHint, _nonce);

// This should never happen; the corresponding native error code is
// documented as being specific to restorePreviousSignIn.
Expand Down Expand Up @@ -100,6 +118,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {

@override
Future<void> signOut(SignOutParams params) {
_updateAuthCodeCache(null);
return _api.signOut();
}

Expand Down Expand Up @@ -155,7 +174,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
// There's no existing sign-in to use, so return the results of the
// combined authn+authz flow, if prompting is allowed.
if (request.promptIfUnauthorized) {
result = await _api.signIn(request.scopes, _nonce);
result = await _signIn(request.scopes, _nonce);
return _processAuthorizationResult(result);
} else {
// No existing authentication, and no prompting allowed, so return
Expand All @@ -174,7 +193,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
SignInResult result =
useExistingAuthorization
? await _api.getRefreshedAuthorizationTokens(userId)
: await _api.addScopes(request.scopes, userId);
: await _addScopes(request.scopes, userId);
if (!useExistingAuthorization &&
result.error?.type == GoogleSignInErrorCode.scopesAlreadyGranted) {
// The Google Sign In SDK returns an error when requesting scopes that are
Expand Down Expand Up @@ -230,6 +249,28 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
return _authorizationTokenDataFromSignInSuccess(result.success);
}

Future<SignInResult> _signIn(List<String> scopeHint, String? nonce) async {
final SignInResult result = await _api.signIn(scopeHint, nonce);
_updateAuthCodeCache(result.success);
return result;
}

Future<SignInResult> _addScopes(List<String> scopes, String userId) async {
final SignInResult result = await _api.addScopes(scopes, userId);
// Don't clear the cache for GoogleSignInErrorCode.scopesAlreadyGranted
// since that indicates that nothing has changed. Otherwise, update the
// cache (with a new token on success, or clearing on failure).
if (result.error?.type != GoogleSignInErrorCode.scopesAlreadyGranted) {
_updateAuthCodeCache(result.success);
}
return result;
}

void _updateAuthCodeCache(SignInSuccess? success) {
_cachedServerAuthCode = success?.serverAuthCode;
_cachedServerAuthCodeUserId = success?.user.userId;
}

AuthenticationResults _authenticationResultsFromSignInSuccess(
SignInSuccess result,
) {
Expand All @@ -248,9 +289,15 @@ class GoogleSignInIOS extends GoogleSignInPlatform {

({String? accessToken, String? serverAuthCode})
_authorizationTokenDataFromSignInSuccess(SignInSuccess? result) {
// Check for a relevant cached auth code to add if needed.
final String? cachedAuthCode =
result != null && result.user.userId == _cachedServerAuthCodeUserId
? _cachedServerAuthCode
: null;

return (
accessToken: result?.accessToken,
serverAuthCode: result?.serverAuthCode,
serverAuthCode: result?.serverAuthCode ?? cachedAuthCode,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ class SignInSuccess {

late List<String> grantedScopes;

// This is set only on a new sign in or scope grant, not a restored sign-in.
// This is set only on a new sign in or scope grant, not a restored sign-in
// or a call to getRefreshedAuthorizationTokens.
// See https://github.com/google/GoogleSignIn-iOS/issues/202
String? serverAuthCode;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/google_sign_in/google_sign_in_ios/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: google_sign_in_ios
description: iOS implementation of the google_sign_in plugin.
repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
version: 6.2.0
version: 6.2.1

environment:
sdk: ^3.7.0
Expand Down
Loading