Skip to content

Commit

Permalink
Allow to retrieve user data item by label
Browse files Browse the repository at this point in the history
Add method descriptions and reformat code.
  • Loading branch information
cheelahim committed Sep 27, 2017
1 parent 7d48ade commit 79fa49d
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 88 deletions.
2 changes: 1 addition & 1 deletion spec/ClientSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace spec\Blockvis\Civic\Sip;

use Blockvis\Civic\Sip\Client;
use Blockvis\Civic\Sip\AppConfig;
use Blockvis\Civic\Sip\Client;
use GuzzleHttp\ClientInterface;
use PhpSpec\ObjectBehavior;

Expand Down
29 changes: 16 additions & 13 deletions spec/UserDataSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,27 @@
namespace spec\Blockvis\Civic\Sip;

use Blockvis\Civic\Sip\UserData;
use Blockvis\Civic\Sip\UserDataItem;
use PhpSpec\ObjectBehavior;

class UserDataSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('userId', []);
$items = [
['label' => 'label1', 'value' => 'value1', 'isValid' => true, 'isOwner' => true],
['label' => 'label2', 'value' => 'value2', 'isValid' => true, 'isOwner' => false],
];

$this->beConstructedWith('userId', $items);
}

function it_is_initializable()
{
$this->shouldHaveType(UserData::class);
}

function it_returns_user_id()
{
$this->userId()->shouldBe('userId');
}

function it_returns_data_items()
{
$items = [
['label' => 'label1', 'value' => 'value1', 'isValid' => true, 'isOwner' => true],
['label' => 'label2', 'value' => 'value2', 'isValid' => true, 'isOwner' => false],
];

$this->beConstructedWith('userId', $items);
$items = $this->items();
$items[0]->label()->shouldBe('label1');
$items[0]->value()->shouldBe('value1');
Expand All @@ -42,4 +35,14 @@ function it_returns_data_items()
$items[1]->isOwner()->shouldBe(false);
}

public function it_returns_item_by_label()
{
$this->getByLabel('label1')->value()->shouldBe('value1');
$this->getByLabel('label2')->value()->shouldBe('value2');
}

function it_returns_user_id()
{
$this->userId()->shouldBe('userId');
}
}
35 changes: 26 additions & 9 deletions src/AppConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,36 @@
class AppConfig
{
/**
* Application environment ('prod' by default).
*
* @var string
*/
private $id;
private $env;

/**
* Application ID.
*
* @var string
*/
private $secret;
private $id;

/**
* Application Private Signing Key.
*
* @var string
*/
private $privateKey;

/**
* Application Secret.
*
* @var string
*/
private $env;
private $secret;

/**
* AppConfig constructor.
*
* @param string $id
* @param string $secret
* @param string $privateKey
Expand All @@ -40,22 +49,28 @@ public function __construct(string $id, string $secret, string $privateKey, stri
}

/**
* Returns the application environment.
*
* @return string
*/
public function id(): string
public function env(): string
{
return $this->id;
return $this->env;
}

/**
* Returns the application id.
*
* @return string
*/
public function secret(): string
public function id(): string
{
return $this->secret;
return $this->id;
}

/**
* Returns the application private signing key.
*
* @return string
*/
public function privateKey(): string
Expand All @@ -64,10 +79,12 @@ public function privateKey(): string
}

/**
* Returns the application secret.
*
* @return string
*/
public function env(): string
public function secret(): string
{
return $this->env;
return $this->secret;
}
}
66 changes: 35 additions & 31 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use GuzzleHttp\Psr7\Request;
use Lcobucci\Jose\Parsing\Parser;
use Lcobucci\JWT\Signer\Ecdsa;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Token\Builder as TokenBuilder;
use Lcobucci\JWT\Token\Parser as TokenParser;
use Lcobucci\JWT\Token\Plain;
Expand Down Expand Up @@ -37,14 +37,14 @@ class Client
private $config;

/**
* @var HttpClient
* @var GeneratorPoint
*/
private $httpClient;
private $eccGenerator;

/**
* @var GeneratorPoint
* @var HttpClient
*/
private $eccGenerator;
private $httpClient;

/**
* @var Parser
Expand All @@ -53,6 +53,7 @@ class Client

/**
* Client constructor.
*
* @param AppConfig $config
* @param HttpClient $httpClient
*/
Expand All @@ -77,19 +78,19 @@ public function exchangeToken(string $jwtToken): UserData
$request = new Request(
$requestMethod,
sprintf('%s/%s/%s', $this->baseUri, $this->config->env(), $path), [
'Content-Length' => strlen($requestBody),
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => $this->makeAuthorizationHeader($path, $requestMethod, $requestBody),
],
'Content-Length' => strlen($requestBody),
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => $this->makeAuthorizationHeader($path, $requestMethod, $requestBody),
],
$requestBody
);

