Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement GetVariables based on new segments layer #53

Merged
merged 8 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 11 additions & 113 deletions lib/Fhp/Response/GetVariables.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace Fhp\Response;

use Fhp\Parser\Exception\MT940Exception;
use Fhp\Segment\BaseSegment;
use Fhp\Segment\HITANS\HITANS;

/**
* Class GetVariables
Expand All @@ -22,121 +23,18 @@ public function getSupportedTanMechanisms() {
return $this->get()->tanModes;
}

public function parseTanModes($segments)
private function parseTanModes($segments)
{
// extracted from https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Security_Sicherheitsverfahren_PINTAN_2018-02-23_final_version.pdf
// Zwei-Schritt-TAN-Einreichung, Parameter
//
// 1. Segmentkopf:
// Beispiel: HITANS:169:6:4
// 1.1. Segmentkennung (HITANS)
// 1.2. Segmentnummer
// 1.3. Segmentversion
// 1.4. Bezugssegment
// 2. Maximale Anzahl Aufträge (int(3))
// 3. Anzahl Signaturen mindestens (0, 1, 2, 3)
// 4. Sicherheitsklasse (0, 1, 2, 3, 4)
// 5. Parameter Zwei-Schritt-TAN Einreichung
// 5.1. Einschrittverfahren erlaubt [jn] (V1-V6)
// 5.2. Mehr als ein TANpflichtiger Auftrag pro Nachricht erlaubt [jn] (V1-V6)
// 5.3. AuftragsHashwertverfahren [code] (V1-V6)
// 5.4. Sicherheitsprofil Banken-Signatur bei HITAN [code] (V1)
// 5.4. Verfahrensparameter ZweiSchritt-Verfahren (V2-V6)
// 5.5. Verfahrensparameter ZweiSchritt-Verfahren (V1)
// Sparkasse has 5 elements but declares version 6
$result = array();
foreach ($segments as $segmentRaw) {
$segment = $this->splitSegment($segmentRaw);

$segmentHeader = $this->splitDeg($segment[0]);
$version = (int) $segmentHeader[2]; // 1.3

$paramsIndex = count($segment) - 1;
$params = $this->splitDeg($segment[$paramsIndex]);

// 5. Parameter Zwei-Schritt-TAN-Einreichung:
// 5.4/5.5 s. Verfahrensparameter Zwei-Schritt-Verfahren
// Beispiel: J:N:0:910:2:HHD1.3.0:::chipTAN manuell:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:911:2:HHD1.3.2OPT:HHDOPT1:1.3.2:chipTAN optisch:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:912:2:HHD1.3.2USB:HHDUSB1:1.3.2:chipTAN-USB:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:913:2:Q1S:Secoder_UC:1.2.0:chipTAN-QR:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:920:2:smsTAN:::smsTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:2:N:5:921:2:pushTAN:::pushTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:2:N:2:900:2:iTAN:::iTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:0"
// -> Version 6
// J:N:0: (-> $processParamsOffset = 4)
// 910:2:HHD1.3.0:::chipTAN manuell:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:
// 911:2:HHD1.3.2OPT:HHDOPT1:1.3.2:chipTAN optisch:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:
// 912:2:HHD1.3.2USB:HHDUSB1:1.3.2:chipTAN-USB:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:
// 913:2:Q1S:Secoder_UC:1.2.0:chipTAN-QR:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:1:
// 920:2:smsTAN:::smsTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:2:N:5:
// 921:2:pushTAN:::pushTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:2:N:2:
// 900:2:iTAN:::iTAN:6:1:TAN-Nummer:3:J:2:N:0:0:N:N:00:0:N:0"

$processParamsOffset = $this->getTanProcessParamsOffsetForVersion($version);
$processNameIndex = $this->getTanProcessNameIndexForVersion($version);
$processParamElementCount = $this->getTanProcessParamElementCountForVersion($version);
array_splice($params, 0, $processParamsOffset);

$paramCount = count($params);
if ($paramCount % $processParamElementCount === $processParamElementCount - 1) {
// From version 3 on, the last parameter is optional and may be omitted in the last group of HITANS parameters
// see https://github.com/nemiah/phpFinTS/pull/40#issuecomment-532362814
$paramCount++;
}

$paramBlockIterations = $paramCount / $processParamElementCount;
for ($i = 0; $i < $paramBlockIterations; $i++) {
$blockOffset = $i * $processParamElementCount;
$num = $params[$blockOffset]; // first element in block
$name = $params[$processNameIndex + $blockOffset];
$result[$num] = $name;
}
}
$hitans = BaseSegment::parse($segmentRaw);
if (!($hitans instanceof HITANS)) {
throw new \InvalidArgumentException("All HITANS segments must implement the HITANS interface");
}
foreach ($hitans->getParameterZweiSchrittTanEinreichung()->getVerfahrensparameterZweiSchrittVerfahren() as $verfahren) {
$result[$verfahren->getSicherheitsfunktion()] = $verfahren->getNameDesZweiSchrittVerfahrens();
}
}
return $result;
}

private function getTanProcessParamsOffsetForVersion($version)
{
switch ($version) {
case 1:
return 4;
case 2:
case 3:
case 4:
case 5:
case 6:
return 3;
default:
throw new MT940Exception('Unknown HITANS version ' . $version);
}
}
private function getTanProcessParamElementCountForVersion($version)
{
switch ($version) {
case 1:
return 11;
break;
case 2:
return 15;
case 3:
return 18;
case 4:
case 5:
return 22;
case 6:
return 21;
default:
throw new MT940Exception('Unknown HITANS version ' . $version);
}
}
private function getTanProcessNameIndexForVersion($version)
{
switch ($version) {
case 1:
case 2:
case 3:
return 3;
case 4:
case 5:
case 6:
return 5;
default:
throw new MT940Exception('Unknown HITANS version ' . $version);
}
}
}
24 changes: 20 additions & 4 deletions lib/Fhp/Segment/BaseSegment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Fhp\Segment;

use Fhp\Syntax\Delimiter;
use Fhp\Syntax\Parser;
use Fhp\Syntax\Serializer;

Expand All @@ -17,6 +18,8 @@
*/
abstract class BaseSegment implements SegmentInterface
{
/** @var string Name of the PHP namespace under which all the segments are stored. */
const SEGMENT_NAMESPACE = 'Fhp\Segment';

/**
* Reference to the descriptor for this type of segment.
Expand Down Expand Up @@ -68,18 +71,31 @@ public function __toString()
}

/**
* Convenience function for {@link Parser#parseSegment()}. This function should not be called on BaseSegment itself,
* but only on one of its sub-classes.
* Convenience function for {@link Parser#parseSegment()}.
* @param string $rawSegment The serialized wire format for a single segment (segment delimiter may be present at
* the end, or not).
* @return BaseSegment The parsed segment.
*/
public static function parse($rawSegment)
{
if (static::class === BaseSegment::class) {
throw new \BadFunctionCallException("Do not call BaseSegment::parse() on the super class");
// Called as BaseSegment::parse(), so we need to determine the right segment type/class.
$firstElementDelimiter = strpos($rawSegment, Delimiter::ELEMENT);
if ($firstElementDelimiter === false) {
throw new \InvalidArgumentException("Invalid segment $rawSegment");
}
/** @var Segmentkopf $segmentkopf */
$segmentkopf = Segmentkopf::parse(substr($rawSegment, 0, $firstElementDelimiter));
$segmentType = static::SEGMENT_NAMESPACE . '\\' . $segmentkopf->segmentkennung . '\\'
. $segmentkopf->segmentkennung . 'v' . $segmentkopf->segmentversion;
if (!class_exists($segmentType)) {
throw new \InvalidArgumentException("Unsupported segment type/version $segmentType");
}
} else {
// The parse() function was called on the segment subclass itself.
$segmentType = static::class;
}
return Parser::parseSegment($rawSegment, static::class);
return Parser::parseSegment($rawSegment, $segmentType);
}

}
18 changes: 18 additions & 0 deletions lib/Fhp/Segment/HITANS/HITANS.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php


