TF-571 Check OIDC is available

This commit is contained in:
dab246
2022-05-20 12:38:31 +07:00
committed by Dat H. Pham
parent c5aa9f7d69
commit 239234f836
29 changed files with 625 additions and 55 deletions
@@ -42,6 +42,8 @@ abstract class BaseLoginView extends GetWidget<LoginController> {
(success) {
if (loginController.loginFormType.value == LoginFormType.credentialForm || kIsWeb) {
return AppLocalizations.of(context).loginInputCredentialMessage;
} else if (loginController.loginFormType.value == LoginFormType.ssoForm) {
return AppLocalizations.of(context).loginInputSSOMessage;
}
return AppLocalizations.of(context).loginInputUrlMessage;
}))
@@ -3,33 +3,48 @@ import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/login/data/datasource/authentication_datasource.dart';
import 'package:tmail_ui_user/features/login/data/datasource/authentication_oidc_datasource.dart';
import 'package:tmail_ui_user/features/login/data/datasource_impl/authentication_datasource_impl.dart';
import 'package:tmail_ui_user/features/login/data/datasource_impl/authentication_oidc_datasource_impl.dart';
import 'package:tmail_ui_user/features/login/data/network/oidc_http_client.dart';
import 'package:tmail_ui_user/features/login/data/repository/authentication_oidc_repository_impl.dart';
import 'package:tmail_ui_user/features/login/data/repository/authentication_repository_impl.dart';
import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart';
import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart';
import 'package:tmail_ui_user/features/login/domain/repository/authentication_repository.dart';
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/authentication_user_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/check_oidc_is_available_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/login_controller.dart';
class LoginBindings extends BaseBindings {
@override
void dependencies() {
Get.lazyPut(() => OIDCHttpClient(Get.find<DioClient>()));
super.dependencies();
}
@override
void bindingsController() {
Get.lazyPut(() => LoginController(
Get.find<AuthenticationInteractor>(),
Get.find<DynamicUrlInterceptors>(),
Get.find<AuthorizationInterceptors>(),
Get.find<CheckOIDCIsAvailableInteractor>(),
));
}
@override
void bindingsDataSource() {
Get.lazyPut<AuthenticationDataSource>(() => Get.find<AuthenticationDataSourceImpl>());
Get.lazyPut<AuthenticationOIDCDataSource>(() => Get.find<AuthenticationOIDCDataSourceImpl>());
}
@override
void bindingsDataSourceImpl() {
Get.lazyPut(() => AuthenticationDataSourceImpl());
Get.lazyPut(() => AuthenticationOIDCDataSourceImpl(Get.find<OIDCHttpClient>()));
}
@override
@@ -38,17 +53,22 @@ class LoginBindings extends BaseBindings {
Get.find<AuthenticationRepository>(),
Get.find<CredentialRepository>(),
));
Get.lazyPut(() => CheckOIDCIsAvailableInteractor(
Get.find<AuthenticationOIDCRepository>(),
));
}
@override
void bindingsRepository() {
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
Get.lazyPut<AuthenticationRepository>(() => Get.find<AuthenticationRepositoryImpl>());
Get.lazyPut<AuthenticationOIDCRepository>(() => Get.find<AuthenticationOIDCRepositoryImpl>());
}
@override
void bindingsRepositoryImpl() {
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
Get.lazyPut(() => AuthenticationRepositoryImpl(Get.find<AuthenticationDataSource>()));
Get.lazyPut(() => AuthenticationOIDCRepositoryImpl(Get.find<AuthenticationOIDCDataSource>()));
}
}
@@ -5,7 +5,9 @@ import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/login/domain/state/authentication_user_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/check_oidc_is_available_state.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/authentication_user_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/check_oidc_is_available_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
@@ -17,6 +19,7 @@ class LoginController extends GetxController {
final AuthenticationInteractor _authenticationInteractor;
final DynamicUrlInterceptors _dynamicUrlInterceptors;
final AuthorizationInterceptors _authorizationInterceptors;
final CheckOIDCIsAvailableInteractor _checkOIDCIsAvailableInteractor;
final TextEditingController urlInputController = TextEditingController();
@@ -24,6 +27,7 @@ class LoginController extends GetxController {
this._authenticationInteractor,
this._dynamicUrlInterceptors,
this._authorizationInterceptors,
this._checkOIDCIsAvailableInteractor,
);
var loginState = LoginState(Right(LoginInitAction())).obs;
@@ -33,20 +37,48 @@ class LoginController extends GetxController {
String? _userNameText;
String? _passwordText;
void setUrlText(String url) => _urlText = url.formatURLValid();
void setUrlText(String url) => _urlText = url.trim().formatURLValid();
void setUserNameText(String userName) => _userNameText = userName;
void setPasswordText(String password) => _passwordText = password;
Uri? _parseUri(String? url) => url != null ? Uri.parse(url.trim()) : null;
Uri? _parseUri(String? url) => url != null && url.trim().isNotEmpty
? Uri.parse(url.trim())
: null;
UserName? _parseUserName(String? userName) => userName != null ? UserName(userName.trim()) : null;
UserName? _parseUserName(String? userName) => userName != null && userName.trim().isNotEmpty
? UserName(userName.trim())
: null;
Password? _parsePassword(String? password) => password != null ? Password(password.trim()) : null;
Password? _parsePassword(String? password) => password != null && password.trim().isNotEmpty
? Password(password.trim())
: null;
void handleNextInUrlInputFormPress() {
completeInputUrlAction();
_checkOIDCIsAvailable();
}
void _checkOIDCIsAvailable() async {
final baseUri = BuildUtils.isWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
if (baseUri == null) {
loginState.value = LoginState(Left(LoginMissUrlAction()));
} else {
loginState.value = LoginState(Right(LoginLoadingAction()));
await _checkOIDCIsAvailableInteractor
.execute(OIDCRequest(baseUrl: baseUri.path))
.then((response) => response.fold(
(failure) => _showFormLoginWithCredentialAction(),
(success) => success is CheckOIDCIsAvailableSuccess
? _showFormLoginWithSSOAction(success)
: _showFormLoginWithCredentialAction()));
}
}
void _showFormLoginWithSSOAction(CheckOIDCIsAvailableSuccess success) {
loginState.value = LoginState(Right(success));
loginFormType.value = LoginFormType.ssoForm;
}
void handleBackInCredentialForm() {
@@ -54,23 +86,27 @@ class LoginController extends GetxController {
loginFormType.value = LoginFormType.baseUrlForm;
}
void completeInputUrlAction() {
void _showFormLoginWithCredentialAction() {
loginState.value = LoginState(Right(InputUrlCompletion()));
loginFormType.value = LoginFormType.credentialForm;
}
void handleLoginPressed() {
final baseUri = kIsWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
final userName = _parseUserName(_userNameText);
final password = _parsePassword(_passwordText);
if (baseUri != null && userName != null && password != null) {
_loginAction(baseUri, userName, password);
} else if (baseUri == null) {
loginState.value = LoginState(Left(LoginMissUrlAction()));
} else if (userName == null) {
loginState.value = LoginState(Left(LoginMissUsernameAction()));
} else if (password == null) {
loginState.value = LoginState(Left(LoginMissPasswordAction()));
if (loginFormType.value == LoginFormType.ssoForm) {
} else {
final baseUri = kIsWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
final userName = _parseUserName(_userNameText);
final password = _parsePassword(_passwordText);
if (baseUri != null && userName != null && password != null) {
_loginAction(baseUri, userName, password);
} else if (baseUri == null) {
loginState.value = LoginState(Left(LoginMissUrlAction()));
} else if (userName == null) {
loginState.value = LoginState(Left(LoginMissUsernameAction()));
} else if (password == null) {
loginState.value = LoginState(Left(LoginMissPasswordAction()));
}
}
}
@@ -1,3 +1,3 @@
enum LoginFormType {
none, baseUrlForm, credentialForm
none, baseUrlForm, credentialForm, ssoForm
}
@@ -26,9 +26,11 @@ class LoginView extends BaseLoginView {
children: [
Center(child: SingleChildScrollView(child: _buildCenterForm(context), scrollDirection: Axis.vertical)),
Obx(() {
return loginController.loginFormType.value == LoginFormType.credentialForm
? _buildBackButton(context)
: const SizedBox.shrink();
if (loginController.loginFormType.value == LoginFormType.credentialForm
|| loginController.loginFormType.value == LoginFormType.ssoForm) {
return _buildBackButton(context);
}
return const SizedBox.shrink();
})
]
)
@@ -36,9 +38,11 @@ class LoginView extends BaseLoginView {
children: [
_buildCenterForm(context),
Obx(() {
return loginController.loginFormType.value == LoginFormType.credentialForm
? _buildBackButton(context)
: const SizedBox.shrink();
if (loginController.loginFormType.value == LoginFormType.credentialForm
|| loginController.loginFormType.value == LoginFormType.ssoForm) {
return _buildBackButton(context);
}
return const SizedBox.shrink();
})
]
),
@@ -78,15 +82,23 @@ class LoginView extends BaseLoginView {
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return _supportScrollForm(context)
? _buildNextButton(context)
: _buildExpandedButton(context, _buildNextButton(context));
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildNextButtonInContext(context),
(success) => success is LoginLoadingAction
? _buildLoadingCircularProgress()
: _buildNextButtonInContext(context)));
case LoginFormType.credentialForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildLoginButtonInContext(context),
(success) => success is LoginLoadingAction
? _buildLoadingCircularProgress()
: _buildLoginButtonInContext(context)));
case LoginFormType.ssoForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildLoginButtonInContext(context),
(success) => success is LoginLoadingAction
? _buildLoadingCircularProgress()
: _buildLoginButtonInContext(context)));
default:
return const SizedBox.shrink();
}
@@ -166,6 +178,12 @@ class LoginView extends BaseLoginView {
);
}
Widget _buildNextButtonInContext(BuildContext context) {
return _supportScrollForm(context)
? _buildNextButton(context)
: _buildExpandedButton(context, _buildNextButton(context));
}
Widget _buildLoginButtonInContext(BuildContext context) {
return _supportScrollForm(context)
? buildLoginButton(context)