extends ICheck with scope and entity support, provide them as initialState

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
Arthur Schiwon 2019-09-05 15:52:11 +02:00
parent d2c8b939d5
commit c2a52813e2
No known key found for this signature in database
GPG Key ID: 7424F1874854DF23
11 changed files with 160 additions and 9 deletions

View File

@ -25,6 +25,7 @@ namespace OCA\WorkflowEngine\Check;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
use OCP\WorkflowEngine\ICheck;
use OCP\WorkflowEngine\IManager;
abstract class AbstractStringCheck implements ICheck {
@ -101,6 +102,16 @@ abstract class AbstractStringCheck implements ICheck {
}
}
public function supportedEntities(): array {
// universal by default
return [];
}
public function isAvailableForScope(int $scope): bool {
// admin only by default
return $scope === IManager::SCOPE_ADMIN;
}
/**
* @param string $pattern
* @param string $subject

View File

@ -22,6 +22,7 @@
namespace OCA\WorkflowEngine\Check;
use OCA\WorkflowEngine\Entity\File;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
@ -195,4 +196,8 @@ class FileMimeType extends AbstractStringCheck {
strpos($this->request->getPathInfo(), '/webdav/') === 0
);
}
public function supportedEntities(): array {
return [ File::class ];
}
}

View File

@ -22,6 +22,7 @@ declare(strict_types=1);
namespace OCA\WorkflowEngine\Check;
use OCA\WorkflowEngine\Entity\File;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
use OCP\IRequest;
@ -75,4 +76,12 @@ class FileName extends AbstractStringCheck {
}
return parent::executeStringCheck($operator, $checkValue, $actualValue);
}
public function supportedEntities(): array {
return [ File::class ];
}
public function isAvailableForScope(int $scope): bool {
return true;
}
}

View File

@ -22,6 +22,7 @@
namespace OCA\WorkflowEngine\Check;
use OCA\WorkflowEngine\Entity\File;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
use OCP\IRequest;
@ -116,4 +117,12 @@ class FileSize implements ICheck {
$this->size = $size;
return $this->size;
}
public function supportedEntities(): array {
return [ File::class ];
}
public function isAvailableForScope(int $scope): bool {
return true;
}
}

View File

@ -22,6 +22,7 @@
namespace OCA\WorkflowEngine\Check;
use OCA\WorkflowEngine\Entity\File;
use OCP\Files\Cache\ICache;
use OCP\Files\IHomeStorage;
use OCP\Files\Storage\IStorage;
@ -166,4 +167,12 @@ class FileSystemTags implements ICheck {
$dir = dirname($path);
return $dir === '.' ? '' : $dir;
}
public function supportedEntities(): array {
return [ File::class ];
}
public function isAvailableForScope(int $scope): bool {
return true;
}
}

View File

@ -126,4 +126,8 @@ class RequestTime implements ICheck {
throw new \UnexpectedValueException($this->l->t('The given end time is invalid'), 4);
}
}
public function isAvailableForScope(int $scope): bool {
return true;
}
}

View File

@ -79,4 +79,8 @@ class RequestUserAgent extends AbstractStringCheck {
protected function getActualValue() {
return (string) $this->request->getHeader('User-Agent');
}
public function isAvailableForScope(int $scope): bool {
return true;
}
}

View File

@ -21,10 +21,18 @@
namespace OCA\WorkflowEngine;
use OC\Files\Storage\Wrapper\Jail;
use Doctrine\DBAL\DBALException;
use OC\Cache\CappedMemoryCache;
use OCA\WorkflowEngine\Check\FileMimeType;
use OCA\WorkflowEngine\Check\FileName;
use OCA\WorkflowEngine\Check\FileSize;
use OCA\WorkflowEngine\Check\FileSystemTags;
use OCA\WorkflowEngine\Check\RequestRemoteAddress;
use OCA\WorkflowEngine\Check\RequestTime;
use OCA\WorkflowEngine\Check\RequestURL;
use OCA\WorkflowEngine\Check\RequestUserAgent;
use OCA\WorkflowEngine\Check\UserGroupMembership;
use OCA\WorkflowEngine\Entity\File;
use OCA\WorkflowEngine\Helper\ScopeContext;
use OCP\AppFramework\QueryException;
@ -80,6 +88,9 @@ class Manager implements IManager, IEntityAware {
/** @var IOperation[] */
protected $registeredOperators = [];
/** @var ICheck[] */
protected $registeredChecks = [];
/** @var ILogger */
protected $logger;
@ -510,6 +521,12 @@ class Manager implements IManager, IEntityAware {
throw new \UnexpectedValueException($this->l->t('Check %s is invalid', [$class]));
}
if (!empty($instance->supportedEntities())
&& !in_array(get_class($entity), $instance->supportedEntities())
) {
throw new \UnexpectedValueException($this->l->t('Check %s is not allowed with this entity', [$class]));
}
$instance->validateCheck($check['operator'], $check['value']);
}
}
@ -653,11 +670,14 @@ class Manager implements IManager, IEntityAware {
}
/**
* Listen to 'OCP/WorkflowEngine::registerEntities' at the EventDispatcher
* for registering your entities
*
* @since 18.0.0
* @return ICheck[]
*/
public function getCheckList(): array {
$this->eventDispatcher->dispatch(IManager::EVENT_NAME_REG_CHECK, new GenericEvent($this));
return array_merge($this->getBuildInChecks(), $this->registeredChecks);
}
public function registerEntity(IEntity $entity): void {
$this->registeredEntities[get_class($entity)] = $entity;
}
@ -666,6 +686,10 @@ class Manager implements IManager, IEntityAware {
$this->registeredOperators[get_class($operator)] = $operator;
}
public function registerCheck(ICheck $check): void {
$this->registeredChecks[get_class($check)] = $check;
}
/**
* @return IEntity[]
*/
@ -693,4 +717,26 @@ class Manager implements IManager, IEntityAware {
return [];
}
}
/**
* @return IEntity[]
*/
protected function getBuildInChecks(): array {
try {
return [
$this->container->query(FileMimeType::class),
$this->container->query(FileName::class),
$this->container->query(FileSize::class),
$this->container->query(FileSystemTags::class),
$this->container->query(RequestRemoteAddress::class),
$this->container->query(RequestTime::class),
$this->container->query(RequestURL::class),
$this->container->query(RequestUserAgent::class),
$this->container->query(UserGroupMembership::class),
];
} catch (QueryException $e) {
$this->logger->logException($e);
return [];
}
}
}

