diff --git a/.drone.yml b/.drone.yml index dd4ec40420..8d3e3551a6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -30,6 +30,7 @@ pipeline: image: nextcloudci/php7.0:php7.0-7 commands: - ./occ app:check-code admin_audit + - ./occ app:check-code bruteforcesettings - ./occ app:check-code comments - ./occ app:check-code federation - ./occ app:check-code sharebymail diff --git a/.gitignore b/.gitignore index d8669fed07..1e0f53a3c0 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ /apps/files_external/3rdparty/irodsphp/prods/tutorials /apps/files_external/3rdparty/irodsphp/prods/test* /apps/files_external/tests/config.*.php - +!/apps/bruteforcesettings # ignore themes except the example and the README diff --git a/apps/bruteforcesettings/appinfo/info.xml b/apps/bruteforcesettings/appinfo/info.xml new file mode 100644 index 0000000000..2c3e1256e8 --- /dev/null +++ b/apps/bruteforcesettings/appinfo/info.xml @@ -0,0 +1,21 @@ + + + bruteforcesettings + Brute force settings + + This applications allows admins to configure the brute force settings. + + AGPL + Roeland Jago Douma + + 1.0.0 + + + + + BruteForceSettings + + + OCA\BruteForceSettings\Settings\IPWhitelist + + diff --git a/apps/bruteforcesettings/appinfo/routes.php b/apps/bruteforcesettings/appinfo/routes.php new file mode 100644 index 0000000000..28ab6e9cee --- /dev/null +++ b/apps/bruteforcesettings/appinfo/routes.php @@ -0,0 +1,30 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +return [ + 'routes' => [ + [ 'name' => 'IPWhitelist#getAll', 'url' => '/ipwhitelist', 'verb' => 'GET' ], + [ 'name' => 'IPWhitelist#add', 'url' => '/ipwhitelist', 'verb' => 'POST' ], + [ 'name' => 'IPWhitelist#remove', 'url' => '/ipwhitelist/{id}', 'verb' => 'DELETE' ], + ] +]; diff --git a/apps/bruteforcesettings/js/IPWhitelist.js b/apps/bruteforcesettings/js/IPWhitelist.js new file mode 100644 index 0000000000..163d5d2852 --- /dev/null +++ b/apps/bruteforcesettings/js/IPWhitelist.js @@ -0,0 +1,44 @@ +/** + * @copyright 2016, Roeland Jago Douma + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +(function() { + + OCA.BruteForceSettings = OCA.BruteForceSettings || {}; + + OCA.BruteForceSettings.WhiteList = { + + collection: null, + view: null, + + init: function () { + this.collection = new OCA.BruteForceSettings.WhitelistCollection(); + this.view = new OCA.BruteForceSettings.WhitelistView({ + collection: this.collection + }); + this.view.reload(); + } + }; +})(); + +$(document).ready(function() { + OCA.BruteForceSettings.WhiteList.init(); +}); diff --git a/apps/bruteforcesettings/js/IPWhitelistCollection.js b/apps/bruteforcesettings/js/IPWhitelistCollection.js new file mode 100644 index 0000000000..bf5b34d1ad --- /dev/null +++ b/apps/bruteforcesettings/js/IPWhitelistCollection.js @@ -0,0 +1,34 @@ +/** + * @copyright 2016, Roeland Jago Douma + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +(function() { + + OCA.BruteForceSettings = OCA.BruteForceSettings || {}; + + OCA.BruteForceSettings.WhitelistCollection = OC.Backbone.Collection.extend({ + model: OCA.BruteForceSettings.WhitelistModel, + + url: function() { + return OC.generateUrl('/apps/bruteforcesettings/ipwhitelist'); + } + }); +})(); diff --git a/apps/bruteforcesettings/js/IPWhitelistModel.js b/apps/bruteforcesettings/js/IPWhitelistModel.js new file mode 100644 index 0000000000..5c309f5af7 --- /dev/null +++ b/apps/bruteforcesettings/js/IPWhitelistModel.js @@ -0,0 +1,29 @@ +/** + * @copyright 2016, Roeland Jago Douma + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +(function() { + + OCA.BruteForceSettings = OCA.BruteForceSettings || {}; + + OCA.BruteForceSettings.WhitelistModel = OC.Backbone.Model.extend({ + }); +})(); diff --git a/apps/bruteforcesettings/js/IPWhitelistView.js b/apps/bruteforcesettings/js/IPWhitelistView.js new file mode 100644 index 0000000000..da711ae122 --- /dev/null +++ b/apps/bruteforcesettings/js/IPWhitelistView.js @@ -0,0 +1,128 @@ +/** + * @copyright 2016, Roeland Jago Douma + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +(function () { + + OCA.BruteForceSettings = OCA.BruteForceSettings || {}; + + var TEMPLATE_WHITELIST = + '' + + '{{ip}}/{{mask}}' + + 'BAD CSS' + + ''; + + OCA.BruteForceSettings.WhitelistView = OC.Backbone.View.extend({ + collection: null, + + ipInput: undefined, + maskInput: undefined, + submit: undefined, + + list: undefined, + listHeader: undefined, + + initialize: function(options) { + this.collection = options.collection; + + this.ipInput = $('#whitelist_ip'); + this.maskInput = $('#whitelist_mask'); + this.submit = $('#whitelist_submit'); + this.submit.click(_.bind(this._addWhitelist, this)); + + this.list = $('#whitelist-list'); + this.listHeader = $('#whitelist-list-header'); + + this.list.on('click', 'a.icon-delete', _.bind(this._onDeleteRetention, this)); + this.listenTo(this.collection, 'sync', this.render); + }, + + + + reload: function() { + var _this = this; + var loadingWhitelists = this.collection.fetch(); + + $.when(loadingWhitelists).done(function () { + _this.render(); + }); + $.when(loadingWhitelists).fail(function () { + OC.Notification.showTemporary(t('bruteforcesettings', 'Error while whitelists.')); + }); + }, + + template: function (data) { + if (_.isUndefined(this._template)) { + this._template = Handlebars.compile(TEMPLATE_WHITELIST); + } + + return this._template(data); + }, + + render: function () { + var _this = this; + this.list.html(''); + + this.collection.forEach(function (model) { + var data = { + id: model.attributes.id, + ip: model.attributes.ip, + mask: model.attributes.mask + }; + var html = _this.template(data); + var $html = $(html); + _this.list.append($html); + }); + }, + + _onDeleteRetention: function(event) { + var $target = $(event.target); + var $row = $target.closest('tr'); + var id = $row.data('id'); + + var whitelist = this.collection.get(id); + + if (_.isUndefined(whitelist)) { + // Ignore event + return; + } + + var destroyingRetention = whitelist.destroy(); + + $row.find('.icon-delete').tooltip('hide'); + + var _this = this; + $.when(destroyingRetention).fail(function () { + OC.Notification.showTemporary(t('bruteforcesettings', 'Error while deleting a whitelist')); + }); + $.when(destroyingRetention).always(function () { + _this.render(); + }); + }, + + _addWhitelist: function() { + this.collection.create({ + ip: this.ipInput.val(), + mask: this.maskInput.val() + }); + } + }); +})(); diff --git a/apps/bruteforcesettings/lib/Controller/IPWhitelistController.php b/apps/bruteforcesettings/lib/Controller/IPWhitelistController.php new file mode 100644 index 0000000000..9b5183f749 --- /dev/null +++ b/apps/bruteforcesettings/lib/Controller/IPWhitelistController.php @@ -0,0 +1,123 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\BruteForceSettings\Controller; + +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IConfig; +use OCP\IRequest; + +class IPWhitelistController extends Controller { + + /** @var IConfig */ + private $config; + + /** + * IPWhitelistController constructor. + * + * @param string $appName + * @param IRequest $request + * @param IConfig $config + */ + public function __construct($appName, + IRequest $request, + IConfig $config) { + parent::__construct($appName, $request); + + $this->config = $config; + } + + /** + * @return JSONResponse + */ + public function getAll() { + $keys = $this->config->getAppKeys('bruteForce'); + $keys = array_filter($keys, function($key) { + $regex = '/^whitelist_/S'; + return preg_match($regex, $key) === 1; + }); + + $result = []; + + foreach ($keys as $key) { + $value = $this->config->getAppValue('bruteForce', $key); + $values = explode('/', $value); + + $result[] = [ + 'id' => (int)substr($key, 10), + 'ip' => $values[0], + 'mask' => $values[1], + ]; + } + + return new JSONResponse($result); + } + + /** + * @param string $ip + * @param int $mask + * @return JSONResponse + */ + public function add($ip, $mask) { + if (!filter_var($ip, FILTER_VALIDATE_IP) || + (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && ($mask < 0 || $mask > 32)) || + (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && ($mask < 0 || $mask > 128))) { + return new JSONResponse([], Http::STATUS_BAD_REQUEST); + } + + $keys = $this->config->getAppKeys('bruteForce'); + $keys = array_filter($keys, function($key) { + $regex = '/^whitelist_/S'; + return preg_match($regex, $key) === 1; + }); + + $id = 0; + foreach ($keys as $key) { + $tmp = (int)substr($key, 10); + if ($tmp > $id) { + $id = $tmp; + } + } + $id++; + + $value = $ip . '/' . $mask; + $this->config->setAppValue('bruteForce', 'whitelist_'.$id, $value); + return new JSONResponse([ + 'id' => $id, + 'ip' => $ip, + 'mask' => $mask, + ]); + } + + /** + * @param int $id + * @return JSONResponse + */ + public function remove($id) { + $this->config->deleteAppValue('bruteForce', 'whitelist_'.$id); + + return new JSONResponse([]); + } +} diff --git a/apps/bruteforcesettings/lib/Settings/IPWhitelist.php b/apps/bruteforcesettings/lib/Settings/IPWhitelist.php new file mode 100644 index 0000000000..7e4aab2f22 --- /dev/null +++ b/apps/bruteforcesettings/lib/Settings/IPWhitelist.php @@ -0,0 +1,42 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\BruteForceSettings\Settings; + +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Settings\ISettings; + +class IPWhitelist implements ISettings { + + public function getForm() { + return new TemplateResponse('bruteforcesettings', 'ipwhitelist'); + } + + public function getSection() { + return 'security'; + } + + public function getPriority() { + return 50; + } +} diff --git a/apps/bruteforcesettings/templates/ipwhitelist.php b/apps/bruteforcesettings/templates/ipwhitelist.php new file mode 100644 index 0000000000..6935495616 --- /dev/null +++ b/apps/bruteforcesettings/templates/ipwhitelist.php @@ -0,0 +1,48 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +script('core', [ + 'oc-backbone-webdav', +]); +script('bruteforcesettings', [ + 'IPWhitelist', + 'IPWhitelistModel', + 'IPWhitelistCollection', + 'IPWhitelistView', +]); + +/** @var \OCP\IL10N $l */ +?> +
+

