From 69b2dbf3cf5ae2a3db652a9f0a0de37c2ffe70d8 Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 2 Jun 2022 16:46:08 +0700 Subject: [PATCH] TF-605 Use bearer token download attachment on iOS --- .../email/data/network/email_api.dart | 8 +++- ...ownload_attachment_for_web_interactor.dart | 5 ++- .../download_attachments_interactor.dart | 5 ++- .../export_attachment_interactor.dart | 43 ++++++++++++++++--- .../email/presentation/email_bindings.dart | 26 +++++++++++ .../email/presentation/email_controller.dart | 1 + .../data/local/token_oidc_cache_manager.dart | 1 + .../presentation_mailbox_extension.dart | 2 +- model/lib/account/account_request.dart | 23 ++++++---- 9 files changed, 96 insertions(+), 18 deletions(-) diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index 9fd849b7e..1e636f707 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -194,11 +194,17 @@ class EmailAPI { AccountRequest accountRequest, CancelToken cancelToken ) async { + final authentication = accountRequest.authenticationType == AuthenticationType.oidc + ? accountRequest.bearerToken + : accountRequest.basicAuth; + + log('EmailAPI::exportAttachment(): authentication: $authentication'); + return _downloadManager.downloadFile( attachment.getDownloadUrl(baseDownloadUrl, accountId), getTemporaryDirectory(), attachment.name ?? '', - accountRequest.basicAuth, + authentication, cancelToken: cancelToken); } diff --git a/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart b/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart index 4b72d2359..6c861db74 100644 --- a/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart +++ b/lib/features/email/domain/usecases/download_attachment_for_web_interactor.dart @@ -20,7 +20,10 @@ class DownloadAttachmentForWebInteractor { [credentialRepository.getUserName(), credentialRepository.getPassword()], eagerError: true ).then((List responses) async { - final accountRequest = AccountRequest(responses.first, responses.last); + final accountRequest = AccountRequest( + userName: responses.first, + password: responses.last, + authenticationType: AuthenticationType.basic); return await emailRepository.downloadAttachmentForWeb( attachment, accountId, diff --git a/lib/features/email/domain/usecases/download_attachments_interactor.dart b/lib/features/email/domain/usecases/download_attachments_interactor.dart index 797d45104..add39dddf 100644 --- a/lib/features/email/domain/usecases/download_attachments_interactor.dart +++ b/lib/features/email/domain/usecases/download_attachments_interactor.dart @@ -22,7 +22,10 @@ class DownloadAttachmentsInteractor { [credentialRepository.getUserName(), credentialRepository.getPassword()], eagerError: true ).then((List responses) async { - final accountRequest = AccountRequest(responses.first, responses.last); + final accountRequest = AccountRequest( + userName: responses.first, + password: responses.last, + authenticationType: AuthenticationType.basic); return await emailRepository.downloadAttachments( attachments, accountId, diff --git a/lib/features/email/domain/usecases/export_attachment_interactor.dart b/lib/features/email/domain/usecases/export_attachment_interactor.dart index ac3115708..240e730ba 100644 --- a/lib/features/email/domain/usecases/export_attachment_interactor.dart +++ b/lib/features/email/domain/usecases/export_attachment_interactor.dart @@ -7,13 +7,22 @@ import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:model/model.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart'; +import 'package:tmail_ui_user/features/login/domain/repository/account_repository.dart'; +import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart'; import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; class ExportAttachmentInteractor { final EmailRepository emailRepository; final CredentialRepository credentialRepository; + final AccountRepository _accountRepository; + final AuthenticationOIDCRepository _authenticationOIDCRepository; - ExportAttachmentInteractor(this.emailRepository, this.credentialRepository); + ExportAttachmentInteractor( + this.emailRepository, + this.credentialRepository, + this._accountRepository, + this._authenticationOIDCRepository, + ); Stream> execute( Attachment attachment, @@ -22,11 +31,34 @@ class ExportAttachmentInteractor { CancelToken cancelToken ) async* { try { - final filePath = await Future.wait( - [credentialRepository.getUserName(), credentialRepository.getPassword()], - eagerError: true + final account = await _accountRepository.getCurrentAccount(); + + log('ExportAttachmentInteractor::execute(): account: $account'); + + final filePath = await Future.wait([ + if (account.authenticationType == AuthenticationType.oidc) + _authenticationOIDCRepository.getStoredTokenOIDC(account.id) + else + ...[ + credentialRepository.getUserName(), + credentialRepository.getPassword() + ] + ], eagerError: true ).then((List responses) async { - final accountRequest = AccountRequest(responses.first, responses.last); + AccountRequest accountRequest; + + if (account.authenticationType == AuthenticationType.oidc) { + final tokenOidc = responses.first as TokenOIDC; + accountRequest = AccountRequest( + token: tokenOidc.toToken(), + authenticationType: AuthenticationType.oidc); + } else { + accountRequest = AccountRequest( + userName: responses.first as UserName, + password: responses.last as Password, + authenticationType: AuthenticationType.basic); + } + return await emailRepository.exportAttachment( attachment, accountId, @@ -36,6 +68,7 @@ class ExportAttachmentInteractor { }); yield Right(ExportAttachmentSuccess(filePath)); } catch (exception) { + log('ExportAttachmentInteractor::execute(): exception: $exception'); yield Left(ExportAttachmentFailure(exception)); } } diff --git a/lib/features/email/presentation/email_bindings.dart b/lib/features/email/presentation/email_bindings.dart index 9c031362a..6a7d4102d 100644 --- a/lib/features/email/presentation/email_bindings.dart +++ b/lib/features/email/presentation/email_bindings.dart @@ -18,7 +18,19 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_ import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/email_controller.dart'; +import 'package:tmail_ui_user/features/login/data/datasource/account_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_oidc_datasource_impl.dart'; +import 'package:tmail_ui_user/features/login/data/datasource_impl/hive_account_datasource_impl.dart'; +import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart'; +import 'package:tmail_ui_user/features/login/data/local/oidc_configuration_cache_manager.dart'; +import 'package:tmail_ui_user/features/login/data/local/token_oidc_cache_manager.dart'; +import 'package:tmail_ui_user/features/login/data/network/oidc_http_client.dart'; +import 'package:tmail_ui_user/features/login/data/repository/account_repository_impl.dart'; +import 'package:tmail_ui_user/features/login/data/repository/authentication_oidc_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/account_repository.dart'; +import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart'; import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; class EmailBindings extends BaseBindings { @@ -41,15 +53,23 @@ class EmailBindings extends BaseBindings { void bindingsDataSource() { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override void bindingsDataSourceImpl() { Get.lazyPut(() => EmailDataSourceImpl(Get.find())); + Get.lazyPut(() => HiveAccountDatasourceImpl(Get.find())); Get.lazyPut(() => HtmlDataSourceImpl( Get.find(), Get.find(), )); + Get.lazyPut(() => AuthenticationOIDCDataSourceImpl( + Get.find(), + Get.find(), + Get.find() + )); } @override @@ -63,6 +83,8 @@ class EmailBindings extends BaseBindings { Get.lazyPut(() => ExportAttachmentInteractor( Get.find(), Get.find(), + Get.find(), + Get.find(), )); Get.lazyPut(() => MoveToMailboxInteractor(Get.find())); Get.lazyPut(() => MarkAsStarEmailInteractor(Get.find())); @@ -76,6 +98,8 @@ class EmailBindings extends BaseBindings { void bindingsRepository() { Get.lazyPut(() => Get.find()); Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); + Get.lazyPut(() => Get.find()); } @override @@ -85,5 +109,7 @@ class EmailBindings extends BaseBindings { Get.find(), )); Get.lazyPut(() => CredentialRepositoryImpl(Get.find())); + Get.lazyPut(() => AccountRepositoryImpl(Get.find())); + Get.lazyPut(() => AuthenticationOIDCRepositoryImpl(Get.find())); } } \ No newline at end of file diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index 0cb8c52db..952e7f472 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -155,6 +155,7 @@ class EmailController extends BaseController { @override void onError(error) { + log('EmailController::onError(): $error'); } void _getEmailContentSuccess(GetEmailContentSuccess success) { diff --git a/lib/features/login/data/local/token_oidc_cache_manager.dart b/lib/features/login/data/local/token_oidc_cache_manager.dart index 6b5bc9cd8..f06874d0e 100644 --- a/lib/features/login/data/local/token_oidc_cache_manager.dart +++ b/lib/features/login/data/local/token_oidc_cache_manager.dart @@ -12,6 +12,7 @@ class TokenOidcCacheManager { Future getTokenOidc(String tokenIdHash) async { final tokenCache = await _tokenOidcCacheClient.getItem(tokenIdHash); + log('TokenOidcCacheManager::getTokenOidc(): tokenCache: $tokenCache'); if (tokenCache == null) { throw NotFoundStoredTokenException(); } else { diff --git a/lib/features/mailbox/domain/extensions/presentation_mailbox_extension.dart b/lib/features/mailbox/domain/extensions/presentation_mailbox_extension.dart index e8411a777..2c2e85790 100644 --- a/lib/features/mailbox/domain/extensions/presentation_mailbox_extension.dart +++ b/lib/features/mailbox/domain/extensions/presentation_mailbox_extension.dart @@ -10,7 +10,7 @@ extension PresentationMailboxExtension on PresentationMailbox { return imagePaths.icMailboxInbox; case 'drafts': return imagePaths.icMailboxDrafts; - case 'outbox': + case 'archive': return imagePaths.icMailboxArchived; case 'sent': return imagePaths.icMailboxSent; diff --git a/model/lib/account/account_request.dart b/model/lib/account/account_request.dart index b23bdf5f3..ba7449022 100644 --- a/model/lib/account/account_request.dart +++ b/model/lib/account/account_request.dart @@ -4,18 +4,23 @@ import 'package:equatable/equatable.dart'; import 'package:model/model.dart'; class AccountRequest with EquatableMixin { - final UserName userName; - final Password password; + final UserName? userName; + final Password? password; + final Token? token; + final AuthenticationType authenticationType; - AccountRequest(this.userName, this.password); + AccountRequest({ + this.userName, + this.password, + this.token, + this.authenticationType = AuthenticationType.none, + }); - Map toJson() => { - 'username': userName.userName, - 'password': password.value, - }; + String get basicAuth => + 'Basic ${base64Encode(utf8.encode('${userName?.userName}:${password?.value}'))}'; - String get basicAuth => 'Basic ${base64Encode(utf8.encode('${userName.userName}:${password.value}'))}'; + String get bearerToken => 'Bearer ${token?.token}'; @override - List get props => [userName, password]; + List get props => [userName, password]; } \ No newline at end of file