summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2016-10-12 12:08:42 +0200
committerJoas Schilling <coding@schilljs.com>2016-10-20 12:14:51 +0200
commit20986488505616654177da1f861238f0232656fa (patch)
tree9019b92a582b25b5dd1dbbef73c16116692ff686
parentf7f271154702883367f418c4f9e35418ab4219ef (diff)
downloadnextcloud-server-20986488505616654177da1f861238f0232656fa.tar.gz
nextcloud-server-20986488505616654177da1f861238f0232656fa.zip
Add Rich Object Definitions and a validator
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php6
-rw-r--r--lib/private/RichObjectStrings/Validator.php108
-rw-r--r--lib/public/RichObjectStrings/IValidator.php39
-rw-r--r--lib/public/RichObjectStrings/InvalidObjectExeption.php31
-rw-r--r--lib/public/RichObjectStrings/definitions.json209
-rw-r--r--tests/lib/RichObjectStrings/ValidatorTest.php53
6 files changed, 446 insertions, 0 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 21d5eaa9503..b2fdf86d9c2 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -44,10 +44,12 @@ use OC\AppFramework\Middleware\Security\SecurityMiddleware;
use OC\AppFramework\Middleware\SessionMiddleware;
use OC\AppFramework\Utility\SimpleContainer;
use OC\Core\Middleware\TwoFactorMiddleware;
+use OC\RichObjectStrings\Validator;
use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer;
use OCP\Files\IAppData;
use OCP\Files\Mount\IMountManager;
+use OCP\RichObjectStrings\IValidator;
class DIContainer extends SimpleContainer implements IAppContainer {
@@ -330,6 +332,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getEncryptionManager();
});
+ $this->registerService(IValidator::class, function($c) {
+ return $c->query(Validator::class);
+ });
+
/**
* App Framework APIs
diff --git a/lib/private/RichObjectStrings/Validator.php b/lib/private/RichObjectStrings/Validator.php
new file mode 100644
index 00000000000..2729b4a3f1b
--- /dev/null
+++ b/lib/private/RichObjectStrings/Validator.php
@@ -0,0 +1,108 @@
+<?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 OC\RichObjectStrings;
+
+
+use OCP\RichObjectStrings\InvalidObjectExeption;
+use OCP\RichObjectStrings\IValidator;
+
+/**
+ * Class Validator
+ *
+ * @package OCP\RichObjectStrings
+ * @since 9.2.0
+ */
+class Validator implements IValidator {
+
+ /** @var array[] */
+ protected $definitions;
+
+ /** @var array[] */
+ protected $requiredParameters = [];
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->definitions = json_decode(file_get_contents(__DIR__ . '/../../public/RichObjectStrings/definitions.json'), true);
+ }
+
+ /**
+ * @param string $subject
+ * @param array[] $parameters
+ * @throws InvalidObjectExeption
+ * @since 9.2.0
+ */
+ public function validate($subject, array $parameters) {
+ $matches = [];
+ $result = preg_match_all('/\{([a-z0-9]+)\}/i', $subject, $matches);
+
+ if ($result === false) {
+ throw new InvalidObjectExeption();
+ }
+
+ if (!empty($matches[1])) {
+ foreach ($matches[1] as $parameter) {
+ if (!isset($parameters[$parameter])) {
+ throw new InvalidObjectExeption('Parameter is undefined');
+ } else {
+ $this->validateParameter($parameters[$parameter]);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param array $parameter
+ * @throws InvalidObjectExeption
+ */
+ protected function validateParameter(array $parameter) {
+ if (!isset($parameter['type']) || !isset($this->definitions[$parameter['type']])) {
+ throw new InvalidObjectExeption('Object type is undefined');
+ }
+
+ $requiredParameters = $this->getRequiredParameters($parameter['type']);
+ $missingKeys = array_diff($requiredParameters, array_keys($parameter));
+ if (!empty($missingKeys)) {
+ throw new InvalidObjectExeption('Object is invalid');
+ }
+ }
+
+ /**
+ * @param string $type
+ * @return string[]
+ */
+ protected function getRequiredParameters($type) {
+ if (isset($this->requiredParameters[$type])) {
+ return $this->requiredParameters[$type];
+ }
+
+ $this->requiredParameters[$type] = [];
+ foreach ($this->definitions[$type]['parameters'] as $parameter => $data) {
+ if ($data['required']) {
+ $this->requiredParameters[$type][] = $parameter;
+ }
+ }
+
+ return $this->requiredParameters[$type];
+ }
+}
diff --git a/lib/public/RichObjectStrings/IValidator.php b/lib/public/RichObjectStrings/IValidator.php
new file mode 100644
index 00000000000..bba098bdfc1
--- /dev/null
+++ b/lib/public/RichObjectStrings/IValidator.php
@@ -0,0 +1,39 @@
+<?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 OCP\RichObjectStrings;
+
+/**
+ * Class Validator
+ *
+ * @package OCP\RichObjectStrings
+ * @since 9.2.0
+ */
+interface IValidator {
+
+ /**
+ * @param string $subject
+ * @param array[] $parameters
+ * @throws InvalidObjectExeption
+ * @since 9.2.0
+ */
+ public function validate($subject, array $parameters);
+}
diff --git a/lib/public/RichObjectStrings/InvalidObjectExeption.php b/lib/public/RichObjectStrings/InvalidObjectExeption.php
new file mode 100644
index 00000000000..8bf597ebe90
--- /dev/null
+++ b/lib/public/RichObjectStrings/InvalidObjectExeption.php
@@ -0,0 +1,31 @@
+<?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 OCP\RichObjectStrings;
+
+/**
+ * Class InvalidObjectExeption
+ *
+ * @package OCP\RichObjectStrings
+ * @since 9.2.0
+ */
+class InvalidObjectExeption extends \InvalidArgumentException {
+}
diff --git a/lib/public/RichObjectStrings/definitions.json b/lib/public/RichObjectStrings/definitions.json
new file mode 100644
index 00000000000..581572eb345
--- /dev/null
+++ b/lib/public/RichObjectStrings/definitions.json
@@ -0,0 +1,209 @@
+{
+ "addressbook": {
+ "author": "Nextcloud",
+ "app": "dav",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the addressbook on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the addressbook which should be used in the visual representation",
+ "example": "Contacts"
+ }
+ }
+ },
+ "addressbook-contact": {
+ "author": "Nextcloud",
+ "app": "dav",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the contact on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the contact which should be used in the visual representation",
+ "example": "John Doe"
+ }
+ }
+ },
+ "announcement": {
+ "author": "Joas Schilling",
+ "app": "announcementcenter",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the announcement on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The announcement subject which should be used in the visual representation",
+ "example": "file.txt"
+ },
+ "link": {
+ "since": "9.2.0",
+ "required": false,
+ "description": "The full URL to the file",
+ "example": "http://localhost/index.php/apps/announcements/#23"
+ }
+ }
+ },
+ "calendar": {
+ "author": "Nextcloud",
+ "app": "dav",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the calendar on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the calendar which should be used in the visual representation",
+ "example": "Personal"
+ }
+ }
+ },
+ "calendar-event": {
+ "author": "Nextcloud",
+ "app": "dav",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the event on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the event which should be used in the visual representation",
+ "example": "Workout"
+ }
+ }
+ },
+ "file": {
+ "author": "Nextcloud",
+ "app": "dav",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the file on the instance",
+ "example": "42"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The file name which should be used in the visual representation",
+ "example": "file.txt"
+ },
+ "path": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The full path of the file for the user",
+ "example": "path/to/file.txt"
+ },
+ "link": {
+ "since": "9.2.0",
+ "required": false,
+ "description": "The full URL to the file",
+ "example": "http://localhost/index.php/f/42"
+ }
+ }
+ },
+ "systemtag": {
+ "author": "Nextcloud",
+ "app": "core",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the systemtag on the instance",
+ "example": "23"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the systemtag which should be used in the visual representation",
+ "example": "Project 1"
+ },
+ "visibility": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "If the user can see the systemtag",
+ "example": "1"
+ },
+ "assignable": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "If the user can assign the systemtag",
+ "example": "0"
+ }
+ }
+ },
+ "user": {
+ "author": "Nextcloud",
+ "app": "core",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the user on the instance",
+ "example": "johndoe"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the user which should be used in the visual representation",
+ "example": "John Doe"
+ },
+ "server": {
+ "since": "9.2.0",
+ "required": false,
+ "description": "The URL of the instance the user lives on",
+ "example": "localhost"
+ }
+ }
+ },
+ "user-group": {
+ "author": "Nextcloud",
+ "app": "core",
+ "since": "9.2.0",
+ "parameters": {
+ "id": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The id used to identify the group on the instance",
+ "example": "supportteam"
+ },
+ "name": {
+ "since": "9.2.0",
+ "required": true,
+ "description": "The display name of the group which should be used in the visual representation",
+ "example": "Support Team"
+ }
+ }
+ }
+}
diff --git a/tests/lib/RichObjectStrings/ValidatorTest.php b/tests/lib/RichObjectStrings/ValidatorTest.php
new file mode 100644
index 00000000000..b97388ab8e0
--- /dev/null
+++ b/tests/lib/RichObjectStrings/ValidatorTest.php
@@ -0,0 +1,53 @@
+<?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 Test\RichObjectStrings;
+
+
+use OC\RichObjectStrings\Validator;
+use Test\TestCase;
+
+class ValidatorTest extends TestCase {
+
+ public function test() {
+ $v = new Validator();
+ $v->validate('test', []);
+ $v->validate('test {string1} test {foo} test {bar}.', [
+ 'string1' => [
+ 'type' => 'user',
+ 'id' => 'johndoe',
+ 'name' => 'John Doe',
+ ],
+ 'foo' => [
+ 'type' => 'user-group',
+ 'id' => 'sample',
+ 'name' => 'Sample Group',
+ ],
+ 'bar' => [
+ 'type' => 'file',
+ 'id' => '42',
+ 'name' => 'test.txt',
+ 'path' => 'path/to/test.txt',
+ ],
+ ]);
+ }
+
+}