diff --git a/README.md b/README.md index 4334ed9..ac24a55 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,12 @@ Each API call is provided via a similarly named function within various classes - [x] DNS Records - [x] Zones - [x] User Administration (partial) -- [ ] Cloudflare IPs +- [x] Cloudflare IPs - [ ] Page Rules - [ ] Web Application Firewall (WAF) - [ ] Virtual DNS Management - [ ] Custom hostnames +- [ ] Zone Lockdown and User-Agent Block rules - [ ] Organization Administration - [ ] [Railgun](https://www.cloudflare.com/railgun/) administration - [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/) diff --git a/src/Adapter/Guzzle.php b/src/Adapter/Guzzle.php index c9ac7cf..fad8129 100644 --- a/src/Adapter/Guzzle.php +++ b/src/Adapter/Guzzle.php @@ -19,8 +19,12 @@ class Guzzle implements Adapter /** * @inheritDoc */ - public function __construct(Auth $auth, String $baseURI = "https://api.cloudflare.com/client/v4/") + public function __construct(Auth $auth, String $baseURI = null) { + if ($baseURI === null) { + $baseURI = "https://api.cloudflare.com/client/v4/"; + } + $headers = $auth->getHeaders(); $this->client = new Client([ diff --git a/src/Auth/None.php b/src/Auth/None.php new file mode 100644 index 0000000..aa203e3 --- /dev/null +++ b/src/Auth/None.php @@ -0,0 +1,18 @@ +adapter = $adapter; } - public function addRecord(string $zoneID, string $type, string $name, string $content, int $ttl = 0, bool $proxied = true): bool - { + public function addRecord( + string $zoneID, + string $type, + string $name, + string $content, + int $ttl = 0, + bool $proxied = true + ): bool { $options = [ 'type' => $type, 'name' => $name, @@ -46,6 +52,7 @@ class DNS implements API public function listRecords( string $zoneID, string $type = "", + string $name = "", string $content = "", int $page = 1, int $perPage = 20, @@ -79,7 +86,9 @@ class DNS implements API $options['direction'] = $direction; } - $user = $this->adapter->get('zones/'.$zoneID.'/dns_records', [], $options); + $query = http_build_query($options); + + $user = $this->adapter->get('zones/' . $zoneID . '/dns_records?' . $query, []); $body = json_decode($user->getBody()); $result = new \stdClass(); @@ -91,20 +100,20 @@ class DNS implements API public function getRecordDetails(string $zoneID, string $recordID): \stdClass { - $user = $this->adapter->get('zones/'.$zoneID.'/dns_records/'.$recordID, []); + $user = $this->adapter->get('zones/' . $zoneID . '/dns_records/' . $recordID, []); $body = json_decode($user->getBody()); return $body->result; } public function updateRecordDetails(string $zoneID, string $recordID, array $details): \stdClass { - $response = $this->adapter->put('zones/'.$zoneID.'/dns_records/'.$recordID, [], $details); + $response = $this->adapter->put('zones/' . $zoneID . '/dns_records/' . $recordID, [], $details); return json_decode($response->getBody()); } public function deleteRecord(string $zoneID, string $recordID): bool { - $user = $this->adapter->delete('zones/'.$zoneID.'/dns_records/'.$recordID, [], []); + $user = $this->adapter->delete('zones/' . $zoneID . '/dns_records/' . $recordID, [], []); $body = json_decode($user->getBody()); diff --git a/src/Endpoints/IPs.php b/src/Endpoints/IPs.php new file mode 100644 index 0000000..d384afc --- /dev/null +++ b/src/Endpoints/IPs.php @@ -0,0 +1,29 @@ +adapter = $adapter; + } + + public function listIPs(): \stdClass { + $ips = $this->adapter->get('ips', []); + $body = json_decode($ips->getBody()); + + return $body->result; + } +} \ No newline at end of file diff --git a/tests/Endpoints/PageRules.php b/src/Endpoints/PageRules.php similarity index 100% rename from tests/Endpoints/PageRules.php rename to src/Endpoints/PageRules.php diff --git a/src/Endpoints/Zones.php b/src/Endpoints/Zones.php index 486fa1b..13dc83b 100644 --- a/src/Endpoints/Zones.php +++ b/src/Endpoints/Zones.php @@ -80,7 +80,9 @@ class Zones implements API $options['direction'] = $direction; } - $user = $this->adapter->get('zones', [], $options); + $query = http_build_query($options); + + $user = $this->adapter->get('zones?' . $query, []); $body = json_decode($user->getBody()); $result = new \stdClass(); diff --git a/tests/Auth/NoneTest.php b/tests/Auth/NoneTest.php new file mode 100644 index 0000000..7fcc81f --- /dev/null +++ b/tests/Auth/NoneTest.php @@ -0,0 +1,20 @@ +getHeaders(); + + $this->assertEquals([], $headers); + } +} diff --git a/tests/Endpoints/DNSTest.php b/tests/Endpoints/DNSTest.php index 697ae3b..25bbc98 100644 --- a/tests/Endpoints/DNSTest.php +++ b/tests/Endpoints/DNSTest.php @@ -1,13 +1,11 @@ expects($this->once()) ->method('post') ->with($this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records'), $this->equalTo([]), - $this->equalTo(['type' => 'A', 'name' => 'example.com', 'content' => '127.0.0.1', 'ttl' => 120, 'proxied' => false]) + $this->equalTo([ + 'type' => 'A', + 'name' => 'example.com', + 'content' => '127.0.0.1', + 'ttl' => 120, + 'proxied' => false + ]) ); $dns = new \Cloudflare\API\Endpoints\DNS($mock); @@ -77,28 +81,19 @@ class DNSTest extends PHPUnit_Framework_TestCase "total_count": 2000 } }'); - + $response = new GuzzleHttp\Psr7\Response(200, ['Content-Type' => 'application/json'], $stream); $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); $mock->method('get')->willReturn($response); $mock->expects($this->once()) ->method('get') - ->with($this->equalTo('zones'), - $this->equalTo([]), - $this->equalTo([ - 'page' => 1, - 'per_page' => 20, - 'match' => 'all', - 'name' => 'example.com', - 'status' => 'active', - 'order' => 'status', - 'direction' => 'desc' - ] - )); + ->with($this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records?page=1&per_page=20&match=all&type=A&name=example.com&content=127.0.0.1&order=type&direction=desc'), + $this->equalTo([]) + ); - $zones = new \Cloudflare\API\Endpoints\Zones($mock); - $result = $zones->listZones("example.com", "active", 1, 20, "status", "desc", "all"); + $zones = new \Cloudflare\API\Endpoints\DNS($mock); + $result = $zones->listRecords("023e105f4ecef8ad9ca31a8372d0c353","A", "example.com", "127.0.0.1", 1, 20, "type", "desc", "all"); $this->assertObjectHasAttribute('result', $result); $this->assertObjectHasAttribute('result_info', $result); diff --git a/tests/Endpoints/IPsTest.php b/tests/Endpoints/IPsTest.php new file mode 100644 index 0000000..1a47bf8 --- /dev/null +++ b/tests/Endpoints/IPsTest.php @@ -0,0 +1,42 @@ + 'application/json'], $stream); + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('get')->willReturn($response); + + $mock->expects($this->once()) + ->method('get') + ->with($this->equalTo('ips'), $this->equalTo([]) + ); + + $ips = new \Cloudflare\API\Endpoints\IPs($mock); + $ips = $ips->listIPs(); + $this->assertObjectHasAttribute("ipv4_cidrs", $ips); + $this->assertObjectHasAttribute("ipv6_cidrs", $ips); + } +} diff --git a/tests/Endpoints/ZonesTest.php b/tests/Endpoints/ZonesTest.php index 71d2f8f..b6bc87a 100644 --- a/tests/Endpoints/ZonesTest.php +++ b/tests/Endpoints/ZonesTest.php @@ -1,13 +1,11 @@ expects($this->once()) ->method('get') - ->with($this->equalTo('zones'), - $this->equalTo([]), - $this->equalTo([ - 'page' => 1, - 'per_page' => 20, - 'match' => 'all', - 'name' => 'example.com', - 'status' => 'active', - 'order' => 'status', - 'direction' => 'desc' - ] - )); + ->with($this->equalTo('zones?page=1&per_page=20&match=all&name=example.com&status=active&order=status&direction=desc'), + $this->equalTo([]) + ); $zones = new \Cloudflare\API\Endpoints\Zones($mock); $result = $zones->listZones("example.com", "active", 1, 20, "status", "desc", "all"); @@ -291,15 +280,9 @@ class ZonesTest extends PHPUnit_Framework_TestCase $mock->expects($this->once()) ->method('get') - ->with($this->equalTo('zones'), - $this->equalTo([]), - $this->equalTo([ - 'name' => 'example.com', - 'page' => 1, - 'per_page' => 20, - 'match' => 'all' - ] - )); + ->with($this->equalTo('zones?page=1&per_page=20&match=all&name=example.com'), + $this->equalTo([]) + ); $zones = new \Cloudflare\API\Endpoints\Zones($mock); $result = $zones->getZoneID("example.com");