View File

@ -30,6 +30,7 @@ use OCP\AppFramework\Http\TemplateResponse;
use OCP\IInitialStateService;
use OCP\IL10N;
use OCP\Settings\ISettings;
use OCP\WorkflowEngine\ICheck;
use OCP\WorkflowEngine\IComplexOperation;
use OCP\WorkflowEngine\IEntity;
use OCP\WorkflowEngine\IEntityEvent;
@ -94,6 +95,13 @@ abstract class ASettings implements ISettings {
$this->operatorsToArray($operators)
);
$checks = $this->manager->getCheckList();
$this->initialStateService->provideInitialState(
Application::APP_ID,
'checks',
$this->checksToArray($checks)
);
$this->initialStateService->provideInitialState(
Application::APP_ID,
'scope',
@ -156,4 +164,17 @@ abstract class ASettings implements ISettings {
];
}, $operators);
}
private function checksToArray(array $checks) {
$checks = array_filter($checks, function(ICheck $check) {
return $check->isAvailableForScope($this->getScope());
});
return array_map(function (ICheck $check) {
return [
'id' => get_class($check),
'supportedEntities' => $check->supportedEntities(),
];
}, $checks);
}
}

View File

@ -55,4 +55,28 @@ interface ICheck {
* @since 9.1
*/
public function validateCheck($operator, $value);
/**
* returns a list of Entities the checker supports. The values must match
* the class name of the entity.
*
* An empty result means the check is universally available.
*
* @since 18.0.0
*/
public function supportedEntities(): array;
/**
* returns whether the operation can be used in the requested scope.
*
* Scope IDs are defined as constants in OCP\WorkflowEngine\IManager. At
* time of writing these are SCOPE_ADMIN and SCOPE_USER.
*
* For possibly unknown future scopes the recommended behaviour is: if
* user scope is permitted, the default behaviour should return `true`,
* otherwise `false`.
*
* @since 18.0.0
*/
public function isAvailableForScope(int $scope): bool;
}

View File

@ -39,6 +39,7 @@ interface IManager {
const EVENT_NAME_REG_OPERATION = 'OCP\WorkflowEngine::registerOperations';
const EVENT_NAME_REG_ENTITY = 'OCP\WorkflowEngine::registerEntities';
const EVENT_NAME_REG_CHECK = 'OCP\WorkflowEngine::registerChecks';
/**
* @param IStorage $storage
@ -56,18 +57,26 @@ interface IManager {
public function getMatchingOperations($class, $returnFirstMatchingOperationOnly = true);
/**
* Listen to 'OCP/WorkflowEngine::registerEntities' at the EventDispatcher
* for registering your entities
* Listen to `\OCP\WorkflowEngine::EVENT_NAME_REG_ENTITY` at the
* EventDispatcher for registering your entities.
*
* @since 18.0.0
*/
public function registerEntity(IEntity $entity): void;
/**
* Listen to 'OCP/WorkflowEngine::registerOperators' at the EventDispatcher
* for registering your operators
* Listen to `\OCP\WorkflowEngine::EVENT_NAME_REG_OPERATION` at the
* EventDispatcher for registering your operators.
*
* @since 18.0.0
*/
public function registerOperation(IOperation $operator): void;
/**
* Listen to `\OCP\WorkflowEngine::EVENT_NAME_REG_CHECK` at the
* EventDispatcher for registering your operators.
*
* @since 18.0.0
*/
public function registerCheck(ICheck $check): void;
}