Skip to content

Commit

Permalink
fix(auth): Fetch AWS credentials after Hosted UI login (aws-amplify#2956
Browse files Browse the repository at this point in the history
  • Loading branch information
dnys1 authored and Stivenmore committed Jun 9, 2023
1 parent ba93a94 commit 1295697
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class HostedUiStateMachine
/// The platform-specific behavior.
late final HostedUiPlatform _platform = getOrCreate();

/// The configured identity pool.
CognitoIdentityCredentialsProvider? get _identityPoolConfig => get();

@override
Future<void> resolve(HostedUiEvent event) async {
switch (event.type) {
Expand Down Expand Up @@ -193,6 +196,16 @@ class HostedUiStateMachine
),
);

// Clear anonymous credentials, if there were any, and fetch authenticated
// credentials.
if (_identityPoolConfig != null) {
await manager.clearCredentials(
CognitoIdentityPoolKeys(_identityPoolConfig!),
);

await manager.loadSession();
}

final idToken = event.tokens.idToken;
final userId = idToken.userId;
final username = CognitoIdToken(idToken).username;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart';
import 'package:amplify_auth_cognito_dart/src/credentials/cognito_keys.dart';
import 'package:amplify_auth_cognito_dart/src/flows/hosted_ui/hosted_ui_platform.dart';
import 'package:amplify_auth_cognito_dart/src/model/hosted_ui/oauth_parameters.dart';
import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity.dart';
import 'package:amplify_auth_cognito_dart/src/state/cognito_state_machine.dart';
import 'package:amplify_auth_cognito_dart/src/state/state.dart';
import 'package:amplify_auth_cognito_test/common/mock_config.dart';
import 'package:amplify_auth_cognito_test/common/mock_dispatcher.dart';
import 'package:amplify_auth_cognito_test/common/mock_hosted_ui.dart';
import 'package:amplify_auth_cognito_test/common/mock_oauth_server.dart';
import 'package:amplify_auth_cognito_test/common/mock_secure_storage.dart';
import 'package:amplify_auth_cognito_test/amplify_auth_cognito_test.dart';
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_secure_storage_dart/amplify_secure_storage_dart.dart';
import 'package:http/http.dart' as http;
Expand Down Expand Up @@ -72,6 +69,7 @@ class FailingHostedUiPlatform extends HostedUiPlatform {
}

void main() {
AWSLogger().logLevel = LogLevel.verbose;
const keys = HostedUiKeys(hostedUiConfig);

group('HostedUiStateMachine', () {
Expand Down Expand Up @@ -263,7 +261,7 @@ void main() {
});

group('onExchange', () {
test('no provider', () async {
setUp(() async {
stateMachine
.dispatch(ConfigurationEvent.configure(mockConfig))
.ignore();
Expand All @@ -277,12 +275,39 @@ void main() {
]),
);

stateMachine.addInstance<CognitoIdentityClient>(
MockCognitoIdentityClient(
getId: () async => GetIdResponse(
identityId: identityId,
),
getCredentialsForIdentity: () async =>
GetCredentialsForIdentityResponse(
credentials: Credentials(
accessKeyId: accessKeyId,
secretKey: secretAccessKey,
sessionToken: sessionToken,
expiration: expiration,
),
),
),
);
});

test('no provider', () async {
await expectLater(
secureStorage.read(
key: identityPoolKeys[CognitoIdentityPoolKey.sessionToken],
),
isNull,
reason: "Shouldn't have AWS credentials before sign in",
);

stateMachine.dispatch(const HostedUiEvent.signIn()).ignore();
final params = await server.authorize(await _launchUrl.future);
stateMachine.dispatch(HostedUiEvent.exchange(params)).ignore();

expect(
sm.stream,
stateMachine.stream.whereType<HostedUiState>(),
emitsInOrder(<Matcher>[
isA<HostedUiSigningIn>(),
isA<HostedUiSignedIn>().having(
Expand All @@ -294,34 +319,38 @@ void main() {
);
expect(
stateMachine.stream.whereType<CredentialStoreState>(),
emitsThrough(
isA<CredentialStoreSuccess>()
.having(
(state) => state.data.userPoolTokens,
'tokens',
isNotNull,
)
.having(
(state) => state.data.userPoolTokens!.signInMethod,
'signInMethod',
CognitoSignInMethod.hostedUi,
),
),
allOf([
emitsThrough(
isA<CredentialStoreSuccess>()
.having(
(state) => state.data.userPoolTokens,
'tokens',
isNotNull,
)
.having(
(state) => state.data.userPoolTokens!.signInMethod,
'signInMethod',
CognitoSignInMethod.hostedUi,
),
),
emitsThrough(
isA<CredentialStoreSuccess>().having(
(state) => state.data.awsCredentials?.sessionToken,
'sessionToken',
sessionToken,
),
),
]),
);
});

test('w/ provider', () async {
stateMachine
.dispatch(ConfigurationEvent.configure(mockConfig))
.ignore();

final sm = stateMachine.getOrCreate(HostedUiStateMachine.type);
await expectLater(
sm.stream,
emitsInOrder(<Matcher>[
isA<HostedUiConfiguring>(),
isA<HostedUiSignedOut>(),
]),
secureStorage.read(
key: identityPoolKeys[CognitoIdentityPoolKey.sessionToken],
),
isNull,
reason: "Shouldn't have AWS credentials before sign in",
);

const provider = AuthProvider.oidc('providerName', 'issuer');
Expand All @@ -334,7 +363,7 @@ void main() {
stateMachine.dispatch(HostedUiEvent.exchange(params)).ignore();

expect(
sm.stream,
stateMachine.stream.whereType<HostedUiState>(),
emitsInOrder(<Matcher>[
isA<HostedUiSigningIn>(),
isA<HostedUiSignedIn>().having(
Expand All @@ -350,36 +379,32 @@ void main() {
);
expect(
stateMachine.stream.whereType<CredentialStoreState>(),
emitsThrough(
isA<CredentialStoreSuccess>()
.having(
(state) => state.data.userPoolTokens,
'tokens',
isNotNull,
)
.having(
(state) => state.data.userPoolTokens!.signInMethod,
'signInMethod',
CognitoSignInMethod.hostedUi,
),
),
allOf([
emitsThrough(
isA<CredentialStoreSuccess>()
.having(
(state) => state.data.userPoolTokens,
'tokens',
isNotNull,
)
.having(
(state) => state.data.userPoolTokens!.signInMethod,
'signInMethod',
CognitoSignInMethod.hostedUi,
),
),
emitsThrough(
isA<CredentialStoreSuccess>().having(
(state) => state.data.awsCredentials?.sessionToken,
'sessionToken',
sessionToken,
),
),
]),
);
});

test('fails with remote error', () async {
stateMachine
.dispatch(ConfigurationEvent.configure(mockConfig))
.ignore();

final sm = stateMachine.getOrCreate(HostedUiStateMachine.type);
await expectLater(
sm.stream,
emitsInOrder(<Matcher>[
isA<HostedUiConfiguring>(),
isA<HostedUiSignedOut>(),
]),
);

stateMachine.dispatch(const HostedUiEvent.signIn()).ignore();
await server.authorize(await _launchUrl.future);

Expand All @@ -397,7 +422,7 @@ void main() {
.ignore();

expect(
sm.stream,
stateMachine.stream.whereType<HostedUiState>(),
emitsInOrder(<Matcher>[
isA<HostedUiSigningIn>(),
isA<HostedUiFailure>(),
Expand All @@ -406,19 +431,6 @@ void main() {
});

test('fails with bad code', () async {
stateMachine
.dispatch(ConfigurationEvent.configure(mockConfig))
.ignore();

final sm = stateMachine.getOrCreate(HostedUiStateMachine.type);
await expectLater(
sm.stream,
emitsInOrder(<Matcher>[
isA<HostedUiConfiguring>(),
isA<HostedUiSignedOut>(),
]),
);

stateMachine.dispatch(const HostedUiEvent.signIn()).ignore();
await server.authorize(await _launchUrl.future);
stateMachine
Expand All @@ -434,7 +446,7 @@ void main() {
.ignore();

expect(
sm.stream,
stateMachine.stream.whereType<HostedUiState>(),
emitsInOrder(<Matcher>[
isA<HostedUiSigningIn>(),
isA<HostedUiFailure>(),
Expand Down

0 comments on commit 1295697

Please sign in to comment.