Implemented checkIfAccountExists() which retrieves user's data and may even first account transactions without asking user for her/his tan procedure

This commit is contained in:
dankl 2019-10-21 00:47:01 +02:00 committed by dankito
parent 1444d93860
commit d03c0eb003
2 changed files with 98 additions and 10 deletions

View File

@ -36,6 +36,8 @@ open class FinTsClient @JvmOverloads constructor(
) {
companion object {
const val NinetyDaysAgoMilliseconds = 90 * 24 * 60 * 60 * 1000L
private val log = LoggerFactory.getLogger(FinTsClient::class.java)
}
@ -109,6 +111,48 @@ open class FinTsClient @JvmOverloads constructor(
}
open fun checkIfAccountExistsAsync(bank: BankData, customer: CustomerData,
callback: (FinTsClientResponse) -> Unit) {
threadPool.runAsync {
callback(checkIfAccountExists(bank, customer))
}
}
open fun checkIfAccountExists(bank: BankData, customer: CustomerData): FinTsClientResponse {
val newUserInfoResponse = getBankAndCustomerInfoForNewUser(bank, customer)
if (newUserInfoResponse.isSuccessful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong
return newUserInfoResponse
}
// do not ask user for tan at this stage
var didOverwriteUserUnselectedTanProcedure = false
if (customer.isTanProcedureSelected == false && customer.supportedTanProcedures.isNotEmpty()) {
didOverwriteUserUnselectedTanProcedure = true
customer.selectedTanProcedure = customer.supportedTanProcedures.first()
}
val synchronizeCustomerResponse = synchronizeCustomerSystemId(bank, customer)
// also check if retrieving account transactions of last 90 days without tan is supported (and thereby may retrieve first account transactions)
val transactionsOfLast90DaysResponse =
tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, true)
if (didOverwriteUserUnselectedTanProcedure) {
customer.resetSelectedTanProcedure()
}
return if (transactionsOfLast90DaysResponse.isSuccessful) transactionsOfLast90DaysResponse
else synchronizeCustomerResponse
}
/**
* Some banks support that according to PSD2 account transactions may be retrieved without
* a TAN (= no strong customer authorization needed).
@ -117,7 +161,7 @@ open class FinTsClient @JvmOverloads constructor(
callback: (GetTransactionsResponse) -> Unit) {
threadPool.runAsync {
callback(tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, false))
callback(tryGetTransactionsOfLast90DaysWithoutTan(bank, customer))
}
}
@ -133,12 +177,12 @@ open class FinTsClient @JvmOverloads constructor(
protected open fun tryGetTransactionsOfLast90DaysWithoutTan(bank: BankData, customer: CustomerData,
skipSettingCustomerFlag: Boolean): GetTransactionsResponse {
val ninetyDaysAgoMilliseconds = 90 * 24 * 60 * 60 * 1000L
val ninetyDaysAgo = Date(Date().time - ninetyDaysAgoMilliseconds)
val ninetyDaysAgo = Date(Date().time - NinetyDaysAgoMilliseconds)
val response = getTransactions(
GetTransactionsParameter(false, ninetyDaysAgo), bank, customer)
customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan = true
if (response.isSuccessful) {
@ -162,8 +206,6 @@ open class FinTsClient @JvmOverloads constructor(
open fun getTransactions(parameter: GetTransactionsParameter, bank: BankData,
customer: CustomerData): GetTransactionsResponse {
// synchronizeCustomerSystemIdIfNotDoneYet(bank, customer) // even though specification says this is required it can be omitted
if (customer.supportsRetrievingTransactionsOfLast90DaysWithoutTan == null &&
customer.triedToRetrieveTransactionsOfLast90DaysWithoutTan == false &&
parameter.fromDate == null) {

View File

@ -10,19 +10,29 @@ import net.dankito.fints.util.Java8Base64Service
import org.assertj.core.api.Assertions.assertThat
import org.junit.Ignore
import org.junit.Test
import java.util.concurrent.atomic.AtomicBoolean
@Ignore // not an automatic test, supply your settings below
class FinTsClientTest {
private val didAskUserForTanProcedure = AtomicBoolean(false)
private val didAskUserToEnterTan = AtomicBoolean(false)
private val callback = object : FinTsClientCallback {
override fun askUserForTanProcedure(supportedTanProcedures: List<TanProcedure>): TanProcedure? {
didAskUserForTanProcedure.set(true)
// TODO: if entering TAN is required select your tan procedure here
return supportedTanProcedures.first()
}
override fun enterTan(tanChallenge: TanChallenge): String? {
didAskUserToEnterTan.set(true)
return null
}
@ -41,11 +51,8 @@ class FinTsClientTest {
private val BankDataAnonymous = BankData("10070000", Laenderkennzeichen.Germany, "https://fints.deutsche-bank.de/")
// TODO: add your settings here:
private val Bank = BankData("", Laenderkennzeichen.Germany, "", bic = "")
private val Customer = CustomerData("", "", iban = "")
// transfer 1 cent to yourself. Transferring money to oneself also doesn't require to enter a TAN according to PSD2
private val BankTransferData = BankTransferData(Customer.name, Customer.iban!!, Bank.bic!!, 0.01.toBigDecimal(), "Give it to me baby")
private val Bank = BankData("", Laenderkennzeichen.Germany, "")
private val Customer = CustomerData("", "")
@ -65,6 +72,34 @@ class FinTsClientTest {
}
@Test
fun checkIfAccountExists() {
// when
val result = underTest.checkIfAccountExists(Bank, Customer)
// then
assertThat(result.isSuccessful).isTrue()
assertThat(didAskUserForTanProcedure).isFalse()
assertThat(Bank.name).isNotEmpty()
assertThat(Bank.supportedJobs).isNotEmpty() // supported jobs are now known
assertThat(Bank.supportedTanProcedures).isNotEmpty() // supported tan procedures are now known
assertThat(Bank.supportedHbciVersions).isNotEmpty() // supported HBIC versions are now known
assertThat(Bank.supportedLanguages).isNotEmpty() // supported languages are now known
assertThat(Customer.name).isNotEmpty()
assertThat(Customer.iban).isNotNull()
assertThat(Customer.supportedTanProcedures).isNotEmpty()
assertThat(Customer.selectedLanguage).isNotEqualTo(Dialogsprache.Default) // language is set now
assertThat(Customer.customerSystemId).isNotEqualTo(KundensystemStatus.SynchronizingCustomerSystemId) // customer system id is now set
assertThat(Customer.customerSystemStatus).isEqualTo(KundensystemStatusWerte.Benoetigt) // customerSystemStatus is set now
assertThat(Customer.accounts).isNotEmpty() // accounts are now known
assertThat(Customer.accounts.first().allowedJobs).isNotEmpty() // allowed jobs are now known
}
@Test
fun synchronizeCustomerSystemId() {
@ -97,6 +132,17 @@ class FinTsClientTest {
@Test
fun testBankTransfer() {
// given
underTest.checkIfAccountExists(Bank, Customer)
// now BIC and IBAN should be set
assertThat(Bank.bic).describedAs("Bank's BIC should now be set").isNotNull()
assertThat(Customer.iban).describedAs("Customer's IBAN should now be set").isNotNull()
// transfer 1 cent to yourself. Transferring money to oneself also doesn't require to enter a TAN according to PSD2
val BankTransferData = BankTransferData(Customer.name, Customer.iban!!, Bank.bic!!, 0.01.toBigDecimal(), "Give it to me baby")
// when
val result = underTest.doBankTransfer(BankTransferData, Bank, Customer)