Implemented parsing SecurityMethods
This commit is contained in:
parent
af35f35ba0
commit
b9c5883942
|
@ -5,8 +5,12 @@ import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
|||
|
||||
enum class Sicherheitsverfahren(override val code: String) : ICodeEnum {
|
||||
|
||||
PIN_TAN_Verfahren("PIN"),
|
||||
|
||||
RSA_AES_Hybridverfahren("RAH"),
|
||||
|
||||
PIN_TAN_Verfahren("PIN")
|
||||
RDH("RDH"),
|
||||
|
||||
DDV("DDV")
|
||||
|
||||
}
|
|
@ -25,9 +25,33 @@ import net.dankito.fints.messages.datenelementgruppen.Datenelementgruppe
|
|||
* - „2“ : bei allen Nachrichten, wenn Dialog im Zwei-Schritt-Verfahren
|
||||
*/
|
||||
open class Sicherheitsprofil(
|
||||
method: Sicherheitsverfahren,
|
||||
version: VersionDesSicherheitsverfahrens
|
||||
val method: Sicherheitsverfahren,
|
||||
val version: VersionDesSicherheitsverfahrens
|
||||
) : Datenelementgruppe(listOf(
|
||||
SicherheitsverfahrenCode(method),
|
||||
VersionDesSicherheitsverfahrensDatenelement(version)
|
||||
), Existenzstatus.Mandatory)
|
||||
), Existenzstatus.Mandatory) {
|
||||
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Sicherheitsprofil) return false
|
||||
|
||||
if (method != other.method) return false
|
||||
if (version != other.version) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = method.hashCode()
|
||||
result = 31 * result + version.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return "$method ${version.methodNumber}"
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,8 @@ enum class InstituteSegmentId(override val id: String) : ISegmentId {
|
|||
|
||||
Synchronization("HISYN"),
|
||||
|
||||
BankParameters("HIBPA")
|
||||
BankParameters("HIBPA"),
|
||||
|
||||
SecurityMethods("HISHV")
|
||||
|
||||
}
|
|
@ -4,12 +4,12 @@ import net.dankito.fints.messages.Separators
|
|||
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.HbciVersion
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.ICodeEnum
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitsverfahren
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.Kreditinstitutskennung
|
||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
|
||||
import net.dankito.fints.messages.segmente.id.MessageSegmentId
|
||||
import net.dankito.fints.response.segments.BankParameters
|
||||
import net.dankito.fints.response.segments.ReceivedMessageHeader
|
||||
import net.dankito.fints.response.segments.ReceivedSegment
|
||||
import net.dankito.fints.response.segments.ReceivedSynchronization
|
||||
import net.dankito.fints.response.segments.*
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
|
||||
|
@ -60,6 +60,7 @@ open class ResponseParser {
|
|||
MessageSegmentId.MessageHeader.id -> parseMessageHeaderSegment(segment, dataElementGroups)
|
||||
InstituteSegmentId.Synchronization.id -> parseSynchronization(segment, dataElementGroups)
|
||||
InstituteSegmentId.BankParameters.id -> parseBankParameters(segment, dataElementGroups)
|
||||
InstituteSegmentId.SecurityMethods.id -> parseSecurityMethods(segment, dataElementGroups)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +102,13 @@ open class ResponseParser {
|
|||
countMaxJobsPerMessage, supportedLanguages, supportedHbciVersions, maxMessageSize, minTimeout, maxTimeout, segment)
|
||||
}
|
||||
|
||||
protected open fun parseSecurityMethods(segment: String, dataElementGroups: List<String>): SecurityMethods {
|
||||
val mixingAllowed = parseBoolean(dataElementGroups[1])
|
||||
val profiles = parseSecurityProfiles(dataElementGroups.subList(2, dataElementGroups.size))
|
||||
|
||||
return SecurityMethods(mixingAllowed, profiles, segment)
|
||||
}
|
||||
|
||||
|
||||
protected open fun parseBankDetails(dataElementsGroup: String): Kreditinstitutskennung {
|
||||
val detailsStrings = getDataElements(dataElementsGroup)
|
||||
|
@ -120,6 +128,28 @@ open class ResponseParser {
|
|||
return parseFromCode(versionStrings, HbciVersion.values())
|
||||
}
|
||||
|
||||
protected open fun parseSecurityProfiles(dataElementsGroups: List<String>): List<Sicherheitsprofil> {
|
||||
return dataElementsGroups.flatMap { dataElementGroup ->
|
||||
val parts = getDataElements(dataElementGroup)
|
||||
|
||||
val method = parseSecurityMethod(parts[0])
|
||||
|
||||
parts.subList(1, parts.size).map {
|
||||
Sicherheitsprofil(method, parseSecurityMethodVersion(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun parseSecurityMethod(methodString: String): Sicherheitsverfahren {
|
||||
return parseFromCode(listOf(methodString), Sicherheitsverfahren.values()).first()
|
||||
}
|
||||
|
||||
protected open fun parseSecurityMethodVersion(versionString: String): VersionDesSicherheitsverfahrens {
|
||||
val versionInt = versionString.toInt()
|
||||
|
||||
return VersionDesSicherheitsverfahrens.values().first { it.methodNumber == versionInt }
|
||||
}
|
||||
|
||||
protected open fun <T : ICodeEnum> parseFromCode(codeValues: List<String>, allValues: Array<T>): List<T> {
|
||||
// mapNotNull: don't crash if new, at time of implementation unknown values get introduced / returned by bank
|
||||
return codeValues.mapNotNull { code -> allValues.first { it.code == code } }
|
||||
|
@ -130,4 +160,12 @@ open class ResponseParser {
|
|||
return dataElementGroup.split(Separators.DataElementsSeparator)
|
||||
}
|
||||
|
||||
protected open fun parseBoolean(dataElement: String): Boolean {
|
||||
if ("J" == dataElement) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.dankito.fints.response.segments
|
||||
|
||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
|
||||
|
||||
|
||||
open class SecurityMethods(
|
||||
|
||||
/**
|
||||
* Kennzeichen dafür, ob das Kreditinstitut die Mischung von Sicherheitsverfahren zulässt, sofern es mehrere
|
||||
* Sicherheitsverfahren anbietet. Hierunter ist zu verstehen,
|
||||
* - dass eine Nachricht von mehreren Benutzern mit unterschiedlichen Verfahren signiert wird.
|
||||
* - dass ein Benutzer die Nachrichten eines Dialoges mit verschiedenen Verfahren signiert.
|
||||
* - dass Signatur und Verschlüsselung einer Nachricht mit verschiedenen Verfahren durchgeführt werden.
|
||||
* - dass zwischen den folgenden Gruppen gemischt werden soll:
|
||||
* + RAH-7, RAH-9, RDH-3, RDH-5, RDH-6, RDH-7, RDH-8 und RDH-9
|
||||
* + RAH-10, RDH-2 und RDH-10
|
||||
* + DDV
|
||||
* + PIN
|
||||
*
|
||||
* Eine Verwendung von Sicherheitsverfahren innerhalb dieser Gruppen gilt nicht als Mischung.
|
||||
*
|
||||
* Ist hier ‘N’ eingestellt, so sind die genannten Fälle nicht zulässig, d. h. alle Signaturen und
|
||||
* Verschlüsselungen eines Dialoges müssen mit demselben Sicherheitsverfahren bzw. mit Verfahren aus der gleichen
|
||||
* Gruppe vorgenommen werden. Ist ‘J’ eingestellt, so müssen kreditinstitutsseitig alle vorgenannten Fälle unterstützt werden.
|
||||
*
|
||||
* Falls das Kreditinstitut nur ein Sicherheitsverfahren anbietet, ist ‘N’ einzustellen.
|
||||
*/
|
||||
val mixingAllowed: Boolean,
|
||||
|
||||
val securityProfiles: List<Sicherheitsprofil>,
|
||||
|
||||
segmentString: String
|
||||
)
|
||||
: ReceivedSegment(segmentString)
|
|
@ -2,11 +2,15 @@ package net.dankito.fints.response
|
|||
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.HbciVersion
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherheitsverfahren
|
||||
import net.dankito.fints.messages.datenelemente.implementierte.signatur.VersionDesSicherheitsverfahrens
|
||||
import net.dankito.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
|
||||
import net.dankito.fints.messages.segmente.id.ISegmentId
|
||||
import net.dankito.fints.messages.segmente.id.MessageSegmentId
|
||||
import net.dankito.fints.response.segments.BankParameters
|
||||
import net.dankito.fints.response.segments.ReceivedMessageHeader
|
||||
import net.dankito.fints.response.segments.ReceivedSynchronization
|
||||
import net.dankito.fints.response.segments.SecurityMethods
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
@ -79,6 +83,30 @@ class ResponseParserTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun parseSecurityMethods() {
|
||||
|
||||
// when
|
||||
val result = underTest.parse("HISHV:7:3:3+N+RDH:1:9:10+DDV:1+PIN:1'")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.SecurityMethods, 7, 3, 3)
|
||||
|
||||
result.getFirstSegmentById<SecurityMethods>(InstituteSegmentId.SecurityMethods)?.let { segment ->
|
||||
assertThat(segment.mixingAllowed).isFalse()
|
||||
|
||||
assertThat(segment.securityProfiles).contains(
|
||||
Sicherheitsprofil(Sicherheitsverfahren.RDH, VersionDesSicherheitsverfahrens.PIN_Ein_Schritt),
|
||||
Sicherheitsprofil(Sicherheitsverfahren.RDH, VersionDesSicherheitsverfahrens.RAH_9),
|
||||
Sicherheitsprofil(Sicherheitsverfahren.RDH, VersionDesSicherheitsverfahrens.RAH_10),
|
||||
Sicherheitsprofil(Sicherheitsverfahren.DDV, VersionDesSicherheitsverfahrens.PIN_Ein_Schritt),
|
||||
Sicherheitsprofil(Sicherheitsverfahren.PIN_TAN_Verfahren, VersionDesSicherheitsverfahrens.PIN_Ein_Schritt)
|
||||
)
|
||||
}
|
||||
?: run { Assert.fail("No segment of type SecurityMethods found in ${result.receivedSegments}") }
|
||||
}
|
||||
|
||||
|
||||
private fun assertSuccessfullyParsedSegment(result: Response, segmentId: ISegmentId, segmentNumber: Int,
|
||||
segmentVersion: Int, referenceSegmentNumber: Int? = null) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue