From 89986cfb029a7a7fc3104dc51c24718ffa844d52 Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Tue, 25 Jun 2019 11:54:56 +0300 Subject: [PATCH 1/8] Added Firewall rules endpoints --- src/Endpoints/Firewall.php | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/Endpoints/Firewall.php diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php new file mode 100644 index 00000000..1734ff45 --- /dev/null +++ b/src/Endpoints/Firewall.php @@ -0,0 +1,84 @@ +adapter = $adapter; + } + + public function createFirewallRules( + string $zoneID, + array $rules + ): array { + $query = $this->adapter->post('zones/' . $zoneID . '/firewall/rules', $rules); + $body = json_decode($query->getBody()); + + return $body->result; + } + + public function createFirewallRule( + string $zoneID, + string $expression, + string $action, + string $description = null, + bool $paused = true, + int $priority = null + ): array { + $rule = [ + 'filter' => [ + 'expression' => $expression, + 'paused' => false + ], + 'action' => $action, + 'paused' => $paused + ]; + + if ($description !== null) { + $options['description'] = $description; + } + + if ($priority !== null) { + $options['priority'] = $priority; + } + + return $this->createFirewallRules($zoneID, [$rule]); + } + + public function listFirewallRules( + string $zoneID, + int $page = 1, + int $perPage = 50 + ): array { + $query = [ + 'page' => $page, + 'per_page' => $perPage, + ]; + + $rules = $this->adapter->get('zones/' . $zoneID . '/firewall/rules', $query); + $body = json_decode($rules->getBody()); + + return $body->result; + } + + public function deleteFirewallRule( + string $zoneID, + string $ruleID + ): bool { + $rule = $this->adapter->delete('zones/' . $zoneID . '/firewall/rules/' . $ruleID); + + $body = json_decode($rule->getBody()); + + if (isset($body->result->id)) { + return true; + } + + return false; + } +} From c5b6bceecbd58f8f4eee038babfaefbe15506ebc Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Thu, 27 Jun 2019 18:19:24 +0300 Subject: [PATCH 2/8] Fixed passing the description and priority of the createFirewallRule method --- src/Endpoints/Firewall.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index 1734ff45..9c025da6 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -41,11 +41,11 @@ public function createFirewallRule( ]; if ($description !== null) { - $options['description'] = $description; + $rule['description'] = $description; } if ($priority !== null) { - $options['priority'] = $priority; + $rule['priority'] = $priority; } return $this->createFirewallRules($zoneID, [$rule]); From 48404cd0ac5819b4b0f51a54768d02ccea37e5cf Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Thu, 27 Jun 2019 18:20:34 +0300 Subject: [PATCH 3/8] Added update to Firewall rules --- src/Endpoints/Firewall.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index 9c025da6..49f68e90 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -81,4 +81,39 @@ public function deleteFirewallRule( return false; } + + public function updateFirewallRule( + string $zoneID, + string $ruleID, + string $filterID, + string $expression, + string $action, + string $description = null, + bool $paused = true, + int $priority = null + ): \stdClass { + $rule = [ + 'id' => $ruleID, + 'filter' => [ + 'id' => $filterID, + 'expression' => $expression, + 'paused' => false + ], + 'action' => $action, + 'paused' => $paused + ]; + + if ($description !== null) { + $rule['description'] = $description; + } + + if ($priority !== null) { + $rule['priority'] = $priority; + } + + $rule = $this->adapter->put('zones/' . $zoneID . '/firewall/rules/' . $ruleID, $rule); + $body = json_decode($rule->getBody()); + + return $body->result; + } } From 29ab1011301cb77570c7e077e13e144be233b8a6 Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Thu, 27 Jun 2019 18:26:23 +0300 Subject: [PATCH 4/8] Fixed enable the firewall rule by default --- src/Endpoints/Firewall.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index 49f68e90..c9cd95d7 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -28,7 +28,7 @@ public function createFirewallRule( string $expression, string $action, string $description = null, - bool $paused = true, + bool $paused = false, int $priority = null ): array { $rule = [ From 66ec1b318fd79f4e391570527dd31ab43c3767d3 Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Mon, 8 Jul 2019 14:09:42 +0300 Subject: [PATCH 5/8] Changed return value of the "listFirewallRules" method --- src/Endpoints/Firewall.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index c9cd95d7..84791f08 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -55,7 +55,7 @@ public function listFirewallRules( string $zoneID, int $page = 1, int $perPage = 50 - ): array { + ): \stdClass { $query = [ 'page' => $page, 'per_page' => $perPage, @@ -64,7 +64,7 @@ public function listFirewallRules( $rules = $this->adapter->get('zones/' . $zoneID . '/firewall/rules', $query); $body = json_decode($rules->getBody()); - return $body->result; + return (object)['result' => $body->result, 'result_info' => $body->result_info]; } public function deleteFirewallRule( From 68d862f7daeade4c53fe2217d9f5c213069e5138 Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Mon, 8 Jul 2019 20:08:57 +0300 Subject: [PATCH 6/8] Changed return value of the "createFirewallRules" method --- src/Endpoints/Firewall.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index 84791f08..97729519 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -16,11 +16,17 @@ public function __construct(Adapter $adapter) public function createFirewallRules( string $zoneID, array $rules - ): array { + ): bool { $query = $this->adapter->post('zones/' . $zoneID . '/firewall/rules', $rules); $body = json_decode($query->getBody()); - return $body->result; + foreach ($body->result as $result) { + if (!isset($result->id)) { + return false; + } + } + + return true; } public function createFirewallRule( @@ -30,7 +36,7 @@ public function createFirewallRule( string $description = null, bool $paused = false, int $priority = null - ): array { + ): bool { $rule = [ 'filter' => [ 'expression' => $expression, From 22a87e1b91cc9c9c70130eceb06e3dc791fbe1ac Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Mon, 8 Jul 2019 21:09:19 +0300 Subject: [PATCH 7/8] Moved the action type and paused or not from the signature to the separate class --- src/Configurations/FirewallRuleOptions.php | 46 ++++++++++++++++++++++ src/Endpoints/Firewall.php | 23 +++++------ 2 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 src/Configurations/FirewallRuleOptions.php diff --git a/src/Configurations/FirewallRuleOptions.php b/src/Configurations/FirewallRuleOptions.php new file mode 100644 index 00000000..93f0531c --- /dev/null +++ b/src/Configurations/FirewallRuleOptions.php @@ -0,0 +1,46 @@ + false, + 'action' => 'block' + ]; + + public function getArray(): array + { + return $this->configs; + } + + public function setPaused(bool $paused) + { + $this->configs['paused'] = $paused; + } + + public function setActionBlock() + { + $this->configs['action'] = 'block'; + } + + public function setActionAllow() + { + $this->configs['action'] = 'allow'; + } + + public function setActionChallenge() + { + $this->configs['action'] = 'challenge'; + } + + public function setActionJsChallenge() + { + $this->configs['action'] = 'js_challenge'; + } + + public function setActionLog() + { + $this->configs['action'] = 'log'; + } +} diff --git a/src/Endpoints/Firewall.php b/src/Endpoints/Firewall.php index 97729519..14ebb761 100644 --- a/src/Endpoints/Firewall.php +++ b/src/Endpoints/Firewall.php @@ -3,6 +3,7 @@ namespace Cloudflare\API\Endpoints; use Cloudflare\API\Adapter\Adapter; +use Cloudflare\API\Configurations\FirewallRuleOptions; class Firewall implements API { @@ -32,19 +33,16 @@ public function createFirewallRules( public function createFirewallRule( string $zoneID, string $expression, - string $action, + FirewallRuleOptions $options, string $description = null, - bool $paused = false, int $priority = null ): bool { - $rule = [ + $rule = array_merge([ 'filter' => [ 'expression' => $expression, 'paused' => false - ], - 'action' => $action, - 'paused' => $paused - ]; + ] + ], $options->getArray()); if ($description !== null) { $rule['description'] = $description; @@ -93,21 +91,18 @@ public function updateFirewallRule( string $ruleID, string $filterID, string $expression, - string $action, + FirewallRuleOptions $options, string $description = null, - bool $paused = true, int $priority = null ): \stdClass { - $rule = [ + $rule = array_merge([ 'id' => $ruleID, 'filter' => [ 'id' => $filterID, 'expression' => $expression, 'paused' => false - ], - 'action' => $action, - 'paused' => $paused - ]; + ] + ], $options->getArray()); if ($description !== null) { $rule['description'] = $description; From 8364249fbb5e21f71c98bf8924eb0549eb2a77e7 Mon Sep 17 00:00:00 2001 From: Vitaliy Dotsenko Date: Mon, 8 Jul 2019 21:12:21 +0300 Subject: [PATCH 8/8] Added unit tests to check Firewall rules --- tests/Endpoints/FirewallTest.php | 177 ++++++++++++++++++ .../Endpoints/createFirewallRule.json | 20 ++ .../Endpoints/createFirewallRules.json | 33 ++++ .../Endpoints/deleteFirewallRule.json | 8 + .../Fixtures/Endpoints/listFirewallRules.json | 27 +++ .../Endpoints/updateFirewallRule.json | 19 ++ 6 files changed, 284 insertions(+) create mode 100644 tests/Endpoints/FirewallTest.php create mode 100644 tests/Fixtures/Endpoints/createFirewallRule.json create mode 100644 tests/Fixtures/Endpoints/createFirewallRules.json create mode 100644 tests/Fixtures/Endpoints/deleteFirewallRule.json create mode 100644 tests/Fixtures/Endpoints/listFirewallRules.json create mode 100644 tests/Fixtures/Endpoints/updateFirewallRule.json diff --git a/tests/Endpoints/FirewallTest.php b/tests/Endpoints/FirewallTest.php new file mode 100644 index 00000000..c2b2ed6c --- /dev/null +++ b/tests/Endpoints/FirewallTest.php @@ -0,0 +1,177 @@ +getPsr7JsonResponseForFixture('Endpoints/createFirewallRules.json'); + + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('post')->willReturn($response); + + $mock->expects($this->once()) + ->method('post') + ->with( + $this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/rules'), + $this->equalTo([ + [ + 'action' => 'block', + 'description' => 'Foo', + 'filter' => [ + 'expression' => 'http.cookie eq "foo"', + 'paused' => false + ], + ], + [ + 'action' => 'block', + 'description' => 'Bar', + 'filter' => [ + 'expression' => 'http.cookie eq "bar"', + 'paused' => false + ], + ] + ]) + ); + + $firewall = new Cloudflare\API\Endpoints\Firewall($mock); + $result = $firewall->createFirewallRules( + '023e105f4ecef8ad9ca31a8372d0c353', + [ + [ + 'filter' => [ + 'expression' => 'http.cookie eq "foo"', + 'paused' => false + ], + 'action' => 'block', + 'description' => 'Foo' + ], + [ + 'filter' => [ + 'expression' => 'http.cookie eq "bar"', + 'paused' => false + ], + 'action' => 'block', + 'description' => 'Bar' + ], + ] + ); + $this->assertTrue($result); + } + + public function testCreatePageRule() + { + $response = $this->getPsr7JsonResponseForFixture('Endpoints/createFirewallRule.json'); + + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('post')->willReturn($response); + + $mock->expects($this->once()) + ->method('post') + ->with( + $this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/rules'), + $this->equalTo([ + [ + 'action' => 'block', + 'description' => 'Foobar', + 'filter' => [ + 'expression' => 'http.cookie eq "foobar"', + 'paused' => false + ], + 'paused' => false + ] + ]) + ); + + $firewall = new Cloudflare\API\Endpoints\Firewall($mock); + $options = new \Cloudflare\API\Configurations\FirewallRuleOptions(); + $options->setActionBlock(); + $result = $firewall->createFirewallRule( + '023e105f4ecef8ad9ca31a8372d0c353', + 'http.cookie eq "foobar"', + $options, + 'Foobar' + ); + $this->assertTrue($result); + } + + public function testListFirewallRules() + { + $response = $this->getPsr7JsonResponseForFixture('Endpoints/listFirewallRules.json'); + + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('get')->willReturn($response); + + $mock->expects($this->once()) + ->method('get') + ->with( + $this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/rules'), + $this->equalTo([ + 'page' => 1, + 'per_page' => 50 + ]) + ); + + $firewall = new Cloudflare\API\Endpoints\Firewall($mock); + $result = $firewall->listFirewallRules('023e105f4ecef8ad9ca31a8372d0c353'); + + $this->assertObjectHasAttribute('result', $result); + $this->assertObjectHasAttribute('result_info', $result); + + $this->assertEquals('970b10321e3f4adda674c912b5f76591', $result->result[0]->id); + } + + public function testDeleteFirewallRule() + { + $response = $this->getPsr7JsonResponseForFixture('Endpoints/deleteFirewallRule.json'); + + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('delete')->willReturn($response); + + $mock->expects($this->once()) + ->method('delete') + ->with( + $this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/rules/970b10321e3f4adda674c912b5f76591') + ); + + $firewall = new Cloudflare\API\Endpoints\Firewall($mock); + $firewall->deleteFirewallRule('023e105f4ecef8ad9ca31a8372d0c353', '970b10321e3f4adda674c912b5f76591'); + } + + public function testUpdateFirewallRule() + { + $response = $this->getPsr7JsonResponseForFixture('Endpoints/updateFirewallRule.json'); + + $mock = $this->getMockBuilder(\Cloudflare\API\Adapter\Adapter::class)->getMock(); + $mock->method('put')->willReturn($response); + + $mock->expects($this->once()) + ->method('put') + ->with( + $this->equalTo('zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/rules/970b10321e3f4adda674c912b5f76591'), + $this->equalTo([ + 'id' => '970b10321e3f4adda674c912b5f76591', + 'action' => 'block', + 'description' => 'Foo', + 'filter' => [ + 'id' => '5def9c4297e0466cb0736b838345d910', + 'expression' => 'http.cookie eq "foo"', + 'paused' => false + ], + 'paused' => false + ]) + ); + + $firewall = new Cloudflare\API\Endpoints\Firewall($mock); + $options = new \Cloudflare\API\Configurations\FirewallRuleOptions(); + $options->setActionBlock(); + $result = $firewall->updateFirewallRule( + '023e105f4ecef8ad9ca31a8372d0c353', + '970b10321e3f4adda674c912b5f76591', + '5def9c4297e0466cb0736b838345d910', + 'http.cookie eq "foo"', + $options, + 'Foo' + ); + $this->assertEquals('970b10321e3f4adda674c912b5f76591', $result->id); + } +} diff --git a/tests/Fixtures/Endpoints/createFirewallRule.json b/tests/Fixtures/Endpoints/createFirewallRule.json new file mode 100644 index 00000000..e00b22cb --- /dev/null +++ b/tests/Fixtures/Endpoints/createFirewallRule.json @@ -0,0 +1,20 @@ +{ + "result": [ + { + "id": "970b10321e3f4adda674c912b5f76591", + "paused": false, + "description": "Foobar", + "action": "block", + "filter": { + "id": "70f39827184d487e97cc286b960f4cc3", + "expression": "http.cookie eq \"foobar\"", + "paused": false + }, + "created_on": "2019-07-05T15:53:15Z", + "modified_on": "2019-07-05T15:53:15Z" + } + ], + "success": true, + "errors": [], + "messages": [] +} diff --git a/tests/Fixtures/Endpoints/createFirewallRules.json b/tests/Fixtures/Endpoints/createFirewallRules.json new file mode 100644 index 00000000..0b08b18b --- /dev/null +++ b/tests/Fixtures/Endpoints/createFirewallRules.json @@ -0,0 +1,33 @@ +{ + "result": [ + { + "id": "970b10321e3f4adda674c912b5f76591", + "paused": false, + "description": "Foo", + "action": "block", + "filter": { + "id": "70f39827184d487e97cc286b960f4cc3", + "expression": "http.cookie eq \"foo\"", + "paused": false + }, + "created_on": "2019-07-05T15:53:15Z", + "modified_on": "2019-07-05T15:53:15Z" + }, + { + "id": "42c05fd0e0af4d17a361d2d1423476bc", + "paused": false, + "description": "Bar", + "action": "block", + "filter": { + "id": "246b4d9f5f51471485bdc95e1c6b53a7", + "expression": "http.cookie eq \"bar\"", + "paused": false + }, + "created_on": "2019-07-05T15:53:15Z", + "modified_on": "2019-07-05T15:53:15Z" + } + ], + "success": true, + "errors": [], + "messages": [] +} diff --git a/tests/Fixtures/Endpoints/deleteFirewallRule.json b/tests/Fixtures/Endpoints/deleteFirewallRule.json new file mode 100644 index 00000000..8a998846 --- /dev/null +++ b/tests/Fixtures/Endpoints/deleteFirewallRule.json @@ -0,0 +1,8 @@ +{ + "result": { + "id": "970b10321e3f4adda674c912b5f76591" + }, + "success": true, + "errors": [], + "messages": [] +} diff --git a/tests/Fixtures/Endpoints/listFirewallRules.json b/tests/Fixtures/Endpoints/listFirewallRules.json new file mode 100644 index 00000000..a3433956 --- /dev/null +++ b/tests/Fixtures/Endpoints/listFirewallRules.json @@ -0,0 +1,27 @@ +{ + "result": [ + { + "id": "970b10321e3f4adda674c912b5f76591", + "paused": false, + "description": "Foobar", + "action": "block", + "filter": { + "id": "70f39827184d487e97cc286b960f4cc3", + "expression": "http.cookie eq \"foobar\"", + "paused": false + }, + "created_on": "2019-07-05T15:53:15Z", + "modified_on": "2019-07-05T15:53:15Z" + } + ], + "success": true, + "errors": [], + "messages": [], + "result_info": { + "page": 1, + "per_page": 50, + "count": 1, + "total_count": 1, + "total_pages": 1 + } +} diff --git a/tests/Fixtures/Endpoints/updateFirewallRule.json b/tests/Fixtures/Endpoints/updateFirewallRule.json new file mode 100644 index 00000000..27359e0f --- /dev/null +++ b/tests/Fixtures/Endpoints/updateFirewallRule.json @@ -0,0 +1,19 @@ +{ + "result": { + "id": "970b10321e3f4adda674c912b5f76591", + "paused": false, + "description": "Foo", + "action": "block", + "filter": { + "id": "5def9c4297e0466cb0736b838345d910", + "expression": "http.cookie eq \"foo\"", + "paused": false + }, + "created_on": "2019-07-05T15:53:15Z", + "modified_on": "2019-07-05T18:07:46Z", + "index": 1 + }, + "success": true, + "errors": [], + "messages": [] +}