namespace Fhp\Segment\HITANS;

/**
* Interface HITANS
* Segment: Zwei-Schritt-TAN-Einreichung, Parameter
* Bezugssegment: HKVVB
* Sender: Kreditinstitut
*
* @package Fhp\Segment\HITANS
*/
interface HITANS
{
/** @return ParameterZweiSchrittTanEinreichung */
public function getParameterZweiSchrittTanEinreichung();
}
8 changes: 7 additions & 1 deletion lib/Fhp/Segment/HITANS/HITANSv1.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* @package Fhp\Segment\HITANS
*/
class HITANSv1 extends BaseSegment
class HITANSv1 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
Expand All @@ -24,4 +24,10 @@ class HITANSv1 extends BaseSegment
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV1 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV1 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
33 changes: 33 additions & 0 deletions lib/Fhp/Segment/HITANS/HITANSv2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php /** @noinspection PhpUnused */

namespace Fhp\Segment\HITANS;

use Fhp\Segment\BaseSegment;

/**
* Class HITANSv2
* Segment: Zwei-Schritt-TAN-Einreichung, Parameter (Version 2)
* Bezugssegment: HKVVB
* Sender: Kreditinstitut
*
* @link: https://www.hbci-zka.de/dokumente/spezifikation_deutsch/archiv/FinTS_V3.0_2017-10-06-FV_RM.zip
*
* @package Fhp\Segment\HITANS
*/
class HITANSv2 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
/** @var integer Allowed values: 0, 1, 2, 3 */
public $anzahlSignaturenMindestens;
/** @var integer Allowed values: 0, 1, 2, 3, 4 */
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV2 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV2 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
8 changes: 7 additions & 1 deletion lib/Fhp/Segment/HITANS/HITANSv3.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* @package Fhp\Segment\HITANS
*/
class HITANSv3 extends BaseSegment
class HITANSv3 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
Expand All @@ -24,4 +24,10 @@ class HITANSv3 extends BaseSegment
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV3 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV3 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
33 changes: 33 additions & 0 deletions lib/Fhp/Segment/HITANS/HITANSv4.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php /** @noinspection PhpUnused */

