Added preferredTanMethods and preferredTanMedium to JobContext
This commit is contained in:
parent
6bf7fdcb44
commit
61d8f2c342
|
@ -80,7 +80,7 @@ open class FinTsClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open suspend fun getAccountTransactions(param: GetAccountDataParameter, bank: BankData, account: AccountData): GetAccountTransactionsResponse {
|
protected open suspend fun getAccountTransactions(param: GetAccountDataParameter, bank: BankData, account: AccountData): GetAccountTransactionsResponse {
|
||||||
val context = JobContext(JobContextType.GetTransactions, this.callback, config, bank, account)
|
val context = JobContext(JobContextType.GetTransactions, this.callback, config, bank, account, param.preferredTanMethods, param.preferredTanMedium)
|
||||||
|
|
||||||
return config.jobExecutor.getTransactionsAsync(context, mapper.toGetAccountTransactionsParameter(param, bank, account))
|
return config.jobExecutor.getTransactionsAsync(context, mapper.toGetAccountTransactionsParameter(param, bank, account))
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ open class FinTsClient(
|
||||||
accountToUse = selectedAccount
|
accountToUse = selectedAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
val context = JobContext(JobContextType.TransferMoney, this.callback, config, bank, accountToUse)
|
val context = JobContext(JobContextType.TransferMoney, this.callback, config, bank, accountToUse, param.preferredTanMethods, param.preferredTanMedium)
|
||||||
|
|
||||||
val response = config.jobExecutor.transferMoneyAsync(context, BankTransferData(param.recipientName, param.recipientAccountIdentifier, recipientBankIdentifier,
|
val response = config.jobExecutor.transferMoneyAsync(context, BankTransferData(param.recipientName, param.recipientAccountIdentifier, recipientBankIdentifier,
|
||||||
param.amount, param.reference, param.instantPayment))
|
param.amount, param.reference, param.instantPayment))
|
||||||
|
@ -205,11 +205,11 @@ open class FinTsClient(
|
||||||
// return GetAccountInfoResponse(it)
|
// return GetAccountInfoResponse(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val context = JobContext(JobContextType.GetAccountInfo, this.callback, config, bank)
|
val context = JobContext(JobContextType.GetAccountInfo, this.callback, config, bank, null, param.preferredTanMethods, param.preferredTanMedium)
|
||||||
|
|
||||||
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */
|
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */
|
||||||
|
|
||||||
val newUserInfoResponse = config.jobExecutor.retrieveBasicDataLikeUsersTanMethods(context, param.preferredTanMethods, param.preferredTanMedium)
|
val newUserInfoResponse = config.jobExecutor.retrieveBasicDataLikeUsersTanMethods(context)
|
||||||
|
|
||||||
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
|
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
|
||||||
strong customer authorization TAN media is required */
|
strong customer authorization TAN media is required */
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package net.codinux.banking.fints
|
package net.codinux.banking.fints
|
||||||
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.datetime.*
|
import kotlinx.datetime.*
|
||||||
import net.codinux.banking.fints.callback.FinTsClientCallback
|
import net.codinux.banking.fints.callback.FinTsClientCallback
|
||||||
import net.codinux.banking.fints.config.FinTsClientConfiguration
|
import net.codinux.banking.fints.config.FinTsClientConfiguration
|
||||||
|
@ -39,13 +37,13 @@ open class FinTsClientDeprecated(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open suspend fun addAccountAsync(parameter: AddAccountParameter): AddAccountResponse {
|
open suspend fun addAccountAsync(param: AddAccountParameter): AddAccountResponse {
|
||||||
val bank = parameter.bank
|
val bank = param.bank
|
||||||
val context = JobContext(JobContextType.AddAccount, this.callback, config, bank)
|
val context = JobContext(JobContextType.AddAccount, this.callback, config, bank, null, param.preferredTanMethods, param.preferredTanMedium)
|
||||||
|
|
||||||
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */
|
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */
|
||||||
|
|
||||||
val newUserInfoResponse = config.jobExecutor.retrieveBasicDataLikeUsersTanMethods(context, parameter.preferredTanMethods, parameter.preferredTanMedium)
|
val newUserInfoResponse = config.jobExecutor.retrieveBasicDataLikeUsersTanMethods(context)
|
||||||
|
|
||||||
if (newUserInfoResponse.successful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong
|
if (newUserInfoResponse.successful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong
|
||||||
return AddAccountResponse(context, newUserInfoResponse)
|
return AddAccountResponse(context, newUserInfoResponse)
|
||||||
|
@ -54,7 +52,7 @@ open class FinTsClientDeprecated(
|
||||||
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
|
/* Second dialog, executed in retrieveBasicDataLikeUsersTanMethods() if required: some banks require that in order to initialize a dialog with
|
||||||
strong customer authorization TAN media is required */
|
strong customer authorization TAN media is required */
|
||||||
|
|
||||||
return addAccountGetAccountsAndTransactions(context, parameter)
|
return addAccountGetAccountsAndTransactions(context, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open suspend fun addAccountGetAccountsAndTransactions(context: JobContext, parameter: AddAccountParameter): AddAccountResponse {
|
protected open suspend fun addAccountGetAccountsAndTransactions(context: JobContext, parameter: AddAccountParameter): AddAccountResponse {
|
||||||
|
@ -120,11 +118,11 @@ open class FinTsClientDeprecated(
|
||||||
return GetAccountTransactionsParameter(bank, account, account.supportsRetrievingBalance, ninetyDaysAgo, abortIfTanIsRequired = true)
|
return GetAccountTransactionsParameter(bank, account, account.supportsRetrievingBalance, ninetyDaysAgo, abortIfTanIsRequired = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun getAccountTransactionsAsync(parameter: GetAccountTransactionsParameter): GetAccountTransactionsResponse {
|
open suspend fun getAccountTransactionsAsync(param: GetAccountTransactionsParameter): GetAccountTransactionsResponse {
|
||||||
|
|
||||||
val context = JobContext(JobContextType.GetTransactions, this.callback, config, parameter.bank, parameter.account)
|
val context = JobContext(JobContextType.GetTransactions, this.callback, config, param.bank, param.account)
|
||||||
|
|
||||||
return config.jobExecutor.getTransactionsAsync(context, parameter)
|
return config.jobExecutor.getTransactionsAsync(context, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.codinux.banking.fints.response.segments.*
|
||||||
import net.codinux.banking.fints.tan.FlickerCodeDecoder
|
import net.codinux.banking.fints.tan.FlickerCodeDecoder
|
||||||
import net.codinux.banking.fints.tan.TanImageDecoder
|
import net.codinux.banking.fints.tan.TanImageDecoder
|
||||||
import net.codinux.banking.fints.util.TanMethodSelector
|
import net.codinux.banking.fints.util.TanMethodSelector
|
||||||
|
import net.codinux.log.Log
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
@ -73,8 +74,7 @@ open class FinTsJobExecutor(
|
||||||
*
|
*
|
||||||
* Be aware this method resets BPD, UPD and selected TAN method!
|
* Be aware this method resets BPD, UPD and selected TAN method!
|
||||||
*/
|
*/
|
||||||
open suspend fun retrieveBasicDataLikeUsersTanMethods(context: JobContext, preferredTanMethods: List<TanMethodType>? = null, preferredTanMedium: String? = null,
|
open suspend fun retrieveBasicDataLikeUsersTanMethods(context: JobContext): BankResponse {
|
||||||
closeDialog: Boolean = false): BankResponse {
|
|
||||||
val bank = context.bank
|
val bank = context.bank
|
||||||
|
|
||||||
// just to ensure settings are in its initial state and that bank sends us bank parameter (BPD),
|
// just to ensure settings are in its initial state and that bank sends us bank parameter (BPD),
|
||||||
|
@ -90,7 +90,7 @@ open class FinTsJobExecutor(
|
||||||
bank.resetSelectedTanMethod()
|
bank.resetSelectedTanMethod()
|
||||||
|
|
||||||
// this is the only case where Einschritt-TAN-Verfahren is accepted: to get user's TAN methods
|
// this is the only case where Einschritt-TAN-Verfahren is accepted: to get user's TAN methods
|
||||||
context.startNewDialog(closeDialog, versionOfSecurityProcedure = VersionDesSicherheitsverfahrens.Version_1)
|
context.startNewDialog(versionOfSecurityProcedure = VersionDesSicherheitsverfahrens.Version_1)
|
||||||
|
|
||||||
val message = messageBuilder.createInitDialogMessage(context)
|
val message = messageBuilder.createInitDialogMessage(context)
|
||||||
|
|
||||||
|
@ -103,12 +103,10 @@ open class FinTsJobExecutor(
|
||||||
if (bank.tanMethodsAvailableForUser.isEmpty()) { // could not retrieve supported tan methods for user
|
if (bank.tanMethodsAvailableForUser.isEmpty()) { // could not retrieve supported tan methods for user
|
||||||
return getTanMethodsResponse
|
return getTanMethodsResponse
|
||||||
} else {
|
} else {
|
||||||
getUsersTanMethod(context, preferredTanMethods)
|
getUsersTanMethod(context)
|
||||||
|
|
||||||
if (bank.isTanMethodSelected == false) {
|
if (bank.isTanMethodSelected && bank.tanMedia.isEmpty() && bank.tanMethodsAvailableForUser.any { it.nameOfTanMediumRequired } && isJobSupported(bank, CustomerSegmentId.TanMediaList)) { // tan media not retrieved yet
|
||||||
return getTanMethodsResponse
|
getTanMediaList(context, TanMedienArtVersion.Alle, TanMediumKlasse.AlleMedien, context.preferredTanMedium)
|
||||||
} else if (bank.tanMedia.isEmpty() && isJobSupported(bank, CustomerSegmentId.TanMediaList)) { // tan media not retrieved yet
|
|
||||||
getTanMediaList(context, TanMedienArtVersion.Alle, TanMediumKlasse.AlleMedien, preferredTanMedium)
|
|
||||||
|
|
||||||
return getTanMethodsResponse // TODO: judge if bank requires selecting TAN media and if though evaluate getTanMediaListResponse
|
return getTanMethodsResponse // TODO: judge if bank requires selecting TAN media and if though evaluate getTanMediaListResponse
|
||||||
} else {
|
} else {
|
||||||
|
@ -384,14 +382,22 @@ open class FinTsJobExecutor(
|
||||||
|
|
||||||
mayRetrieveAutomaticallyIfUserEnteredDecoupledTan(context, tanChallenge, tanResponse)
|
mayRetrieveAutomaticallyIfUserEnteredDecoupledTan(context, tanChallenge, tanResponse)
|
||||||
|
|
||||||
|
var invocationCount = 0 // TODO: remove again
|
||||||
|
|
||||||
while (tanChallenge.isEnteringTanDone == false) {
|
while (tanChallenge.isEnteringTanDone == false) {
|
||||||
delay(500)
|
delay(500)
|
||||||
|
|
||||||
|
if (++invocationCount % 10 == 0) {
|
||||||
|
Log.info { "Waiting for TAN input invocation count: $invocationCount" }
|
||||||
|
}
|
||||||
|
|
||||||
val now = Instant.nowExt()
|
val now = Instant.nowExt()
|
||||||
if ((tanChallenge.tanExpirationTime != null && now > tanChallenge.tanExpirationTime) ||
|
if ((tanChallenge.tanExpirationTime != null && now > tanChallenge.tanExpirationTime) ||
|
||||||
// most TANs a valid 5 - 15 minutes. So terminate wait process after that time
|
// most TANs a valid 5 - 15 minutes. So terminate wait process after that time
|
||||||
(tanChallenge.tanExpirationTime == null && now > tanChallenge.challengeCreationTimestamp.plusMinutes(15))) {
|
(tanChallenge.tanExpirationTime == null && now > tanChallenge.challengeCreationTimestamp.plusMinutes(15))) {
|
||||||
if (tanChallenge.isEnteringTanDone == false) {
|
if (tanChallenge.isEnteringTanDone == false) {
|
||||||
|
Log.info { "Terminating waiting for TAN input" } // TODO: remove again
|
||||||
|
|
||||||
tanChallenge.tanExpired()
|
tanChallenge.tanExpired()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,7 +630,7 @@ open class FinTsJobExecutor(
|
||||||
|
|
||||||
protected open suspend fun initDialogWithStrongCustomerAuthenticationAfterSuccessfulPreconditionChecks(context: JobContext): BankResponse {
|
protected open suspend fun initDialogWithStrongCustomerAuthenticationAfterSuccessfulPreconditionChecks(context: JobContext): BankResponse {
|
||||||
|
|
||||||
context.startNewDialog(false) // don't know if it's ok for all invocations of this method to set closeDialog to false (was actually only set in getAccounts())
|
context.startNewDialog() // don't know if it's ok for all invocations of this method to set closeDialog to false (was actually only set in getAccounts())
|
||||||
|
|
||||||
val message = messageBuilder.createInitDialogMessage(context)
|
val message = messageBuilder.createInitDialogMessage(context)
|
||||||
|
|
||||||
|
@ -700,7 +706,7 @@ open class FinTsJobExecutor(
|
||||||
return BankResponse(true, noTanMethodSelected = noTanMethodSelected, internalError = errorMessage)
|
return BankResponse(true, noTanMethodSelected = noTanMethodSelected, internalError = errorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun getUsersTanMethod(context: JobContext, preferredTanMethods: List<TanMethodType>? = null): Boolean {
|
open suspend fun getUsersTanMethod(context: JobContext): Boolean {
|
||||||
val bank = context.bank
|
val bank = context.bank
|
||||||
|
|
||||||
if (bank.tanMethodsAvailableForUser.size == 1) { // user has only one TAN method -> set it and we're done
|
if (bank.tanMethodsAvailableForUser.size == 1) { // user has only one TAN method -> set it and we're done
|
||||||
|
@ -708,7 +714,7 @@ open class FinTsJobExecutor(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tanMethodSelector.findPreferredTanMethod(bank.tanMethodsAvailableForUser, preferredTanMethods)?.let {
|
tanMethodSelector.findPreferredTanMethod(bank.tanMethodsAvailableForUser, context.preferredTanMethods)?.let {
|
||||||
bank.selectedTanMethod = it
|
bank.selectedTanMethod = it
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ open class JobContext(
|
||||||
* Only set if the current context is for a specific account (like get account's transactions).
|
* Only set if the current context is for a specific account (like get account's transactions).
|
||||||
*/
|
*/
|
||||||
open val account: AccountData? = null,
|
open val account: AccountData? = null,
|
||||||
|
open val preferredTanMethods: List<TanMethodType>? = null,
|
||||||
|
open val preferredTanMedium: String? = null,
|
||||||
protected open val messageLogCollector: MessageLogCollector = MessageLogCollector(callback, config.options)
|
protected open val messageLogCollector: MessageLogCollector = MessageLogCollector(callback, config.options)
|
||||||
) : MessageBaseData(bank, config.options.product), IMessageLogAppender {
|
) : MessageBaseData(bank, config.options.product), IMessageLogAppender {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue