TF-4049 Pre-fill OIDC login form
This commit is contained in:
@@ -8,7 +8,13 @@ abstract class AuthenticationOIDCDataSource {
|
||||
|
||||
Future<OIDCDiscoveryResponse> discoverOIDC(OIDCConfiguration oidcConfiguration);
|
||||
|
||||
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl, String discoveryUrl, List<String> scopes);
|
||||
Future<TokenOIDC> getTokenOIDC(
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
});
|
||||
|
||||
Future<void> persistTokenOIDC(TokenOIDC tokenOidc);
|
||||
|
||||
|
||||
@@ -56,9 +56,21 @@ class AuthenticationOIDCDataSourceImpl extends AuthenticationOIDCDataSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl, String discoveryUrl, List<String> scopes) {
|
||||
Future<TokenOIDC> getTokenOIDC(
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
}) {
|
||||
return Future.sync(() async {
|
||||
return await _authenticationClient.getTokenOIDC(clientId, redirectUrl, discoveryUrl, scopes);
|
||||
return await _authenticationClient.getTokenOIDC(
|
||||
clientId,
|
||||
redirectUrl,
|
||||
discoveryUrl,
|
||||
scopes,
|
||||
loginHint: loginHint,
|
||||
);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -13,10 +13,12 @@ abstract class AuthenticationClientBase {
|
||||
List<String> scopes);
|
||||
|
||||
Future<TokenOIDC> getTokenOIDC(
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes);
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
});
|
||||
|
||||
Future<TokenOIDC> refreshingTokensOIDC(
|
||||
String clientId,
|
||||
|
||||
+4
-2
@@ -59,14 +59,16 @@ mixin AuthenticationClientInteractionMixin {
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes,
|
||||
) {
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
}) {
|
||||
return AuthorizationTokenRequest(
|
||||
clientId,
|
||||
redirectUrl,
|
||||
discoveryUrl: discoveryUrl,
|
||||
scopes: scopes,
|
||||
externalUserAgent: getExternalUserAgent(),
|
||||
loginHint: loginHint,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -27,13 +27,15 @@ class AuthenticationClientMobile with AuthenticationClientInteractionMixin
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes,
|
||||
) async {
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
}) async {
|
||||
final authorizationTokenRequest = getAuthorizationTokenRequest(
|
||||
clientId,
|
||||
redirectUrl,
|
||||
discoveryUrl,
|
||||
scopes,
|
||||
loginHint: loginHint,
|
||||
);
|
||||
final authorizationTokenResponse = await _appAuth.authorizeAndExchangeCode(
|
||||
authorizationTokenRequest,
|
||||
|
||||
+4
-2
@@ -25,13 +25,15 @@ class AuthenticationClientWeb with AuthenticationClientInteractionMixin
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes,
|
||||
) async {
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
}) async {
|
||||
final authorizationTokenRequest = getAuthorizationTokenRequest(
|
||||
clientId,
|
||||
redirectUrl,
|
||||
discoveryUrl,
|
||||
scopes,
|
||||
loginHint: loginHint,
|
||||
);
|
||||
final authorizationTokenResponse = await _appAuthWeb.authorizeAndExchangeCode(
|
||||
authorizationTokenRequest,
|
||||
|
||||
@@ -28,8 +28,20 @@ class AuthenticationOIDCRepositoryImpl extends AuthenticationOIDCRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl, String discoveryUrl, List<String> scopes) {
|
||||
return _oidcDataSource.getTokenOIDC(clientId, redirectUrl, discoveryUrl, scopes);
|
||||
Future<TokenOIDC> getTokenOIDC(
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
}) {
|
||||
return _oidcDataSource.getTokenOIDC(
|
||||
clientId,
|
||||
redirectUrl,
|
||||
discoveryUrl,
|
||||
scopes,
|
||||
loginHint: loginHint,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -8,7 +8,13 @@ abstract class AuthenticationOIDCRepository {
|
||||
|
||||
Future<OIDCDiscoveryResponse> discoverOIDC(OIDCConfiguration oidcConfiguration);
|
||||
|
||||
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl, String discoveryUrl, List<String> scopes);
|
||||
Future<TokenOIDC> getTokenOIDC(
|
||||
String clientId,
|
||||
String redirectUrl,
|
||||
String discoveryUrl,
|
||||
List<String> scopes, {
|
||||
String? loginHint,
|
||||
});
|
||||
|
||||
Future<void> persistTokenOIDC(TokenOIDC tokenOidc);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:model/oidc/oidc_configuration.dart';
|
||||
import 'package:model/oidc/response/oidc_response.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/model/base_url_oidc_response.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart';
|
||||
@@ -12,12 +13,20 @@ class GetOIDCConfigurationInteractor {
|
||||
|
||||
GetOIDCConfigurationInteractor(this._oidcRepository);
|
||||
|
||||
Stream<Either<Failure, Success>> execute(OIDCResponse oidcResponse) async* {
|
||||
Stream<Either<Failure, Success>> execute(
|
||||
OIDCResponse oidcResponse, {
|
||||
String? loginHint,
|
||||
}) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(GetOIDCConfigurationLoading());
|
||||
final oidcConfiguration = await _oidcRepository.getOIDCConfiguration(oidcResponse);
|
||||
await _oidcRepository.persistOidcConfiguration(oidcConfiguration);
|
||||
yield Right<Failure, Success>(GetOIDCConfigurationSuccess(oidcConfiguration));
|
||||
final configWithLoginHint = oidcConfiguration.copyWidth(
|
||||
loginHint: loginHint,
|
||||
);
|
||||
await _oidcRepository.persistOidcConfiguration(configWithLoginHint);
|
||||
yield Right<Failure, Success>(
|
||||
GetOIDCConfigurationSuccess(configWithLoginHint),
|
||||
);
|
||||
} catch (e) {
|
||||
logError('$runtimeType::execute():oidcResponse = ${oidcResponse.runtimeType} | Exception = $e');
|
||||
if (oidcResponse is BaseUrlOidcResponse) {
|
||||
|
||||
@@ -27,10 +27,12 @@ class GetTokenOIDCInteractor {
|
||||
try {
|
||||
yield Right<Failure, Success>(GetTokenOIDCLoading());
|
||||
final tokenOIDC = await authenticationOIDCRepository.getTokenOIDC(
|
||||
config.clientId,
|
||||
config.redirectUrl,
|
||||
config.discoveryUrl,
|
||||
config.scopes);
|
||||
config.clientId,
|
||||
config.redirectUrl,
|
||||
config.discoveryUrl,
|
||||
config.scopes,
|
||||
loginHint: config.loginHint,
|
||||
);
|
||||
|
||||
await Future.wait([
|
||||
_credentialRepository.saveBaseUrl(baseUri),
|
||||
|
||||
@@ -188,7 +188,7 @@ class LoginController extends ReloadableController {
|
||||
} else if (success is CheckOIDCIsAvailableSuccess) {
|
||||
getOIDCConfiguration(success.oidcResponse);
|
||||
} else if (success is GetOIDCConfigurationSuccess) {
|
||||
_getOIDCConfigurationSuccess(success);
|
||||
_getOIDCConfigurationSuccess(success.oidcConfiguration);
|
||||
} else if (success is GetTokenOIDCSuccess) {
|
||||
_getTokenOIDCSuccess(success);
|
||||
} else if (success is AuthenticationUserSuccess) {
|
||||
@@ -413,16 +413,23 @@ class LoginController extends ReloadableController {
|
||||
}
|
||||
|
||||
void getOIDCConfiguration(OIDCResponse oidcResponse) {
|
||||
consumeState(_getOIDCConfigurationInteractor.execute(oidcResponse));
|
||||
final loginHint = PlatformInfo.isMobile ? _username?.value : null;
|
||||
log('$runtimeType::getOIDCConfiguration:loginHint = $loginHint');
|
||||
consumeState(
|
||||
_getOIDCConfigurationInteractor.execute(
|
||||
oidcResponse,
|
||||
loginHint: loginHint,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _getOIDCConfigurationSuccess(GetOIDCConfigurationSuccess success) {
|
||||
void _getOIDCConfigurationSuccess(OIDCConfiguration config) {
|
||||
if (PlatformInfo.isWeb) {
|
||||
_authenticateOidcOnBrowserAction(success.oidcConfiguration);
|
||||
} else if (success.oidcConfiguration.authority == AppConfig.saasRegistrationUrl) {
|
||||
_getTokenOIDCOnSaaSPlatform(success.oidcConfiguration);
|
||||
_authenticateOidcOnBrowserAction(config);
|
||||
} else if (config.authority == AppConfig.saasRegistrationUrl) {
|
||||
_getTokenOIDCOnSaaSPlatform(config);
|
||||
} else {
|
||||
_getTokenOIDCAction(success.oidcConfiguration);
|
||||
_getTokenOIDCAction(config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,14 @@ class OIDCConfiguration with EquatableMixin {
|
||||
final String clientId;
|
||||
final List<String> scopes;
|
||||
final bool isTWP;
|
||||
final String? loginHint;
|
||||
|
||||
OIDCConfiguration({
|
||||
required this.authority,
|
||||
required this.clientId,
|
||||
required this.scopes,
|
||||
this.isTWP = false,
|
||||
this.loginHint,
|
||||
});
|
||||
|
||||
String get discoveryUrl {
|
||||
@@ -30,5 +32,23 @@ class OIDCConfiguration with EquatableMixin {
|
||||
clientId,
|
||||
scopes,
|
||||
isTWP,
|
||||
loginHint,
|
||||
];
|
||||
}
|
||||
|
||||
extension OIDCConfigurationExtension on OIDCConfiguration {
|
||||
OIDCConfiguration copyWidth({
|
||||
String? authority,
|
||||
String? clientId,
|
||||
List<String>? scopes,
|
||||
bool? isTWP,
|
||||
String? loginHint,
|
||||
}) =>
|
||||
OIDCConfiguration(
|
||||
authority: authority ?? this.authority,
|
||||
clientId: clientId ?? this.clientId,
|
||||
scopes: scopes ?? this.scopes,
|
||||
isTWP: isTWP ?? this.isTWP,
|
||||
loginHint: loginHint ?? this.loginHint,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user