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

SDK-2265 Retrieve Receipt #323

Merged
merged 14 commits into from
Jun 21, 2024
Merged
113 changes: 113 additions & 0 deletions src/DigitalIdentityClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

declare(strict_types=1);

namespace Yoti;

use Yoti\Exception\DigitalIdentityException;
use Yoti\Exception\PemFileException;
use Yoti\Identity\DigitalIdentityService;
use Yoti\Identity\ShareSessionRequest;
use Yoti\Util\Config;
use Yoti\Util\Env;
use Yoti\Util\PemFile;
use Yoti\Util\Validation;

/**
* Class DigitalIdentityClient
*
* @package Yoti
* @author Yoti SDK <[email protected]>
*/
class DigitalIdentityClient
{
private DigitalIdentityService $digitalIdentityService;

/**
* DigitalIdentityClient constructor.
*
* @param string $sdkId
* The SDK identifier generated by Yoti Hub when you create your app.
* @param string $pem
* PEM file path or string
* @param array<string, mixed> $options (optional)
* SDK configuration options - {@see \Yoti\Util\Config} for available options.
*
* @throws PemFileException
*/
public function __construct(
string $sdkId,
string $pem,
array $options = []
) {
Validation::notEmptyString($sdkId, 'SDK ID');
$pemFile = PemFile::resolveFromString($pem);

// Set API URL from environment variable.
$options[Config::API_URL] = $options[Config::API_URL] ?? Env::get(Constants::ENV_API_URL);
saurabh-yoti marked this conversation as resolved.
Show resolved Hide resolved

$config = new Config($options);

$this->digitalIdentityService = new DigitalIdentityService($sdkId, $pemFile, $config);
}

/**
* Create a sharing session to initiate a sharing process based on a policy
*
* @throws DigitalIdentityException
*
* Aggregate exception signalling issues during the call
*/
public function createShareSession(ShareSessionRequest $request): Identity\ShareSessionCreated
{
return $this->digitalIdentityService->createShareSession($request);
}

/**
* Create a sharing session QR code to initiate a sharing process based on a policy
*
* @throws DigitalIdentityException
*
* Aggregate exception signalling issues during the call
*/
public function createShareQrCode(string $sessionId): Identity\ShareSessionCreatedQrCode
{
return $this->digitalIdentityService->createShareQrCode($sessionId);
}

/**
* Retrieve the sharing session QR code
*
* @throws DigitalIdentityException
*
* Aggregate exception signalling issues during the call
*/
public function fetchShareQrCode(string $qrCodeId): Identity\ShareSessionFetchedQrCode
{
return $this->digitalIdentityService->fetchShareQrCode($qrCodeId);
}

/**
* Retrieve the sharing session
*
* @throws DigitalIdentityException
*
* Aggregate exception signalling issues during the call
*/
public function fetchShareSession(string $sessionId): Identity\ShareSessionFetched
{
return $this->digitalIdentityService->fetchShareSession($sessionId);
}

/**
* Retrieve the decrypted share receipt.
*
* @throws DigitalIdentityException
*
* Aggregate exception signalling issues during the call
*/
public function fetchShareReceipt(string $receiptId): Identity\Receipt
{
return $this->digitalIdentityService->fetchShareReceipt($receiptId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

use Yoti\Exception\base\YotiException;

class IdentityException extends YotiException
class DigitalIdentityException extends YotiException
{
}
28 changes: 28 additions & 0 deletions src/Identity/Content/ApplicationContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Yoti\Identity\Content;

use Yoti\Profile\ApplicationProfile;
use Yoti\Profile\ExtraData;

class ApplicationContent
{
private ?ApplicationProfile $profile;
private ?ExtraData $extraData;

public function __construct(ApplicationProfile $profile = null, ExtraData $extraData = null)
{
$this->profile = $profile;
$this->extraData = $extraData;
}

public function getProfile(): ?ApplicationProfile
{
return $this->profile;
}

public function getExtraData(): ?ExtraData
{
return $this->extraData;
}
}
45 changes: 45 additions & 0 deletions src/Identity/Content/Content.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Yoti\Identity\Content;

use Yoti\Exception\EncryptedDataException;

class Content
{
private ?string $profile;
private ?string $extraData;

public function __construct(string $profile = null, string $extraData = null)
{
$this->profile = $profile;
$this->extraData = $extraData;
}

public function getProfile(): ?string
{
if (null !== $this->profile) {
$decoded = base64_decode($this->profile, true);
if ($decoded === false) {
throw new EncryptedDataException('Could not decode data');
}

return $decoded;
}

return null;
}

public function getExtraData(): ?string
{
if (null !== $this->extraData) {
$decoded = base64_decode($this->extraData, true);
if ($decoded === false) {
throw new EncryptedDataException('Could not decode data');
}

return $decoded;
}

return null;
}
}
28 changes: 28 additions & 0 deletions src/Identity/Content/UserContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Yoti\Identity\Content;

use Yoti\Profile\ExtraData;
use Yoti\Profile\UserProfile;

class UserContent
{
private ?UserProfile $profile;
private ?ExtraData $extraData;

public function __construct(UserProfile $profile = null, ExtraData $extraData = null)
{
$this->profile = $profile;
$this->extraData = $extraData;
}

public function getProfile(): ?UserProfile
{
return $this->profile;
}

public function getExtraData(): ?ExtraData
{
return $this->extraData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
namespace Yoti\Identity;

use Yoti\Constants;
use Yoti\Exception\IdentityException;
use Yoti\Exception\DigitalIdentityException;
use Yoti\Http\Payload;
use Yoti\Http\RequestBuilder;
use Yoti\Util\Config;
use Yoti\Util\Json;
use Yoti\Util\PemFile;

class IdentityService
class DigitalIdentityService
{
private const IDENTITY_SESSION_CREATION = '/v2/sessions';
private const IDENTITY_SESSION_RETRIEVAL = '/v2/sessions/%s';
private const IDENTITY_SESSION_QR_CODE_CREATION = '/v2/sessions/%s/qr-codes';
private const IDENTITY_SESSION_QR_CODE_RETRIEVAL = '/v2/qr-codes/%s';
private const IDENTITY_SESSION_RECEIPT_RETRIEVAL = '/v2/receipts/%s';
private const IDENTITY_SESSION_RECEIPT_KEY_RETRIEVAL = '/v2/wrapped-item-keys/%s';

private string $sdkId;

Expand Down Expand Up @@ -44,7 +46,7 @@ public function createShareSession(ShareSessionRequest $shareSessionRequest): Sh

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new IdentityException("Server responded with {$httpCode}", $response);
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new ShareSessionCreated(Json::decode((string)$response->getBody()));
Expand All @@ -63,7 +65,7 @@ public function createShareQrCode(string $sessionId): ShareSessionCreatedQrCode

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new IdentityException("Server responded with {$httpCode}", $response);
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new ShareSessionCreatedQrCode(Json::decode((string)$response->getBody()));
Expand All @@ -82,7 +84,7 @@ public function fetchShareQrCode(string $qrCodeId): ShareSessionFetchedQrCode

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new IdentityException("Server responded with {$httpCode}", $response);
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new ShareSessionFetchedQrCode(Json::decode((string)$response->getBody()));
Expand All @@ -101,9 +103,67 @@ public function fetchShareSession(string $sessionId): ShareSessionFetched

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new IdentityException("Server responded with {$httpCode}", $response);
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new ShareSessionFetched(Json::decode((string)$response->getBody()));
}

/**
* @throws DigitalIdentityException
*/
public function fetchShareReceipt(string $receiptId): Receipt
{
$receiptParser = new ReceiptParser();
$wrappedReceipt = $this->doFetchShareReceipt($receiptId);

if (null === $wrappedReceipt->getError()) {
$receiptKey = $this->fetchShareReceiptKey($wrappedReceipt);

return $receiptParser->createSuccess($wrappedReceipt, $receiptKey, $this->pemFile);
}

return $receiptParser->createFailure($wrappedReceipt);
}

private function doFetchShareReceipt(string $receiptId): WrappedReceipt
{
$response = (new RequestBuilder($this->config))
saurabh-yoti marked this conversation as resolved.
Show resolved Hide resolved
->withBaseUrl($this->config->getApiUrl() ?? Constants::API_URL)
->withEndpoint(sprintf(self::IDENTITY_SESSION_RECEIPT_RETRIEVAL, $receiptId))
->withHeader('X-Yoti-Auth-Id', $this->sdkId)
->withGet()
->withPemFile($this->pemFile)
->build()
->execute();

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new WrappedReceipt(Json::decode((string)$response->getBody()));
}

private function fetchShareReceiptKey(WrappedReceipt $wrappedReceipt): ReceiptItemKey
{
$response = (new RequestBuilder($this->config))
->withBaseUrl($this->config->getApiUrl() ?? Constants::API_URL)
->withEndpoint(sprintf(
self::IDENTITY_SESSION_RECEIPT_KEY_RETRIEVAL,
$wrappedReceipt->getWrappedItemKeyId()
))
->withHeader('X-Yoti-Auth-Id', $this->sdkId)
->withGet()
->withPemFile($this->pemFile)
->build()
->execute();

$httpCode = $response->getStatusCode();
if ($httpCode < 200 || $httpCode > 299) {
throw new DigitalIdentityException("Server responded with {$httpCode}", $response);
}

return new ReceiptItemKey(Json::decode((string)$response->getBody()));
}
}
7 changes: 7 additions & 0 deletions src/Identity/Reader/AttributeListReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Yoti\Identity\Reader;

class AttributeListReader
{
}
7 changes: 7 additions & 0 deletions src/Identity/Reader/ExtraDataReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Yoti\Identity\Reader;

class ExtraDataReader
{
}
Loading