Skip to content

Commit 8bbacbb

Browse files
authored
Merge pull request #5556 from LibreSign/backport/5551/stable32
[stable32] fix: workaround to make compatible with different structures
2 parents afdf28f + 9bd2921 commit 8bbacbb

File tree

2 files changed

+220
-62
lines changed

2 files changed

+220
-62
lines changed

lib/Helper/ValidateHelper.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ public function validateIdentifySigners(array $data): void {
512512
}
513513

514514
private function validateSignersDataStructure(array $data): void {
515-
if (empty($data) || !array_key_exists('users', $data) || !is_array($data['users'])) {
515+
if (empty($data) || !array_key_exists('users', $data) || !is_array($data['users']) || empty($data['users'])) {
516516
throw new LibresignException($this->l10n->t('No signers'));
517517
}
518518
}
@@ -526,14 +526,58 @@ private function validateSignerData(mixed $signer): void {
526526
}
527527

528528
private function validateSignerIdentifyMethods(array $signer): void {
529-
if (empty($signer['identify']) || !is_array($signer['identify'])) {
530-
// It's an api error, don't translate
529+
$normalizedMethods = $this->normalizeIdentifyMethods($signer);
530+
531+
foreach ($normalizedMethods as $method) {
532+
$this->validateIdentifyMethodForRequest($method['name'], $method['value']);
533+
}
534+
}
535+
536+
/**
537+
* @todo unify the key to be only 'identify' or only 'identifyMethods'
538+
*/
539+
private function normalizeIdentifyMethods(array $signer): array {
540+
$key = array_key_exists('identifyMethods', $signer) ? 'identifyMethods' : 'identify';
541+
542+
if (empty($signer[$key]) || !is_array($signer[$key])) {
531543
throw new LibresignException('No identify methods for signer');
532544
}
533545

534-
foreach ($signer['identify'] as $name => $identifyValue) {
535-
$this->validateIdentifyMethodForRequest($name, $identifyValue);
546+
$normalizedMethods = [];
547+
548+
foreach ($signer[$key] as $name => $data) {
549+
$normalizedMethods[] = $this->normalizeIdentifyMethodEntry($key, $name, $data);
536550
}
551+
return $normalizedMethods;
552+
}
553+
554+
/**
555+
* Extracted from normalizeIdentifyMethods to reduce cyclomatic complexity.
556+
*/
557+
private function normalizeIdentifyMethodEntry(string $key, $name, $data): array {
558+
if ($key === 'identifyMethods') {
559+
return $this->normalizeIdentifyMethodsStructure($data);
560+
} else {
561+
return $this->normalizeIdentifyStructure($name, $data);
562+
}
563+
}
564+
565+
private function normalizeIdentifyMethodsStructure(mixed $data): array {
566+
if (!is_array($data) || !array_key_exists('method', $data) || !array_key_exists('value', $data)) {
567+
throw new LibresignException('Invalid identify method structure');
568+
}
569+
570+
return [
571+
'name' => $data['method'],
572+
'value' => $data['value'],
573+
];
574+
}
575+
576+
private function normalizeIdentifyStructure(string $name, mixed $value): array {
577+
return [
578+
'name' => $name,
579+
'value' => $value,
580+
];
537581
}
538582

539583
private function validateIdentifyMethodForRequest(string $name, string $identifyValue): void {

tests/php/Unit/Helper/ValidateHelperTest.php

Lines changed: 171 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -625,63 +625,6 @@ public static function datavalidateIfIdentifyMethodExists(): array {
625625
];
626626
}
627627

628-
#[DataProvider('providerValidateSignersDataStructure')]
629-
public function testValidateSignersDataStructure(array $data, ?string $expectedException, ?string $expectedMessage): void {
630-
$validateHelper = $this->getValidateHelper();
631-
632-
if ($expectedException) {
633-
$this->expectException($expectedException);
634-
if ($expectedMessage) {
635-
$this->expectExceptionMessage($expectedMessage);
636-
}
637-
}
638-
639-
// Use reflection to test private method
640-
$method = new \ReflectionMethod($validateHelper, 'validateSignersDataStructure');
641-
$method->invoke($validateHelper, $data);
642-
643-
if (!$expectedException) {
644-
$this->assertTrue(true);
645-
}
646-
}
647-
648-
public static function providerValidateSignersDataStructure(): array {
649-
return [
650-
'Empty data' => [[], LibresignException::class, 'No signers'],
651-
'No users key' => [['invalid' => 'data'], LibresignException::class, 'No signers'],
652-
'Users is not array' => [['users' => 'invalid'], LibresignException::class, 'No signers'],
653-
'Valid structure' => [['users' => []], null, null],
654-
];
655-
}
656-
657-
#[DataProvider('providerValidateSignerData')]
658-
public function testValidateSignerData($signer, ?string $expectedException, ?string $expectedMessage): void {
659-
$validateHelper = $this->getValidateHelper();
660-
661-
if ($expectedException) {
662-
$this->expectException($expectedException);
663-
if ($expectedMessage) {
664-
$this->expectExceptionMessage($expectedMessage);
665-
}
666-
}
667-
668-
$method = new \ReflectionMethod($validateHelper, 'validateSignerData');
669-
$method->invoke($validateHelper, $signer);
670-
671-
if (!$expectedException) {
672-
$this->assertTrue(true);
673-
}
674-
}
675-
676-
public static function providerValidateSignerData(): array {
677-
return [
678-
'Signer is not array' => ['invalid', LibresignException::class, 'No signers'],
679-
'Empty signer' => [[], LibresignException::class, 'No signers'],
680-
'No identify methods' => [['name' => 'User'], LibresignException::class, 'No identify methods for signer'],
681-
'Identify is not array' => [['identify' => 'invalid'], LibresignException::class, 'No identify methods for signer'],
682-
];
683-
}
684-
685628
public function testValidateIdentifyMethodForRequestWithNoSignatureMethods(): void {
686629
$identifyMethod = $this->createMock(IIdentifyMethod::class);
687630
$identifyMethod->method('getSignatureMethods')->willReturn([]);
@@ -739,4 +682,175 @@ public function testValidateIdentifySignersIntegration(): void {
739682

740683
$this->assertNull($result);
741684
}
685+
686+
#[DataProvider('providerValidateIdentifySigners')]
687+
public function testValidateIdentifySigners(array $data, bool $shouldThrow = false, string $expectedMessage = ''): void {
688+
// Mock signature method for valid cases
689+
$signatureMethod = $this->createMock(ISignatureMethod::class);
690+
$identifyMethod = $this->createMock(IIdentifyMethod::class);
691+
$identifyMethod->method('getSignatureMethods')->willReturn([$signatureMethod]);
692+
$identifyMethod->method('validateToRequest');
693+
694+
$this->identifyMethodService
695+
->method('getInstanceOfIdentifyMethod')
696+
->willReturn($identifyMethod);
697+
698+
$validateHelper = $this->getValidateHelper();
699+
700+
if ($shouldThrow) {
701+
$this->expectException(LibresignException::class);
702+
if ($expectedMessage) {
703+
$this->expectExceptionMessage($expectedMessage);
704+
}
705+
}
706+
707+
$validateHelper->validateIdentifySigners($data);
708+
709+
if (!$shouldThrow) {
710+
$this->addToAssertionCount(1); // If we get here without exception, test passed
711+
}
712+
}
713+
714+
public static function providerValidateIdentifySigners(): array {
715+
return [
716+
'valid data with identify structure single method' => [
717+
[
718+
'users' => [
719+
[
720+
'identify' => [
721+
'account' => '[email protected]'
722+
]
723+
]
724+
]
725+
],
726+
false, // should not throw
727+
],
728+
'valid data with identify structure multiple methods' => [
729+
[
730+
'users' => [
731+
[
732+
'identify' => [
733+
'account' => '[email protected]',
734+
'email' => '[email protected]'
735+
]
736+
]
737+
]
738+
],
739+
false, // should not throw
740+
],
741+
'valid data with identifyMethods structure single method' => [
742+
[
743+
'users' => [
744+
[
745+
'identifyMethods' => [
746+
['method' => 'account', 'value' => '[email protected]']
747+
]
748+
]
749+
]
750+
],
751+
false, // should not throw
752+
],
753+
'valid data with identifyMethods structure multiple methods' => [
754+
[
755+
'users' => [
756+
[
757+
'identifyMethods' => [
758+
['method' => 'account', 'value' => '[email protected]'],
759+
['method' => 'email', 'value' => '[email protected]']
760+
]
761+
]
762+
]
763+
],
764+
false, // should not throw
765+
],
766+
'mixed structures in same data' => [
767+
[
768+
'users' => [
769+
[
770+
'identify' => [
771+
'account' => '[email protected]'
772+
]
773+
],
774+
[
775+
'identifyMethods' => [
776+
['method' => 'email', 'value' => '[email protected]']
777+
]
778+
]
779+
]
780+
],
781+
false, // should not throw
782+
],
783+
'empty data structure' => [
784+
[],
785+
true, // should throw
786+
'No signers'
787+
],
788+
'missing users key' => [
789+
['someOtherKey' => 'value'],
790+
true, // should throw
791+
'No signers'
792+
],
793+
'empty users array' => [
794+
['users' => []],
795+
true, // should throw
796+
'No signers'
797+
],
798+
'users not array' => [
799+
['users' => 'not-an-array'],
800+
true, // should throw
801+
'No signers'
802+
],
803+
'empty signer' => [
804+
['users' => [[]]],
805+
true, // should throw
806+
'No signers'
807+
],
808+
'signer not array' => [
809+
['users' => ['not-an-array']],
810+
true, // should throw
811+
'No signers'
812+
],
813+
'signer without identify methods' => [
814+
['users' => [['someKey' => 'value']]],
815+
true, // should throw
816+
'No identify methods for signer'
817+
],
818+
'signer with empty identify' => [
819+
['users' => [['identify' => []]]],
820+
true, // should throw
821+
'No identify methods for signer'
822+
],
823+
'signer with empty identifyMethods' => [
824+
['users' => [['identifyMethods' => []]]],
825+
true, // should throw
826+
'No identify methods for signer'
827+
],
828+
'invalid identifyMethods structure - missing method' => [
829+
[
830+
'users' => [
831+
[
832+
'identifyMethods' => [
833+
['value' => '[email protected]'] // missing 'method'
834+
]
835+
]
836+
]
837+
],
838+
true, // should throw
839+
'Invalid identify method structure'
840+
],
841+
'invalid identifyMethods structure - missing value' => [
842+
[
843+
'users' => [
844+
[
845+
'identifyMethods' => [
846+
['method' => 'email'] // missing 'value'
847+
]
848+
]
849+
]
850+
],
851+
true, // should throw
852+
'Invalid identify method structure'
853+
],
854+
];
855+
}
742856
}

0 commit comments

Comments
 (0)