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 new file mode 100644 index 00000000..14ebb761 --- /dev/null +++ b/src/Endpoints/Firewall.php @@ -0,0 +1,120 @@ +adapter = $adapter; + } + + public function createFirewallRules( + string $zoneID, + array $rules + ): bool { + $query = $this->adapter->post('zones/' . $zoneID . '/firewall/rules', $rules); + $body = json_decode($query->getBody()); + + foreach ($body->result as $result) { + if (!isset($result->id)) { + return false; + } + } + + return true; + } + + public function createFirewallRule( + string $zoneID, + string $expression, + FirewallRuleOptions $options, + string $description = null, + int $priority = null + ): bool { + $rule = array_merge([ + 'filter' => [ + 'expression' => $expression, + 'paused' => false + ] + ], $options->getArray()); + + if ($description !== null) { + $rule['description'] = $description; + } + + if ($priority !== null) { + $rule['priority'] = $priority; + } + + return $this->createFirewallRules($zoneID, [$rule]); + } + + public function listFirewallRules( + string $zoneID, + int $page = 1, + int $perPage = 50 + ): \stdClass { + $query = [ + 'page' => $page, + 'per_page' => $perPage, + ]; + + $rules = $this->adapter->get('zones/' . $zoneID . '/firewall/rules', $query); + $body = json_decode($rules->getBody()); + + return (object)['result' => $body->result, 'result_info' => $body->result_info]; + } + + 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; + } + + public function updateFirewallRule( + string $zoneID, + string $ruleID, + string $filterID, + string $expression, + FirewallRuleOptions $options, + string $description = null, + int $priority = null + ): \stdClass { + $rule = array_merge([ + 'id' => $ruleID, + 'filter' => [ + 'id' => $filterID, + 'expression' => $expression, + 'paused' => false + ] + ], $options->getArray()); + + 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; + } +} 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": [] +}