diff --git a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/BankTransferDialog.kt b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/BankTransferDialog.kt index 2d33a856..2f04686b 100644 --- a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/BankTransferDialog.kt +++ b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/dialogs/BankTransferDialog.kt @@ -13,6 +13,8 @@ import kotlinx.android.synthetic.main.dialog_bank_transfer.* import kotlinx.android.synthetic.main.dialog_bank_transfer.view.* import net.dankito.banking.fints4java.android.R import net.dankito.banking.fints4java.android.ui.MainWindowPresenter +import net.dankito.fints.messages.segmente.implementierte.sepa.ISepaMessageCreator +import net.dankito.fints.messages.segmente.implementierte.sepa.SepaMessageCreator import net.dankito.fints.model.BankTransferData import net.dankito.fints.response.client.FinTsClientResponse import net.dankito.utils.android.extensions.asActivity @@ -30,6 +32,8 @@ open class BankTransferDialog : DialogFragment() { protected var preselectedValues: BankTransferData? = null + protected val sepaMessageCreator: ISepaMessageCreator = SepaMessageCreator() + open fun show(activity: AppCompatActivity, presenter: MainWindowPresenter, fullscreen: Boolean = false) { show(activity, presenter, null, fullscreen) @@ -64,6 +68,7 @@ open class BankTransferDialog : DialogFragment() { rootView.edtxtRemitteeBic.addTextChangedListener(otherEditTextChangedWatcher) rootView.edtxtAmount.addTextChangedListener(otherEditTextChangedWatcher) + rootView.edtxtUsage.addTextChangedListener(otherEditTextChangedWatcher) rootView.btnCancel.setOnClickListener { dismiss() } @@ -184,9 +189,11 @@ open class BankTransferDialog : DialogFragment() { protected open fun checkIfRequiredDataEnteredOnUiThread() { val requiredDataEntered = edtxtRemitteeName.text.toString().isNotEmpty() + && sepaMessageCreator.containsOnlyAllowedCharacters(edtxtRemitteeName.text.toString()) // TODO: show error message for illegal characters && edtxtRemitteeIban.text.toString().isNotEmpty() // TODO: check if it is of length > 12, in Germany > 22? && edtxtRemitteeBic?.text.toString().isNotEmpty() // TODO: check if it is of length is 8 or 11? && isAmountGreaterZero() + && sepaMessageCreator.containsOnlyAllowedCharacters(edtxtUsage.text.toString()) // TODO: show error message for illegal characters btnDoBankTransfer.isEnabled = requiredDataEntered } diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/ISepaMessageCreator.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/ISepaMessageCreator.kt index 0805157d..8865a344 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/ISepaMessageCreator.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/ISepaMessageCreator.kt @@ -5,4 +5,8 @@ interface ISepaMessageCreator { fun createXmlFile(filename: String, replacementStrings: Map): String + fun containsOnlyAllowedCharacters(stringToTest: String): Boolean + + fun convertToAllowedCharacters(input: String): String + } \ No newline at end of file diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaEinzelueberweisung.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaEinzelueberweisung.kt index 8db66777..b321131b 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaEinzelueberweisung.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaEinzelueberweisung.kt @@ -23,14 +23,14 @@ open class SepaEinzelueberweisung( debitorBic, mapOf( SepaMessageCreator.NumberOfTransactionsKey to "1", // TODO: may someday support more then one transaction per file - "DebitorName" to debitor.name, + "DebitorName" to messageCreator.convertToAllowedCharacters(debitor.name), "DebitorIban" to debitor.iban!!, "DebitorBic" to debitorBic, - "CreditorName" to data.creditorName, + "CreditorName" to messageCreator.convertToAllowedCharacters(data.creditorName), "CreditorIban" to data.creditorIban, "CreditorBic" to data.creditorBic, - "Amount" to data.amount.toString(), - "Usage" to data.usage, + "Amount" to data.amount.toString(), // TODO: check if ',' or '.' should be used as decimal separator + "Usage" to messageCreator.convertToAllowedCharacters(data.usage), "RequestedExecutionDate" to RequestedExecutionDateValueForNotScheduledTransfers ), messageCreator diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreator.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreator.kt index 0c0afd58..f121a278 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreator.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreator.kt @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory import java.io.File import java.text.SimpleDateFormat import java.util.* +import java.util.regex.Pattern /** @@ -19,6 +20,10 @@ import java.util.* open class SepaMessageCreator : ISepaMessageCreator { companion object { + const val AllowedSepaCharacters = "A-Za-z0-9\\?,\\-\\+\\./\\(\\) " + + val AllowedSepaCharactersPattern: Pattern = Pattern.compile("^[$AllowedSepaCharacters]*$") + const val MessageIdKey = "MessageId" const val CreationDateTimeKey = "CreationDateTime" @@ -33,6 +38,21 @@ open class SepaMessageCreator : ISepaMessageCreator { } + override fun containsOnlyAllowedCharacters(stringToTest: String): Boolean { + return AllowedSepaCharactersPattern.matcher(stringToTest).matches() + } + + override fun convertToAllowedCharacters(input: String): String { + // TODO: add other replacement strings + return input + .replace("\"", """) + .replace("\'", "'") + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + } + + override fun createXmlFile(filename: String, replacementStrings: Map): String { var xmlFile = loadXmlFile(filename) diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt new file mode 100644 index 00000000..8eeee835 --- /dev/null +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt @@ -0,0 +1,82 @@ +package net.dankito.fints.messages.segmente.implementierte.sepa + +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + + +class SepaMessageCreatorTest { + + private val underTest = SepaMessageCreator() + + + @Test + fun containsOnlyAllowedCharacters_SimpleName() { + + // when + val result = underTest.containsOnlyAllowedCharacters("Marieke Musterfrau") + + // then + assertThat(result).isTrue() + } + + @Test + fun containsOnlyAllowedCharacters_WithAllAllowedCharacters() { + + // when + val result = underTest.containsOnlyAllowedCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.?+-/()") + + // then + assertThat(result).isTrue() + } + + @Test + fun `containsOnlyAllowedCharacters ! is an illegal character`() { + + // when + val result = underTest.containsOnlyAllowedCharacters("!") + + // then + assertThat(result).isFalse() + } + + @Test + fun `containsOnlyAllowedCharacters € is an illegal character`() { + + // when + val result = underTest.containsOnlyAllowedCharacters("€") + + // then + assertThat(result).isFalse() + } + + @Test + fun `containsOnlyAllowedCharacters @ is an illegal character`() { + + // when + val result = underTest.containsOnlyAllowedCharacters("@") + + // then + assertThat(result).isFalse() + } + + @Test + fun `containsOnlyAllowedCharacters colon is an illegal character`() { + + // when + val result = underTest.containsOnlyAllowedCharacters(":") + + // then + assertThat(result).isFalse() + } + + @Test + fun `containsOnlyAllowedCharacters ö is an illegal character`() { + + // when + val result = underTest.containsOnlyAllowedCharacters("ö") + + // then + assertThat(result).isFalse() + } + +} \ No newline at end of file