$response = $this->httpClient->send($request);
$payload = json_decode($response->getBody());

/** @var Plain $token */
$token = (new TokenParser(new Parser))->parse((string) $payload->data);
$token = (new TokenParser(new Parser))->parse((string)$payload->data);
$this->verify($token);

$userData = $token->claims()->get('data');
Expand All @@ -106,7 +107,7 @@ public function exchangeToken(string $jwtToken): UserData
*/
private function decrypt(string $encrypted): string
{
$iv = substr($encrypted,0, 32);
$iv = substr($encrypted, 0, 32);
$encodedData = substr($encrypted, 32);

return openssl_decrypt(
Expand All @@ -119,11 +120,14 @@ private function decrypt(string $encrypted): string
}

/**
* @param Plain $token
* @return Key
*/
private function verify(Plain $token)
private function getTokenSingingKey(): Key
{
(new Validator)->assert($token, new SignedWith(Ecdsa\Sha256::create(), $this->getTokenVerificationKey()));
$privateKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer(EccFactory::getAdapter()));
$privateKey = $this->eccGenerator->getPrivateKeyFrom(gmp_init($this->config->privateKey(), 16));

return new Key($privateKeySerializer->serialize($privateKey));
}

/**
Expand All @@ -134,23 +138,12 @@ private function getTokenVerificationKey(): Key
$publicKeySerializer = new PemPublicKeySerializer(new DerPublicKeySerializer(EccFactory::getAdapter()));
$publicKey = $this->eccGenerator->getPublicKeyFrom(
gmp_init(substr(self::SIP_PUB_HEX, 2, 64), 16),
gmp_init(substr(self::SIP_PUB_HEX, 66,64), 16)
gmp_init(substr(self::SIP_PUB_HEX, 66, 64), 16)
);

return new Key($publicKeySerializer->serialize($publicKey));
}

/**
* @return Key
*/
private function getTokenSingingKey(): Key
{
$privateKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer(EccFactory::getAdapter()));
$privateKey = $this->eccGenerator->getPrivateKeyFrom(gmp_init($this->config->privateKey(), 16));

return new Key($privateKeySerializer->serialize($privateKey));
}

/**
* @param string $targetPath
* @param string $requestMethod
Expand All @@ -167,10 +160,13 @@ private function makeAuthorizationHeader(string $targetPath, string $requestMeth
->issuedAt(new DateTimeImmutable())
->canOnlyBeUsedAfter((new DateTimeImmutable())->modify('+1 minute'))
->expiresAt((new DateTimeImmutable())->modify('+3 minute'))
->withClaim('data', [
'method' => $requestMethod,
'path' => $targetPath
]);
->withClaim(
'data',
[
'method' => $requestMethod,
'path' => $targetPath,
]
);

// Generate signed token.
$token = $tokenBuilder->getToken(Ecdsa\Sha256::create(), $this->getTokenSingingKey());
Expand All @@ -180,4 +176,12 @@ private function makeAuthorizationHeader(string $targetPath, string $requestMeth

return sprintf('Civic %s.%s', $token, $extension);
}

/**
* @param Plain $token
*/
private function verify(Plain $token)
{
(new Validator)->assert($token, new SignedWith(Ecdsa\Sha256::create(), $this->getTokenVerificationKey()));
}
}
36 changes: 27 additions & 9 deletions src/UserData.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
class UserData
{
/**
* @var string
* @var UserDataItem[]
*/
private $userId;
private $items = [];

/**
* @var UserDataItem[]
* @var string
*/
private $items = [];
private $userId;

/**
* UserData constructor.
*
* @param string $userId
* @param array $data
*/
Expand All @@ -26,30 +27,47 @@ public function __construct(string $userId, array $data = [])
}

/**
* @return string
* Returns user data item by its label.
*
* @param string $label
* @return UserDataItem|null
*/
public function userId(): string
public function getByLabel(string $label): ?UserDataItem
{
return $this->userId;
return $this->items[$label] ?? null;
}

/**
* Returns all the user data items.
*
* @return UserDataItem[]
*/
public function items(): array
{
return $this->items;
return array_values($this->items);
}

/**
* Returns the user id.
*
* @return string
*/
public function userId(): string
{
return $this->userId;
}

/**
* Creates data item object from array.
*
* @param array $data
* @return array
*/
private function createDataItems(array $data): array
{
$items = [];
foreach ($data as $item) {
$items[] = new UserDataItem(
$items[$item['label']] = new UserDataItem(
$item['label'],
$item['value'],
$item['isValid'],
Expand Down
Loading

0 comments on commit 79fa49d

Please sign in to comment.