refactor(googleapis_auth): rename AuthProvider to AuthEndpoints (#1755)
This commit is contained in:
@@ -8,7 +8,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:jwt/jwt.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/providers/providers.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/command_runner.dart';
|
||||
import 'package:shorebird_cli/src/http_client/http_client.dart';
|
||||
@@ -30,7 +30,7 @@ const googleJwtIssuer = 'https://accounts.google.com';
|
||||
const microsoftJwtIssuerPrefix = 'https://login.microsoftonline.com/';
|
||||
|
||||
typedef ObtainAccessCredentials = Future<oauth2.AccessCredentials> Function(
|
||||
oauth2.AuthProvider authProvider,
|
||||
oauth2.AuthEndpoints authEndpoints,
|
||||
oauth2.ClientId clientId,
|
||||
List<String> scopes,
|
||||
http.Client client,
|
||||
@@ -38,7 +38,7 @@ typedef ObtainAccessCredentials = Future<oauth2.AccessCredentials> Function(
|
||||
);
|
||||
|
||||
typedef RefreshCredentials = Future<oauth2.AccessCredentials> Function(
|
||||
oauth2.AuthProvider authProvider,
|
||||
oauth2.AuthEndpoints authEndpoints,
|
||||
oauth2.ClientId clientId,
|
||||
oauth2.AccessCredentials credentials,
|
||||
http.Client client,
|
||||
@@ -98,7 +98,7 @@ class AuthenticatedClient extends http.BaseClient {
|
||||
if (credentials == null) {
|
||||
final token = _token!;
|
||||
final jwt = Jwt.parse(token);
|
||||
final authProvider = jwt.authProvider;
|
||||
final authProvider = jwt.authEndpoints;
|
||||
credentials = _credentials = await _refreshCredentials(
|
||||
authProvider,
|
||||
authProvider.clientId,
|
||||
@@ -115,7 +115,7 @@ class AuthenticatedClient extends http.BaseClient {
|
||||
|
||||
if (credentials.accessToken.hasExpired && credentials.idToken != null) {
|
||||
final jwt = Jwt.parse(credentials.idToken!);
|
||||
final authProvider = jwt.authProvider;
|
||||
final authProvider = jwt.authEndpoints;
|
||||
|
||||
credentials = _credentials = await _refreshCredentials(
|
||||
authProvider,
|
||||
@@ -176,15 +176,15 @@ class Auth {
|
||||
}
|
||||
|
||||
Future<AccessCredentials> loginCI(
|
||||
oauth2.AuthProvider authProvider, {
|
||||
oauth2.AuthEndpoints authEndpoints, {
|
||||
required void Function(String) prompt,
|
||||
}) async {
|
||||
final client = http.Client();
|
||||
try {
|
||||
final credentials = await _obtainAccessCredentials(
|
||||
authProvider,
|
||||
authProvider.clientId,
|
||||
authProvider.scopes,
|
||||
authEndpoints,
|
||||
authEndpoints.clientId,
|
||||
authEndpoints.scopes,
|
||||
client,
|
||||
prompt,
|
||||
);
|
||||
@@ -206,7 +206,7 @@ class Auth {
|
||||
}
|
||||
|
||||
Future<void> login(
|
||||
oauth2.AuthProvider authProvider, {
|
||||
oauth2.AuthEndpoints authEndpoints, {
|
||||
required void Function(String) prompt,
|
||||
}) async {
|
||||
if (_credentials != null) {
|
||||
@@ -216,9 +216,9 @@ class Auth {
|
||||
final client = http.Client();
|
||||
try {
|
||||
_credentials = await _obtainAccessCredentials(
|
||||
authProvider,
|
||||
authProvider.clientId,
|
||||
authProvider.scopes,
|
||||
authEndpoints,
|
||||
authEndpoints.clientId,
|
||||
authEndpoints.scopes,
|
||||
client,
|
||||
prompt,
|
||||
);
|
||||
@@ -326,22 +326,22 @@ class UserNotFoundException implements Exception {
|
||||
final String email;
|
||||
}
|
||||
|
||||
extension OauthAuthProvider on Jwt {
|
||||
oauth2.AuthProvider get authProvider {
|
||||
extension OauthAuthEndpoints on Jwt {
|
||||
oauth2.AuthEndpoints get authEndpoints {
|
||||
if (payload.iss == googleJwtIssuer) {
|
||||
return oauth2.GoogleAuthProvider();
|
||||
return oauth2.GoogleAuthEndpoints();
|
||||
} else if (payload.iss.startsWith(microsoftJwtIssuerPrefix)) {
|
||||
return MicrosoftAuthProvider();
|
||||
return MicrosoftAuthEndpoints();
|
||||
}
|
||||
|
||||
throw Exception('Unknown jwt issuer: ${payload.iss}');
|
||||
}
|
||||
}
|
||||
|
||||
extension OauthValues on oauth2.AuthProvider {
|
||||
extension OauthValues on oauth2.AuthEndpoints {
|
||||
oauth2.ClientId get clientId {
|
||||
switch (runtimeType) {
|
||||
case oauth2.GoogleAuthProvider:
|
||||
case oauth2.GoogleAuthEndpoints:
|
||||
return oauth2.ClientId(
|
||||
/// Shorebird CLI's OAuth 2.0 identifier for GCP,
|
||||
'''523302233293-eia5antm0tgvek240t46orctktiabrek.apps.googleusercontent.com''',
|
||||
@@ -358,7 +358,7 @@ extension OauthValues on oauth2.AuthProvider {
|
||||
/// For more info see: https://developers.google.com/identity/protocols/oauth2/native-app
|
||||
'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',
|
||||
);
|
||||
case MicrosoftAuthProvider:
|
||||
case MicrosoftAuthEndpoints:
|
||||
return oauth2.ClientId(
|
||||
/// Shorebird CLI's OAuth 2.0 identifier for Azure/Entra.
|
||||
'0ff83897-ec85-4642-a250-48d5f595137c',
|
||||
@@ -370,9 +370,9 @@ extension OauthValues on oauth2.AuthProvider {
|
||||
|
||||
List<String> get scopes {
|
||||
switch (runtimeType) {
|
||||
case oauth2.GoogleAuthProvider:
|
||||
case oauth2.GoogleAuthEndpoints:
|
||||
return ['openid', 'https://www.googleapis.com/auth/userinfo.email'];
|
||||
case MicrosoftAuthProvider:
|
||||
case MicrosoftAuthEndpoints:
|
||||
return ['openid'];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export 'package:googleapis_auth/auth_io.dart' show GoogleAuthEndpoints;
|
||||
export 'microsoft_auth_endpoints.dart';
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import 'package:googleapis_auth/googleapis_auth.dart';
|
||||
|
||||
/// Endpoints for OAuth authentication with Azure/Entra/Microsoft.
|
||||
class MicrosoftAuthProvider extends AuthProvider {
|
||||
class MicrosoftAuthEndpoints extends AuthEndpoints {
|
||||
@override
|
||||
Uri get authorizationEndpoint =>
|
||||
Uri.https('login.microsoftonline.com', 'common/oauth2/v2.0/authorize');
|
||||
@@ -1,2 +0,0 @@
|
||||
export 'package:googleapis_auth/auth_io.dart' show GoogleAuthProvider;
|
||||
export 'microsoft_auth_provider.dart';
|
||||
@@ -20,7 +20,7 @@ class LoginCiCommand extends ShorebirdCommand {
|
||||
final AccessCredentials credentials;
|
||||
|
||||
try {
|
||||
credentials = await auth.loginCI(GoogleAuthProvider(), prompt: prompt);
|
||||
credentials = await auth.loginCI(GoogleAuthEndpoints(), prompt: prompt);
|
||||
} on UserNotFoundException catch (error) {
|
||||
logger
|
||||
..err(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:googleapis_auth/auth_io.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:shorebird_cli/src/command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
|
||||
@@ -18,7 +19,7 @@ class LoginCommand extends ShorebirdCommand {
|
||||
@override
|
||||
Future<int> run() async {
|
||||
try {
|
||||
await auth.login(GoogleAuthProvider(), prompt: prompt);
|
||||
await auth.login(GoogleAuthEndpoints(), prompt: prompt);
|
||||
} on UserAlreadyLoggedInException catch (error) {
|
||||
logger
|
||||
..info('You are already logged in as <${error.email}>.')
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/auth/providers/providers.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:shorebird_cli/src/command_runner.dart';
|
||||
import 'package:shorebird_cli/src/http_client/http_client.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
@@ -22,7 +22,7 @@ import 'package:test/test.dart';
|
||||
import '../fakes.dart';
|
||||
import '../mocks.dart';
|
||||
|
||||
class FakeProvider extends oauth2.AuthProvider {
|
||||
class FakeAuthEndpoints extends oauth2.AuthEndpoints {
|
||||
@override
|
||||
Uri get authorizationEndpoint => Uri.https('example.com');
|
||||
|
||||
@@ -52,17 +52,17 @@ void main() {
|
||||
});
|
||||
|
||||
group('OauthValues', () {
|
||||
final fakeAuthProvider = FakeProvider();
|
||||
final fakeAuthEndpoints = FakeAuthEndpoints();
|
||||
|
||||
group('clientId', () {
|
||||
test('throws UnsupportedError when provider is not a known type', () {
|
||||
expect(() => fakeAuthProvider.clientId, throwsUnsupportedError);
|
||||
test('throws UnsupportedError when endpoints is not a known type', () {
|
||||
expect(() => fakeAuthEndpoints.clientId, throwsUnsupportedError);
|
||||
});
|
||||
});
|
||||
|
||||
group('scopes', () {
|
||||
test('throws UnsupportedError when provider is not a known type', () {
|
||||
expect(() => fakeAuthProvider.scopes, throwsUnsupportedError);
|
||||
test('throws UnsupportedError when endpoints is not a known type', () {
|
||||
expect(() => fakeAuthEndpoints.scopes, throwsUnsupportedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -86,7 +86,7 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('OauthAuthProvider', () {
|
||||
group('OauthAuthEndpoints', () {
|
||||
late Jwt jwt;
|
||||
late JwtPayload payload;
|
||||
|
||||
@@ -99,14 +99,14 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
group('authProvider', () {
|
||||
group('authEndpoints', () {
|
||||
group('when issuer is login.microsoft.online', () {
|
||||
setUp(() {
|
||||
when(() => payload.iss).thenReturn(microsoftJwtIssuer);
|
||||
});
|
||||
|
||||
test('returns AuthProvider.microsoft', () {
|
||||
expect(jwt.authProvider, isA<MicrosoftAuthProvider>());
|
||||
test('returns MicrosoftAuthEndpoints', () {
|
||||
expect(jwt.authEndpoints, isA<MicrosoftAuthEndpoints>());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -115,8 +115,8 @@ void main() {
|
||||
when(() => payload.iss).thenReturn(googleJwtIssuer);
|
||||
});
|
||||
|
||||
test('returns AuthProvider.google', () {
|
||||
expect(jwt.authProvider, isA<GoogleAuthProvider>());
|
||||
test('returns GoogleAuthEndpoints', () {
|
||||
expect(jwt.authEndpoints, isA<GoogleAuthEndpoints>());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -127,7 +127,7 @@ void main() {
|
||||
|
||||
test('throws exception', () {
|
||||
expect(
|
||||
() => jwt.authProvider,
|
||||
() => jwt.authEndpoints,
|
||||
throwsA(
|
||||
isA<Exception>().having(
|
||||
(e) => e.toString(),
|
||||
@@ -152,8 +152,8 @@ void main() {
|
||||
);
|
||||
const refreshToken = '';
|
||||
const scopes = <String>[];
|
||||
final googleAuthProvider = GoogleAuthProvider();
|
||||
final microsoftAuthProvider = MicrosoftAuthProvider();
|
||||
final googleAuthEndpoints = GoogleAuthEndpoints();
|
||||
final microsoftAuthEndpoints = MicrosoftAuthEndpoints();
|
||||
final accessToken = oauth2.AccessToken(
|
||||
'Bearer',
|
||||
'accessToken',
|
||||
@@ -198,7 +198,7 @@ void main() {
|
||||
return codePushClient;
|
||||
},
|
||||
obtainAccessCredentials:
|
||||
(authProvider, clientId, scopes, client, userPrompt) async {
|
||||
(authEndpoints, clientId, scopes, client, userPrompt) async {
|
||||
return accessCredentials;
|
||||
},
|
||||
),
|
||||
@@ -235,7 +235,7 @@ void main() {
|
||||
token: token,
|
||||
httpClient: httpClient,
|
||||
refreshCredentials:
|
||||
(authProvider, clientId, credentials, client) async =>
|
||||
(authEndpoints, clientId, credentials, client) async =>
|
||||
accessCredentials,
|
||||
),
|
||||
returnsNormally,
|
||||
@@ -258,7 +258,7 @@ void main() {
|
||||
httpClient: httpClient,
|
||||
onRefreshCredentials: onRefreshCredentialsCalls.add,
|
||||
refreshCredentials:
|
||||
(authProvider, clientId, credentials, client) async =>
|
||||
(authEndpoints, clientId, credentials, client) async =>
|
||||
accessCredentials,
|
||||
);
|
||||
|
||||
@@ -292,7 +292,7 @@ void main() {
|
||||
httpClient: httpClient,
|
||||
onRefreshCredentials: onRefreshCredentialsCalls.add,
|
||||
refreshCredentials:
|
||||
(authProvider, clientId, credentials, client) async =>
|
||||
(authEndpoints, clientId, credentials, client) async =>
|
||||
accessCredentials,
|
||||
);
|
||||
|
||||
@@ -342,7 +342,7 @@ void main() {
|
||||
httpClient: httpClient,
|
||||
onRefreshCredentials: onRefreshCredentialsCalls.add,
|
||||
refreshCredentials:
|
||||
(authProvider, clientId, credentials, client) async =>
|
||||
(authEndpoints, clientId, credentials, client) async =>
|
||||
accessCredentials,
|
||||
);
|
||||
|
||||
@@ -400,7 +400,7 @@ void main() {
|
||||
HttpStatus.ok,
|
||||
),
|
||||
);
|
||||
await auth.login(googleAuthProvider, prompt: (_) {});
|
||||
await auth.login(googleAuthEndpoints, prompt: (_) {});
|
||||
final client = auth.client;
|
||||
expect(client, isA<http.Client>());
|
||||
expect(client, isA<AuthenticatedClient>());
|
||||
@@ -445,18 +445,18 @@ void main() {
|
||||
group('login', () {
|
||||
test('should set the email when claims are valid and current user exists',
|
||||
() async {
|
||||
await auth.login(googleAuthProvider, prompt: (_) {});
|
||||
await auth.login(googleAuthEndpoints, prompt: (_) {});
|
||||
expect(auth.email, email);
|
||||
expect(auth.isAuthenticated, isTrue);
|
||||
expect(buildAuth().email, email);
|
||||
expect(buildAuth().isAuthenticated, isTrue);
|
||||
});
|
||||
|
||||
group('with a custom auth provider', () {
|
||||
group('with custom auth endpoints', () {
|
||||
test(
|
||||
'''should set the email when claims are valid and current user exists''',
|
||||
() async {
|
||||
await auth.login(microsoftAuthProvider, prompt: (_) {});
|
||||
await auth.login(microsoftAuthEndpoints, prompt: (_) {});
|
||||
expect(auth.email, email);
|
||||
expect(auth.isAuthenticated, isTrue);
|
||||
expect(buildAuth().email, email);
|
||||
@@ -470,7 +470,7 @@ void main() {
|
||||
auth = buildAuth();
|
||||
|
||||
await expectLater(
|
||||
auth.login(googleAuthProvider, prompt: (_) {}),
|
||||
auth.login(googleAuthEndpoints, prompt: (_) {}),
|
||||
throwsA(isA<UserAlreadyLoggedInException>()),
|
||||
);
|
||||
|
||||
@@ -483,7 +483,7 @@ void main() {
|
||||
.thenAnswer((_) async => null);
|
||||
|
||||
await expectLater(
|
||||
auth.login(googleAuthProvider, prompt: (_) {}),
|
||||
auth.login(googleAuthEndpoints, prompt: (_) {}),
|
||||
throwsA(isA<UserNotFoundException>()),
|
||||
);
|
||||
|
||||
@@ -505,7 +505,7 @@ void main() {
|
||||
'returns credentials and does not set the email or cache credentials',
|
||||
() async {
|
||||
await expectLater(
|
||||
auth.loginCI(googleAuthProvider, prompt: (_) {}),
|
||||
auth.loginCI(googleAuthEndpoints, prompt: (_) {}),
|
||||
completion(equals(accessCredentials)),
|
||||
);
|
||||
expect(auth.email, isNull);
|
||||
@@ -522,7 +522,7 @@ void main() {
|
||||
).thenAnswer((_) async => null);
|
||||
|
||||
await expectLater(
|
||||
auth.loginCI(googleAuthProvider, prompt: (_) {}),
|
||||
auth.loginCI(googleAuthEndpoints, prompt: (_) {}),
|
||||
throwsA(isA<UserNotFoundException>()),
|
||||
);
|
||||
|
||||
@@ -532,7 +532,7 @@ void main() {
|
||||
|
||||
group('logout', () {
|
||||
test('clears session and wipes state', () async {
|
||||
await auth.login(googleAuthProvider, prompt: (_) {});
|
||||
await auth.login(googleAuthEndpoints, prompt: (_) {});
|
||||
expect(auth.email, email);
|
||||
expect(auth.isAuthenticated, isTrue);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:shorebird_cli/src/auth/providers/providers.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group(MicrosoftAuthProvider, () {
|
||||
group(MicrosoftAuthEndpoints, () {
|
||||
test('has valid endpoints', () {
|
||||
final provider = MicrosoftAuthProvider();
|
||||
final provider = MicrosoftAuthEndpoints();
|
||||
expect(provider.authorizationEndpoint, isNotNull);
|
||||
expect(provider.tokenEndpoint, isNotNull);
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:shorebird_cli/src/commands/commands.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:test/test.dart';
|
||||
@@ -30,7 +31,7 @@ void main() {
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(GoogleAuthProvider());
|
||||
registerFallbackValue(GoogleAuthEndpoints());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:mocktail/mocktail.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:scoped/scoped.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/auth/endpoints/endpoints.dart';
|
||||
import 'package:shorebird_cli/src/commands/login_command.dart';
|
||||
import 'package:shorebird_cli/src/logger.dart';
|
||||
import 'package:test/test.dart';
|
||||
@@ -34,7 +35,7 @@ void main() {
|
||||
}
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(GoogleAuthProvider());
|
||||
registerFallbackValue(GoogleAuthEndpoints());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
||||
+10
-10
@@ -37,7 +37,7 @@ export 'src/typedefs.dart';
|
||||
/// {@macro googleapis_auth_not_close_the_baseClient}
|
||||
/// {@macro googleapis_auth_listen_port}
|
||||
Future<AutoRefreshingAuthClient> clientViaUserConsent(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
List<String> scopes,
|
||||
PromptUserForConsent userPrompt, {
|
||||
@@ -52,7 +52,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsent(
|
||||
}
|
||||
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
baseClient,
|
||||
@@ -73,7 +73,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsent(
|
||||
}
|
||||
return AutoRefreshingClient(
|
||||
baseClient,
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
closeUnderlyingClient: closeUnderlyingClient,
|
||||
@@ -96,7 +96,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsent(
|
||||
/// {@macro googleapis_auth_close_the_client}
|
||||
/// {@macro googleapis_auth_not_close_the_baseClient}
|
||||
Future<AutoRefreshingAuthClient> clientViaUserConsentManual(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
List<String> scopes,
|
||||
PromptUserForConsentManual userPrompt, {
|
||||
@@ -110,7 +110,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsentManual(
|
||||
}
|
||||
|
||||
final flow = AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
baseClient,
|
||||
@@ -131,7 +131,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsentManual(
|
||||
|
||||
return AutoRefreshingClient(
|
||||
baseClient,
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
closeUnderlyingClient: closeUnderlyingClient,
|
||||
@@ -159,7 +159,7 @@ Future<AutoRefreshingAuthClient> clientViaUserConsentManual(
|
||||
/// on the Google Cloud console.
|
||||
/// {@endtemplate}
|
||||
Future<AccessCredentials> obtainAccessCredentialsViaUserConsent(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
List<String> scopes,
|
||||
Client client,
|
||||
@@ -168,7 +168,7 @@ Future<AccessCredentials> obtainAccessCredentialsViaUserConsent(
|
||||
int listenPort = 0,
|
||||
}) =>
|
||||
AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
client,
|
||||
@@ -190,7 +190,7 @@ Future<AccessCredentials> obtainAccessCredentialsViaUserConsent(
|
||||
///
|
||||
/// {@macro googleapis_auth_user_consent_return}
|
||||
Future<AccessCredentials> obtainAccessCredentialsViaUserConsentManual(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
List<String> scopes,
|
||||
Client client,
|
||||
@@ -198,7 +198,7 @@ Future<AccessCredentials> obtainAccessCredentialsViaUserConsentManual(
|
||||
String? hostedDomain,
|
||||
}) =>
|
||||
AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
client,
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ library googleapis_auth;
|
||||
|
||||
export 'src/auth_client.dart';
|
||||
export 'src/auth_functions.dart';
|
||||
export 'src/auth_provider.dart';
|
||||
export 'src/auth_endpoints.dart';
|
||||
export 'src/client_id.dart';
|
||||
export 'src/exceptions.dart';
|
||||
export 'src/response_type.dart';
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ import 'auth_http_utils.dart';
|
||||
|
||||
Future<AutoRefreshingAuthClient> fromApplicationsCredentialsFile(
|
||||
File file,
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
String fileSource,
|
||||
List<String> scopes,
|
||||
Client baseClient,
|
||||
@@ -38,10 +38,10 @@ Future<AutoRefreshingAuthClient> fromApplicationsCredentialsFile(
|
||||
);
|
||||
return AutoRefreshingClient(
|
||||
baseClient,
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
await refreshCredentials(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
AccessCredentials(
|
||||
// Hack: Create empty credentials that have expired.
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import 'known_uris.dart';
|
||||
|
||||
abstract class AuthProvider {
|
||||
abstract class AuthEndpoints {
|
||||
Uri get authorizationEndpoint;
|
||||
Uri get tokenEndpoint;
|
||||
}
|
||||
|
||||
class GoogleAuthProvider extends AuthProvider {
|
||||
class GoogleAuthEndpoints extends AuthEndpoints {
|
||||
@override
|
||||
Uri get authorizationEndpoint => googleOauth2AuthorizationEndpoint;
|
||||
|
||||
+4
-4
@@ -80,7 +80,7 @@ AuthClient authenticatedClient(
|
||||
/// {@macro googleapis_auth_close_the_client}
|
||||
/// {@macro googleapis_auth_not_close_the_baseClient}
|
||||
AutoRefreshingAuthClient autoRefreshingClient(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
AccessCredentials credentials,
|
||||
Client baseClient,
|
||||
@@ -91,7 +91,7 @@ AutoRefreshingAuthClient autoRefreshingClient(
|
||||
if (credentials.refreshToken == null) {
|
||||
throw ArgumentError('Refresh token in AccessCredentials was `null`.');
|
||||
}
|
||||
return AutoRefreshingClient(baseClient, authProvider, clientId, credentials);
|
||||
return AutoRefreshingClient(baseClient, authEndpoints, clientId, credentials);
|
||||
}
|
||||
|
||||
/// Obtains refreshed [AccessCredentials] for [clientId] and [credentials].
|
||||
@@ -100,7 +100,7 @@ AutoRefreshingAuthClient autoRefreshingClient(
|
||||
///
|
||||
/// {@macro googleapis_auth_client_for_creds}
|
||||
Future<AccessCredentials> refreshCredentials(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
ClientId clientId,
|
||||
AccessCredentials credentials,
|
||||
Client client,
|
||||
@@ -123,7 +123,7 @@ Future<AccessCredentials> refreshCredentials(
|
||||
'refresh_token': refreshToken,
|
||||
'grant_type': 'refresh_token',
|
||||
},
|
||||
authProvider: authProvider,
|
||||
authEndpoints: authEndpoints,
|
||||
);
|
||||
|
||||
final accessToken = parseAccessToken(jsonMap);
|
||||
|
||||
@@ -87,11 +87,11 @@ class AutoRefreshingClient extends AutoRefreshDelegatingClient {
|
||||
@override
|
||||
AccessCredentials credentials;
|
||||
late Client authClient;
|
||||
final AuthProvider authProvider;
|
||||
final AuthEndpoints authEndpoints;
|
||||
|
||||
AutoRefreshingClient(
|
||||
super.client,
|
||||
this.authProvider,
|
||||
this.authEndpoints,
|
||||
this.clientId,
|
||||
this.credentials, {
|
||||
super.closeUnderlyingClient,
|
||||
@@ -113,7 +113,7 @@ class AutoRefreshingClient extends AutoRefreshDelegatingClient {
|
||||
return authClient.send(request);
|
||||
} else {
|
||||
final cred = await refreshCredentials(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
baseClient,
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'package:http/http.dart' as http;
|
||||
import '../utils.dart';
|
||||
|
||||
Uri createAuthenticationUri({
|
||||
required AuthProvider authProvider,
|
||||
required AuthEndpoints authEndpoints,
|
||||
required String redirectUri,
|
||||
required String clientId,
|
||||
required Iterable<String> scopes,
|
||||
@@ -34,7 +34,7 @@ Uri createAuthenticationUri({
|
||||
if (hostedDomain != null) 'hd': hostedDomain,
|
||||
if (state != null) 'state': state,
|
||||
};
|
||||
return authProvider.authorizationEndpoint.replace(
|
||||
return authEndpoints.authorizationEndpoint.replace(
|
||||
queryParameters: queryValues,
|
||||
);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ String _stripBase64Equals(String value) {
|
||||
/// to the server. You should use "anti-request forgery state tokens" to guard
|
||||
/// against "cross site request forgery" attacks.
|
||||
Future<AccessCredentials> obtainAccessCredentialsViaCodeExchange(
|
||||
AuthProvider authProvider,
|
||||
AuthEndpoints authEndpoints,
|
||||
http.Client client,
|
||||
ClientId clientId,
|
||||
String code, {
|
||||
@@ -120,7 +120,7 @@ Future<AccessCredentials> obtainAccessCredentialsViaCodeExchange(
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': redirectUrl,
|
||||
},
|
||||
authProvider: authProvider,
|
||||
authEndpoints: authEndpoints,
|
||||
);
|
||||
final accessToken = parseAccessToken(jsonMap);
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -2,23 +2,23 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:googleapis_auth/src/auth_provider.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../access_credentials.dart';
|
||||
import '../auth_endpoints.dart';
|
||||
import '../client_id.dart';
|
||||
import 'auth_code.dart';
|
||||
import 'base_flow.dart';
|
||||
|
||||
abstract class AuthorizationCodeGrantAbstractFlow implements BaseFlow {
|
||||
final AuthProvider authProvider;
|
||||
final AuthEndpoints authEndpoints;
|
||||
final ClientId clientId;
|
||||
final String? hostedDomain;
|
||||
final List<String> scopes;
|
||||
final http.Client _client;
|
||||
|
||||
AuthorizationCodeGrantAbstractFlow(
|
||||
this.authProvider,
|
||||
this.authEndpoints,
|
||||
this.clientId,
|
||||
this.scopes,
|
||||
this._client, {
|
||||
@@ -28,11 +28,11 @@ abstract class AuthorizationCodeGrantAbstractFlow implements BaseFlow {
|
||||
Future<AccessCredentials> obtainAccessCredentialsUsingCodeImpl(
|
||||
String code,
|
||||
String redirectUri, {
|
||||
required AuthProvider authProvider,
|
||||
required AuthEndpoints authEndpoints,
|
||||
required String codeVerifier,
|
||||
}) =>
|
||||
obtainAccessCredentialsViaCodeExchange(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
_client,
|
||||
clientId,
|
||||
code,
|
||||
@@ -46,7 +46,7 @@ abstract class AuthorizationCodeGrantAbstractFlow implements BaseFlow {
|
||||
required String codeVerifier,
|
||||
}) =>
|
||||
createAuthenticationUri(
|
||||
authProvider: authProvider,
|
||||
authEndpoints: authEndpoints,
|
||||
redirectUri: redirectUri,
|
||||
clientId: clientId.identifier,
|
||||
scopes: scopes,
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ class AuthorizationCodeGrantManualFlow
|
||||
final PromptUserForConsentManual userPrompt;
|
||||
|
||||
AuthorizationCodeGrantManualFlow(
|
||||
super.authProvider,
|
||||
super.authEndpoints,
|
||||
super.clientId,
|
||||
super.scopes,
|
||||
super.client,
|
||||
@@ -48,7 +48,7 @@ class AuthorizationCodeGrantManualFlow
|
||||
return obtainAccessCredentialsUsingCodeImpl(
|
||||
code,
|
||||
_redirectionUri,
|
||||
authProvider: authProvider,
|
||||
authEndpoints: authEndpoints,
|
||||
codeVerifier: codeVerifier,
|
||||
);
|
||||
}
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ class AuthorizationCodeGrantServerFlow
|
||||
final int listenPort;
|
||||
|
||||
AuthorizationCodeGrantServerFlow(
|
||||
super.authProvider,
|
||||
super.authEndpoints,
|
||||
super.clientId,
|
||||
super.scopes,
|
||||
super.client,
|
||||
@@ -90,7 +90,7 @@ class AuthorizationCodeGrantServerFlow
|
||||
final credentials = await obtainAccessCredentialsUsingCodeImpl(
|
||||
code,
|
||||
redirectionUri,
|
||||
authProvider: authProvider,
|
||||
authEndpoints: authEndpoints,
|
||||
codeVerifier: codeVerifier,
|
||||
);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class JwtFlow extends BaseFlow {
|
||||
'grant_type': _uri,
|
||||
'assertion': jwt,
|
||||
},
|
||||
authProvider: GoogleAuthProvider(),
|
||||
authEndpoints: GoogleAuthEndpoints(),
|
||||
);
|
||||
final accessToken = parseAccessToken(response);
|
||||
return AccessCredentials(accessToken, null, _scopes);
|
||||
|
||||
+2
-2
@@ -108,7 +108,7 @@ extension ClientExtensions on Client {
|
||||
|
||||
Future<Map<String, dynamic>> oauthTokenRequest(
|
||||
Map<String, String> postValues, {
|
||||
required AuthProvider authProvider,
|
||||
required AuthEndpoints authEndpoints,
|
||||
}) async {
|
||||
final body = Stream<List<int>>.value(
|
||||
ascii.encode(
|
||||
@@ -117,7 +117,7 @@ extension ClientExtensions on Client {
|
||||
.join('&'),
|
||||
),
|
||||
);
|
||||
final request = RequestImpl('POST', authProvider.tokenEndpoint, body)
|
||||
final request = RequestImpl('POST', authEndpoints.tokenEndpoint, body)
|
||||
..headers['content-type'] = _contentTypeUrlEncoded;
|
||||
|
||||
return requestJson(request, 'Failed to obtain access credentials.');
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ import 'test_utils.dart';
|
||||
|
||||
void main() {
|
||||
test('fromApplicationsCredentialsFile', () async {
|
||||
final authProvider = GoogleAuthProvider();
|
||||
final authEndpoints = GoogleAuthEndpoints();
|
||||
final tmp = await Directory.systemTemp.createTemp('googleapis_auth-test');
|
||||
try {
|
||||
final credsFile = File.fromUri(tmp.uri.resolve('creds.json'));
|
||||
@@ -27,7 +27,7 @@ void main() {
|
||||
}));
|
||||
final c = await fromApplicationsCredentialsFile(
|
||||
credsFile,
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
'test-credentials-file',
|
||||
[],
|
||||
mockClient((Request request) async {
|
||||
@@ -83,7 +83,7 @@ void main() {
|
||||
}));
|
||||
final c = await fromApplicationsCredentialsFile(
|
||||
credsFile,
|
||||
GoogleAuthProvider(),
|
||||
GoogleAuthEndpoints(),
|
||||
'test-credentials-file',
|
||||
[],
|
||||
mockClient((Request request) async {
|
||||
|
||||
@@ -31,7 +31,7 @@ final _browserFlowRedirectMatcher = predicate<String>((object) {
|
||||
void main() {
|
||||
final clientId = ClientId('id', 'secret');
|
||||
final scopes = ['s1', 's2'];
|
||||
final authProvider = GoogleAuthProvider();
|
||||
final authEndpoints = GoogleAuthEndpoints();
|
||||
|
||||
// Validation + Responses from the authorization server.
|
||||
|
||||
@@ -137,7 +137,7 @@ void main() {
|
||||
|
||||
test('successful', () async {
|
||||
final flow = AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: true), expectClose: false),
|
||||
@@ -152,7 +152,7 @@ void main() {
|
||||
Future.error(TransportException());
|
||||
|
||||
final flow = AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: true), expectClose: false),
|
||||
@@ -163,7 +163,7 @@ void main() {
|
||||
|
||||
test('transport-exception', () async {
|
||||
final flow = AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
transportFailure,
|
||||
@@ -174,7 +174,7 @@ void main() {
|
||||
|
||||
test('invalid-server-response', () async {
|
||||
final flow = AuthorizationCodeGrantManualFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(invalidResponse, expectClose: false),
|
||||
@@ -271,7 +271,7 @@ void main() {
|
||||
|
||||
test('successful', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: false), expectClose: false),
|
||||
@@ -282,7 +282,7 @@ void main() {
|
||||
|
||||
test('transport-exception', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
transportFailure,
|
||||
@@ -293,7 +293,7 @@ void main() {
|
||||
|
||||
test('non-GET request', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: false), expectClose: false),
|
||||
@@ -313,7 +313,7 @@ void main() {
|
||||
|
||||
test('request with invalid state parameter', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: false), expectClose: false),
|
||||
@@ -333,7 +333,7 @@ void main() {
|
||||
|
||||
test('invalid-server-response', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(invalidResponse, expectClose: false),
|
||||
@@ -344,7 +344,7 @@ void main() {
|
||||
|
||||
test('failed-authentication', () async {
|
||||
final flow = AuthorizationCodeGrantServerFlow(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
scopes,
|
||||
mockClient(successFullResponse(manual: false), expectClose: false),
|
||||
|
||||
+9
-9
@@ -19,7 +19,7 @@ final _defaultResponse = Response('', 500);
|
||||
Future<Response> _defaultResponseHandler(Request _) async => _defaultResponse;
|
||||
|
||||
void main() {
|
||||
final authProvider = GoogleAuthProvider();
|
||||
final authEndpoints = GoogleAuthEndpoints();
|
||||
|
||||
test('access-token', () {
|
||||
final expiry = DateTime.now().subtract(const Duration(seconds: 1));
|
||||
@@ -165,7 +165,7 @@ void main() {
|
||||
|
||||
test('refreshCredentials-successful', () async {
|
||||
final newCredentials = await refreshCredentials(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(expectAsync1(successfulRefresh), expectClose: false),
|
||||
@@ -187,7 +187,7 @@ void main() {
|
||||
test('refreshCredentials-http-error', () async {
|
||||
await expectLater(
|
||||
refreshCredentials(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(serverError, expectClose: false),
|
||||
@@ -205,7 +205,7 @@ void main() {
|
||||
test('refreshCredentials-error-response', () async {
|
||||
await expectLater(
|
||||
refreshCredentials(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(refreshErrorResponse, expectClose: false),
|
||||
@@ -276,7 +276,7 @@ void main() {
|
||||
|
||||
test('up-to-date', () async {
|
||||
final client = autoRefreshingClient(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(
|
||||
@@ -296,7 +296,7 @@ void main() {
|
||||
|
||||
expect(
|
||||
() => autoRefreshingClient(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(_defaultResponseHandler, expectClose: false),
|
||||
@@ -310,7 +310,7 @@ void main() {
|
||||
AccessToken('Bearer', 'bar', yesterday), 'refresh', ['s1', 's2']);
|
||||
|
||||
final client = autoRefreshingClient(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(expectAsync1((request) {
|
||||
@@ -331,7 +331,7 @@ void main() {
|
||||
AccessToken('Bearer', 'bar', yesterday), 'refresh', ['s1', 's2']);
|
||||
|
||||
final client = autoRefreshingClient(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(expectAsync1((request) async {
|
||||
@@ -356,7 +356,7 @@ void main() {
|
||||
AccessToken('Bearer', 'bar', yesterday), 'refresh', ['s1']);
|
||||
|
||||
final client = autoRefreshingClient(
|
||||
authProvider,
|
||||
authEndpoints,
|
||||
clientId,
|
||||
credentials,
|
||||
mockClient(
|
||||
|
||||
Reference in New Issue
Block a user