t('Brute force ip whitelist')); ?>

+ + + + + +
+ + / + + +
diff --git a/apps/bruteforcesettings/tests/Controller/IPWhitelistControllerTest.php b/apps/bruteforcesettings/tests/Controller/IPWhitelistControllerTest.php new file mode 100644 index 0000000000..c45fc6a941 --- /dev/null +++ b/apps/bruteforcesettings/tests/Controller/IPWhitelistControllerTest.php @@ -0,0 +1,151 @@ + + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\BruteForceSettings\Tests\Controller; + +use OCA\BruteForceSettings\Controller\IPWhitelistController; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IConfig; +use OCP\IRequest; +use Test\TestCase; + +class IPWhitelistControllerTest extends TestCase { + + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var IPWhitelistController */ + private $controller; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->controller = new IPWhitelistController( + 'bruteforce', + $this->createMock(IRequest::class), + $this->config + ); + } + + public function testGetAll() { + $this->config->method('getAppKeys') + ->with($this->equalTo('bruteForce')) + ->willReturn([ + 'foobar', + 'whitelist_0', + 'whitelist_99', + ]); + + $this->config->method('getAppValue') + ->will($this->returnCallback(function($app, $key) { + if ($app !== 'bruteForce') { + $this->fail(); + } + if ($key === 'whitelist_0') { + return '192.168.2.0/24'; + } else if ($key === 'whitelist_99') { + return 'dead:beef:cafe::/92'; + } + $this->fail(); + })); + + $expected = new JSONResponse([ + [ + 'id' => 0, + 'ip' => '192.168.2.0', + 'mask' => '24', + ], + [ + 'id' => 99, + 'ip' => 'dead:beef:cafe::', + 'mask' => '92', + ] + ]); + + $this->assertEquals($expected, $this->controller->getAll()); + } + + public function dataAdd() { + return [ + ['8.500.2.3', 24, false], + ['1.2.3.4', 24, true], + ['1.2.3.4', -1, false], + ['1.2.3.4', 33, false], + + ['dead:nope::8', 24, false], + ['1234:567:abef::1a2b', 24, true], + ['1234:567:abef::1a2b', -1, false], + ['1234:567:abef::1a2b', 129, false], + ]; + } + + /** + * @dataProvider dataAdd + * + * @param string $ip + * @param int $mask + * @param bool $valid + */ + public function testAdd($ip, $mask, $valid) { + if (!$valid) { + $expected = new JSONResponse([], Http::STATUS_BAD_REQUEST); + } else { + $this->config->method('getAppKeys') + ->with($this->equalTo('bruteForce')) + ->willReturn([ + 'foobar', + 'whitelist_0', + 'whitelist_99', + ]); + + $this->config->expects($this->once()) + ->method('setAppValue') + ->with( + $this->equalTo('bruteForce'), + $this->equalTo('whitelist_100'), + $this->equalTo($ip.'/'.$mask) + ); + + $expected = new JSONResponse([ + 'id' => 100, + 'ip' => $ip, + 'mask' => $mask, + ]); + } + + $this->assertEquals($expected, $this->controller->add($ip, $mask)); + } + + public function testRemove() { + $this->config->expects($this->once()) + ->method('deleteAppValue') + ->with( + $this->equalTo('bruteForce'), + $this->equalTo('whitelist_42') + ); + + $expected = new JSONResponse([]); + $this->assertEquals($expected, $this->controller->remove(42)); + } +} diff --git a/apps/bruteforcesettings/tests/Settings/IPWhitelistTest.php b/apps/bruteforcesettings/tests/Settings/IPWhitelistTest.php new file mode 100644 index 0000000000..37d13a86d5 --- /dev/null +++ b/apps/bruteforcesettings/tests/Settings/IPWhitelistTest.php @@ -0,0 +1,33 @@ +settings = new IPWhitelist(); + } + + public function testGetForm() { + $expected = new TemplateResponse('bruteforcesettings', 'ipwhitelist'); + + $this->assertEquals($expected, $this->settings->getForm()); + } + + public function testGetSection() { + $this->assertSame('security', $this->settings->getSection()); + } + + public function testGetPriority() { + $this->assertSame(50, $this->settings->getPriority()); + } +} diff --git a/apps/bruteforcesettings/tests/js/IPWhitelistSpec.js b/apps/bruteforcesettings/tests/js/IPWhitelistSpec.js new file mode 100644 index 0000000000..21ba32faa3 --- /dev/null +++ b/apps/bruteforcesettings/tests/js/IPWhitelistSpec.js @@ -0,0 +1,174 @@ +/** + * @copyright 2016, Roeland Jago Douma + * + * @author Roeland Jago Douma + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +describe('OCA.BruteForceSettings.IPWhiteList tests', function() { + beforeEach(function() { + // init parameters and test table elements + $('#testArea').append( + ''+ + '' + + '' + + '
' + + '/' + + '' + + '' + ); + }); + + it('get intial empty', function() { + OCA.BruteForceSettings.WhiteList.init(); + + expect(fakeServer.requests.length).toEqual(1); + expect(fakeServer.requests[0].method).toEqual('GET'); + expect(fakeServer.requests[0].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist') + ); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + '[]' + ); + + expect($('#whitelist-list > tr').length).toEqual(0); + }); + it('get intial filled', function() { + OCA.BruteForceSettings.WhiteList.init(); + + expect(fakeServer.requests.length).toEqual(1); + expect(fakeServer.requests[0].method).toEqual('GET'); + expect(fakeServer.requests[0].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist') + ); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify([ + { + id: 1, + ip: '11.22.0.0', + mask: 16 + }, + { + id: 12, + ip: 'cafe:cafe::', + mask: 80 + } + ]) + ); + + expect($('#whitelist-list > tr').length).toEqual(2); + + var el1 = $($('#whitelist-list > tr').get(0)); + expect(el1.data('id')).toEqual(1); + expect($(el1.find('td > span')[0]).html()).toEqual('11.22.0.0/16'); + + var el2 = $($('#whitelist-list > tr').get(1)); + expect(el2.data('id')).toEqual(12); + expect($(el2.find('td > span')[0]).html()).toEqual('cafe:cafe::/80'); + }); + it('add whitelist', function() { + OCA.BruteForceSettings.WhiteList.init(); + + expect(fakeServer.requests.length).toEqual(1); + expect(fakeServer.requests[0].method).toEqual('GET'); + expect(fakeServer.requests[0].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist') + ); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + '[]' + ); + + expect($('#whitelist-list > tr').length).toEqual(0); + + $('#whitelist_ip').val('2.4.8.16'); + $('#whitelist_mask').val('8'); + $('#whitelist_submit').click(); + + expect(fakeServer.requests.length).toEqual(2); + expect(fakeServer.requests[1].method).toEqual('POST'); + expect(JSON.parse(fakeServer.requests[1].requestBody)).toEqual({ + ip: '2.4.8.16', + mask: '8' + }); + expect(fakeServer.requests[1].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist') + ); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ + id: 99, + ip: '2.4.8.16', + mask: 8 + }) + ); + + expect($('#whitelist-list > tr').length).toEqual(1); + + var el1 = $($('#whitelist-list > tr').get(0)); + expect(el1.data('id')).toEqual(99); + expect($(el1.find('td > span')[0]).html()).toEqual('2.4.8.16/8'); + }); + it('delete whitelist', function() { + OCA.BruteForceSettings.WhiteList.init(); + + expect(fakeServer.requests.length).toEqual(1); + expect(fakeServer.requests[0].method).toEqual('GET'); + expect(fakeServer.requests[0].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist') + ); + fakeServer.requests[0].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify([ + { + id: 1, + ip: '1.2.3.4', + mask: 8 + } + ]) + ); + + expect($('#whitelist-list > tr').length).toEqual(1); + + var el1 = $($('#whitelist-list > tr').get(0)); + expect(el1.data('id')).toEqual(1); + expect($(el1.find('td > span')[0]).html()).toEqual('1.2.3.4/8'); + el1.find('.icon-delete').click(); + + expect(fakeServer.requests.length).toEqual(2); + expect(fakeServer.requests[1].method).toEqual('DELETE'); + expect(fakeServer.requests[1].url).toEqual( + OC.generateUrl('/apps/bruteforcesettings/ipwhitelist/1') + ); + + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + '[]' + ); + + expect($('#whitelist-list > tr').length).toEqual(0); + }); +}); diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature index ad9d901d05..856d17e5c1 100644 --- a/build/integration/features/provisioning-v1.feature +++ b/build/integration/features/provisioning-v1.feature @@ -282,6 +282,7 @@ Feature: provisioning Then the OCS status code should be "100" And the HTTP status code should be "200" And apps returned are + | bruteforcesettings | | comments | | dav | | federatedfilesharing | diff --git a/tests/karma.config.js b/tests/karma.config.js index 91052f62cd..f965738872 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -118,6 +118,19 @@ module.exports = function(config) { 'settings/tests/js/appsSpec.js', 'settings/tests/js/users/deleteHandlerSpec.js' ] + }, + { + name: 'bruteforcesettings', + srcFiles: [ + // need to enforce loading order... + 'apps/bruteforcesettings/js/IPWhitelistModel.js', + 'apps/bruteforcesettings/js/IPWhitelistCollection.js', + 'apps/bruteforcesettings/js/IPWhitelistView.js', + 'apps/bruteforcesettings/js/IPWhitelist.js', + ], + testFiles: [ + 'apps/bruteforcesettings/tests/js/IPWhitelistSpec.js' + ] } ]; } diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml index 9a9c9c957e..40633aff5a 100644 --- a/tests/phpunit-autotest.xml +++ b/tests/phpunit-autotest.xml @@ -21,6 +21,7 @@ .. ../3rdparty + ../apps/bruteforcesettings/tests ../apps/dav/tests ../apps/encryption/tests ../apps/federatedfilesharing/tests