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
|
open val responseContainsErrors: Boolean
|
||||||
get() = errorMessage == null && messageFeedback?.isError == true
|
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 tanRequiredButUserDidNotEnterOne = false
|
||||||
|
|
||||||
open var tanRequiredButWeWereToldToAbortIfSo = false
|
open var tanRequiredButWeWereToldToAbortIfSo = false
|
||||||
|
|
||||||
open val successful: Boolean
|
open val successful: Boolean
|
||||||
get() = noTanMethodSelected == false && couldCreateMessage && didReceiveResponse
|
get() = noTanMethodSelected == false && couldCreateMessage && didReceiveResponse
|
||||||
&& responseContainsErrors == false && tanRequiredButUserDidNotEnterOne == false
|
&& responseContainsErrors == false && wrongCredentialsEntered == false
|
||||||
&& tanRequiredButWeWereToldToAbortIfSo == false
|
&& tanRequiredButUserDidNotEnterOne == false && tanRequiredButWeWereToldToAbortIfSo == false
|
||||||
|
|
||||||
open val isStrongAuthenticationRequired: Boolean
|
open val isStrongAuthenticationRequired: Boolean
|
||||||
get() = tanResponse?.isStrongAuthenticationRequired == true
|
get() = tanResponse?.isStrongAuthenticationRequired == true
|
||||||
|
|
|
@ -20,6 +20,8 @@ open class FinTsClientResponse(
|
||||||
*/
|
*/
|
||||||
open val errorMessage: String? = null,
|
open val errorMessage: String? = null,
|
||||||
|
|
||||||
|
open val wrongCredentialsEntered: Boolean = false,
|
||||||
|
|
||||||
open val userCancelledAction: Boolean = false,
|
open val userCancelledAction: Boolean = false,
|
||||||
|
|
||||||
open val tanRequiredButWeWereToldToAbortIfSo: Boolean = false,
|
open val tanRequiredButWeWereToldToAbortIfSo: Boolean = false,
|
||||||
|
@ -33,7 +35,8 @@ open class FinTsClientResponse(
|
||||||
|
|
||||||
constructor(response: BankResponse) : this(response.successful, response.noTanMethodSelected,
|
constructor(response: BankResponse) : this(response.successful, response.noTanMethodSelected,
|
||||||
response.isStrongAuthenticationRequired, response.tanResponse, response.errorsToShowToUser,
|
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?.isJobAllowed ?: true,
|
||||||
response.messageCreationError?.isJobVersionSupported ?: true,
|
response.messageCreationError?.isJobVersionSupported ?: true,
|
||||||
response.messageCreationError?.allowedVersions ?: listOf(),
|
response.messageCreationError?.allowedVersions ?: listOf(),
|
||||||
|
|
|
@ -12,4 +12,18 @@ open class RetrievedAccountData(
|
||||||
open val unbookedTransactions: List<Any>,
|
open val unbookedTransactions: List<Any>,
|
||||||
open val retrievedTransactionsFrom: Date?,
|
open val retrievedTransactionsFrom: Date?,
|
||||||
open val retrievedTransactionsTo: 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,
|
open val bank: TypedBankData,
|
||||||
retrievedData: List<RetrievedAccountData> = listOf(),
|
retrievedData: List<RetrievedAccountData> = listOf(),
|
||||||
errorToShowToUser: String?,
|
errorToShowToUser: String?,
|
||||||
|
wrongCredentialsEntered: Boolean = false,
|
||||||
userCancelledAction: Boolean = false
|
userCancelledAction: Boolean = false
|
||||||
) : GetTransactionsResponse(retrievedData, errorToShowToUser, userCancelledAction) {
|
) : GetTransactionsResponse(retrievedData, errorToShowToUser, wrongCredentialsEntered, userCancelledAction) {
|
||||||
|
|
||||||
constructor(bank: TypedBankData, errorToShowToUser: String?) : this(bank, listOf(), errorToShowToUser)
|
constructor(bank: TypedBankData, errorToShowToUser: String?) : this(bank, listOf(), errorToShowToUser)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ package net.dankito.banking.ui.model.responses
|
||||||
open class BankingClientResponse(
|
open class BankingClientResponse(
|
||||||
open val successful: Boolean,
|
open val successful: Boolean,
|
||||||
open val errorToShowToUser: String?,
|
open val errorToShowToUser: String?,
|
||||||
|
open val wrongCredentialsEntered: Boolean = false,
|
||||||
open val userCancelledAction: Boolean = false // TODO: not implemented in hbci4jBankingClient yet
|
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 class GetTransactionsResponse(
|
||||||
open val retrievedData: List<RetrievedAccountData>,
|
open val retrievedData: List<RetrievedAccountData>,
|
||||||
errorToShowToUser: String?,
|
errorToShowToUser: String?,
|
||||||
|
wrongCredentialsEntered: Boolean = false,
|
||||||
userCancelledAction: Boolean = false,
|
userCancelledAction: Boolean = false,
|
||||||
open val tanRequiredButWeWereToldToAbortIfSo: 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))
|
constructor(retrievedData: RetrievedAccountData) : this(listOf(retrievedData))
|
||||||
|
|
||||||
|
@ -20,6 +24,7 @@ open class GetTransactionsResponse(
|
||||||
|
|
||||||
override val successful: Boolean
|
override val successful: Boolean
|
||||||
get() = errorToShowToUser == null
|
get() = errorToShowToUser == null
|
||||||
|
&& wrongCredentialsEntered == false
|
||||||
&& retrievedData.isNotEmpty()
|
&& retrievedData.isNotEmpty()
|
||||||
&& retrievedData.none { it.account.supportsRetrievingAccountTransactions && it.successfullyRetrievedData == false }
|
&& retrievedData.none { it.account.supportsRetrievingAccountTransactions && it.successfullyRetrievedData == false }
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,14 @@ open class fints4kBankingClient(
|
||||||
override fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
override fun getTransactionsAsync(parameter: GetTransactionsParameter, callback: (GetTransactionsResponse) -> Unit) {
|
||||||
val account = parameter.account
|
val account = parameter.account
|
||||||
|
|
||||||
findAccountForAccount(account) { accountData, errorMessage ->
|
findAccountForAccount(account) { accountData, response ->
|
||||||
if (accountData == null) {
|
if (accountData == null) {
|
||||||
callback(GetTransactionsResponse(account, errorMessage ?: ""))
|
if (response != null) {
|
||||||
|
callback(GetTransactionsResponse(account, response))
|
||||||
|
}
|
||||||
|
else { // should never be the case
|
||||||
|
callback(GetTransactionsResponse(account, ""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val mappedParameter = GetTransactionsParameter(accountData, parameter.alsoRetrieveBalance, parameter.fromDate,
|
val mappedParameter = GetTransactionsParameter(accountData, parameter.alsoRetrieveBalance, parameter.fromDate,
|
||||||
|
@ -113,9 +118,15 @@ open class fints4kBankingClient(
|
||||||
|
|
||||||
|
|
||||||
override fun transferMoneyAsync(data: TransferMoneyData, callback: (BankingClientResponse) -> Unit) {
|
override fun transferMoneyAsync(data: TransferMoneyData, callback: (BankingClientResponse) -> Unit) {
|
||||||
findAccountForAccount(data.account) { account, errorMessage ->
|
findAccountForAccount(data.account) { account, response ->
|
||||||
if (account == null) {
|
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 {
|
else {
|
||||||
val mappedData = BankTransferData(data.recipientName, data.recipientAccountId, data.recipientBankCode, data.amount.toMoney(), data.reference, data.realTimeTransfer)
|
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)
|
val mappedAccount = mapper.findMatchingAccount(fintsBank, account)
|
||||||
|
|
||||||
if (mappedAccount != null) {
|
if (mappedAccount != null) {
|
||||||
|
@ -158,10 +169,10 @@ open class fints4kBankingClient(
|
||||||
else { // then try to get account data by fetching data from bank
|
else { // then try to get account data by fetching data from bank
|
||||||
addAccountAsync { response ->
|
addAccountAsync { response ->
|
||||||
if (response.successful) {
|
if (response.successful) {
|
||||||
findAccountResult(mapper.findMatchingAccount(fintsBank, account), response.errorToShowToUser)
|
findAccountResult(mapper.findMatchingAccount(fintsBank, account), response)
|
||||||
}
|
}
|
||||||
else {
|
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 {
|
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 {
|
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 {
|
open fun mapResponse(account: TypedBankAccount, response: net.dankito.banking.fints.response.client.GetTransactionsResponse): GetTransactionsResponse {
|
||||||
|
|
||||||
return GetTransactionsResponse(map(account.bank as TypedBankData, response.retrievedData),
|
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> {
|
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()
|
response.retrievedData.first()
|
||||||
}
|
}
|
||||||
else {
|
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