From ad975fce8e52df6e3d166310bb39698dc1b8a68b Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 4 Mar 2025 11:50:15 +0700 Subject: [PATCH] TF-3484 Try get oidc configuration if possible when web finger is not available Signed-off-by: dab246 --- .../domain/model/base_url_oidc_response.dart | 14 ++++++++++ .../state/get_oidc_configuration_state.dart | 5 ++++ .../get_oidc_configuration_interactor.dart | 9 +++++-- .../handle_openid_configuration.dart | 14 ++++++++++ .../login/presentation/login_controller.dart | 26 ++++++++++++++++--- 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 lib/features/login/domain/model/base_url_oidc_response.dart create mode 100644 lib/features/login/presentation/extensions/handle_openid_configuration.dart diff --git a/lib/features/login/domain/model/base_url_oidc_response.dart b/lib/features/login/domain/model/base_url_oidc_response.dart new file mode 100644 index 000000000..06373b21f --- /dev/null +++ b/lib/features/login/domain/model/base_url_oidc_response.dart @@ -0,0 +1,14 @@ + +import 'package:model/oidc/response/oidc_link_dto.dart'; +import 'package:model/oidc/response/oidc_response.dart'; + +class BaseUrlOidcResponse extends OIDCResponse { + + BaseUrlOidcResponse(Uri baseUri) : super( + '', + [ + OIDCLinkDto(baseUri, baseUri) + ], + ); +} + diff --git a/lib/features/login/domain/state/get_oidc_configuration_state.dart b/lib/features/login/domain/state/get_oidc_configuration_state.dart index af9f16b98..2965f7153 100644 --- a/lib/features/login/domain/state/get_oidc_configuration_state.dart +++ b/lib/features/login/domain/state/get_oidc_configuration_state.dart @@ -17,4 +17,9 @@ class GetOIDCConfigurationSuccess extends UIState { class GetOIDCConfigurationFailure extends FeatureFailure { GetOIDCConfigurationFailure(dynamic exception) : super(exception: exception); +} + +class GetOIDCConfigurationFromBaseUrlFailure extends FeatureFailure { + + GetOIDCConfigurationFromBaseUrlFailure(dynamic exception) : super(exception: exception); } \ No newline at end of file diff --git a/lib/features/login/domain/usecases/get_oidc_configuration_interactor.dart b/lib/features/login/domain/usecases/get_oidc_configuration_interactor.dart index 714358263..92698b767 100644 --- a/lib/features/login/domain/usecases/get_oidc_configuration_interactor.dart +++ b/lib/features/login/domain/usecases/get_oidc_configuration_interactor.dart @@ -3,6 +3,7 @@ import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.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'; import 'package:tmail_ui_user/features/login/domain/state/get_oidc_configuration_state.dart'; @@ -18,8 +19,12 @@ class GetOIDCConfigurationInteractor { await _oidcRepository.persistOidcConfiguration(oidcConfiguration); yield Right(GetOIDCConfigurationSuccess(oidcConfiguration)); } catch (e) { - log('GetOIDCConfigurationInteractor::execute(): ERROR: $e'); - yield Left(GetOIDCConfigurationFailure(e)); + logError('$runtimeType::execute():oidcResponse = ${oidcResponse.runtimeType} | Exception = $e'); + if (oidcResponse is BaseUrlOidcResponse) { + yield Left(GetOIDCConfigurationFromBaseUrlFailure(e)); + } else { + yield Left(GetOIDCConfigurationFailure(e)); + } } } } \ No newline at end of file diff --git a/lib/features/login/presentation/extensions/handle_openid_configuration.dart b/lib/features/login/presentation/extensions/handle_openid_configuration.dart new file mode 100644 index 000000000..d8b35fd1b --- /dev/null +++ b/lib/features/login/presentation/extensions/handle_openid_configuration.dart @@ -0,0 +1,14 @@ + +import 'package:tmail_ui_user/features/login/domain/model/base_url_oidc_response.dart'; +import 'package:tmail_ui_user/features/login/presentation/login_controller.dart'; + +extension HandleOpenidConfiguration on LoginController { + + void tryGetOIDCConfigurationFromBaseUrl(Uri baseUri) { + getOIDCConfiguration(BaseUrlOidcResponse(baseUri)); + } + + void handleGetOIDCConfigurationFromBaseUrlFailure() { + handleOIDCIsNotAvailable(featureFailure); + } +} \ No newline at end of file diff --git a/lib/features/login/presentation/login_controller.dart b/lib/features/login/presentation/login_controller.dart index c2be4505e..e46f42249 100644 --- a/lib/features/login/presentation/login_controller.dart +++ b/lib/features/login/presentation/login_controller.dart @@ -50,6 +50,7 @@ import 'package:tmail_ui_user/features/login/domain/usecases/get_stored_oidc_con import 'package:tmail_ui_user/features/login/domain/usecases/get_token_oidc_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/save_login_url_on_mobile_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/save_login_username_on_mobile_interactor.dart'; +import 'package:tmail_ui_user/features/login/presentation/extensions/handle_openid_configuration.dart'; import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart'; import 'package:tmail_ui_user/features/login/presentation/model/login_arguments.dart'; import 'package:tmail_ui_user/features/starting_page/domain/state/sign_in_twake_workplace_state.dart'; @@ -92,7 +93,7 @@ class LoginController extends ReloadableController { UserName? _username; Password? _password; Uri? _baseUri; - + FeatureFailure? featureFailure; DeepLinksManager? _deepLinksManager; StreamSubscription? _deepLinkDataStreamSubscription; @@ -147,6 +148,8 @@ class LoginController extends ReloadableController { getAuthenticatedAccountAction(); } else if (failure is CheckOIDCIsAvailableFailure) { _handleCheckOIDCIsAvailableFailure(failure); + } else if (failure is GetOIDCConfigurationFromBaseUrlFailure) { + handleGetOIDCConfigurationFromBaseUrlFailure(); } else if (failure is GetStoredOidcConfigurationFailure || failure is GetOIDCConfigurationFailure || failure is SignInTwakeWorkplaceFailure @@ -176,7 +179,7 @@ class LoginController extends ReloadableController { } else if (success is GetStoredOidcConfigurationSuccess) { _getTokenOIDCAction(success.oidcConfiguration); } else if (success is CheckOIDCIsAvailableSuccess) { - _getOIDCConfiguration(success.oidcResponse); + getOIDCConfiguration(success.oidcResponse); } else if (success is GetOIDCConfigurationSuccess) { _getOIDCConfigurationSuccess(success); } else if (success is GetTokenOIDCSuccess) { @@ -201,6 +204,8 @@ class LoginController extends ReloadableController { logError('LoginController::handleUrgentException:Exception: $exception | Failure: $failure'); if (failure is CheckOIDCIsAvailableFailure) { _handleCheckOIDCIsAvailableFailure(failure); + } else if (failure is GetOIDCConfigurationFromBaseUrlFailure) { + handleGetOIDCConfigurationFromBaseUrlFailure(); } else if (failure is GetStoredOidcConfigurationFailure || failure is GetOIDCConfigurationFailure || failure is SignInTwakeWorkplaceFailure @@ -264,11 +269,23 @@ class LoginController extends ReloadableController { } void _handleCheckOIDCIsAvailableFailure(CheckOIDCIsAvailableFailure failure) { - if (failure.exception is CanNotFoundOIDCLinks || failure.exception is InvalidOIDCResponseException) { + try { + featureFailure = failure; + tryGetOIDCConfigurationFromBaseUrl(_currentBaseUrl!); + } catch (e) { + logError('LoginController::_handleCheckOIDCIsAvailableFailure:Exception = $e'); + handleOIDCIsNotAvailable(failure); + } + } + + void handleOIDCIsNotAvailable(FeatureFailure? failure) { + if (failure?.exception is CanNotFoundOIDCLinks || + failure?.exception is InvalidOIDCResponseException) { _handleCommonOIDCFailure(); } else { loginFormType.value = LoginFormType.retry; } + featureFailure = null; } void retryCheckOidc() { @@ -368,7 +385,7 @@ class LoginController extends ReloadableController { } } - void _getOIDCConfiguration(OIDCResponse oidcResponse) { + void getOIDCConfiguration(OIDCResponse oidcResponse) { consumeState(_getOIDCConfigurationInteractor.execute(oidcResponse)); } @@ -599,6 +616,7 @@ class LoginController extends ReloadableController { @override void onClose() { + featureFailure = null; passFocusNode.dispose(); baseUrlFocusNode.dispose(); userNameFocusNode.dispose();