namespace Fhp\Segment\HITANS;

use Fhp\Segment\BaseSegment;

/**
* Class HITANSv4
* Segment: Zwei-Schritt-TAN-Einreichung, Parameter (Version 4)
* Bezugssegment: HKVVB
* Sender: Kreditinstitut
*
* @link: https://www.hbci-zka.de/dokumente/spezifikation_deutsch/archiv/FinTS_V3.0_2017-10-06-FV_RM.zip
*
* @package Fhp\Segment\HITANS
*/
class HITANSv4 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
/** @var integer Allowed values: 0, 1, 2, 3 */
public $anzahlSignaturenMindestens;
/** @var integer Allowed values: 0, 1, 2, 3, 4 */
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV4 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV4 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
33 changes: 33 additions & 0 deletions lib/Fhp/Segment/HITANS/HITANSv5.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php /** @noinspection PhpUnused */

namespace Fhp\Segment\HITANS;

use Fhp\Segment\BaseSegment;

/**
* Class HITANSv5
* Segment: Zwei-Schritt-TAN-Einreichung, Parameter (Version 5)
* Bezugssegment: HKVVB
* Sender: Kreditinstitut
*
* @link: https://www.hbci-zka.de/dokumente/spezifikation_deutsch/archiv/FinTS_V3.0_2017-10-06-FV_RM.zip
*
* @package Fhp\Segment\HITANS
*/
class HITANSv5 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
/** @var integer Allowed values: 0, 1, 2, 3 */
public $anzahlSignaturenMindestens;
/** @var integer Allowed values: 0, 1, 2, 3, 4 */
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV5 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV5 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
33 changes: 33 additions & 0 deletions lib/Fhp/Segment/HITANS/HITANSv6.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php /** @noinspection PhpUnused */

namespace Fhp\Segment\HITANS;

use Fhp\Segment\BaseSegment;

/**
* Class HITANSv6
* Segment: Zwei-Schritt-TAN-Einreichung, Parameter (Version 6)
* Bezugssegment: HKVVB
* Sender: Kreditinstitut
*
* @link: https://www.hbci-zka.de/dokumente/spezifikation_deutsch/archiv/FinTS_V3.0_2017-10-06-FV_RM.zip
*
* @package Fhp\Segment\HITANS
*/
class HITANSv6 extends BaseSegment implements HITANS
{
/** @var integer */
public $maximaleAnzahlAuftraege;
/** @var integer Allowed values: 0, 1, 2, 3 */
public $anzahlSignaturenMindestens;
/** @var integer Allowed values: 0, 1, 2, 3, 4 */
public $sicherheitsklasse;
/** @var ParameterZweiSchrittTanEinreichungV6 */
public $parameterZweiSchrittTanEinreichung;

/** @return ParameterZweiSchrittTanEinreichungV6 */
public function getParameterZweiSchrittTanEinreichung()
{
return $this->parameterZweiSchrittTanEinreichung;
}
}
9 changes: 9 additions & 0 deletions lib/Fhp/Segment/HITANS/ParameterZweiSchrittTanEinreichung.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php /** @noinspection PhpUnused */

namespace Fhp\Segment\HITANS;

interface ParameterZweiSchrittTanEinreichung
{
/** @return VerfahrensparameterZweiSchrittVerfahren[] */
public function getVerfahrensparameterZweiSchrittVerfahren();
}
Loading