[RFR]: Added Origin CA Certificate endpoint (#123)
* Added Certificate endpoint * Implement all calls in /certificates endpoint * Added to travis more php versions * Fix package compatibility * Added CertificateTest * Added test for Certificate endpoint * Added more tests * Updated README Co-authored-by: haphan <thanhha.phan@myrepublic.net>
This commit is contained in:
@@ -3,6 +3,15 @@ language: php
|
|||||||
php:
|
php:
|
||||||
- 7.0
|
- 7.0
|
||||||
- 7.1
|
- 7.1
|
||||||
|
- 7.2
|
||||||
|
- 7.3
|
||||||
|
- 7.4
|
||||||
|
- nightly
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
allow_failures:
|
||||||
|
- php: 7.4
|
||||||
|
- php: nightly
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- composer self-update
|
- composer self-update
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Each API call is provided via a similarly named function within various classes
|
|||||||
- [ ] Organization Administration
|
- [ ] Organization Administration
|
||||||
- [x] [Railgun](https://www.cloudflare.com/railgun/) administration
|
- [x] [Railgun](https://www.cloudflare.com/railgun/) administration
|
||||||
- [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/)
|
- [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/)
|
||||||
- [ ] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/)
|
- [x] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/)
|
||||||
- [x] Crypto
|
- [x] Crypto
|
||||||
- [x] Load Balancers
|
- [x] Load Balancers
|
||||||
- [x] Firewall Settings
|
- [x] Firewall Settings
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "5.7.5",
|
"phpunit/phpunit": "^5.7",
|
||||||
"phpmd/phpmd" : "@stable",
|
"phpmd/phpmd" : "@stable",
|
||||||
"friendsofphp/php-cs-fixer": "^2.6"
|
"friendsofphp/php-cs-fixer": "^2.6"
|
||||||
},
|
},
|
||||||
|
|||||||
534
composer.lock
generated
534
composer.lock
generated
File diff suppressed because it is too large
Load Diff
58
src/Configurations/Certificate.php
Normal file
58
src/Configurations/Certificate.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Cloudflare\API\Configurations;
|
||||||
|
|
||||||
|
class Certificate implements Configurations
|
||||||
|
{
|
||||||
|
const ORIGIN_RSA = 'origin-rsa';
|
||||||
|
const ORIGIN_ECC = 'origin-ecc';
|
||||||
|
const KEYLESS_CERTIFICATE = 'keyless-certificate';
|
||||||
|
|
||||||
|
private $config = [];
|
||||||
|
|
||||||
|
public function getArray(): array
|
||||||
|
{
|
||||||
|
return $this->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of hostnames or wildcard names (e.g., *.example.com) bound to the certificate
|
||||||
|
* Example: $hostnames = ["example.com", "foo.example.com"]
|
||||||
|
* @param array $hostnames
|
||||||
|
*/
|
||||||
|
public function setHostnames(array $hostnames)
|
||||||
|
{
|
||||||
|
$this->config['hostnames'] = $hostnames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of days for which the certificate should be valid
|
||||||
|
* Default value: 5475
|
||||||
|
* Valid values: 7, 30, 90, 365, 730, 1095, 5475
|
||||||
|
* @param int $validity
|
||||||
|
*/
|
||||||
|
public function setRequestedValidity(int $validity)
|
||||||
|
{
|
||||||
|
$this->config['requested_validity'] = $validity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature type desired on certificate ("origin-rsa" (rsa), "origin-ecc" (ecdsa), or "keyless-certificate" (for Keyless SSL servers)
|
||||||
|
* Valid values: origin-rsa, origin-ecc, keyless-certificate
|
||||||
|
* @param string $type
|
||||||
|
*/
|
||||||
|
public function setRequestType(string $type)
|
||||||
|
{
|
||||||
|
$this->config['request_type'] = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Certificate Signing Request (CSR). Must be newline-encoded.
|
||||||
|
*
|
||||||
|
* @param string $csr
|
||||||
|
*/
|
||||||
|
public function setCsr(string $csr)
|
||||||
|
{
|
||||||
|
$this->config['csr'] = $csr;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/Endpoints/Certificates.php
Normal file
86
src/Endpoints/Certificates.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Cloudflare\API\Endpoints;
|
||||||
|
|
||||||
|
use Cloudflare\API\Adapter\Adapter;
|
||||||
|
use Cloudflare\API\Configurations\Certificate as CertificateConfig;
|
||||||
|
use Cloudflare\API\Traits\BodyAccessorTrait;
|
||||||
|
|
||||||
|
class Certificates implements API
|
||||||
|
{
|
||||||
|
use BodyAccessorTrait;
|
||||||
|
|
||||||
|
private $adapter;
|
||||||
|
|
||||||
|
public function __construct(Adapter $adapter)
|
||||||
|
{
|
||||||
|
$this->adapter = $adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all existing Origin CA certificates for a given zone
|
||||||
|
*
|
||||||
|
* @param string $zoneID
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listCertificates(string $zoneID): \stdClass
|
||||||
|
{
|
||||||
|
$certificates = $this->adapter->get('certificates', ['zone_id' => $zoneID]);
|
||||||
|
$this->body = json_decode($certificates->getBody());
|
||||||
|
|
||||||
|
return (object)['result' => $this->body->result];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing Origin CA certificate by its serial number
|
||||||
|
*
|
||||||
|
* @param string $certificateID
|
||||||
|
* @param string $zoneID
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getCertificate(string $certificateID, string $zoneID)
|
||||||
|
{
|
||||||
|
$certificates = $this->adapter->get('certificates/'.$certificateID, ['zone_id' => $zoneID]);
|
||||||
|
$this->body = json_decode($certificates->getBody());
|
||||||
|
|
||||||
|
return (object)['result' => $this->body->result];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke an existing Origin CA certificate by its serial number
|
||||||
|
*
|
||||||
|
* @param string $certificateID
|
||||||
|
* @param string $zoneID
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function revokeCertificate(string $certificateID, string $zoneID): bool
|
||||||
|
{
|
||||||
|
$certificates = $this->adapter->delete('certificates/'.$certificateID, ['zone_id' => $zoneID]);
|
||||||
|
$this->body = json_decode($certificates->getBody());
|
||||||
|
|
||||||
|
if (isset($this->body->result->id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an Origin CA certificate
|
||||||
|
*
|
||||||
|
* @param CertificateConfig $config
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function createCertificate(CertificateConfig $config): bool
|
||||||
|
{
|
||||||
|
$certificate = $this->adapter->post('certificates', $config->getArray());
|
||||||
|
|
||||||
|
$this->body = json_decode($certificate->getBody());
|
||||||
|
|
||||||
|
if (isset($this->body->result->id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
tests/Configurations/CertificateTest.php
Normal file
22
tests/Configurations/CertificateTest.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Cloudflare\API\Configurations\Certificate;
|
||||||
|
|
||||||
|
class CertificateTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testGetArray()
|
||||||
|
{
|
||||||
|
$certificate = new Certificate();
|
||||||
|
$certificate->setHostnames(['foo.com', '*.bar.com']);
|
||||||
|
$certificate->setRequestType(Certificate::ORIGIN_ECC);
|
||||||
|
$certificate->setRequestedValidity(365);
|
||||||
|
$certificate->setCsr('some-csr-encoded-text');
|
||||||
|
|
||||||
|
$array = $certificate->getArray();
|
||||||
|
$this->assertEquals(['foo.com', '*.bar.com'], $array['hostnames']);
|
||||||
|
$this->assertEquals('origin-ecc', $array['request_type']);
|
||||||
|
$this->assertEquals(365, $array['requested_validity']);
|
||||||
|
$this->assertEquals('some-csr-encoded-text', $array['csr']);
|
||||||
|
}
|
||||||
|
}
|
||||||
120
tests/Endpoints/CertificatesTest.php
Normal file
120
tests/Endpoints/CertificatesTest.php
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Cloudflare\API\Endpoints\Certificates;
|
||||||
|
|
||||||
|
class CertificatesTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testListCertificates()
|
||||||
|
{
|
||||||
|
$response = $this->getPsr7JsonResponseForFixture('Endpoints/listCertificates.json');
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock();
|
||||||
|
$mock->method('get')->willReturn($response);
|
||||||
|
|
||||||
|
$mock->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with(
|
||||||
|
$this->equalTo('certificates'),
|
||||||
|
$this->equalTo(
|
||||||
|
[
|
||||||
|
'zone_id' => '023e105f4ecef8ad9ca31a8372d0c353',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$certEndpoint = new Certificates($mock);
|
||||||
|
$result = $certEndpoint->listCertificates('023e105f4ecef8ad9ca31a8372d0c353');
|
||||||
|
|
||||||
|
$this->assertObjectHasAttribute('result', $result);
|
||||||
|
|
||||||
|
$cert = $result->result[0];
|
||||||
|
$this->assertEquals('328578533902268680212849205732770752308931942346', $cert->id);
|
||||||
|
$this->assertEquals('origin-rsa', $cert->request_type);
|
||||||
|
$this->assertEquals(5475, $cert->requested_validity);
|
||||||
|
$this->assertEquals(['example.com', '*.example.com'], $cert->hostnames);
|
||||||
|
$this->assertEquals('some-cert-data', $cert->certificate);
|
||||||
|
$this->assertEquals('some-csr-data', $cert->csr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetCertificate()
|
||||||
|
{
|
||||||
|
$response = $this->getPsr7JsonResponseForFixture('Endpoints/getCertificate.json');
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock();
|
||||||
|
$mock->method('get')->willReturn($response);
|
||||||
|
|
||||||
|
$mock->expects($this->once())
|
||||||
|
->method('get')
|
||||||
|
->with(
|
||||||
|
$this->equalTo('certificates/6666699999996666699999999966666666'),
|
||||||
|
$this->equalTo(['zone_id' => '023e105f4ecef8ad9ca31a8372d0c353']),
|
||||||
|
$this->equalTo([])
|
||||||
|
);
|
||||||
|
|
||||||
|
$certEndpoint = new Certificates($mock);
|
||||||
|
$response = $certEndpoint->getCertificate(
|
||||||
|
'6666699999996666699999999966666666',
|
||||||
|
'023e105f4ecef8ad9ca31a8372d0c353'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertObjectHasAttribute('result', $response);
|
||||||
|
$cert = $response->result;
|
||||||
|
$this->assertEquals('6666699999996666699999999966666666', $cert->id);
|
||||||
|
$this->assertEquals('origin-ecc', $cert->request_type);
|
||||||
|
$this->assertEquals(5475, $cert->requested_validity);
|
||||||
|
$this->assertEquals(['foo.example.com', 'bar.example.com'], $cert->hostnames);
|
||||||
|
$this->assertEquals('some-cert-data-foobar', $cert->certificate);
|
||||||
|
$this->assertEquals('some-csr-data-foobar', $cert->csr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRevokeCertificate()
|
||||||
|
{
|
||||||
|
$response = $this->getPsr7JsonResponseForFixture('Endpoints/getCertificate.json');
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock();
|
||||||
|
$mock->method('delete')->willReturn($response);
|
||||||
|
|
||||||
|
$mock->expects($this->once())
|
||||||
|
->method('delete')
|
||||||
|
->with(
|
||||||
|
$this->equalTo('certificates/11112222233333444455555'),
|
||||||
|
$this->equalTo(['zone_id' => '023e105f4ecef8ad9ca31a8372d0c353']),
|
||||||
|
$this->equalTo([])
|
||||||
|
);
|
||||||
|
|
||||||
|
$certEndpoint = new Certificates($mock);
|
||||||
|
$result = $certEndpoint->revokeCertificate(
|
||||||
|
'11112222233333444455555',
|
||||||
|
'023e105f4ecef8ad9ca31a8372d0c353'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateCertificate()
|
||||||
|
{
|
||||||
|
$certificate = new \Cloudflare\API\Configurations\Certificate();
|
||||||
|
$certificate->setHostnames(['foo.example.com', 'bar.exapmle.com']);
|
||||||
|
$certificate->setRequestType(\Cloudflare\API\Configurations\Certificate::ORIGIN_ECC);
|
||||||
|
$certificate->setRequestedValidity(365);
|
||||||
|
$certificate->setCsr('some-csr-data-barbar');
|
||||||
|
|
||||||
|
$response = $this->getPsr7JsonResponseForFixture('Endpoints/getCertificate.json');
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock();
|
||||||
|
$mock->method('post')->willReturn($response);
|
||||||
|
|
||||||
|
$mock->expects($this->once())
|
||||||
|
->method('post')
|
||||||
|
->with(
|
||||||
|
$this->equalTo('certificates'),
|
||||||
|
$this->equalTo($certificate->getArray()),
|
||||||
|
$this->equalTo([])
|
||||||
|
);
|
||||||
|
|
||||||
|
$certEndpoint = new Certificates($mock);
|
||||||
|
$result = $certEndpoint->createCertificate($certificate);
|
||||||
|
|
||||||
|
$this->assertTrue($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
tests/Fixtures/Endpoints/createCertificate.json
Normal file
17
tests/Fixtures/Endpoints/createCertificate.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"errors": [],
|
||||||
|
"messages": [],
|
||||||
|
"result": {
|
||||||
|
"id": "12341234123412341234",
|
||||||
|
"certificate": "some-cert-data-foofoo",
|
||||||
|
"hostnames": [
|
||||||
|
"foo.example.com",
|
||||||
|
"bar.example.com"
|
||||||
|
],
|
||||||
|
"expires_on": "2014-01-01T05:20:00.12345Z",
|
||||||
|
"request_type": "origin-ecc",
|
||||||
|
"requested_validity": 365,
|
||||||
|
"csr": "some-csr-data-barbar"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
tests/Fixtures/Endpoints/getCertificate.json
Normal file
17
tests/Fixtures/Endpoints/getCertificate.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"errors": [],
|
||||||
|
"messages": [],
|
||||||
|
"result": {
|
||||||
|
"id": "6666699999996666699999999966666666",
|
||||||
|
"certificate": "some-cert-data-foobar",
|
||||||
|
"hostnames": [
|
||||||
|
"foo.example.com",
|
||||||
|
"bar.example.com"
|
||||||
|
],
|
||||||
|
"expires_on": "2014-01-01T05:20:00.12345Z",
|
||||||
|
"request_type": "origin-ecc",
|
||||||
|
"requested_validity": 5475,
|
||||||
|
"csr": "some-csr-data-foobar"
|
||||||
|
}
|
||||||
|
}
|
||||||
19
tests/Fixtures/Endpoints/listCertificates.json
Normal file
19
tests/Fixtures/Endpoints/listCertificates.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"errors": [],
|
||||||
|
"messages": [],
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"id": "328578533902268680212849205732770752308931942346",
|
||||||
|
"certificate": "some-cert-data",
|
||||||
|
"hostnames": [
|
||||||
|
"example.com",
|
||||||
|
"*.example.com"
|
||||||
|
],
|
||||||
|
"expires_on": "2014-01-01T05:20:00.12345Z",
|
||||||
|
"request_type": "origin-rsa",
|
||||||
|
"requested_validity": 5475,
|
||||||
|
"csr": "some-csr-data"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
8
tests/Fixtures/Endpoints/revokeCertificate.json
Normal file
8
tests/Fixtures/Endpoints/revokeCertificate.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"errors": [],
|
||||||
|
"messages": [],
|
||||||
|
"result": {
|
||||||
|
"id": "11112222233333444455555"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user