From d9442d5ab255f8752dffb84326b3bd958ba54dbc Mon Sep 17 00:00:00 2001
From: mehmet-yoti <111424390+mehmet-yoti@users.noreply.github.com>
Date: Thu, 4 Jul 2024 18:50:09 +0300
Subject: [PATCH] Sdk 2420 php add support for advanced identity profiles to
share v 2 and examples (#360)
* SDK-2420 Added support for advanced identity profile and examples
* SDK-2420 Added test and updated tests for Advanced Identity Profile Share V2
---
.php-cs-fixer.cache | 1 -
.../AdvancedIdentityController.php | 71 +++++++++++++++
.../views/advancedidentity.blade.php | 89 +++++++++++++++++++
examples/digitalidentity/routes/web.php | 2 +
src/Identity/Policy/Policy.php | 21 ++++-
src/Identity/Policy/PolicyBuilder.php | 15 +++-
tests/Identity/Policy/PolicyBuilderTest.php | 76 +++++++++++++++-
7 files changed, 268 insertions(+), 7 deletions(-)
delete mode 100644 .php-cs-fixer.cache
create mode 100644 examples/digitalidentity/app/Http/Controllers/AdvancedIdentityController.php
create mode 100644 examples/digitalidentity/resources/views/advancedidentity.blade.php
diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache
deleted file mode 100644
index f684c0c8..00000000
--- a/.php-cs-fixer.cache
+++ /dev/null
@@ -1 +0,0 @@
-{"php":"8.1.29","version":"3.59.3:v3.59.3#30ba9ecc2b0e5205e578fe29973c15653d9bfd29","indent":" ","lineEnding":"\n","rules":{"array_syntax":{"syntax":"short"},"no_unused_imports":true,"ordered_imports":{"imports_order":["const","class","function"]},"php_unit_fqcn_annotation":true,"phpdoc_return_self_reference":true,"phpdoc_scalar":true},"hashes":{"\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder861\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"6df4324fbc01516f544e380a2fcdad1d","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder3196\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"81fbf5d555938c2c1693fa70c5d2f06b","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder10280\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"6df4324fbc01516f544e380a2fcdad1d","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder2372\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"81fbf5d555938c2c1693fa70c5d2f06b","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder12059\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"01fd3c6b4102578a5cbe7b9ca5a9620b","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder4216\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"2b29b8fd1369f029fdd2626aff9574a1","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder7923\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"a92ce4d8cf8cba9fc31b0b862a238e7d","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder9888\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"99cf5679ad3fbe693f1318efc4c7562e","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder7837\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"29258793b15beceaafceef4b742beca0","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder5368\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/FailureReasonResponse.php":"9f3471f97753fd479ff323dbab8f8ff8","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder9615\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/FailureReasonResponse.php":"fa7416c72cb9a21e375a580d0711b4a3","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder2220\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/FailureReasonResponse.php":"3f1b675e645966f11d6fe283ff3d1a5c","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder10144\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/FailureReasonResponse.php":"9f3471f97753fd479ff323dbab8f8ff8","\/private\/var\/folders\/hs\/kw0d0_0d2kj8xl5yd5_t2rz40000gn\/T\/PHP CS Fixertemp_folder7956\/src\/DocScan\/Session\/Retrieve\/IdentityProfile\/RequirementNotMetDetails.php":"29258793b15beceaafceef4b742beca0"}}
diff --git a/examples/digitalidentity/app/Http/Controllers/AdvancedIdentityController.php b/examples/digitalidentity/app/Http/Controllers/AdvancedIdentityController.php
new file mode 100644
index 00000000..cdfda0f6
--- /dev/null
+++ b/examples/digitalidentity/app/Http/Controllers/AdvancedIdentityController.php
@@ -0,0 +1,71 @@
+ [(object)[
+
+ "trust_framework" => "YOTI_GLOBAL",
+ "schemes" => [(object)[
+
+ "label" => "identity-AL-L1",
+ "type" => "IDENTITY",
+ "objective"=> "AL_L1"
+ ],
+ [
+ "label" => "identity-AL-M1",
+ "type" => "IDENTITY",
+ "objective" => "AL_M1"
+ ]
+ ]
+ ]
+ ]
+ ]
+ ;
+
+ $policy = (new PolicyBuilder())
+ ->withAdvancedIdentityProfileRequirements((object)$advancedIdentityProfileJson)
+ ->build();
+
+ $redirectUri = 'https://host/redirect/';
+
+ $shareSessionRequest = (new ShareSessionRequestBuilder())
+ ->withPolicy($policy)
+ ->withRedirectUri($redirectUri)
+ ->build();
+ $session = $client->createShareSession($shareSessionRequest);
+ return $session->getId();
+ }
+ catch (\Throwable $e) {
+ Log::error($e->getTraceAsString());
+ throw new BadRequestHttpException($e->getMessage());
+ }
+ }
+ public function show(DigitalIdentityClient $client)
+ {
+ try {
+ return view('advancedidentity', [
+ 'title' => 'Digital Identity(Advanced) Complete Example',
+ 'sdkId' => $client->id
+ ]);
+ } catch (\Throwable $e) {
+ Log::error($e->getTraceAsString());
+ throw new BadRequestHttpException($e->getMessage());
+ }
+ }
+}
diff --git a/examples/digitalidentity/resources/views/advancedidentity.blade.php b/examples/digitalidentity/resources/views/advancedidentity.blade.php
new file mode 100644
index 00000000..289e9e1e
--- /dev/null
+++ b/examples/digitalidentity/resources/views/advancedidentity.blade.php
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+ {{ $title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/digitalidentity/routes/web.php b/examples/digitalidentity/routes/web.php
index c592b91f..44933279 100644
--- a/examples/digitalidentity/routes/web.php
+++ b/examples/digitalidentity/routes/web.php
@@ -16,3 +16,5 @@
Route::get('/generate-share', 'IdentityController@show');
Route::get('/receipt-info', 'ReceiptController@show');
Route::get('/generate-session', 'IdentityController@generateSession');
+Route::get('/generate-advanced-identity-share', 'AdvancedIdentityController@show');
+Route::get('/generate-advanced-identity-session', 'AdvancedIdentityController@generateSession');
diff --git a/src/Identity/Policy/Policy.php b/src/Identity/Policy/Policy.php
index 62ade060..a71e1fdc 100644
--- a/src/Identity/Policy/Policy.php
+++ b/src/Identity/Policy/Policy.php
@@ -26,19 +26,26 @@ class Policy implements \JsonSerializable
*/
private $identityProfileRequirements;
+ /**
+ * @var object|null
+ */
+ private $advancedIdentityProfileRequirements;
+
/**
* @param WantedAttribute[] $wantedAttributes
* Array of attributes to be requested.
* @param int[] $wantedAuthTypes
* Auth types represents the authentication type to be used.
* @param object $identityProfileRequirements
+ * @param object $advancedidentityProfileRequirements
*/
public function __construct(
array $wantedAttributes,
array $wantedAuthTypes,
bool $wantedRememberMe = false,
bool $wantedRememberMeOptional = false,
- $identityProfileRequirements = null
+ $identityProfileRequirements = null,
+ $advancedIdentityProfileRequirements = null
) {
Validation::isArrayOfType($wantedAttributes, [WantedAttribute::class], 'wantedAttributes');
$this->wantedAttributes = $wantedAttributes;
@@ -49,6 +56,7 @@ public function __construct(
$this->wantedRememberMe = $wantedRememberMe;
$this->wantedRememberMeOptional = $wantedRememberMeOptional;
$this->identityProfileRequirements = $identityProfileRequirements;
+ $this->advancedIdentityProfileRequirements = $advancedIdentityProfileRequirements;
}
@@ -60,6 +68,7 @@ public function jsonSerialize(): stdClass
'wanted_remember_me' => $this->wantedRememberMe,
'wanted_remember_me_optional' => $this->wantedRememberMeOptional,
'identity_profile_requirements' => $this->identityProfileRequirements,
+ 'advanced_identity_profile_requirements' => $this->advancedIdentityProfileRequirements,
];
}
@@ -72,4 +81,14 @@ public function getIdentityProfileRequirements()
{
return $this->identityProfileRequirements;
}
+
+ /**
+ * AdvancedIdentityProfileRequirements requested in the policy
+ *
+ * @return object|null
+ */
+ public function getAdvancedIdentityProfileRequirements()
+ {
+ return $this->advancedIdentityProfileRequirements;
+ }
}
diff --git a/src/Identity/Policy/PolicyBuilder.php b/src/Identity/Policy/PolicyBuilder.php
index e8a8b190..a3b8f479 100644
--- a/src/Identity/Policy/PolicyBuilder.php
+++ b/src/Identity/Policy/PolicyBuilder.php
@@ -27,6 +27,7 @@ class PolicyBuilder
private bool $wantedRememberMeOptional = false;
private ?object $identityProfileRequirements = null;
+ private ?object $advancedIdentityProfileRequirements = null;
public function withWantedAttribute(WantedAttribute $wantedAttribute): self
{
@@ -318,6 +319,17 @@ public function withIdentityProfileRequirements($identityProfileRequirements): s
return $this;
}
+ /**
+ * Use an Advanced Identity Profile Requirement object for the share
+ *
+ * @param object $advancedIdentityProfileRequirements
+ * @return $this
+ */
+ public function withAdvancedIdentityProfileRequirements($advancedIdentityProfileRequirements): self
+ {
+ $this->advancedIdentityProfileRequirements = $advancedIdentityProfileRequirements;
+ return $this;
+ }
public function build(): Policy
{
@@ -326,7 +338,8 @@ public function build(): Policy
array_values($this->wantedAuthTypes),
$this->wantedRememberMe,
$this->wantedRememberMeOptional,
- $this->identityProfileRequirements
+ $this->identityProfileRequirements,
+ $this->advancedIdentityProfileRequirements
);
}
}
diff --git a/tests/Identity/Policy/PolicyBuilderTest.php b/tests/Identity/Policy/PolicyBuilderTest.php
index d223bd79..58b7968e 100644
--- a/tests/Identity/Policy/PolicyBuilderTest.php
+++ b/tests/Identity/Policy/PolicyBuilderTest.php
@@ -75,6 +75,7 @@ public function testBuildWithAttributes()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -124,6 +125,7 @@ public function testWithWantedAttributeByNameWithConstraints()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertJsonStringEqualsJsonString(
@@ -151,6 +153,7 @@ public function testWithDuplicateAttribute()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -205,6 +208,7 @@ public function testWithWantedAttributeByName()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -238,6 +242,7 @@ public function testWithAttributeObjects()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -269,6 +274,7 @@ public function testWithAgeDerivedAttributes()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -314,6 +320,7 @@ public function testWithAgeDerivedAttributesWithConstraints()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertJsonStringEqualsJsonString(
@@ -343,6 +350,7 @@ public function testWithDuplicateAgeDerivedAttributes()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -367,6 +375,7 @@ public function testWithAuthTypes()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -390,7 +399,8 @@ public function testWithAuthTypesTrue()
'wanted_auth_types' => [self::SELFIE_AUTH_TYPE, self::PIN_AUTH_TYPE, 99],
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
- 'identity_profile_requirements' => null
+ 'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -415,6 +425,7 @@ public function testWithAuthTypesFalse()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -439,6 +450,7 @@ public function testWithAuthEnabledThenDisabled()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -461,6 +473,7 @@ public function testWithSameAuthTypeAddedOnlyOnce()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -482,6 +495,7 @@ public function testWithOnlyTwoAuthTypes()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -503,6 +517,7 @@ public function testWithNoSelfieAuthAfterRemoval()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -524,6 +539,7 @@ public function testWithNoPinAuthAfterRemoval()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -545,6 +561,7 @@ public function testWithRememberMe()
'wanted_remember_me' => true,
'wanted_remember_me_optional' => false,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -564,7 +581,8 @@ public function testWithoutRememberMe()
'wanted_auth_types' => [],
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
- 'identity_profile_requirements' => null
+ 'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -585,6 +603,7 @@ public function testWithRememberMeOptional()
'wanted_remember_me' => false,
'wanted_remember_me_optional' => true,
'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -604,7 +623,8 @@ public function testWithoutRememberMeOptional()
'wanted_auth_types' => [],
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
- 'identity_profile_requirements' => null
+ 'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => null
];
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
@@ -631,7 +651,8 @@ public function testWithIdentityProfileRequirements()
'wanted_auth_types' => [],
'wanted_remember_me' => false,
'wanted_remember_me_optional' => false,
- 'identity_profile_requirements' => $identityProfileSample
+ 'identity_profile_requirements' => $identityProfileSample,
+ 'advanced_identity_profile_requirements' => null
];
$policy = (new PolicyBuilder())
@@ -641,4 +662,51 @@ public function testWithIdentityProfileRequirements()
$this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
$this->assertEquals($identityProfileSample, $policy->getIdentityProfileRequirements());
}
+
+ /**
+ * @covers ::withAdvancedIdentityProfileRequirements
+ * @covers \Yoti\Identity\Policy\Policy::__construct
+ * @covers \Yoti\Identity\Policy\Policy::getAdvancedIdentityProfileRequirements
+ * @covers \Yoti\Identity\Policy\Policy::jsonSerialize
+ */
+ public function testWithAdvancedIdentityProfileRequirements()
+ {
+ $advancedIdentityProfileSample =
+ (object)[
+ "profiles" => [(object)[
+
+ "trust_framework" => "YOTI_GLOBAL",
+ "schemes" => [(object)[
+
+ "label" => "identity-AL-L1",
+ "type" => "IDENTITY",
+ "objective"=> "AL_L1"
+ ],
+ [
+ "label" => "identity-AL-M1",
+ "type" => "IDENTITY",
+ "objective" => "AL_M1"
+ ]
+ ]
+ ]
+ ]
+ ]
+ ;
+
+ $expectedWantedAttributeData = [
+ 'wanted' => [],
+ 'wanted_auth_types' => [],
+ 'wanted_remember_me' => false,
+ 'wanted_remember_me_optional' => false,
+ 'identity_profile_requirements' => null,
+ 'advanced_identity_profile_requirements' => $advancedIdentityProfileSample
+ ];
+
+ $policy = (new PolicyBuilder())
+ ->withAdvancedIdentityProfileRequirements($advancedIdentityProfileSample)
+ ->build();
+
+ $this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($policy));
+ $this->assertEquals($advancedIdentityProfileSample, $policy->getAdvancedIdentityProfileRequirements());
+ }
}