summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2016-10-25 10:57:48 +0200
committerGitHub <noreply@github.com>2016-10-25 10:57:48 +0200
commit890f752a6b57598ee6b2088a615c41f60d697847 (patch)
tree191c38b854d23f34a285b6fab711c82b2d5ed1f7 /apps
parent79706e0ddc6ab970d5709e89b8d0caec4d34662b (diff)
parent2aca56f207048e6dff44983fe4cd7af834e70b42 (diff)
downloadnextcloud-server-890f752a6b57598ee6b2088a615c41f60d697847.tar.gz
nextcloud-server-890f752a6b57598ee6b2088a615c41f60d697847.zip
Merge pull request #1452 from nextcloud/appconfig-endpoint
Appconfig endpoint
Diffstat (limited to 'apps')
-rw-r--r--apps/federatedfilesharing/js/settings-admin.js2
-rw-r--r--apps/files_external/js/settings.js6
-rw-r--r--apps/provisioning_api/appinfo/routes.php17
-rw-r--r--apps/provisioning_api/lib/Controller/AppConfigController.php157
-rw-r--r--apps/provisioning_api/tests/Controller/AppConfigControllerTest.php382
-rw-r--r--apps/updatenotification/js/admin.js2
6 files changed, 553 insertions, 13 deletions
diff --git a/apps/federatedfilesharing/js/settings-admin.js b/apps/federatedfilesharing/js/settings-admin.js
index 257c864b04f..a0b8feb945e 100644
--- a/apps/federatedfilesharing/js/settings-admin.js
+++ b/apps/federatedfilesharing/js/settings-admin.js
@@ -5,7 +5,7 @@ $(document).ready(function() {
if (this.checked) {
value = 'yes';
}
- OC.AppConfig.setValue('files_sharing', $(this).attr('name'), value);
+ OCP.AppConfig.setValue('files_sharing', $(this).attr('name'), value);
});
});
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index da3e2397b7e..0270b7a6957 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -1317,12 +1317,12 @@ $(document).ready(function() {
$allowUserMounting.bind('change', function() {
OC.msg.startSaving('#userMountingMsg');
if (this.checked) {
- OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');
+ OCP.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');
$('input[name="allowUserMountingBackends\\[\\]"]').prop('checked', true);
$('#userMountingBackends').removeClass('hidden');
$('input[name="allowUserMountingBackends\\[\\]"]').eq(0).trigger('change');
} else {
- OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');
+ OCP.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');
$('#userMountingBackends').addClass('hidden');
}
OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('files_external', 'Saved')}});
@@ -1342,7 +1342,7 @@ $(document).ready(function() {
}).get();
userMountingBackends = userMountingBackends.concat(deprecatedBackends);
- OC.AppConfig.setValue('files_external', 'user_mounting_backends', userMountingBackends.join());
+ OCP.AppConfig.setValue('files_external', 'user_mounting_backends', userMountingBackends.join());
OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('files_external', 'Saved')}});
// disable allowUserMounting
diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php
index a7366a32a06..04a34fba903 100644
--- a/apps/provisioning_api/appinfo/routes.php
+++ b/apps/provisioning_api/appinfo/routes.php
@@ -26,12 +26,7 @@
*
*/
-use OCA\Provisioning_API\Apps;
-use OCA\Provisioning_API\Users;
-use OCP\API;
-
-$app = new \OCA\Provisioning_API\AppInfo\Application();
-$app->registerRoutes($this, [
+return [
'ocs' => [
// Apps
['root' => '/cloud', 'name' => 'Apps#getApps', 'url' => '/apps', 'verb' => 'GET'],
@@ -46,7 +41,7 @@ $app->registerRoutes($this, [
['root' => '/cloud', 'name' => 'Groups#deleteGroup', 'url' => '/groups/{groupId}', 'verb' => 'DELETE'],
['root' => '/cloud', 'name' => 'Groups#getSubAdminsOfGroup', 'url' => '/groups/{groupId}/subadmins', 'verb' => 'GET'],
- //Users
+ // Users
['root' => '/cloud', 'name' => 'Users#getUsers', 'url' => '/users', 'verb' => 'GET'],
['root' => '/cloud', 'name' => 'Users#addUser', 'url' => '/users', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'Users#getUser', 'url' => '/users/{userId}', 'verb' => 'GET'],
@@ -61,5 +56,11 @@ $app->registerRoutes($this, [
['root' => '/cloud', 'name' => 'Users#addSubAdmin', 'url' => '/users/{userId}/subadmins', 'verb' => 'POST'],
['root' => '/cloud', 'name' => 'Users#removeSubAdmin', 'url' => '/users/{userId}/subadmins', 'verb' => 'DELETE'],
+ // Config
+ ['name' => 'AppConfig#getApps', 'url' => '/api/v1/config/apps', 'verb' => 'GET'],
+ ['name' => 'AppConfig#getKeys', 'url' => '/api/v1/config/apps/{app}', 'verb' => 'GET'],
+ ['name' => 'AppConfig#getValue', 'url' => '/api/v1/config/apps/{app}/{key}', 'verb' => 'GET'],
+ ['name' => 'AppConfig#setValue', 'url' => '/api/v1/config/apps/{app}/{key}', 'verb' => 'POST'],
+ ['name' => 'AppConfig#deleteKey', 'url' => '/api/v1/config/apps/{app}/{key}', 'verb' => 'DELETE'],
],
-]);
+];
diff --git a/apps/provisioning_api/lib/Controller/AppConfigController.php b/apps/provisioning_api/lib/Controller/AppConfigController.php
new file mode 100644
index 00000000000..f710eda6529
--- /dev/null
+++ b/apps/provisioning_api/lib/Controller/AppConfigController.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Provisioning_API\Controller;
+
+
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCSController;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IRequest;
+
+class AppConfigController extends OCSController {
+
+ /** @var IConfig */
+ protected $config;
+
+ /** @var IAppConfig */
+ protected $appConfig;
+
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param IConfig $config
+ * @param IAppConfig $appConfig
+ */
+ public function __construct($appName,
+ IRequest $request,
+ IConfig $config,
+ IAppConfig $appConfig) {
+ parent::__construct($appName, $request);
+ $this->config = $config;
+ $this->appConfig = $appConfig;
+ }
+
+ /**
+ * @return DataResponse
+ */
+ public function getApps() {
+ return new DataResponse([
+ 'data' => $this->appConfig->getApps(),
+ ]);
+ }
+
+ /**
+ * @param string $app
+ * @return DataResponse
+ */
+ public function getKeys($app) {
+ try {
+ $this->verifyAppId($app);
+ } catch (\InvalidArgumentException $e) {
+ return new DataResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_FORBIDDEN);
+ }
+ return new DataResponse([
+ 'data' => $this->config->getAppKeys($app),
+ ]);
+ }
+
+ /**
+ * @param string $app
+ * @param string $key
+ * @param string $defaultValue
+ * @return DataResponse
+ */
+ public function getValue($app, $key, $defaultValue = '') {
+ try {
+ $this->verifyAppId($app);
+ } catch (\InvalidArgumentException $e) {
+ return new DataResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_FORBIDDEN);
+ }
+ return new DataResponse([
+ 'data' => $this->config->getAppValue($app, $key, $defaultValue),
+ ]);
+ }
+
+ /**
+ * @PasswordConfirmationRequired
+ * @param string $app
+ * @param string $key
+ * @param string $value
+ * @return DataResponse
+ */
+ public function setValue($app, $key, $value) {
+ try {
+ $this->verifyAppId($app);
+ $this->verifyConfigKey($app, $key);
+ } catch (\InvalidArgumentException $e) {
+ return new DataResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_FORBIDDEN);
+ }
+
+ $this->config->setAppValue($app, $key, $value);
+ return new DataResponse();
+ }
+
+ /**
+ * @PasswordConfirmationRequired
+ * @param string $app
+ * @param string $key
+ * @return DataResponse
+ */
+ public function deleteKey($app, $key) {
+ try {
+ $this->verifyAppId($app);
+ $this->verifyConfigKey($app, $key);
+ } catch (\InvalidArgumentException $e) {
+ return new DataResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_FORBIDDEN);
+ }
+
+ $this->config->deleteAppValue($app, $key);
+ return new DataResponse();
+ }
+
+ /**
+ * @param string $app
+ * @throws \InvalidArgumentException
+ */
+ protected function verifyAppId($app) {
+ if (\OC_App::cleanAppId($app) !== $app) {
+ throw new \InvalidArgumentException('Invalid app id given');
+ }
+ }
+
+ /**
+ * @param string $app
+ * @param string $key
+ * @throws \InvalidArgumentException
+ */
+ protected function verifyConfigKey($app, $key) {
+ if (in_array($key, ['installed_version', 'enabled', 'types'])) {
+ throw new \InvalidArgumentException('The given key can not be set');
+ }
+
+ if ($app === 'core' && (strpos($key, 'public_') === 0 || strpos($key, 'remote_') === 0)) {
+ throw new \InvalidArgumentException('The given key can not be set');
+ }
+ }
+}
diff --git a/apps/provisioning_api/tests/Controller/AppConfigControllerTest.php b/apps/provisioning_api/tests/Controller/AppConfigControllerTest.php
new file mode 100644
index 00000000000..b7cb76c77c6
--- /dev/null
+++ b/apps/provisioning_api/tests/Controller/AppConfigControllerTest.php
@@ -0,0 +1,382 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Provisioning_API\Tests\Controller;
+
+
+use OCA\Provisioning_API\Controller\AppConfigController;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IRequest;
+use Test\TestCase;
+
+/**
+ * Class AppConfigControllerTest
+ *
+ * @package OCA\Provisioning_API\Tests
+ */
+class AppConfigControllerTest extends TestCase {
+
+ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+ private $config;
+ /** @var IAppConfig|\PHPUnit_Framework_MockObject_MockObject */
+ private $appConfig;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->config = $this->createMock(IConfig::class);
+ $this->appConfig = $this->createMock(IAppConfig::class);
+
+ }
+
+ /**
+ * @param string[] $methods
+ * @return AppConfigController|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected function getInstance(array $methods = []) {
+ $request = $this->createMock(IRequest::class);
+
+ if (empty($methods)) {
+ return new AppConfigController(
+ 'provisioning_api',
+ $request,
+ $this->config,
+ $this->appConfig
+ );
+ } else {
+ return $this->getMockBuilder(AppConfigController::class)
+ ->setConstructorArgs([
+ 'provisioning_api',
+ $request,
+ $this->config,
+ $this->appConfig,
+ ])
+ ->setMethods($methods)
+ ->getMock();
+ }
+ }
+
+ public function testGetApps() {
+ $this->appConfig->expects($this->once())
+ ->method('getApps')
+ ->willReturn(['apps']);
+
+ $result = $this->getInstance()->getApps();
+ $this->assertInstanceOf(DataResponse::class, $result);
+ $this->assertSame(Http::STATUS_OK, $result->getStatus());
+ $this->assertEquals(['data' => ['apps']], $result->getData());
+ }
+
+ public function dataGetKeys() {
+ return [
+ ['app1 ', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
+ ['app2', ['keys'], null, Http::STATUS_OK],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetKeys
+ * @param string $app
+ * @param array|null $keys
+ * @param \Exception|null $throws
+ * @param int $status
+ */
+ public function testGetKeys($app, $keys, $throws, $status) {
+
+ $api = $this->getInstance(['verifyAppId']);
+ if ($throws instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app)
+ ->willThrowException($throws);
+
+ $this->config->expects($this->never())
+ ->method('getAppKeys');
+ } else {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+
+ $this->config->expects($this->once())
+ ->method('getAppKeys')
+ ->with($app)
+ ->willReturn($keys);
+ }
+
+ $result = $api->getKeys($app);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ $this->assertSame($status, $result->getStatus());
+ if ($throws instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
+ } else {
+ $this->assertEquals(['data' => $keys], $result->getData());
+ }
+ }
+
+ public function dataGetValue() {
+ return [
+ ['app1 ', null, null, null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
+ ['app2', 'key', 'default', 'return', null, Http::STATUS_OK],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetValue
+ * @param string $app
+ * @param string|null $key
+ * @param string|null $default
+ * @param string|null $return
+ * @param \Exception|null $throws
+ * @param int $status
+ */
+ public function testGetValue($app, $key, $default, $return, $throws, $status) {
+
+ $api = $this->getInstance(['verifyAppId']);
+ if ($throws instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app)
+ ->willThrowException($throws);
+
+ $this->config->expects($this->never())
+ ->method('getAppValue');
+ } else {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+
+ $this->config->expects($this->once())
+ ->method('getAppValue')
+ ->with($app, $key, $default)
+ ->willReturn($return);
+ }
+
+ $result = $api->getValue($app, $key, $default);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ $this->assertSame($status, $result->getStatus());
+ if ($throws instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
+ } else {
+ $this->assertEquals(['data' => $return], $result->getData());
+ }
+ }
+
+ public function dataSetValue() {
+ return [
+ ['app1 ', null, null, new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
+ ['app2', 'key', null, null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
+ ['app2', 'key', 'default', null, null, Http::STATUS_OK],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSetValue
+ * @param string $app
+ * @param string|null $key
+ * @param string|null $value
+ * @param \Exception|null $appThrows
+ * @param \Exception|null $keyThrows
+ * @param int $status
+ */
+ public function testSetValue($app, $key, $value, $appThrows, $keyThrows, $status) {
+
+ $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
+ if ($appThrows instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app)
+ ->willThrowException($appThrows);
+
+ $api->expects($this->never())
+ ->method('verifyConfigKey');
+ $this->config->expects($this->never())
+ ->method('setAppValue');
+ } else if ($keyThrows instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+ $api->expects($this->once())
+ ->method('verifyConfigKey')
+ ->with($app, $key)
+ ->willThrowException($keyThrows);
+
+ $this->config->expects($this->never())
+ ->method('setAppValue');
+ } else {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+ $api->expects($this->once())
+ ->method('verifyConfigKey')
+ ->with($app, $key);
+
+ $this->config->expects($this->once())
+ ->method('setAppValue')
+ ->with($app, $key, $value);
+ }
+
+ $result = $api->setValue($app, $key, $value);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ $this->assertSame($status, $result->getStatus());
+ if ($appThrows instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
+ } else if ($keyThrows instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
+ } else {
+ $this->assertEquals([], $result->getData());
+ }
+ }
+
+ public function dataDeleteValue() {
+ return [
+ ['app1 ', null, new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
+ ['app2', 'key', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
+ ['app2', 'key', null, null, Http::STATUS_OK],
+ ];
+ }
+
+ /**
+ * @dataProvider dataDeleteValue
+ * @param string $app
+ * @param string|null $key
+ * @param \Exception|null $appThrows
+ * @param \Exception|null $keyThrows
+ * @param int $status
+ */
+ public function testDeleteValue($app, $key, $appThrows, $keyThrows, $status) {
+
+ $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
+ if ($appThrows instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app)
+ ->willThrowException($appThrows);
+
+ $api->expects($this->never())
+ ->method('verifyConfigKey');
+ $this->config->expects($this->never())
+ ->method('deleteAppValue');
+ } else if ($keyThrows instanceof \Exception) {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+ $api->expects($this->once())
+ ->method('verifyConfigKey')
+ ->with($app, $key)
+ ->willThrowException($keyThrows);
+
+ $this->config->expects($this->never())
+ ->method('deleteAppValue');
+ } else {
+ $api->expects($this->once())
+ ->method('verifyAppId')
+ ->with($app);
+ $api->expects($this->once())
+ ->method('verifyConfigKey')
+ ->with($app, $key);
+
+ $this->config->expects($this->once())
+ ->method('deleteAppValue')
+ ->with($app, $key);
+ }
+
+ $result = $api->deleteKey($app, $key);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ $this->assertSame($status, $result->getStatus());
+ if ($appThrows instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
+ } else if ($keyThrows instanceof \Exception) {
+ $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
+ } else {
+ $this->assertEquals([], $result->getData());
+ }
+ }
+
+ public function testVerifyAppId() {
+ $api = $this->getInstance();
+ $this->invokePrivate($api, 'verifyAppId', ['activity']);
+ $this->assertTrue(true);
+ }
+
+ public function dataVerifyAppIdThrows() {
+ return [
+ ['activity..'],
+ ['activity/'],
+ ['activity\\'],
+ ['activity\0'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataVerifyAppIdThrows
+ * @expectedException \InvalidArgumentException
+ * @param string $app
+ */
+ public function testVerifyAppIdThrows($app) {
+ $api = $this->getInstance();
+ $this->invokePrivate($api, 'verifyAppId', [$app]);
+ }
+
+ public function dataVerifyConfigKey() {
+ return [
+ ['activity', 'abc'],
+ ['dav', 'public_route'],
+ ['files', 'remote_route'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataVerifyConfigKey
+ * @param string $app
+ * @param string $key
+ */
+ public function testVerifyConfigKey($app, $key) {
+ $api = $this->getInstance();
+ $this->invokePrivate($api, 'verifyConfigKey', [$app, $key]);
+ $this->assertTrue(true);
+ }
+
+ public function dataVerifyConfigKeyThrows() {
+ return [
+ ['activity', 'installed_version'],
+ ['calendar', 'enabled'],
+ ['contacts', 'types'],
+ ['core', 'public_files'],
+ ['core', 'public_dav'],
+ ['core', 'remote_files'],
+ ['core', 'remote_dav'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataVerifyConfigKeyThrows
+ * @expectedException \InvalidArgumentException
+ * @param string $app
+ * @param string $key
+ */
+ public function testVerifyConfigKeyThrows($app, $key) {
+ $api = $this->getInstance();
+ $this->invokePrivate($api, 'verifyConfigKey', [$app, $key]);
+ }
+}
diff --git a/apps/updatenotification/js/admin.js b/apps/updatenotification/js/admin.js
index 91d9f80b605..813ec48c87a 100644
--- a/apps/updatenotification/js/admin.js
+++ b/apps/updatenotification/js/admin.js
@@ -70,6 +70,6 @@ $(document).ready(function(){
$notificationTargetGroups.change(function(ev) {
var groups = ev.val || [];
groups = JSON.stringify(groups);
- OC.AppConfig.setValue('updatenotification', 'notify_groups', groups);
+ OCP.AppConfig.setValue('updatenotification', 'notify_groups', groups);
});
});