Added bindings for Signable, SigningConfig, Signing (#23)

* Added bindings for Signable, SigningConfig, Signing

* Fixed PHP5.6 argument vector madness

* Added SigningConfigAWS implementation and lifetime tests

* Updated .gitignore

* Added impl for Signing::signRequestAws(), laid out sigv4 test
This commit is contained in:
Justin Boswell
2021-05-18 14:06:26 -07:00
committed by GitHub
parent beda2f5376
commit a99fdeb9d3
17 changed files with 930 additions and 134 deletions
+9 -11
View File
@@ -20,12 +20,12 @@ use AWS\CRT\Options as Options;
final class AwsCredentials extends NativeResource {
static function defaults() {
return array(
return [
'access_key_id' => '',
'secret_access_key' => '',
'session_token' => '',
'expiration_timepoint_seconds' => 0,
);
];
}
private $access_key_id;
@@ -37,16 +37,14 @@ final class AwsCredentials extends NativeResource {
return $this->$name;
}
function __construct($options = []) {
function __construct(array $options = []) {
parent::__construct();
if (count($options) == 0) {
$options = self::defaults();
}
$options = new Options($options);
$this->access_key_id = $options->getString('access_key_id');
$this->secret_access_key = $options->getString('secret_access_key');
$this->session_token = $options->getString('session_token');
$this->expiration_timepoint_seconds = $options->getInt('expiration_timepoint_seconds');
$options = new Options($options, self::defaults());
$this->access_key_id = $options->access_key_id->asString();
$this->secret_access_key = $options->secret_access_key->asString();
$this->session_token = $options->session_token ? $options->session_token->asString() : null;
$this->expiration_timepoint_seconds = $options->expiration_timepoint_seconds->asInt();
if (strlen($this->access_key_id) == 0) {
throw new \InvalidArgumentException("access_key_id must be provided");
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
use AWS\CRT\IO\InputStream;
use AWS\CRT\NativeResource as NativeResource;
class Signable extends NativeResource {
public static function fromHttpRequest($http_message) {
return new Signable(function() use ($http_message) {
return self::$crt->signable_new_from_http_request($http_message->native);
});
}
public static function fromChunk($chunk_stream, $previous_signature="") {
if (!($chunk_stream instanceof InputStream)) {
$chunk_stream = new InputStream($chunk_stream);
}
return new Signable(function() use($chunk_stream, $previous_signature) {
return self::$crt->signable_new_from_chunk($chunk_stream->native, $previous_signature);
});
}
public static function fromCanonicalRequest($canonical_request) {
return new Signable(function() use($canonical_request) {
return self::$crt->signable_new_from_canonical_request($canonical_request);
});
}
protected function __construct($ctor) {
parent::__construct();
$this->acquire($ctor());
}
function __destruct() {
self::$crt->signable_release($this->release());
parent::__destruct();
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
class SignatureType {
const HTTP_REQUEST_HEADERS = 0;
const HTTP_REQUEST_QUERY_PARAMS = 1;
const HTTP_REQUEST_CHUNK = 2;
const HTTP_REQUEST_EVENT = 3;
const CANONICAL_REQUEST_HEADERS = 4;
const CANONICAL_REQUEST_QUERY_PARAMS = 5;
}
+11
View File
@@ -0,0 +1,11 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
class SignedBodyHeaderType {
const NONE = 0;
const X_AMZ_CONTENT_SHA256 = 1;
}
+14
View File
@@ -0,0 +1,14 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
use AWS\CRT\NativeResource;
abstract class Signing extends NativeResource {
static function signRequestAws($signable, $signing_config, $on_complete) {
return self::$crt->sign_request_aws($signable, $signing_config, $on_complete);
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
class SigningAlgorithm {
const SIGv4 = 0;
}
+57
View File
@@ -0,0 +1,57 @@
<?php
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
namespace AWS\CRT\Auth;
use AWS\CRT\NativeResource as NativeResource;
use AWS\CRT\Options as Options;
class SigningConfigAWS extends NativeResource {
public static function defaults() {
return [
'algorithm' => SigningAlgorithm::SIGv4,
'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
'credentials_provider' => null,
'region' => null,
'service' => null,
'use_double_uri_encode' => false,
'should_normalize_uri_path' => false,
'omit_session_token' => false,
'signed_body_value' => null,
'signed_body_header_type' => SignedBodyHeaderType::NONE,
'expiration_in_seconds' => 0,
];
}
private $options;
public function __construct(array $options = []) {
parent::__construct();
$this->options = $options = new Options($options, self::defaults());
$sc = $this->acquire(self::$crt->signing_config_aws_new());
self::$crt->signing_config_aws_set_algorithm($sc, $options->algorithm->asInt());
self::$crt->signing_config_aws_set_signature_type($sc, $options->signature_type->asInt());
self::$crt->signing_config_aws_set_credentials_provider($sc, $options->credentials_provider->asObject());
self::$crt->signing_config_aws_set_region($sc, $options->region->asString());
self::$crt->signing_config_aws_set_service($sc, $options->service->asString());
self::$crt->signing_config_aws_set_use_double_uri_encode($sc, $options->use_double_uri_encode->asBool());
self::$crt->signing_config_aws_set_should_normalize_uri_path($sc, $options->should_normalize_uri_path->asBool());
self::$crt->signing_config_aws_set_omit_session_token($sc, $options->omit_session_token->asBool());
self::$crt->signing_config_aws_set_signed_body_value($sc, $options->signed_body_value->asString());
self::$crt->signing_config_aws_set_signed_body_header_type($sc, $options->signed_body_header_type->asInt());
self::$crt->signing_config_aws_set_expiration_in_seconds($sc, $options->expiration_in_seconds->asInt());
}
function __destruct()
{
self::$crt->signing_config_aws_release($this->release());
parent::__destruct();
}
public function __get($name) {
return $this->options->get($name);
}
}
+1 -12
View File
@@ -15,15 +15,7 @@ namespace AWS\CRT\Auth;
*/
final class StaticCredentialsProvider extends CredentialsProvider {
static function defaults() {
return array(
'access_key_id' => '',
'secret_access_key' => '',
'session_token' => '',
);
}
private $credentials = null;
private $credentials;
public function __get($name) {
return $this->$name;
@@ -31,9 +23,6 @@ final class StaticCredentialsProvider extends CredentialsProvider {
function __construct(array $options = []) {
parent::__construct();
if (count($options) == 0) {
$options = self::defaults();
}
$this->credentials = new AwsCredentials($options);
$provider_options = self::$crt->credentials_provider_static_options_new();
+72
View File
@@ -214,4 +214,76 @@ final class CRT {
function http_message_release($message) {
self::$impl->aws_crt_http_message_release($message);
}
function signing_config_aws_new() {
return self::$impl->aws_crt_signing_config_aws_new();
}
function signing_config_aws_release($signing_config) {
return self::$impl->aws_crt_signing_config_aws_release($signing_config);
}
function signing_config_aws_set_algorithm($signing_config, $algorithm) {
self::$impl->aws_crt_signing_config_aws_set_algorithm($signing_config, (int)$algorithm);
}
function signing_config_aws_set_signature_type($signing_config, $signature_type) {
self::$impl->aws_crt_signing_config_aws_set_signature_type($signing_config, (int)$signature_type);
}
function signing_config_aws_set_credentials_provider($signing_config, $credentials_provider) {
self::$impl->aws_crt_signing_config_aws_set_credentials_provider($signing_config, $credentials_provider);
}
function signing_config_aws_set_region($signing_config, $region) {
self::$impl->aws_crt_signing_config_aws_set_region($signing_config, $region);
}
function signing_config_aws_set_service($signing_config, $service) {
self::$impl->aws_crt_signing_config_aws_set_service($signing_config, $service);
}
function signing_config_aws_set_use_double_uri_encode($signing_config, $use_double_uri_encode) {
self::$impl->aws_crt_signing_config_aws_set_use_double_uri_encode($signing_config, $use_double_uri_encode);
}
function signing_config_aws_set_should_normalize_uri_path($signing_config, $should_normalize_uri_path) {
self::$impl->aws_crt_signing_config_aws_set_should_normalize_uri_path($signing_config, $should_normalize_uri_path);
}
function signing_config_aws_set_omit_session_token($signing_config, $omit_session_token) {
self::$impl->aws_crt_signing_config_aws_set_omit_session_token($signing_config, $omit_session_token);
}
function signing_config_aws_set_signed_body_value($signing_config, $signed_body_value) {
self::$impl->aws_crt_signing_config_aws_set_signed_body_value($signing_config, $signed_body_value);
}
function signing_config_aws_set_signed_body_header_type($signing_config, $signed_body_header_type) {
self::$impl->aws_crt_signing_config_aws_set_signed_body_header_type($signing_config, $signed_body_header_type);
}
function signing_config_aws_set_expiration_in_seconds($signing_config, $expiration_in_seconds) {
self::$impl->aws_crt_signing_config_aws_set_expiration_in_seconds($signing_config, $expiration_in_seconds);
}
function signable_new_from_http_request($http_message) {
return self::$impl->aws_crt_signable_new_from_http_request($http_message);
}
function signable_new_from_chunk($chunk_stream, $previous_signature) {
return self::$impl->aws_crt_signable_new_from_chunk($chunk_stream, $previous_signature);
}
function signable_new_from_canonical_request($canonical_request) {
return self::$impl->aws_crt_signable_new_from_canonical_request($canonical_request);
}
function signable_release($signable) {
self::$impl->aws_crt_signable_release($signable);
}
function sign_request_aws($signable, $signing_config, $on_complete) {
return self::$impl->aws_crt_sign_request_aws($signable, $signing_config, $on_complete);
}
}
+3 -6
View File
@@ -18,17 +18,14 @@ use AWS\CRT\Options as Options;
final class EventLoopGroup extends NativeResource {
static function defaults() {
return array(
return [
'max_threads' => 0,
);
];
}
function __construct(array $options = []) {
parent::__construct();
if (count($options) == 0) {
$options = self::defaults();
}
$options = new Options($options);
$options = new Options($options, self::defaults());
$elg_options = self::$crt->event_loop_group_options_new();
self::$crt->event_loop_group_options_set_max_threads($elg_options, $options->getInt('max_threads'));
$this->acquire(self::$crt->event_loop_group_new($elg_options));
+2 -2
View File
@@ -16,7 +16,7 @@ abstract class NativeResource {
protected static $resources = [];
protected $native = null;
function __construct() {
protected function __construct() {
if (is_null(self::$crt)) {
self::$crt = new CRT();
}
@@ -25,7 +25,7 @@ abstract class NativeResource {
}
protected function acquire($handle) {
$this->native = $handle;
return $this->native = $handle;
}
protected function release() {
+46 -8
View File
@@ -5,15 +5,46 @@
*/
namespace AWS\CRT;
final class Options {
private $options = [];
final class OptionValue {
private $value;
function __construct($value) {
$this->value = $value;
}
public function __construct($opts = []) {
$this->options = $opts;
public function asObject() {
return $this->value;
}
public function asMixed() {
return $this->value;
}
public function asInt() {
return empty($this->value) ? 0 : (int)$this->value;
}
public function asBool() {
return boolval($this->value);
}
public function asString() {
return !empty($this->value) ? strval($this->value) : "";
}
public function asArray() {
return is_array($this->value) ? $this->value : (!empty($this->value) ? [$this->value] : []);
}
}
final class Options {
private $options;
public function __construct($opts = [], $defaults = []) {
$this->options = array_replace($defaults, empty($opts) ? [] : $opts);
}
public function __get($name) {
return (isset($this->options[$name])) ? $this->options[$name] : null;
return $this->get($name);
}
public function asArray() {
@@ -24,12 +55,19 @@ final class Options {
return array_merge_recursive([], $this->options);
}
public function get($name) {
return new OptionValue($this->options[$name]);
}
public function getInt($name) {
$val = $this->$name;
return (is_null($val)) ? 0 : (int)$val;
return $this->get($name)->asInt();
}
public function getString($name) {
return !empty($this->options[$name]) ? strval($this->options[$name]) : "";
return $this->get($name)->asString();
}
public function getBool($name) {
return $this->get($name)->asBool();
}
}