From 87e272565f8720f938ea00a966eb19061164971a Mon Sep 17 00:00:00 2001 From: dankito Date: Sun, 6 Dec 2020 18:24:22 +0100 Subject: [PATCH] Extracted --- .../net/dankito/banking/fints/FinTsClient.kt | 56 +------------- .../banking/fints/FinTsClientForCustomer.kt | 4 +- .../banking/fints/log/MessageLogCollector.kt | 77 +++++++++++++++++++ 3 files changed, 84 insertions(+), 53 deletions(-) create mode 100644 fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt index af9ad260..26c09cd4 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -3,6 +3,7 @@ package net.dankito.banking.fints import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.dankito.banking.fints.callback.FinTsClientCallback +import net.dankito.banking.fints.log.MessageLogCollector import net.dankito.banking.fints.messages.MessageBuilder import net.dankito.banking.fints.messages.MessageBuilderResult import net.dankito.banking.fints.messages.datenelemente.implementierte.Dialogsprache @@ -39,15 +40,13 @@ open class FinTsClient( protected val messageBuilder: MessageBuilder = MessageBuilder(), protected val responseParser: ResponseParser = ResponseParser(), protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(), + protected val messageLogCollector: MessageLogCollector = MessageLogCollector(), protected val product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "1.0.0") // TODO: get version dynamically ) { companion object { val SupportedAccountTypes = listOf(AccountType.Girokonto, AccountType.Festgeldkonto, AccountType.Kreditkartenkonto) - val FindAccountTransactionsStartRegex = Regex("^HIKAZ:\\d:\\d:\\d\\+@\\d+@", RegexOption.MULTILINE) - val FindAccountTransactionsEndRegex = Regex("^-'", RegexOption.MULTILINE) - const val OneDayMillis = 24 * 60 * 60 * 1000L const val NinetyDaysMillis = 90 * OneDayMillis @@ -56,11 +55,8 @@ open class FinTsClient( } - protected val messageLog = ArrayList() // TODO: make thread safe like with CopyOnWriteArrayList - - // in either case remove sensitive data after response is parsed as otherwise some information like account holder name and accounts may is not set yet on BankData open val messageLogWithoutSensitiveData: List - get() = messageLog.map { MessageLogEntry(removeSensitiveDataFromMessage(it.message, it.bank), it.time, it.bank) } + get() = messageLogCollector.messageLogWithoutSensitiveData /** @@ -789,51 +785,7 @@ open class FinTsClient( protected open fun addMessageLog(message: String, type: MessageLogEntryType, dialogContext: DialogContext) { - val timeStamp = Date() - val messagePrefix = "${if (type == MessageLogEntryType.Sent) "Sending" else "Received"} message:\r\n" // currently no need to translate - val prettyPrintMessage = prettyPrintHbciMessage(message) - val prettyPrintMessageWithPrefix = "$messagePrefix$prettyPrintMessage" - - log.debug { prettyPrintMessageWithPrefix } - - messageLog.add(MessageLogEntry(prettyPrintMessageWithPrefix, timeStamp, dialogContext.bank)) - } - - protected fun prettyPrintHbciMessage(message: String): String { - return message.replace("'", "'\r\n") - } - - protected open fun removeSensitiveDataFromMessage(message: String, bank: BankData): String { - var prettyPrintMessageWithoutSensitiveData = message - .replace(bank.customerId, "") - .replace("+" + bank.pin, "+") - - if (bank.customerName.isNotBlank()) { - prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData - .replace(bank.customerName, "", true) - } - - bank.accounts.forEach { account -> - prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData - .replace(account.accountIdentifier, "") - - if (account.accountHolderName.isNotBlank()) { - prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData - .replace(account.accountHolderName, "", true) - } - } - - return removeAccountTransactions(prettyPrintMessageWithoutSensitiveData) - } - - protected open fun removeAccountTransactions(message: String): String { - FindAccountTransactionsStartRegex.find(message)?.let { startMatchResult -> - FindAccountTransactionsEndRegex.find(message, startMatchResult.range.endInclusive)?.let { endMatchResult -> - return message.replaceRange(IntRange(startMatchResult.range.endInclusive, endMatchResult.range.start), "") - } - } - - return message + messageLogCollector.addMessageLog(message, type, dialogContext.bank) } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt index 175e1628..df0fea19 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt @@ -1,6 +1,7 @@ package net.dankito.banking.fints import net.dankito.banking.fints.callback.FinTsClientCallback +import net.dankito.banking.fints.log.MessageLogCollector import net.dankito.banking.fints.messages.MessageBuilder import net.dankito.banking.fints.model.* import net.dankito.banking.fints.response.ResponseParser @@ -23,10 +24,11 @@ open class FinTsClientForCustomer( messageBuilder: MessageBuilder = MessageBuilder(), responseParser: ResponseParser = ResponseParser(), mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(), + messageLogCollector: MessageLogCollector = MessageLogCollector(), product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "1.0.0") // TODO: get version dynamically){} ) { - protected val client = FinTsClient(callback, webClient, base64Service, messageBuilder, responseParser, mt940Parser, product) + protected val client = FinTsClient(callback, webClient, base64Service, messageBuilder, responseParser, mt940Parser, messageLogCollector, product) open val messageLogWithoutSensitiveData: List diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt new file mode 100644 index 00000000..ee3bea50 --- /dev/null +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt @@ -0,0 +1,77 @@ +package net.dankito.banking.fints.log + +import net.dankito.banking.fints.model.BankData +import net.dankito.banking.fints.model.MessageLogEntry +import net.dankito.banking.fints.model.MessageLogEntryType +import net.dankito.utils.multiplatform.log.LoggerFactory +import net.dankito.utils.multiplatform.Date +import net.dankito.utils.multiplatform.getInnerExceptionMessage + + +open class MessageLogCollector { + + companion object { + val FindAccountTransactionsStartRegex = Regex("^HIKAZ:\\d:\\d:\\d\\+@\\d+@", RegexOption.MULTILINE) + val FindAccountTransactionsEndRegex = Regex("^-'", RegexOption.MULTILINE) + + private val log = LoggerFactory.getLogger(MessageLogCollector::class) + } + + + protected open val messageLog = ArrayList() // TODO: make thread safe like with CopyOnWriteArrayList + + // in either case remove sensitive data after response is parsed as otherwise some information like account holder name and accounts may is not set yet on BankData + open val messageLogWithoutSensitiveData: List + get() = messageLog.map { MessageLogEntry(removeSensitiveDataFromMessage(it.message, it.bank), it.time, it.bank) } + + + open fun addMessageLog(message: String, type: MessageLogEntryType, bank: BankData) { + val timeStamp = Date() + val messagePrefix = "${if (type == MessageLogEntryType.Sent) "Sending" else "Received"} message:\r\n" // currently no need to translate + val prettyPrintMessage = prettyPrintHbciMessage(message) + val prettyPrintMessageWithPrefix = "$messagePrefix$prettyPrintMessage" + + log.debug { prettyPrintMessageWithPrefix } + + messageLog.add(MessageLogEntry(prettyPrintMessageWithPrefix, timeStamp, bank)) + } + + protected open fun prettyPrintHbciMessage(message: String): String { + return message.replace("'", "'\r\n") + } + + + protected open fun removeSensitiveDataFromMessage(message: String, bank: BankData): String { + var prettyPrintMessageWithoutSensitiveData = message + .replace(bank.customerId, "") + .replace("+" + bank.pin, "+") + + if (bank.customerName.isNotBlank()) { + prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData + .replace(bank.customerName, "", true) + } + + bank.accounts.forEach { account -> + prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData + .replace(account.accountIdentifier, "") + + if (account.accountHolderName.isNotBlank()) { + prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData + .replace(account.accountHolderName, "", true) + } + } + + return removeAccountTransactions(prettyPrintMessageWithoutSensitiveData) + } + + protected open fun removeAccountTransactions(message: String): String { + FindAccountTransactionsStartRegex.find(message)?.let { startMatchResult -> + FindAccountTransactionsEndRegex.find(message, startMatchResult.range.endInclusive)?.let { endMatchResult -> + return message.replaceRange(IntRange(startMatchResult.range.endInclusive, endMatchResult.range.start), "") + } + } + + return message + } + +} \ No newline at end of file