From 74ad64ff7d9b003f249c3005759b116a7348352b Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Mon, 31 Jan 2022 16:30:33 +0200 Subject: [PATCH 01/13] Adding email to composer --- composer.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 9852ad5..9da91cf 100644 --- a/composer.json +++ b/composer.json @@ -5,9 +5,10 @@ "homepage" : "https://github.com/smileidentity/smile-identity-core-php", "license" : "MIT", "authors" : [{ - "name" : "Smile Identity", - "email" : "support@smileidentity.com" - }], + "name" : "Smile Identity", + "email" : "support@smileidentity.com" + } + ], "require" : { "php" : "~7.4", "ext-curl" : "*", From f44f6c4bee2657415eae7124732fc773e23beac9 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Fri, 6 May 2022 16:06:29 +0200 Subject: [PATCH 02/13] Performed code cleanup and documentation update; test deprecated method calls; update library dependencies; bumped version for release --- lib/IdApi.php | 10 ++-------- lib/Signature.php | 18 ++++++++++++++---- lib/SmileIdentityCore.php | 29 ++++++----------------------- tests/IdApiTest.php | 2 +- tests/SignatureTest.php | 19 +------------------ 5 files changed, 24 insertions(+), 54 deletions(-) diff --git a/lib/IdApi.php b/lib/IdApi.php index 1f43886..df6f268 100644 --- a/lib/IdApi.php +++ b/lib/IdApi.php @@ -65,13 +65,7 @@ public function setClient(Client $client): void public function submit_job($partner_params, $id_info, $options): ResponseInterface { $user_async = array_value_by_key("user_async", $options); - $signature = array_value_by_key("signature", $options); - - if ($signature) { - $sec_params = $this->sig_class->generate_signature(); - } else { - $sec_params = $this->sig_class->generate_sec_key(); - } + $sec_params = $this->sig_class->generate_signature(); $data = array( 'language' => 'php', @@ -88,4 +82,4 @@ public function submit_job($partner_params, $id_info, $options): ResponseInterfa 'body' => $json_data ]); } -} +} \ No newline at end of file diff --git a/lib/Signature.php b/lib/Signature.php index 8d1f100..d07b92e 100644 --- a/lib/Signature.php +++ b/lib/Signature.php @@ -13,10 +13,10 @@ class Signature /** * Signature constructor. - * @param $api_key * @param $partner_id + * @param $api_key */ - function __construct($api_key, $partner_id) + function __construct($partner_id, $api_key) { $this->api_key = $api_key; $this->partner_id = $partner_id; @@ -24,8 +24,10 @@ function __construct($api_key, $partner_id) } /** + * Generates a sec_key for the provided timestamp or the current timestamp by default * @param $timestamp * @return array + * @deprecated deprecated since version 3.0.0 */ function generate_sec_key($timestamp = null): array { @@ -39,7 +41,13 @@ function generate_sec_key($timestamp = null): array return array("sec_key" => $sec_key, "timestamp" => $timestamp); } - function confirm_sec_key($sec_key): bool + /** + * Confirms the sec-key against a newly generated sec-key based on the same timestamp + * @param string $sec_key + * @return bool + * @deprecated deprecated since version 3.0.0 + */ + function confirm_sec_key($sec_key): bool { $sec_key_exploded = explode("|", $sec_key); $encrypted = base64_decode($sec_key_exploded[0]); @@ -50,6 +58,7 @@ function confirm_sec_key($sec_key): bool } /** + * Generates a signature for the provided timestamp or the current timestamp by default * @param $timestamp * @return array */ @@ -62,6 +71,7 @@ function generate_signature($timestamp = null): array } /** + * Confirms the signature against a newly generated signature based on the same timestamp * @param $timestamp * @param string $signature * @return bool @@ -83,4 +93,4 @@ private function isTimestamp($timestamp): bool return false; } } -} +} \ No newline at end of file diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index 002a03c..447ef38 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -43,7 +43,7 @@ public function __construct($partner_id, $default_callback, $api_key, $sid_serve $this->partner_id = $partner_id; $this->api_key = $api_key; $this->default_callback = $default_callback; - $this->sig_class = new Signature($api_key, $partner_id); + $this->sig_class = new Signature($partner_id, $api_key); if (strlen($sid_server) == 1) { if (intval($sid_server) < 2) { $this->sid_server = Config::SID_SERVERS[intval($sid_server)]; @@ -67,10 +67,7 @@ public function get_version(): string */ public function generate_sec_key(bool $use_signature): array { - if ($use_signature){ - return $this->sig_class->generate_signature(); - } - return $this->sig_class->generate_sec_key(); + return $this->sig_class->generate_signature(); } /** @@ -86,7 +83,6 @@ public function submit_job($partner_params, $image_details, $id_info, $_options) validatePartnerParams($partner_params); validateIdParams($id_info, $job_type); - if ($job_type == 5) { $id_api = new IdApi($this->partner_id, $this->default_callback, $this->api_key, $this->sid_server); return $id_api->submit_job($partner_params, $id_info, $options); @@ -94,11 +90,7 @@ public function submit_job($partner_params, $image_details, $id_info, $_options) validateImageParams($image_details, $job_type, key_exists('use_enrolled_image', $options) && $options['use_enrolled_image']); validateOptions($options); - if ($options['signature']) { - $sec_params = $this->sig_class->generate_signature(); - } else { - $sec_params = $this->sig_class->generate_sec_key(); - } + $sec_params = $this->sig_class->generate_signature(); $response_body = $this->call_prep_upload($partner_params, $options, $sec_params); $code = array_value_by_key('code', $response_body); @@ -136,11 +128,7 @@ public function submit_job($partner_params, $image_details, $id_info, $_options) */ public function query_job_status($partner_params, $options): array { - if ($options['signature']) { - $sec_params = $this->sig_class->generate_signature(); - } else { - $sec_params = $this->sig_class->generate_sec_key(); - } + $sec_params = $this->sig_class->generate_signature(); $data = array( 'user_id' => $partner_params['user_id'], @@ -156,12 +144,7 @@ public function query_job_status($partner_params, $options): array $client = $this->getClient(); $resp = $client->post('job_status', ['content-type' => 'application/json', 'body' => $json_data]); $result = json_decode($resp->getBody()->getContents(), true); - - if ($options['signature']) { - $valid = $this->sig_class->confirm_signature($result['timestamp'], $result['signature']); - } else { - $valid = $this->sig_class->confirm_sec_key($result['signature']); - } + $valid = $this->sig_class->confirm_signature($result['timestamp'], $result['signature']); if (!$valid) { throw new Exception("Unable to confirm validity of the job_status response"); @@ -213,7 +196,7 @@ public function get_job_status($partner_params, $options) } /*** - * Will query the backend for web session token with a specific timestamp + * Queries the backend for web session token with a specific timestamp * @param timestamp the timestamp to generate the token from * @param user_id * @param job_id diff --git a/tests/IdApiTest.php b/tests/IdApiTest.php index 85f1377..4d435b5 100644 --- a/tests/IdApiTest.php +++ b/tests/IdApiTest.php @@ -48,7 +48,7 @@ protected function setUp(): void 'phone_number' => '0726789065' ); - $signature = new Signature($this->api_key, $this->partner_id); + $signature = new Signature($this->partner_id, $this->api_key); $this->data = array( 'language' => 'php', 'callback_url' => $this->default_callback, diff --git a/tests/SignatureTest.php b/tests/SignatureTest.php index 44bc3aa..1dca18e 100644 --- a/tests/SignatureTest.php +++ b/tests/SignatureTest.php @@ -15,24 +15,7 @@ protected function setUp(): void Clock::freeze('2011-01-02 12:34'); $partner_id = 212; $api_key = file_get_contents(__DIR__ . "/assets/ApiKey.pub"); - $this->sig = new Signature($api_key, $partner_id); - } - - public function testGenerateSecKey(): void - { - $generatedKey = $this->sig->generate_sec_key(); - $timestamp = Clock::now()->getTimestamp(); - $this->assertSame(2, count($generatedKey)); - $this->assertSame($timestamp, $generatedKey['timestamp']); - } - - public function testConfirmSecKey(): void - { - // skipping this because it was not working in phpunit - $this->markTestSkipped('must be revisited.'); - $generatedKey = $this->sig->generate_sec_key(); - $confirmSecKey = $this->sig->confirm_sec_key($generatedKey); - $this->assertTrue($confirmSecKey);; + $this->sig = new Signature($partner_id, $api_key); } public function testGenerateSignature() From 2471affea4852f526ed7fb7b1cd43677f7c9b030 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Fri, 13 May 2022 13:54:37 +0200 Subject: [PATCH 03/13] Updated comments and docs --- lib/IdApi.php | 19 +++++++++++-------- lib/Signature.php | 4 ++-- lib/SmileIdentityCore.php | 27 ++++++++++++++++----------- tests/IdApiTest.php | 2 +- tests/SignatureTest.php | 2 +- tests/SmileIdentityCoreTest.php | 29 ++++++++++------------------- 6 files changed, 41 insertions(+), 42 deletions(-) diff --git a/lib/IdApi.php b/lib/IdApi.php index df6f268..9d5514b 100644 --- a/lib/IdApi.php +++ b/lib/IdApi.php @@ -23,17 +23,19 @@ class IdApi /** * IdApi constructor. - * @param $partner_id - * @param $default_callback - * @param $api_key , - * @param $sid_server + * @param string $partner_id the provided partner ID string + * @param string $default_callback + * @param string $api_key the partner-provided API key + * @param string $sid_server an integer value corresponding to the chosen server + * 0 for test/sandbox + * 1 for production * @throws Exception */ public function __construct($partner_id, $default_callback, $api_key, $sid_server) { $this->partner_id = $partner_id; $this->default_callback = $default_callback; - $this->sig_class = new Signature($api_key, $partner_id); + $this->sig_class = new Signature($partner_id, $api_key); if (strlen($sid_server) == 1) { if (intval($sid_server) < 2) { $this->sid_server = Config::SID_SERVERS[intval($sid_server)]; @@ -54,10 +56,11 @@ public function setClient(Client $client): void } /** - * @param $partner_params - * @param $id_info + * Submits a job with specified partner parameters and ID information + * @param array $partner_params a key-value pair object containing partner's specified parameters + * @param array $id_info a key-value pair object containing user's specified ID information * @param $use_async - * @param $options + * @param array $options a key-value pair object containing additional, optional parameters * @return ResponseInterface * @throws GuzzleException * @throws Exception diff --git a/lib/Signature.php b/lib/Signature.php index d07b92e..fd36228 100644 --- a/lib/Signature.php +++ b/lib/Signature.php @@ -66,8 +66,8 @@ function generate_signature($timestamp = null): array { $timestamp = $timestamp != null ? $timestamp : Clock::now()->format(DateTimeInterface::ISO8601); $message = $timestamp . $this->partner_id . "sid_request"; - $sec_key = base64_encode(hash_hmac('sha256', $message, $this->api_key, true)); - return array("signature" => $sec_key, "timestamp" => $timestamp); + $signature = base64_encode(hash_hmac('sha256', $message, $this->api_key, true)); + return array("signature" => $signature, "timestamp" => $timestamp); } /** diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index 447ef38..f744ebb 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -10,7 +10,7 @@ use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7; -const VERSION = '1.1.0'; +const VERSION = '2.0.0'; const DEFAULT_JOB_STATUS_SLEEP = 2; const default_options = array( 'optional_callback' => '', @@ -62,15 +62,19 @@ public function get_version(): string } /** - * @param bool $use_signature + * Generates signature based current timestamp * @return array */ - public function generate_sec_key(bool $use_signature): array + public function generate_signature(): array { return $this->sig_class->generate_signature(); } /** + * @param array $partner_params a key-value pair object containing partner's specified parameters + * @param array $image_details a key-value pair object containing details for each image to be uploaded along with the job + * @param array $id_info a key-value pair object containing user's specified ID information + * @param array $options a key-value pair object containing additional, optional parameters * @throws GuzzleException * @throws Exception */ @@ -120,8 +124,9 @@ public function submit_job($partner_params, $image_details, $id_info, $_options) } /** - * @param $partner_params - * @param $options + * Gets the status of a specific job + * @param array $partner_params a key-value pair object containing partner's specified parameters + * @param array $options a key-value pair object containing additional, optional parameters * @return array * @throws GuzzleException * @throws Exception @@ -151,10 +156,10 @@ public function query_job_status($partner_params, $options): array } return $result; - } - + } /** + * Queries the list of Smile ID services * @return array * @throws GuzzleException * @throws Exception @@ -185,8 +190,9 @@ public function query_smile_id_services(): array { } /** - * @param $partner_params - * @param $options + * Gets the status of a specific job + * @param array $partner_params a key-value pair object containing partner's specified parameters + * @param array $options a key-value pair object containing additional, optional parameters * @return mixed * @throws GuzzleException */ @@ -213,7 +219,7 @@ public function get_web_token($timestamp, $user_id, $job_id, $product_type): arr 'user_id' => $user_id, 'job_id' => $job_id, 'product' => $product_type, - 'signature' => $this->sig_class->generate_signature($timestamp), + 'signature' => $this->sig_class->generate_signature($timestamp) ); $json_data = json_encode($data, JSON_PRETTY_PRINT); @@ -372,7 +378,6 @@ private function configure_info_json($prep_upload_response_array, $id_info, $ima */ private function generate_zip_file($response_body, $id_info, $images_info, $partner_params, $sec_param, $options): string { - $info_json = $this->configure_info_json($response_body, $id_info, $images_info, $partner_params, $sec_param, $options); $file = tempnam(sys_get_temp_dir(), "selfie"); $zip = new ZipArchive(); diff --git a/tests/IdApiTest.php b/tests/IdApiTest.php index 4d435b5..fc036e4 100644 --- a/tests/IdApiTest.php +++ b/tests/IdApiTest.php @@ -53,7 +53,7 @@ protected function setUp(): void 'language' => 'php', 'callback_url' => $this->default_callback, 'partner_params' => $this->partner_params, - 'sec_key' => $signature->generate_sec_key()["sec_key"], + 'sec_key' => $signature->generate_signature()["signature"], 'timestamp' => Clock::now()->getTimestamp(), 'partner_id' => $this->partner_id ); diff --git a/tests/SignatureTest.php b/tests/SignatureTest.php index 1dca18e..59d3cb8 100644 --- a/tests/SignatureTest.php +++ b/tests/SignatureTest.php @@ -38,4 +38,4 @@ public function testConfirmSignature() $confirm_signature = $this->sig->confirm_signature($timestamp, $signature); $this->assertTrue($confirm_signature); } -} +} \ No newline at end of file diff --git a/tests/SmileIdentityCoreTest.php b/tests/SmileIdentityCoreTest.php index f068914..ef1d539 100644 --- a/tests/SmileIdentityCoreTest.php +++ b/tests/SmileIdentityCoreTest.php @@ -54,7 +54,6 @@ protected function setUp(): void "job_id" => "job-id", "job_type" => 1, ]; - } public function testInitialize(): void @@ -94,7 +93,6 @@ public function testSubmitJobUploadsZipFileWhenReturnJobStatusIsFalse(): void "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; $mock = new MockHandler([ @@ -109,7 +107,6 @@ public function testSubmitJobUploadsZipFileWhenReturnJobStatusIsFalse(): void $this->options["return_job_status"] = false; $result = $this->sic->submit_job($this->partnerParams, $this->imageDetails, $this->idParams, $this->options); $this->assertEquals(["smile_job_id" => "0000058873", "success" => true], $result); - } /** @@ -123,9 +120,8 @@ public function testSubmitJobUploadsZipFileWhenReturnJobStatusIsTrue(): void "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; - $secParam = $this->sic->generate_sec_key($this->options["signature"] ); + $secParam = $this->sic->generate_signature(); $timestamp = $secParam['timestamp']; $signature = $secParam['signature']; $getStatusResult = '{"timestamp": "' . $timestamp . '", "signature": "' . $signature . '", "job_complete": true, "job_success": false, "code": "2302", "result": {}, "history": [], "image_links": {"selfie_image": "https://selfie-image.com"}}'; @@ -145,7 +141,6 @@ public function testSubmitJobUploadsZipFileWhenReturnJobStatusIsTrue(): void $expectedResult = array_merge(json_decode($getStatusResult, true), ["success" => true]); $this->assertEquals($expectedResult, $result); - } public function shouldCallIDApiWhenSubmitJobIsCalledWithJobType5(): void @@ -183,7 +178,6 @@ public function testSubmitJobShouldRequireIdCardImageForJT6(): void "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; $partnerParams = [ "user_id" => "user-id", @@ -196,7 +190,7 @@ public function testSubmitJobShouldRequireIdCardImageForJT6(): void "id_number" => "A00000000", ]; $imageDetails = [["image_type_id" => 0, "image" => "base6image"]]; - $secParam = $this->sic->generate_sec_key($this->options["signature"] ); + $secParam = $this->sic->generate_signature(); $timestamp = $secParam['timestamp']; $signature = $secParam['signature']; $getStatusResult = '{"timestamp": "' . $timestamp . '", "signature": "' . $signature . '", "job_complete": true, "job_success": false, "code": "2302", "result": {}, "history": [], "image_links": {"selfie_image": "https://selfie-image.com"}}'; @@ -227,7 +221,6 @@ public function testSubmitJobShouldRequireCountryInIdInfoForJT6(): void "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; $partnerParams = [ "user_id" => "user-id", @@ -239,7 +232,7 @@ public function testSubmitJobShouldRequireCountryInIdInfoForJT6(): void "id_number" => "A00000000", ]; $imageDetails = [["image_type_id" => 0, "image" => "base6image"]]; - $secParam = $this->sic->generate_sec_key($this->options["signature"] ); + $secParam = $this->sic->generate_signature(); $timestamp = $secParam['timestamp']; $signature = $secParam['signature']; $getStatusResult = '{"timestamp": "' . $timestamp . '", "signature": "' . $signature . '", "job_complete": true, "job_success": false, "code": "2302", "result": {}, "history": [], "image_links": {"selfie_image": "https://selfie-image.com"}}'; @@ -270,7 +263,6 @@ public function testSubmitJobShouldRequireIdTypeInIdInfoForJT6(): void "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; $partnerParams = [ "user_id" => "user-id", @@ -282,7 +274,7 @@ public function testSubmitJobShouldRequireIdTypeInIdInfoForJT6(): void "id_number" => "A00000000", ]; $imageDetails = [["image_type_id" => 0, "image" => "base6image"]]; - $secParam = $this->sic->generate_sec_key($this->options["signature"] ); + $secParam = $this->sic->generate_signature(); $timestamp = $secParam['timestamp']; $signature = $secParam['signature']; $getStatusResult = '{"timestamp": "' . $timestamp . '", "signature": "' . $signature . '", "job_complete": true, "job_success": false, "code": "2302", "result": {}, "history": [], "image_links": {"selfie_image": "https://selfie-image.com"}}'; @@ -313,7 +305,6 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): "smile_job_id" => "0000058873", "camera_config" => null, "code" => 2202 - ]; $partnerParams = [ "user_id" => "user-id", @@ -325,9 +316,9 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): "id_number" => "A00000000", ]; $imageDetails = [["image_type_id" => 1, "image" => "base6image"]]; - $secParam = $this->sic->generate_sec_key($this->options["signature"] ); - $timestamp = $secParam['timestamp']; - $signature = $secParam['signature']; + $sigParam = $this->sic->generate_signature(); + $timestamp = $sigParam['timestamp']; + $signature = $sigParam['signature']; $getStatusResult = '{"timestamp": "' . $timestamp . '", "signature": "' . $signature . '", "job_complete": true, "job_success": false, "code": "2302", "result": {}, "history": [], "image_links": {"selfie_image": "https://selfie-image.com"}}'; $mock = new MockHandler([ @@ -343,11 +334,11 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): $this->sic->submit_job($this->partnerParams, $imageDetails, $this->idParams, $this->options); } - public function testGenerateKey(): void + public function testGenerateSignature(): void { $timestamp = Clock::now()->getTimestamp(); - $sec_key = $this->sic->generate_sec_key(false); - $this->assertEquals($timestamp, $sec_key["timestamp"]); + $signature = $this->sic->generate_signature(); + $this->assertEquals($timestamp, $signature["timestamp"]); } public function testGetWebToken(): void From 9fe1dd2cc112ffb1d4ef242e53cd56543dd5ab05 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Tue, 17 May 2022 13:13:52 +0200 Subject: [PATCH 04/13] Fixing missing client details --- lib/IdApi.php | 5 +++-- lib/SmileIdentityCore.php | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/IdApi.php b/lib/IdApi.php index 9d5514b..02d1b16 100644 --- a/lib/IdApi.php +++ b/lib/IdApi.php @@ -59,7 +59,6 @@ public function setClient(Client $client): void * Submits a job with specified partner parameters and ID information * @param array $partner_params a key-value pair object containing partner's specified parameters * @param array $id_info a key-value pair object containing user's specified ID information - * @param $use_async * @param array $options a key-value pair object containing additional, optional parameters * @return ResponseInterface * @throws GuzzleException @@ -74,7 +73,9 @@ public function submit_job($partner_params, $id_info, $options): ResponseInterfa 'language' => 'php', 'callback_url' => $this->default_callback, 'partner_params' => $partner_params, - 'partner_id' => $this->partner_id + 'partner_id' => $this->partner_id, + 'source_sdk' => 'PHP', + 'source_sdk_version' => '2.0.0' ); $data = array_merge($data, $id_info, $sec_params); $json_data = json_encode($data, JSON_PRETTY_PRINT); diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index f744ebb..7a0845f 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -141,6 +141,8 @@ public function query_job_status($partner_params, $options): array 'partner_id' => $this->partner_id, 'image_links' => $options['return_image_links'], 'history' => $options['return_history'], + 'source_sdk' => 'PHP', + 'source_sdk_version' => '2.0.0' ); $data = array_merge($data, $sec_params); @@ -219,7 +221,9 @@ public function get_web_token($timestamp, $user_id, $job_id, $product_type): arr 'user_id' => $user_id, 'job_id' => $job_id, 'product' => $product_type, - 'signature' => $this->sig_class->generate_signature($timestamp) + 'signature' => $this->sig_class->generate_signature($timestamp), + 'source_sdk' => 'PHP', + 'source_sdk_version' => '2.0.0' ); $json_data = json_encode($data, JSON_PRETTY_PRINT); @@ -285,7 +289,9 @@ private function call_prep_upload($partner_params, $options, $sec_params): array 'model_parameters' => '', 'partner_params' => $partner_params, 'smile_client_id' => $this->partner_id, - 'use_enrolled_image' => $use_enrolled_image + 'use_enrolled_image' => $use_enrolled_image, + 'source_sdk' => 'PHP', + 'source_sdk_version' => '2.0.0' ); $data = array_merge($sec_params, $data); From f72e6e1de50247ca35e0682bff23de2525dfff03 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Tue, 17 May 2022 15:34:55 +0200 Subject: [PATCH 05/13] Updated README file and other documentations --- README.md | 45 +++++++++++++++++++++++++++++++++++++-------- lib/utils.php | 3 --- tests/IdApiTest.php | 2 +- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 33eb7e9..aee513f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,46 @@ -# smile-identity-core-php +# Smile Identity PHP Server Side -The Official Smile Identity PHP library +Smile Identity provides the best solutions for real time Digital KYC, identity verification, user onboarding, and user authentication across Africa. Our server side libraries make it easy to integrate us on the server-side. Since the library is server-side, you will be required to pass the images (if required) to the library. +If you haven’t already, sign up for a free Smile Identity account, which comes with Sandbox access. + +## Dependencies + +* Composer build tool + +## Documentation + +For extensive instructions on usage of the library and sample codes, please refer to the [official Smile Identity documentation](https://docs.smileidentity.com/server-to-server/php) ## Installation -Download smile-identity-core-php repo to a directory on your server where PHP and Composer is installed. +### Installing from the Repository + +Download [smile-identity-core-php repository](https://github.com/smileidentity/smile-identity-core-php) to a directory on your server where PHP and Composer is installed. + +In that directory, run `composer install` + +### Installing from Packagist + +View the package on [Packagist](https://packagist.org/packages/smile-identity/smile-identity-core). + +Alternatively, the package can be searched locally from a composer-based project by typing the command `composer search ` in the command line where `PACKAGE_NAME` can the full name of the package (in this case `smile-identity/smile-identity-core`) or any part of the name distinct enough to return a match. + +In the project's directory, run `composer install smile-identity/smile-identity-core` + +## License + +MIT License + +## Documentation + +For extensive instructions on usage of the library and sample codes, please refer to the official Smile [Identity documentation](https://docs.smileidentity.com/server-to-server/php). -In that directory run `composer install` +## Getting Help -### Usage +For usage questions, the best resource is [our official documentation](docs.smileidentity.com). However, if you require further assistance, you can file a [support ticket via our portal](https://portal.smileidentity.com/partner/support/tickets) or visit the [contact us page](https://portal.smileidentity.com/partner/support/tickets) on our website. -Edit the example_core.php file and replace sections marked with <> +## Contributing -### Run tests +Bug reports and pull requests are welcome on GitHub at https://github.com/smileidentity/smile-identity-core-php -In same directory run `vendor/bin/phpunit tests` +Please format the code with [black](https://github.com/psf/black) prior to submitting pull requests, by running `black .` from the project's root. \ No newline at end of file diff --git a/lib/utils.php b/lib/utils.php index 520a50d..bfba36c 100644 --- a/lib/utils.php +++ b/lib/utils.php @@ -9,7 +9,6 @@ function endsWith($haystack, $needle) return substr($haystack, -$length) === $needle; } - /** * @throws Exception */ @@ -34,7 +33,6 @@ function validatePartnerParams($partner_params) } } - /** * @throws Exception */ @@ -120,4 +118,3 @@ function array_value_by_key($key, $array) } else { return null; } -} diff --git a/tests/IdApiTest.php b/tests/IdApiTest.php index fc036e4..1974bc1 100644 --- a/tests/IdApiTest.php +++ b/tests/IdApiTest.php @@ -99,4 +99,4 @@ public function testSyncSubmitJob() $this->assertEquals(200, $job->getStatusCode()); $this->assertEquals('{"success":true}', $job->getBody()->getContents()); } -} +} \ No newline at end of file From adeb0222072d47560b04a3165cca639735afce46 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Tue, 17 May 2022 15:44:41 +0200 Subject: [PATCH 06/13] Fix mild bug --- lib/utils.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/utils.php b/lib/utils.php index bfba36c..56f914f 100644 --- a/lib/utils.php +++ b/lib/utils.php @@ -118,3 +118,4 @@ function array_value_by_key($key, $array) } else { return null; } +} \ No newline at end of file From 2ffe3d2c4fbdd4eed147d71c1e92f19ff32f904f Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Tue, 17 May 2022 16:38:20 +0200 Subject: [PATCH 07/13] Fix broken tests --- example_core.php | 26 +++++++++++++------------- tests/SignatureTest.php | 2 +- tests/SmileIdentityCoreTest.php | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/example_core.php b/example_core.php index 07d947a..a250e61 100644 --- a/example_core.php +++ b/example_core.php @@ -17,7 +17,7 @@ $default_callback, $api_key, $sid_server -); + ); // Create required tracking parameters // Every communication between your server and the Smile Identity servers contain these parameters. @@ -33,10 +33,10 @@ // 4 for registering a user with just a selfie // 8 for updating an registered photo 'job_type' => <1 | 2 | 4 | 8>, - // You can add as many key value pairs as you line but all MUST be strings. + // You can add as many key value pairs as you line but all MUST be strings. 'optional_info' => 'PHP Test Data', 'signature' => - ); +); // Create options $options = array( @@ -48,7 +48,7 @@ 'return_history' => , // If you want signed links to the images used in processing the job to be returned 'return_image_links' => - ); +); // Create image list // image_type_id Integer @@ -61,16 +61,16 @@ $selfie_image_detail = array( 'image_type_id' => 0, // Selfie image jpg or png 'image' => $selfie_filename - ); +); // ID card image can be omitted if selfie comparison to issuer image is desired $id_card_image_detail = array( 'image_type_id' => 1, // ID card image jpg or png 'image' => $id_card_filename - ); +); $image_details = array( $selfie_image_detail, $id_card_image_detail - ); +); // Create ID number info // Only required fields need to be filled in. The rest should be blank strings @@ -84,7 +84,7 @@ 'id_number' => '', // Always required 'dob' => '', // yyyy-mm-dd 'entered' => '' // MUST BE A STRING - ); +); // submit_job returns an array with at least a Boolean using the key "success" and the Smile Identity job number. // If options.return_job_status is true it will add to the array the returned job_status information. @@ -100,7 +100,7 @@ $default_callback, // Used if $use_async is true otherwise should be "" $api_key, $sid_server -); + ); // If use_async is false $result contains the returned ID information // If true then the ID information will be sent to the callback specified - >> RECOMMENDED << @@ -116,9 +116,9 @@ 'user_id' => ' 5, - // You can add as many key value pairs as you line but all MUST be strings. + // You can add as many key value pairs as you line but all MUST be strings. 'optional_info' => 'PHP Test Data' - ); +); // Create ID number info // Only required fields need to be filled in. The rest should be blank strings @@ -132,7 +132,7 @@ 'id_number' => '', // Always required 'dob' => '', // yyyy-mm-dd 'entered' => '' // MUST BE A STRING - ); +); // @@ -140,4 +140,4 @@ -?> +?> \ No newline at end of file diff --git a/tests/SignatureTest.php b/tests/SignatureTest.php index 59d3cb8..dc45f08 100644 --- a/tests/SignatureTest.php +++ b/tests/SignatureTest.php @@ -21,7 +21,7 @@ protected function setUp(): void public function testGenerateSignature() { $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); - $signature = $this->sig->generate_signature(); + $signature = $this->sig->generate_signature($timestamp); $this->assertSame(2, count($signature)); $this->assertSame($timestamp, $signature['timestamp']); } diff --git a/tests/SmileIdentityCoreTest.php b/tests/SmileIdentityCoreTest.php index ef1d539..9e1b124 100644 --- a/tests/SmileIdentityCoreTest.php +++ b/tests/SmileIdentityCoreTest.php @@ -336,8 +336,8 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): public function testGenerateSignature(): void { - $timestamp = Clock::now()->getTimestamp(); - $signature = $this->sic->generate_signature(); + $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); + $signature = $this->sic->generate_signature($timestamp); $this->assertEquals($timestamp, $signature["timestamp"]); } From 5b6245a843140b7b101ab92b74b87308a68481eb Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Thu, 19 May 2022 14:29:29 +0200 Subject: [PATCH 08/13] Doc fix, config update --- README.md | 4 +--- lib/Config.php | 3 ++- lib/IdApi.php | 4 ++-- lib/SmileIdentityCore.php | 15 +++++++-------- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index aee513f..901ab31 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,4 @@ For usage questions, the best resource is [our official documentation](docs.smil ## Contributing -Bug reports and pull requests are welcome on GitHub at https://github.com/smileidentity/smile-identity-core-php - -Please format the code with [black](https://github.com/psf/black) prior to submitting pull requests, by running `black .` from the project's root. \ No newline at end of file +Bug reports and pull requests are welcome on GitHub at https://github.com/smileidentity/smile-identity-core-php \ No newline at end of file diff --git a/lib/Config.php b/lib/Config.php index 8dd39dc..797e518 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -2,7 +2,8 @@ class Config { - const VERSION = '1.1.0'; + const SDK_CLIENT = 'PHP'; + const VERSION = '4.0.0'; const DEFAULT_JOB_STATUS_TIMEOUT = 20; const DEFAULT_JOB_STATUS_SLEEP = 2; const SID_SERVERS = [ diff --git a/lib/IdApi.php b/lib/IdApi.php index 02d1b16..01d287a 100644 --- a/lib/IdApi.php +++ b/lib/IdApi.php @@ -74,8 +74,8 @@ public function submit_job($partner_params, $id_info, $options): ResponseInterfa 'callback_url' => $this->default_callback, 'partner_params' => $partner_params, 'partner_id' => $this->partner_id, - 'source_sdk' => 'PHP', - 'source_sdk_version' => '2.0.0' + 'source_sdk' => Config::SDK_CLIENT, + 'source_sdk_version' => Config::VERSION ); $data = array_merge($data, $id_info, $sec_params); $json_data = json_encode($data, JSON_PRETTY_PRINT); diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index 7a0845f..55b738b 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -6,11 +6,10 @@ include 'utils.php'; use GuzzleHttp\Client; +use GuzzleHttp\Psr7; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\RequestException; -use GuzzleHttp\Psr7; -const VERSION = '2.0.0'; const DEFAULT_JOB_STATUS_SLEEP = 2; const default_options = array( 'optional_callback' => '', @@ -141,8 +140,8 @@ public function query_job_status($partner_params, $options): array 'partner_id' => $this->partner_id, 'image_links' => $options['return_image_links'], 'history' => $options['return_history'], - 'source_sdk' => 'PHP', - 'source_sdk_version' => '2.0.0' + 'source_sdk' => Config::SDK_CLIENT, + 'source_sdk_version' => Config::VERSION ); $data = array_merge($data, $sec_params); @@ -222,8 +221,8 @@ public function get_web_token($timestamp, $user_id, $job_id, $product_type): arr 'job_id' => $job_id, 'product' => $product_type, 'signature' => $this->sig_class->generate_signature($timestamp), - 'source_sdk' => 'PHP', - 'source_sdk_version' => '2.0.0' + 'source_sdk' => Config::SDK_CLIENT, + 'source_sdk_version' => Config::VERSION ); $json_data = json_encode($data, JSON_PRETTY_PRINT); @@ -290,8 +289,8 @@ private function call_prep_upload($partner_params, $options, $sec_params): array 'partner_params' => $partner_params, 'smile_client_id' => $this->partner_id, 'use_enrolled_image' => $use_enrolled_image, - 'source_sdk' => 'PHP', - 'source_sdk_version' => '2.0.0' + 'source_sdk' => Config::SDK_CLIENT, + 'source_sdk_version' => Config::VERSION ); $data = array_merge($sec_params, $data); From 1d5adeefb1a61879ef13c883eeba26eeca365e52 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Thu, 19 May 2022 14:34:26 +0200 Subject: [PATCH 09/13] Fix version test --- tests/SmileIdentityCoreTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SmileIdentityCoreTest.php b/tests/SmileIdentityCoreTest.php index 9e1b124..384b51b 100644 --- a/tests/SmileIdentityCoreTest.php +++ b/tests/SmileIdentityCoreTest.php @@ -64,7 +64,7 @@ public function testInitialize(): void public function testGetVersion(): void { $version = $this->sic->get_version(); - $this->assertEquals('1.1.0', $version); + $this->assertEquals(Config::VERSION, $version); } /** From 71ea02fe9ca4ddf6349eaaff3adef504034ecbf2 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Mon, 20 Jun 2022 14:13:19 +0200 Subject: [PATCH 10/13] Update tests/SmileIdentityCoreTest.php Replace deprecated time format from the DateTimeInterface Co-authored-by: Titilope Morolari --- tests/SmileIdentityCoreTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SmileIdentityCoreTest.php b/tests/SmileIdentityCoreTest.php index 384b51b..16f83d1 100644 --- a/tests/SmileIdentityCoreTest.php +++ b/tests/SmileIdentityCoreTest.php @@ -336,7 +336,7 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): public function testGenerateSignature(): void { - $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); + $timestamp = Clock::now()->format(DateTimeInterface::ATOM); $signature = $this->sic->generate_signature($timestamp); $this->assertEquals($timestamp, $signature["timestamp"]); } From a0ff07abf6c547e6ce8583ae9591158b534b55e0 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Tue, 21 Jun 2022 12:19:10 +0200 Subject: [PATCH 11/13] Removedeprecated lib --- lib/Config.php | 2 +- lib/Signature.php | 2 +- lib/SmileIdentityCore.php | 2 +- tests/SignatureTest.php | 4 ++-- tests/SmileIdentityCoreTest.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Config.php b/lib/Config.php index 797e518..c8618b0 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -3,7 +3,7 @@ class Config { const SDK_CLIENT = 'PHP'; - const VERSION = '4.0.0'; + const VERSION = '2.0.0'; const DEFAULT_JOB_STATUS_TIMEOUT = 20; const DEFAULT_JOB_STATUS_SLEEP = 2; const SID_SERVERS = [ diff --git a/lib/Signature.php b/lib/Signature.php index fd36228..ed16cf0 100644 --- a/lib/Signature.php +++ b/lib/Signature.php @@ -64,7 +64,7 @@ function confirm_sec_key($sec_key): bool */ function generate_signature($timestamp = null): array { - $timestamp = $timestamp != null ? $timestamp : Clock::now()->format(DateTimeInterface::ISO8601); + $timestamp = $timestamp != null ? $timestamp : Clock::now()->format(DateTimeInterface::ATOM); $message = $timestamp . $this->partner_id . "sid_request"; $signature = base64_encode(hash_hmac('sha256', $message, $this->api_key, true)); return array("signature" => $signature, "timestamp" => $timestamp); diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index 55b738b..66852ee 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -214,7 +214,7 @@ public function get_job_status($partner_params, $options) public function get_web_token($timestamp, $user_id, $job_id, $product_type): array { $data = array( - 'timestamp' => date(DateTimeInterface::ISO8601, $timestamp), + 'timestamp' => date(DateTimeInterface::ATOM, $timestamp), 'callback_url' => $this->default_callback, 'partner_id' => $this->partner_id, 'user_id' => $user_id, diff --git a/tests/SignatureTest.php b/tests/SignatureTest.php index dc45f08..788b038 100644 --- a/tests/SignatureTest.php +++ b/tests/SignatureTest.php @@ -20,7 +20,7 @@ protected function setUp(): void public function testGenerateSignature() { - $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); + $timestamp = Clock::now()->format(DateTimeInterface::ATOM); $signature = $this->sig->generate_signature($timestamp); $this->assertSame(2, count($signature)); $this->assertSame($timestamp, $signature['timestamp']); @@ -33,7 +33,7 @@ public function testConfirmSignature() $confirm_signature = $this->sig->confirm_signature($timestamp, $signature); $this->assertTrue($confirm_signature); - $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); + $timestamp = Clock::now()->format(DateTimeInterface::ATOM); $signature = $this->sig->generate_signature($timestamp)['signature']; $confirm_signature = $this->sig->confirm_signature($timestamp, $signature); $this->assertTrue($confirm_signature); diff --git a/tests/SmileIdentityCoreTest.php b/tests/SmileIdentityCoreTest.php index 384b51b..16f83d1 100644 --- a/tests/SmileIdentityCoreTest.php +++ b/tests/SmileIdentityCoreTest.php @@ -336,7 +336,7 @@ public function testSubmitJobShouldRequiresAtLeastOneSelfieForJTOtherThanJT6(): public function testGenerateSignature(): void { - $timestamp = Clock::now()->format(DateTimeInterface::ISO8601); + $timestamp = Clock::now()->format(DateTimeInterface::ATOM); $signature = $this->sic->generate_signature($timestamp); $this->assertEquals($timestamp, $signature["timestamp"]); } From 5dc325cb20701b845ce6afd042f09603e08daf3d Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Wed, 22 Jun 2022 15:10:15 +0200 Subject: [PATCH 12/13] Update composer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c1ec829..3ec89ca 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "ext-curl" : "*", "ext-json" : "*", "ext-openssl" : "*", - "ext-zip": "*", + "ext-zip" : "*", "guzzlehttp/guzzle" : "^7.0", "letsdrink/ouzo-goodies" : "~1.0" }, From 1a1f1fbc314c83e8f6ef2e90b70c7099cd313760 Mon Sep 17 00:00:00 2001 From: Arlon Mukeba Date: Wed, 22 Jun 2022 15:58:41 +0200 Subject: [PATCH 13/13] Fixing broken test --- lib/SmileIdentityCore.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/SmileIdentityCore.php b/lib/SmileIdentityCore.php index a34674a..6b46952 100644 --- a/lib/SmileIdentityCore.php +++ b/lib/SmileIdentityCore.php @@ -204,27 +204,16 @@ public function get_job_status($partner_params, $options) } /*** -<<<<<<< HEAD * Queries the backend for web session token with a specific timestamp * @param timestamp the timestamp to generate the token from * @param user_id * @param job_id * @param product_type - Literal value of any of the 6 product type options -======= - * Will query the backend for web session token with a specific timestamp - * @param $user_id - user's id - * @param $job_id - job id - * @param $product_type - Literal value of the 6 product type options - * @param $timestamp - the iso 8601 date/time format to generate the token from - * @param $callback_url - the iso 8601 date/time format to generate the token from ->>>>>>> master * @return array * @throws GuzzleException */ public function get_web_token($user_id, $job_id, $product_type, $timestamp = null, $callback_url = null): array { - $generate_signature = $this->sig_class->generate_signature($timestamp); - $data = array( 'timestamp' => date(DateTimeInterface::ATOM, $timestamp), 'callback_url' => $callback_url != null ? $callback_url : $this->default_callback, @@ -296,7 +285,6 @@ private function call_prep_upload($partner_params, $options, $sec_params): array 'model_parameters' => '', 'partner_params' => $partner_params, 'smile_client_id' => $this->partner_id, - 'use_enrolled_image' => $use_enrolled_image, 'source_sdk' => Config::SDK_CLIENT, 'source_sdk_version' => Config::VERSION );