Implemented detecting if wrong credentials have been entered (not 100 % reliable though)
This commit is contained in:
parent
572f8d81ec
commit
38bb0c90ff
|
@ -24,4 +24,5 @@ open class RetrievedAccountData(
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -27,14 +27,23 @@ open class BankResponse(
|
|||
open val responseContainsErrors: Boolean
|
||||
get() = errorMessage == null && messageFeedback?.isError == true
|
||||
|
||||
open val wrongCredentialsEntered: Boolean
|
||||
get() {
|
||||
val wrongCredentialsEnteredFeedbacks = segmentFeedbacks.flatMap { it.feedbacks }
|
||||
.filter { it.responseCode in 9910..9949 || (it.responseCode == 9210 && it.message.contains("Unbekannt", true)) } // this is not 100 % correct, there are e.g. messages like "9941 TAN ungültig" or "9910 Chipkarte gesperrt", see p. 22-23 FinTS_Rueckmeldungscodes ->
|
||||
.filterNot { it.message.contains("TAN", true) || it.message.contains("Chipkarte", true) } // ... try to filter these
|
||||
|
||||
return wrongCredentialsEnteredFeedbacks.isNotEmpty()
|
||||
}
|
||||
|
||||
open var tanRequiredButUserDidNotEnterOne = false
|
||||
|
||||
open var tanRequiredButWeWereToldToAbortIfSo = false
|
||||
|
||||
open val successful: Boolean
|
||||
get() = noTanMethodSelected == false && couldCreateMessage && didReceiveResponse
|
||||
&& responseContainsErrors == false && tanRequiredButUserDidNotEnterOne == false
|
||||
&& tanRequiredButWeWereToldToAbortIfSo == false
|
||||
&& responseContainsErrors == false && wrongCredentialsEntered == false
|
||||
&& tanRequiredButUserDidNotEnterOne == false && tanRequiredButWeWereToldToAbortIfSo == false
|
||||
|
||||
open val isStrongAuthenticationRequired: Boolean
|
||||
get() = tanResponse?.isStrongAuthenticationRequired == true
|
||||
|
|
|
@ -20,6 +20,8 @@ open class FinTsClientResponse(
|
|||
*/
|
||||
open val errorMessage: String? = null,
|
||||
|
||||
open val wrongCredentialsEntered: Boolean = false,
|
||||
|
||||
open val userCancelledAction: Boolean = false,
|
||||
|
||||
open val tanRequiredButWeWereToldToAbortIfSo: Boolean = false,
|
||||
|
@ -33,7 +35,8 @@ open class FinTsClientResponse(
|
|||
|
||||
constructor(response: BankResponse) : this(response.successful, response.noTanMethodSelected,
|
||||
response.isStrongAuthenticationRequired, response.tanResponse, response.errorsToShowToUser,
|
||||
response.errorMessage, response.tanRequiredButUserDidNotEnterOne, response.tanRequiredButWeWereToldToAbortIfSo,
|
||||
response.errorMessage, response.wrongCredentialsEntered,
|
||||
response.tanRequiredButUserDidNotEnterOne, response.tanRequiredButWeWereToldToAbortIfSo,
|
||||
response.messageCreationError?.isJobAllowed ?: true,
|
||||
response.messageCreationError?.isJobVersionSupported ?: true,
|
||||
response.messageCreationError?.allowedVersions ?: listOf(),
|
||||
|
|
|
@ -12,4 +12,18 @@ open class RetrievedAccountData(
|
|||
open val unbookedTransactions: List<Any>,
|
||||
open val retrievedTransactionsFrom: Date?,
|
||||
open val retrievedTransactionsTo: Date?
|
||||
)
|
||||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
fun unsuccessful(account: TypedBankAccount): RetrievedAccountData {
|
||||
return RetrievedAccountData(account, false, null, listOf(), listOf(), null, null)
|
||||
}
|
||||
|
||||
fun unsuccessfulList(account: TypedBankAccount): List<RetrievedAccountData> {
|
||||
return listOf(unsuccessful(account))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -7,8 +7,9 @@ open class AddAccountResponse(
|
|||
open val bank: TypedBankData,
|
||||
retrievedData: List<RetrievedAccountData> = listOf(),
|
||||
errorToShowToUser: String?,
|
||||
wrongCredentialsEntered: Boolean = false,
|
||||
userCancelledAction: Boolean = false
|
||||
) : GetTransactionsResponse(retrievedData, errorToShowToUser, userCancelledAction) {
|
||||
) : GetTransactionsResponse(retrievedData, errorToShowToUser, wrongCredentialsEntered, userCancelledAction) {
|
||||
|
||||
constructor(bank: TypedBankData, errorToShowToUser: String?) : this(bank, listOf(), errorToShowToUser)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ package net.dankito.banking.ui.model.responses
|
|||
open class BankingClientResponse(
|
||||
open val successful: Boolean,
|
||||
open val errorToShowToUser: String?,
|
||||
open val wrongCredentialsEntered: Boolean = false,
|
||||
open val userCancelledAction: Boolean = false // TODO: not implemented in hbci4jBankingClient yet
|
||||
) {
|
||||
|
||||
|
|
|
@ -7,11 +7,15 @@ import net.dankito.banking.ui.model.TypedBankAccount
|
|||
open class GetTransactionsResponse(
|
||||
open val retrievedData: List<RetrievedAccountData>,
|
||||
errorToShowToUser: String?,
|
||||
wrongCredentialsEntered: Boolean = false,
|
||||
userCancelledAction: Boolean = false,
|
||||
open val tanRequiredButWeWereToldToAbortIfSo: Boolean = false
|
||||
) : BankingClientResponse(true /* any value */, errorToShowToUser, userCancelledAction) {
|
||||
) : BankingClientResponse(true /* any value */, errorToShowToUser, wrongCredentialsEntered, userCancelledAction) {
|
||||
|
||||
constructor(account: TypedBankAccount, errorToShowToUser: String) : this(listOf(RetrievedAccountData(account, false, null, listOf(), listOf(), null, null)), errorToShowToUser)
|
||||
constructor(account: TypedBankAccount, errorToShowToUser: String) : this(RetrievedAccountData.unsuccessfulList(account), errorToShowToUser)
|
||||
|
||||
constructor(account: TypedBankAccount, response: BankingClientResponse) : this(RetrievedAccountData.unsuccessfulList(account), response.errorToShowToUser,
|
||||
response.wrongCredentialsEntered, response.userCancelledAction, (response as? GetTransactionsResponse)?.tanRequiredButWeWereToldToAbortIfSo ?: false)
|
||||
|
||||
constructor(retrievedData: RetrievedAccountData) : this(listOf(retrievedData))
|
||||
|
||||
|
@ -20,6 +24,7 @@ open class GetTransactionsResponse(
|
|||
|
||||
override val successful: Boolean
|
||||
get() = errorToShowToUser == null
|
||||
&& wrongCredentialsEntered == false
|
||||
&& retrievedData.isNotEmpty()
|
||||
&& retrievedData.none { it.account.supportsRetrievingAccountTransactions && it.successfullyRetrievedData == false }
|
||||
|
||||
|
|
|
@ -80,9 +80,14 @@ open class fints4kBankingClient(
|
|||
override fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
||||
val account = parameter.account
|
||||
|
||||
findAccountForAccount(account) { accountData, errorMessage ->
|
||||
findAccountForAccount(account) { accountData, response ->
|
||||
if (accountData == null) {
|
||||
callback(GetTransactionsResponse(account, errorMessage ?: ""))
|
||||
if (response != null) {
|
||||
callback(GetTransactionsResponse(account, response))
|
||||
}
|
||||
else { // should never be the case
|
||||
callback(GetTransactionsResponse(account, ""))
|
||||
}
|
||||
}
|
||||
else {
|
||||
val mappedParameter = GetTransactionsParameter(accountData, parameter.alsoRetrieveBalance, parameter.fromDate,
|
||||
|
@ -113,9 +118,15 @@ open class fints4kBankingClient(
|
|||
|
||||
|
||||
override fun transferMoneyAsync(data: TransferMoneyData, callback: (BankingClientResponse) -> Unit) {
|
||||
findAccountForAccount(data.account) { account, errorMessage ->
|
||||
findAccountForAccount(data.account) { account, response ->
|
||||
if (account == null) {
|
||||
callback(BankingClientResponse(false, errorMessage))
|
||||
if (response != null) {
|
||||
callback(response)
|
||||
}
|
||||
else { // should never be the case
|
||||
callback(BankingClientResponse(false, "Konnte Kontodaten nicht vom Bankserver abrufen für ${data.account.identifier}. " +
|
||||
"Besteht eine Netzwerkverbindung und sind der eingegebenen Benutzername und Passwort korrekt?")) // TODO: translate
|
||||
}
|
||||
}
|
||||
else {
|
||||
val mappedData = BankTransferData(data.recipientName, data.recipientAccountId, data.recipientBankCode, data.amount.toMoney(), data.reference, data.realTimeTransfer)
|
||||
|
@ -149,7 +160,7 @@ open class fints4kBankingClient(
|
|||
}
|
||||
|
||||
|
||||
protected open fun findAccountForAccount(account: TypedBankAccount, findAccountResult: (AccountData?, error: String?) -> Unit) {
|
||||
protected open fun findAccountForAccount(account: TypedBankAccount, findAccountResult: (AccountData?, BankingClientResponse?) -> Unit) {
|
||||
val mappedAccount = mapper.findMatchingAccount(fintsBank, account)
|
||||
|
||||
if (mappedAccount != null) {
|
||||
|
@ -158,10 +169,10 @@ open class fints4kBankingClient(
|
|||
else { // then try to get account data by fetching data from bank
|
||||
addAccountAsync { response ->
|
||||
if (response.successful) {
|
||||
findAccountResult(mapper.findMatchingAccount(fintsBank, account), response.errorToShowToUser)
|
||||
findAccountResult(mapper.findMatchingAccount(fintsBank, account), response)
|
||||
}
|
||||
else {
|
||||
findAccountResult(null, response.errorToShowToUser)
|
||||
findAccountResult(null, response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,18 +24,18 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) {
|
|||
|
||||
|
||||
open fun mapResponse(response: FinTsClientResponse): BankingClientResponse {
|
||||
return BankingClientResponse(response.successful, mapErrorToShowToUser(response), response.userCancelledAction)
|
||||
return BankingClientResponse(response.successful, mapErrorToShowToUser(response), response.wrongCredentialsEntered, response.userCancelledAction)
|
||||
}
|
||||
|
||||
open fun mapResponse(bank: TypedBankData, response: net.dankito.banking.fints.response.client.AddAccountResponse): AddAccountResponse {
|
||||
|
||||
return AddAccountResponse(bank, map(bank, response.retrievedData), mapErrorToShowToUser(response), response.userCancelledAction)
|
||||
return AddAccountResponse(bank, map(bank, response.retrievedData), mapErrorToShowToUser(response), response.wrongCredentialsEntered, response.userCancelledAction)
|
||||
}
|
||||
|
||||
open fun mapResponse(account: TypedBankAccount, response: net.dankito.banking.fints.response.client.GetTransactionsResponse): GetTransactionsResponse {
|
||||
|
||||
return GetTransactionsResponse(map(account.bank as TypedBankData, response.retrievedData),
|
||||
mapErrorToShowToUser(response), response.userCancelledAction, response.tanRequiredButWeWereToldToAbortIfSo)
|
||||
mapErrorToShowToUser(response), response.wrongCredentialsEntered, response.userCancelledAction, response.tanRequiredButWeWereToldToAbortIfSo)
|
||||
}
|
||||
|
||||
open fun map(bank: TypedBankData, retrievedData: List<net.dankito.banking.fints.model.RetrievedAccountData>): List<RetrievedAccountData> {
|
||||
|
|
|
@ -102,11 +102,11 @@ open class hbci4jBankingClient(
|
|||
response.retrievedData.first()
|
||||
}
|
||||
else {
|
||||
RetrievedAccountData(account, false, null, listOf(), listOf(), null)
|
||||
RetrievedAccountData.unsuccessful(account)
|
||||
}
|
||||
}
|
||||
|
||||
return AddAccountResponse(bank, retrievedData, null, userCancelledAction)
|
||||
return AddAccountResponse(bank, retrievedData, null, false, userCancelledAction)
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue