[google_sign_in_web] Fixes force unwrap on values that can be null (#4374)

During Google Sign-in, the code uses two force unwraps on values (name and picture) that can be not present in the response. This cause an unhandled error that blocks sign-in.

Fixes https://github.com/flutter/flutter/issues/130002 reported by me. The bug report describes how to get that error together with a screenshot of a given line.

My PR fixes that and add additional test for the future.
This commit is contained in:
Kamil Powałowski
2023-07-06 07:42:17 +02:00
committed by GitHub
parent c768b143db
commit 61df84d1bd
5 changed files with 48 additions and 3 deletions

View File

@ -1,3 +1,7 @@
## 0.12.0+3
* Fixes null cast error on accounts without picture or name details.
## 0.12.0+2
* Adds compatibility with `http` 1.0.

View File

@ -18,6 +18,12 @@ final CredentialResponse goodCredential =
'credential': goodJwtToken,
});
/// A CredentialResponse wrapping a known good JWT Token as its `credential`.
final CredentialResponse minimalCredential =
jsifyAs<CredentialResponse>(<String, Object?>{
'credential': minimalJwtToken,
});
/// A JWT token with predefined values.
///
/// 'email': 'adultman@example.com',
@ -38,6 +44,22 @@ const String goodJwtToken =
const String goodPayload =
'eyJlbWFpbCI6ImFkdWx0bWFuQGV4YW1wbGUuY29tIiwic3ViIjoiMTIzNDU2IiwibmFtZSI6IlZpbmNlbnQgQWR1bHRtYW4iLCJwaWN0dXJlIjoiaHR0cHM6Ly90aGlzcGVyc29uZG9lc25vdGV4aXN0LmNvbS9pbWFnZT94PS5qcGcifQ';
/// A JWT token with minimal set of predefined values.
///
/// 'email': 'adultman@example.com',
/// 'sub': '123456'
///
/// Signed with HS256 and the private key: 'symmetric-encryption-is-weak'
const String minimalJwtToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.$minimalPayload.UTAe7dpdtFIMwsOqkZkjyjqyHnho5xHCcQylUFmOutM';
/// The payload of a JWT token that contains only non-nullable values.
///
/// "email": "adultman@example.com",
/// "sub": "123456"
const String minimalPayload =
'eyJlbWFpbCI6ImFkdWx0bWFuQGV4YW1wbGUuY29tIiwic3ViIjoiMTIzNDU2In0';
// More encrypted JWT Tokens may be created on https://jwt.io.
//
// First, decode the `goodJwtToken` above, modify to your heart's

View File

@ -57,6 +57,17 @@ void main() {
expect(data.idToken, goodJwtToken);
});
testWidgets('happy case (minimal)', (_) async {
final GoogleSignInUserData data =
gisResponsesToUserData(minimalCredential)!;
expect(data.displayName, isNull);
expect(data.id, '123456');
expect(data.email, 'adultman@example.com');
expect(data.photoUrl, isNull);
expect(data.idToken, minimalJwtToken);
});
testWidgets('null response -> null', (_) async {
expect(gisResponsesToUserData(null), isNull);
});
@ -90,6 +101,14 @@ void main() {
));
});
testWidgets('happy case (minimal) -> data', (_) async {
final Map<String, Object?>? data = getJwtTokenPayload(minimalJwtToken);
expect(data, isNotNull);
expect(data, containsPair('email', 'adultman@example.com'));
expect(data, containsPair('sub', '123456'));
});
testWidgets('null Token -> null', (_) async {
final Map<String, Object?>? data = getJwtTokenPayload(null);

View File

@ -72,8 +72,8 @@ GoogleSignInUserData? gisResponsesToUserData(
return GoogleSignInUserData(
email: payload['email']! as String,
id: payload['sub']! as String,
displayName: payload['name']! as String,
photoUrl: payload['picture']! as String,
displayName: payload['name'] as String?,
photoUrl: payload['picture'] as String?,
idToken: credentialResponse.credential,
);
}

View File

@ -3,7 +3,7 @@ description: Flutter plugin for Google Sign-In, a secure authentication system
for signing in with a Google account on Android, iOS and Web.
repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
version: 0.12.0+2
version: 0.12.0+3
environment:
sdk: ">=2.18.0 <4.0.0"