Skip to content

Commit

Permalink
Extend the Client to support dynamic registration
Browse files Browse the repository at this point in the history
Instantiating the client still requires a full set of authentication credentials (this is likely easy to change in the future).

Ensure that new clients can be dynamically created via registration tokens.

Update integration tests to only run the client setup _once_ instead of on every test.

Fixes E3DB-659
  • Loading branch information
Eric Mann committed Aug 22, 2017
1 parent 3359488 commit 2539dd6
Show file tree
Hide file tree
Showing 6 changed files with 367 additions and 57 deletions.
9 changes: 2 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
API_KEY_ID=""
API_SECRET=""
API_URL="https://api.e3db.com"
CLIENT_ID=""
PUBLIC_KEY=""
PRIVATE_KEY=""
API_KEY_ID_2=""
API_SECRET_2=""
API_URL_2="https://api.e3db.com"
CLIENT_ID_2=""
PUBLIC_KEY_2=""
PRIVATE_KEY_2=""
REGISTRATION_TOKEN=""
API_URL="https://api.e3db.com"
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ Then run `php composer.phar install`

## Registering a client

1. Download and install the E3DB Command-Line interface (CLI) from our [GitHub releases page](https://github.com/tozny/e3db-go/releases).

2. Register an account and create a client with [InnoVault](https://innovault.io).
Register an account with [InnoVault](https://inoovault.io) to get started. From the Admin Console you can create clients directly (and grab their credentials from the console).

## Loading configuration and creating a client

Expand Down Expand Up @@ -105,9 +103,9 @@ See [the simple example code](https://github.com/tozny/e3db-php/blob/master/exam

# Development

Before running tests, create _two_ integration test clients through your [InnoVault](https://innovault.io) account.
Before running tests, create both a client and a registration token through your [InnoVault](https://innovault.io) account.

Store the credentials returned for both clients in a `.env` file at the project root (see `.env.example` for the example file layout).
Store the generated credentials and registration token in a `.env` file at the project root (see `.env.example` for the example file layout).

After checking out the repo, install dependencies using `composer install` then run PHPUnit with `./vendor/bin/phpunit` to execute all of the integration tests.

Expand Down
24 changes: 24 additions & 0 deletions php/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use Tozny\E3DB\Exceptions\ConflictException;
use Tozny\E3DB\Exceptions\NotFoundException;
use Tozny\E3DB\Types\Accessor;
use Tozny\E3DB\Types\ClientDetails;
use Tozny\E3DB\Types\ClientInfo;
use Tozny\E3DB\Types\Meta;
use Tozny\E3DB\Types\PublicKey;
Expand Down Expand Up @@ -340,6 +341,29 @@ public function revoke(string $type, string $reader_id)
$this->conn->put($path, $deny);
}

/**
* Register a new client with a specific account.
*
* @param string $registration_token Registration token as presented by the admin console
* @param string $client_name Distinguishable name to be used for the token in the console
* @param PublicKey $public_key Curve25519 public key component used for encryption
*
* @return ClientDetails
*/
public function register_client(string $registration_token, string $client_name, PublicKey $public_key): ClientDetails
{
$path = $this->conn->uri('v1', 'account', 'e3db', 'clients', 'register');
$payload = ['token' => $registration_token, 'client' => ['name' => $client_name, 'public_key' => $public_key]];

try {
$resp = $this->conn->post($path, (object) $payload);
} catch (RequestException $re) {
throw new \RuntimeException('Error while registering a new client!');
}

return ClientDetails::decode((string) $resp->getBody());
}

/**
* Fetch the access key for a record type and use it to decrypt a given record.
*
Expand Down
152 changes: 152 additions & 0 deletions php/Types/ClientDetails.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php
/**
* Tozny E3DB
*
* LICENSE
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @package Tozny\E3DB
* @copyright Copyright (c) 2017 Tozny, LLC (https://tozny.com)
* @license MIT License
*/

declare(strict_types=1);

namespace Tozny\E3DB\Types;

/**
* Full nformation about a specific E3DB client, including the client's
* public/private keys for cryptographic operations and API credentials.
*
* @property-read string $client_id UUID representing the client.
* @property-read string $api_key_id API key to be used when authenticating with e3db
* @property-read string $api_secret API password to be used when authenticating with e3db
* @property-read PublicKey $public_key Curve 25519 public key for the client.
* @property-read string $name Description of the client
*
* @package Tozny\E3DB\Types
*/
class ClientDetails extends JsonUnserializable
{
use Accessor;

/**
* @var string UUID representing the client.
*/
protected $_client_id;

/**
* @var string API key to be used when authenticating with e3db
*/
protected $_api_key_id;

/**
* @var string API password to be used when authenticating with e3db
*/
protected $_api_secret;

/**
* @var PublicKey Curve 25519 public key for the client.
*/
protected $_public_key;

/**
* @var string Description of the client
*/
protected $_name;

/**
* @var array Fields that cannot be overwritten externally.
*/
protected $immutableFields = ['client_id', 'api_key_id', 'api_secret', 'public_key', 'name'];

/**
* Constructor is private as this object cannot and should not be instantiated outside of
* deserialization.
*
* @param string $client_id
* @param string $api_key_id
* @param string $api_secret
* @param PublicKey $public_key
* @param string $name
*/
private function __construct(string $client_id, string $api_key_id, string $api_secret, PublicKey $public_key, string $name)
{
$this->_client_id = $client_id;
$this->_api_key_id = $api_key_id;
$this->_api_secret = $api_secret;
$this->_public_key = $public_key;
$this->_name = $name;
}

/**
* Serialize the object to JSON
*/
public function jsonSerialize(): array
{
return [
'client_id' => $this->_client_id,
'api_key_id' => $this->_api_key_id,
'api_secret' => $this->_api_secret,
'public_key' => $this->_public_key,
'name' => $this->_name,
];
}

/**
* Specify how an already unserialized JSON array should be marshaled into
* an object representation.
*
* Client information contains the ID of the client, API credentials for interacting
* with the e3db server, a Curve25519 public key component, and a description of the
* client as specified during creation.
*
* <code>
* $info = ClientDetails::decodeArray([
* 'client_id' => '',
* 'api_key_id' => '',
* 'api_secret' => '',
* 'public_key' => [
* 'curve25519' => ''
* ],
* 'name' => ''
* ]);
* <code>
*
* @see \Tozny\E3DB\Types\PublicKey::decodeArray()
*
* @param array $parsed
*
* @return ClientDetails
*/
public static function decodeArray(array $parsed): ClientDetails
{
$details = new ClientDetails(
$parsed['client_id'],
$parsed['api_key_id'],
$parsed['api_secret'],
PublicKey::decodeArray($parsed['public_key']),
$parsed['name']
);

return $details;
}
}

0 comments on commit 2539dd6

Please sign in to comment.