Implemented retrieving user's TAN procedures with a non-strong authenticated dialog init with one step TAN procedure (the only process where one step TAN procedure is still allowed) as some banks like Postbank require this
This commit is contained in:
parent
639653f430
commit
b07e84b31c
|
@ -8,10 +8,8 @@ import net.dankito.banking.fints.messages.MessageBuilderResult
|
|||
import net.dankito.banking.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.ZkaTanProcedure
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.*
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.response.GetUserTanProceduresResponse
|
||||
import net.dankito.banking.fints.response.InstituteSegmentId
|
||||
|
@ -113,7 +111,7 @@ open class FinTsClient(
|
|||
}
|
||||
|
||||
|
||||
open fun getBankAndCustomerInfoForNewUser(bank: BankData, customer: CustomerData, callback: (AddAccountResponse) -> Unit) {
|
||||
open fun getUsersTanProcedures(bank: BankData, customer: CustomerData, callback: (AddAccountResponse) -> Unit) {
|
||||
// just to ensure settings are in its initial state and that bank sends use bank parameter (BPD),
|
||||
// user parameter (UPD) and allowed tan procedures for user (therefore the resetSelectedTanProcedure())
|
||||
bank.resetBpdVersion()
|
||||
|
@ -126,18 +124,30 @@ open class FinTsClient(
|
|||
*/
|
||||
customer.resetSelectedTanProcedure()
|
||||
|
||||
val dialogContext = DialogContext(bank, customer, product)
|
||||
// this is the only case where Einschritt-TAN-Verfahren is accepted: to get user's TAN procedures
|
||||
val dialogContext = DialogContext(bank, customer, product, versionOfSecurityProcedure = VersionDesSicherheitsverfahrens.Version_1)
|
||||
|
||||
initDialogAfterSuccessfulChecks(dialogContext) { initDialogResponse ->
|
||||
val message = messageBuilder.createInitDialogMessage(dialogContext)
|
||||
|
||||
getAndHandleResponseForMessage(message, dialogContext) { response ->
|
||||
closeDialog(dialogContext)
|
||||
|
||||
// even though it is required by specification some banks don't support retrieving user's TAN procedure by setting TAN procedure to '999'
|
||||
if (bankDoesNotSupportRetrievingUsersTanProcedures(initDialogResponse)) {
|
||||
getBankAndCustomerInfoForNewUserViaAnonymousDialog(bank, customer, callback)
|
||||
}
|
||||
else {
|
||||
callback(AddAccountResponse(initDialogResponse, bank, customer))
|
||||
}
|
||||
handleGetUsersTanProceduresResponse(response, dialogContext, callback)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun handleGetUsersTanProceduresResponse(response: Response, dialogContext: DialogContext, callback: (AddAccountResponse) -> Unit) {
|
||||
if (response.successful) { // TODO: really update data only on complete successfully response? as it may contain useful information anyway // TODO: extract method for this code part
|
||||
updateBankData(dialogContext.bank, response)
|
||||
updateCustomerData(dialogContext.customer, dialogContext.bank, response)
|
||||
}
|
||||
|
||||
// even though it is required by specification some banks don't support retrieving user's TAN procedure by setting TAN procedure to '999'
|
||||
if (bankDoesNotSupportRetrievingUsersTanProcedures(response)) {
|
||||
getBankAndCustomerInfoForNewUserViaAnonymousDialog(dialogContext.bank, dialogContext.customer, callback) // TODO: should not be necessary anymore
|
||||
}
|
||||
else {
|
||||
callback(AddAccountResponse(response, dialogContext.bank, dialogContext.customer))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,9 +218,9 @@ open class FinTsClient(
|
|||
val originalAreWeThatGentleToCloseDialogs = areWeThatGentleToCloseDialogs
|
||||
areWeThatGentleToCloseDialogs = false
|
||||
|
||||
/* First dialog: Get user's basic data like her TAN procedures */
|
||||
/* First dialog: Get user's basic data like BPD, customer system ID and her TAN procedures */
|
||||
|
||||
getBankAndCustomerInfoForNewUser(bank, customer) { newUserInfoResponse ->
|
||||
getUsersTanProcedures(bank, customer) { newUserInfoResponse ->
|
||||
|
||||
if (newUserInfoResponse.isSuccessful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong
|
||||
callback(newUserInfoResponse)
|
||||
|
@ -541,7 +551,7 @@ open class FinTsClient(
|
|||
|
||||
protected open fun ensureBasicBankDataRetrieved(bank: BankData, customer: CustomerData, callback: (Response) -> Unit) {
|
||||
if (bank.supportedTanProcedures.isEmpty() || bank.supportedJobs.isEmpty()) {
|
||||
getBankAndCustomerInfoForNewUser(bank, customer) { getBankInfoResponse ->
|
||||
getUsersTanProcedures(bank, customer) { getBankInfoResponse ->
|
||||
if (getBankInfoResponse.isSuccessful == false || bank.supportedTanProcedures.isEmpty()
|
||||
|| bank.supportedJobs.isEmpty()) {
|
||||
|
||||
|
@ -561,7 +571,7 @@ open class FinTsClient(
|
|||
protected open fun ensureTanProcedureIsSelected(bank: BankData, customer: CustomerData, callback: (Response) -> Unit) {
|
||||
if (customer.isTanProcedureSelected == false) {
|
||||
if (customer.supportedTanProcedures.isEmpty()) {
|
||||
getBankAndCustomerInfoForNewUser(bank, customer) {
|
||||
getUsersTanProcedures(bank, customer) {
|
||||
if (customer.supportedTanProcedures.isEmpty()) { // could not retrieve supported tan procedures for user
|
||||
callback(Response(false, noTanProcedureSelected = true))
|
||||
}
|
||||
|
|
|
@ -3,6 +3,17 @@ package net.dankito.banking.fints.messages.datenelemente.implementierte.signatur
|
|||
|
||||
enum class VersionDesSicherheitsverfahrens(val methodNumber: Int) {
|
||||
|
||||
/*
|
||||
PinTan:
|
||||
|
||||
Version des Sicherheitsverfahrens
|
||||
„1“ : bei allen Nachrichten, wenn Dialog im Einschritt-Verfahren
|
||||
„2“ : bei allen Nachrichten, wenn Dialog im Zwei-Schritt-Verfahren
|
||||
|
||||
Die Verwendung des Ein-Schritt-Verfahrens ist jedoch nur noch in bestimmten Situationen,
|
||||
z. B. zur Ermittlung der zugelassenen Sicherheitsverfahren, zugelassen.
|
||||
*/
|
||||
|
||||
Version_1(1),
|
||||
|
||||
Version_2(2),
|
||||
|
@ -21,6 +32,13 @@ enum class VersionDesSicherheitsverfahrens(val methodNumber: Int) {
|
|||
|
||||
Version_9(9),
|
||||
|
||||
Version_10(10)
|
||||
Version_10(10);
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
val PinTanDefaultVersion = Version_2
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
package net.dankito.banking.fints.messages.segmente.implementierte
|
||||
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.OperationsmodusKodiert
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Schluesselnummer
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Schluesselversion
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.SignaturalgorithmusKodiert
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.*
|
||||
import net.dankito.banking.fints.model.MessageBaseData
|
||||
|
||||
|
||||
|
@ -18,6 +15,7 @@ open class PinTanSignaturkopf(
|
|||
segmentNumber,
|
||||
baseData.bank,
|
||||
baseData.customer,
|
||||
baseData.versionOfSecurityProcedure,
|
||||
securityControlReference,
|
||||
date,
|
||||
time,
|
||||
|
|
|
@ -14,6 +14,7 @@ open class PinTanVerschluesselungskopf(
|
|||
) : Verschluesselungskopf(
|
||||
baseData.bank,
|
||||
baseData.customer,
|
||||
baseData.versionOfSecurityProcedure,
|
||||
date,
|
||||
time,
|
||||
Operationsmodus.Cipher_Block_Chaining,
|
||||
|
|
|
@ -26,6 +26,7 @@ open class Signaturkopf(
|
|||
segmentNumber: Int,
|
||||
bank: BankData,
|
||||
customer: CustomerData,
|
||||
versionOfSecurityProcedure: VersionDesSicherheitsverfahrens,
|
||||
securityControlReference: String,
|
||||
date: Int,
|
||||
time: Int,
|
||||
|
@ -36,7 +37,10 @@ open class Signaturkopf(
|
|||
|
||||
) : Segment(listOf(
|
||||
Segmentkopf(MessageSegmentId.SignatureHeader, 4, segmentNumber), // allowed
|
||||
Sicherheitsprofil(Sicherheitsverfahren.PIN_TAN_Verfahren, VersionDesSicherheitsverfahrens.Version_2), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure
|
||||
Sicherheitsprofil(
|
||||
Sicherheitsverfahren.PIN_TAN_Verfahren,
|
||||
versionOfSecurityProcedure
|
||||
), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure; the only exception is the first dialog to get user's TAN procedures which allows to use one step tan procedure (as we don't know TAN procedures yet)
|
||||
SicherheitsfunktionKodiert(customer.selectedTanProcedure.securityFunction),
|
||||
Sicherheitskontrollreferenz(securityControlReference), // allowed: <>0
|
||||
BereichDerSicherheitsapplikationKodiert(BereichDerSicherheitsapplikation.SignaturkopfUndHBCINutzdaten), // allowed: 1 ?
|
||||
|
|
|
@ -36,6 +36,7 @@ import net.dankito.banking.fints.model.CustomerData
|
|||
open class Verschluesselungskopf(
|
||||
bank: BankData,
|
||||
customer: CustomerData,
|
||||
versionOfSecurityProcedure: VersionDesSicherheitsverfahrens,
|
||||
date: Int,
|
||||
time: Int,
|
||||
mode: Operationsmodus,
|
||||
|
@ -47,7 +48,7 @@ open class Verschluesselungskopf(
|
|||
|
||||
) : Segment(listOf(
|
||||
Segmentkopf(MessageSegmentId.EncryptionHeader, 3, 998),
|
||||
Sicherheitsprofil(Sicherheitsverfahren.PIN_TAN_Verfahren, VersionDesSicherheitsverfahrens.Version_2), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure
|
||||
Sicherheitsprofil(Sicherheitsverfahren.PIN_TAN_Verfahren, versionOfSecurityProcedure), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure; the only exception is the first dialog to get user's TAN procedures which allows to use one step tan procedure (as we don't know TAN procedures yet)
|
||||
SicherheitsfunktionKodiert(Sicherheitsfunktion.Klartext),
|
||||
RolleDesSicherheitslieferantenKodiert(), // allowed: 1, 4
|
||||
SicherheitsidentifikationDetails(customer.customerSystemId),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
import net.dankito.banking.fints.messages.MessageBuilderResult
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
import net.dankito.banking.fints.response.Response
|
||||
|
||||
|
||||
|
@ -13,9 +14,10 @@ open class DialogContext(
|
|||
var dialogId: String = InitialDialogId,
|
||||
var response: Response? = null,
|
||||
var didBankCloseDialog: Boolean = false,
|
||||
versionOfSecurityProcedure: VersionDesSicherheitsverfahrens = VersionDesSicherheitsverfahrens.Version_2, // for PinTan almost always the case except for getting a user's TAN procedures
|
||||
var previousMessageInDialog: MessageBuilderResult? = null,
|
||||
var chunkedResponseHandler: ((Response) -> Unit)? = null
|
||||
) : MessageBaseData(bank, customer, product) {
|
||||
) : MessageBaseData(bank, customer, product, versionOfSecurityProcedure) {
|
||||
|
||||
companion object {
|
||||
const val InitialDialogId = "0"
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
|
||||
|
||||
open class MessageBaseData(
|
||||
val bank: BankData,
|
||||
val customer: CustomerData,
|
||||
val product: ProductData
|
||||
val product: ProductData,
|
||||
val versionOfSecurityProcedure: VersionDesSicherheitsverfahrens = VersionDesSicherheitsverfahrens.PinTanDefaultVersion
|
||||
)
|
Loading…
Reference in New Issue