Extracted

This commit is contained in:
dankito 2020-12-06 18:24:22 +01:00
parent ae37442d86
commit 87e272565f
3 changed files with 84 additions and 53 deletions

View File

@ -3,6 +3,7 @@ package net.dankito.banking.fints
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.dankito.banking.fints.callback.FinTsClientCallback 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.MessageBuilder
import net.dankito.banking.fints.messages.MessageBuilderResult import net.dankito.banking.fints.messages.MessageBuilderResult
import net.dankito.banking.fints.messages.datenelemente.implementierte.Dialogsprache import net.dankito.banking.fints.messages.datenelemente.implementierte.Dialogsprache
@ -39,15 +40,13 @@ open class FinTsClient(
protected val messageBuilder: MessageBuilder = MessageBuilder(), protected val messageBuilder: MessageBuilder = MessageBuilder(),
protected val responseParser: ResponseParser = ResponseParser(), protected val responseParser: ResponseParser = ResponseParser(),
protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(), protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(),
protected val messageLogCollector: MessageLogCollector = MessageLogCollector(),
protected val product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "1.0.0") // TODO: get version dynamically protected val product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "1.0.0") // TODO: get version dynamically
) { ) {
companion object { companion object {
val SupportedAccountTypes = listOf(AccountType.Girokonto, AccountType.Festgeldkonto, AccountType.Kreditkartenkonto) 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 OneDayMillis = 24 * 60 * 60 * 1000L
const val NinetyDaysMillis = 90 * OneDayMillis const val NinetyDaysMillis = 90 * OneDayMillis
@ -56,11 +55,8 @@ open class FinTsClient(
} }
protected val messageLog = ArrayList<MessageLogEntry>() // 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<MessageLogEntry> open val messageLogWithoutSensitiveData: List<MessageLogEntry>
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) { protected open fun addMessageLog(message: String, type: MessageLogEntryType, dialogContext: DialogContext) {
val timeStamp = Date() messageLogCollector.addMessageLog(message, type, dialogContext.bank)
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, "<customer_id>")
.replace("+" + bank.pin, "+<pin>")
if (bank.customerName.isNotBlank()) {
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(bank.customerName, "<customer_name>", true)
}
bank.accounts.forEach { account ->
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(account.accountIdentifier, "<account_identifier>")
if (account.accountHolderName.isNotBlank()) {
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(account.accountHolderName, "<account_holder>", 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), "<account_transactions>")
}
}
return message
} }

View File

@ -1,6 +1,7 @@
package net.dankito.banking.fints package net.dankito.banking.fints
import net.dankito.banking.fints.callback.FinTsClientCallback 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.MessageBuilder
import net.dankito.banking.fints.model.* import net.dankito.banking.fints.model.*
import net.dankito.banking.fints.response.ResponseParser import net.dankito.banking.fints.response.ResponseParser
@ -23,10 +24,11 @@ open class FinTsClientForCustomer(
messageBuilder: MessageBuilder = MessageBuilder(), messageBuilder: MessageBuilder = MessageBuilder(),
responseParser: ResponseParser = ResponseParser(), responseParser: ResponseParser = ResponseParser(),
mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(), mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(),
messageLogCollector: MessageLogCollector = MessageLogCollector(),
product: ProductData = ProductData("15E53C26816138699C7B6A3E8", "1.0.0") // TODO: get version dynamically){} 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<MessageLogEntry> open val messageLogWithoutSensitiveData: List<MessageLogEntry>

View File

@ -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<MessageLogEntry>() // 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<MessageLogEntry>
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, "<customer_id>")
.replace("+" + bank.pin, "+<pin>")
if (bank.customerName.isNotBlank()) {
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(bank.customerName, "<customer_name>", true)
}
bank.accounts.forEach { account ->
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(account.accountIdentifier, "<account_identifier>")
if (account.accountHolderName.isNotBlank()) {
prettyPrintMessageWithoutSensitiveData = prettyPrintMessageWithoutSensitiveData
.replace(account.accountHolderName, "<account_holder>", 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), "<account_transactions>")
}
}
return message
}
}