Skip to content

Commit 8a9eba2

Browse files
authored
[google_sign_in] Move plugin to its subdir to allow for federated implementations. Add platform interface. (flutter#2244)
* google_sign_in: * Move google_sign_in to google_sign_in/google_sign_in * Update docs * Add the google_sign_in_platform_interface package.
1 parent da580fc commit 8a9eba2

File tree

80 files changed

+518
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+518
-4
lines changed

packages/google_sign_in/CHANGELOG.md renamed to packages/google_sign_in/google_sign_in/CHANGELOG.md

Lines changed: 4 additions & 0 deletions

packages/google_sign_in/README.md renamed to packages/google_sign_in/google_sign_in/README.md

Lines changed: 2 additions & 2 deletions

packages/google_sign_in/pubspec.yaml renamed to packages/google_sign_in/google_sign_in/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ name: google_sign_in
22
description: Flutter plugin for Google Sign-In, a secure authentication system
33
for signing in with a Google account on Android and iOS.
44
author: Flutter Team <[email protected]>
5-
homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in
6-
version: 4.0.11
5+
homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in
6+
version: 4.0.12
77

88
flutter:
99
plugin:
Lines changed: 3 additions & 0 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are
5+
// met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above
10+
// copyright notice, this list of conditions and the following disclaimer
11+
// in the documentation and/or other materials provided with the
12+
// distribution.
13+
// * Neither the name of Google Inc. nor the names of its
14+
// contributors may be used to endorse or promote products derived from
15+
// this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 26 additions & 0 deletions
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'package:meta/meta.dart' show required, visibleForTesting;
7+
import 'src/method_channel_google_sign_in.dart';
8+
import 'src/types.dart';
9+
10+
export 'src/method_channel_google_sign_in.dart';
11+
export 'src/types.dart';
12+
13+
/// The interface that implementations of google_sign_in must implement.
14+
///
15+
/// Platform implementations that live in a separate package should extend this
16+
/// class rather than implement it as `google_sign_in` does not consider newly
17+
/// added methods to be breaking changes. Extending this class (using `extends`)
18+
/// ensures that the subclass will get the default implementation, while
19+
/// platform implementations that `implements` this interface will be broken by
20+
/// newly added [GoogleSignInPlatform] methods.
21+
abstract class GoogleSignInPlatform {
22+
/// Only mock implementations should set this to `true`.
23+
///
24+
/// Mockito mocks implement this class with `implements` which is forbidden
25+
/// (see class docs). This property provides a backdoor for mocks to skip the
26+
/// verification that the class isn't implemented with `implements`.
27+
@visibleForTesting
28+
bool get isMock => false;
29+
30+
/// The default instance of [GoogleSignInPlatform] to use.
31+
///
32+
/// Platform-specific plugins should override this with their own
33+
/// platform-specific class that extends [GoogleSignInPlatform] when they
34+
/// register themselves.
35+
///
36+
/// Defaults to [MethodChannelGoogleSignIn].
37+
static GoogleSignInPlatform get instance => _instance;
38+
39+
static GoogleSignInPlatform _instance = MethodChannelGoogleSignIn();
40+
41+
// TODO(amirh): Extract common platform interface logic.
42+
// https://github.com/flutter/flutter/issues/43368
43+
static set instance(GoogleSignInPlatform instance) {
44+
if (!instance.isMock) {
45+
try {
46+
instance._verifyProvidesDefaultImplementations();
47+
} on NoSuchMethodError catch (_) {
48+
throw AssertionError(
49+
'Platform interfaces must not be implemented with `implements`');
50+
}
51+
}
52+
_instance = instance;
53+
}
54+
55+
/// This method ensures that [GoogleSignInPlatform] isn't implemented with `implements`.
56+
///
57+
/// See class docs for more details on why using `implements` to implement
58+
/// [GoogleSignInPlatform] is forbidden.
59+
///
60+
/// This private method is called by the [instance] setter, which should fail
61+
/// if the provided instance is a class implemented with `implements`.
62+
void _verifyProvidesDefaultImplementations() {}
63+
64+
/// Initializes the plugin. You must call this method before calling other methods.
65+
/// See: https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams
66+
Future<void> init(
67+
{@required String hostedDomain,
68+
List<String> scopes,
69+
SignInOption signInOption,
70+
String clientId}) async {
71+
throw UnimplementedError('init() has not been implemented.');
72+
}
73+
74+
/// Attempts to reuse pre-existing credentials to sign in again, without user interaction.
75+
Future<GoogleSignInUserData> signInSilently() async {
76+
throw UnimplementedError('signInSilently() has not been implemented.');
77+
}
78+
79+
/// Signs in the user with the options specified to [init].
80+
Future<GoogleSignInUserData> signIn() async {
81+
throw UnimplementedError('signIn() has not been implemented.');
82+
}
83+
84+
/// Returns the Tokens used to authenticate other API calls.
85+
Future<GoogleSignInTokenData> getTokens(
86+
{@required String email, bool shouldRecoverAuth}) async {
87+
throw UnimplementedError('getTokens() has not been implemented.');
88+
}
89+
90+
/// Signs out the current account from the application.
91+
Future<void> signOut() async {
92+
throw UnimplementedError('signOut() has not been implemented.');
93+
}
94+
95+
/// Revokes all of the scopes that the user granted.
96+
Future<void> disconnect() async {
97+
throw UnimplementedError('disconnect() has not been implemented.');
98+
}
99+
100+
/// Returns whether the current user is currently signed in.
101+
Future<bool> isSignedIn() async {
102+
throw UnimplementedError('isSignedIn() has not been implemented.');
103+
}
104+
105+
/// Clears any cached information that the plugin may be holding on to.
106+
Future<void> clearAuthCache({@required String token}) async {
107+
throw UnimplementedError('clearAuthCache() has not been implemented.');
108+
}
109+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter/services.dart';
8+
import 'package:meta/meta.dart' show required, visibleForTesting;
9+
10+
import '../google_sign_in_platform_interface.dart';
11+
import 'types.dart';
12+
import 'utils.dart';
13+
14+
/// An implementation of [GoogleSignInPlatform] that uses method channels.
15+
class MethodChannelGoogleSignIn extends GoogleSignInPlatform {
16+
@visibleForTesting
17+
MethodChannel channel =
18+
const MethodChannel('plugins.flutter.io/google_sign_in');
19+
20+
@override
21+
Future<void> init(
22+
{@required String hostedDomain,
23+
List<String> scopes = const <String>[],
24+
SignInOption signInOption = SignInOption.standard,
25+
String clientId}) {
26+
return channel.invokeMethod<void>('init', <String, dynamic>{
27+
'signInOption': signInOption.toString(),
28+
'scopes': scopes,
29+
'hostedDomain': hostedDomain,
30+
});
31+
}
32+
33+
@override
34+
Future<GoogleSignInUserData> signInSilently() {
35+
return channel
36+
.invokeMapMethod<String, dynamic>('signInSilently')
37+
.then(getUserDataFromMap);
38+
}
39+
40+
@override
41+
Future<GoogleSignInUserData> signIn() {
42+
return channel
43+
.invokeMapMethod<String, dynamic>('signIn')
44+
.then(getUserDataFromMap);
45+
}
46+
47+
@override
48+
Future<GoogleSignInTokenData> getTokens(
49+
{String email, bool shouldRecoverAuth = true}) {
50+
return channel
51+
.invokeMapMethod<String, dynamic>('getTokens', <String, dynamic>{
52+
'email': email,
53+
'shouldRecoverAuth': shouldRecoverAuth,
54+
}).then(getTokenDataFromMap);
55+
}
56+
57+
@override
58+
Future<void> signOut() {
59+
return channel.invokeMapMethod<String, dynamic>('signOut');
60+
}
61+
62+
@override
63+
Future<void> disconnect() {
64+
return channel.invokeMapMethod<String, dynamic>('disconnect');
65+
}
66+
67+
@override
68+
Future<bool> isSignedIn() {
69+
return channel.invokeMethod<bool>('isSignedIn');
70+
}
71+
72+
@override
73+
Future<void> clearAuthCache({String token}) {
74+
return channel.invokeMethod<void>(
75+
'clearAuthCache',
76+
<String, String>{'token': token},
77+
);
78+
}
79+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:quiver_hashcode/hashcode.dart';
6+
7+
enum SignInOption { standard, games }
8+
9+
class GoogleSignInUserData {
10+
GoogleSignInUserData(
11+
{this.displayName, this.email, this.id, this.photoUrl, this.idToken});
12+
String displayName;
13+
String email;
14+
String id;
15+
String photoUrl;
16+
String idToken;
17+
18+
@override
19+
int get hashCode =>
20+
hashObjects(<String>[displayName, email, id, photoUrl, idToken]);
21+
22+
@override
23+
bool operator ==(dynamic other) {
24+
if (identical(this, other)) return true;
25+
if (other is! GoogleSignInUserData) return false;
26+
final GoogleSignInUserData otherUserData = other;
27+
return otherUserData.displayName == displayName &&
28+
otherUserData.email == email &&
29+
otherUserData.id == id &&
30+
otherUserData.photoUrl == photoUrl &&
31+
otherUserData.idToken == idToken;
32+
}
33+
}
34+
35+
class GoogleSignInTokenData {
36+
GoogleSignInTokenData({this.idToken, this.accessToken});
37+
String idToken;
38+
String accessToken;
39+
40+
@override
41+
int get hashCode => hash2(idToken, accessToken);
42+
43+
@override
44+
bool operator ==(dynamic other) {
45+
if (identical(this, other)) return true;
46+
if (other is! GoogleSignInTokenData) return false;
47+
final GoogleSignInTokenData otherTokenData = other;
48+
return otherTokenData.idToken == idToken &&
49+
otherTokenData.accessToken == accessToken;
50+
}
51+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2017 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import '../google_sign_in_platform_interface.dart';
6+
7+
/// Converts user data coming from native code into the proper platform interface type.
8+
GoogleSignInUserData getUserDataFromMap(Map<String, dynamic> data) {
9+
if (data == null) {
10+
return null;
11+
}
12+
return GoogleSignInUserData(
13+
displayName: data['displayName'],
14+
email: data['email'],
15+
id: data['id'],
16+
photoUrl: data['photoUrl'],
17+
idToken: data['idToken']);
18+
}
19+
20+
/// Converts token data coming from native code into the proper platform interface type.
21+
GoogleSignInTokenData getTokenDataFromMap(Map<String, dynamic> data) {
22+
if (data == null) {
23+
return null;
24+
}
25+
return GoogleSignInTokenData(
26+
idToken: data['idToken'],
27+
accessToken: data['accessToken'],
28+
);
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: google_sign_in_platform_interface
2+
description: A common platform interface for the google_sign_in plugin.
3+
author: Flutter Team <[email protected]>
4+
homepage: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in_platform_interface
5+
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
6+
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
7+
version: 1.0.0
8+
9+
dependencies:
10+
flutter:
11+
sdk: flutter
12+
meta: ^1.0.5
13+
quiver_hashcode: ^2.0.0
14+
15+
dev_dependencies:
16+
flutter_test:
17+
sdk: flutter
18+
mockito: ^4.1.1
19+
20+
environment:
21+
sdk: ">=2.0.0-dev.28.0 <3.0.0"
22+
flutter: ">=1.5.0 <2.0.0"

0 commit comments

Comments
 (0)