Add Rich Object Definitions and a validator

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2016-10-12 12:08:42 +02:00
parent f7f2711547
commit 2098648850
No known key found for this signature in database
GPG Key ID: E166FD8976B3BAC8
6 changed files with 446 additions and 0 deletions

View File

@ -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

View File

@ -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];
}
}

View File

@ -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);
}

View File

@ -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 {
}

View File

@ -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"
}
}
}
}

View File

@ -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',
],
]);
}
}