Skip to content

Commit

Permalink
Move to new operation interface for Nextcloud 18
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <jus@bitgrid.net>
  • Loading branch information
juliushaertl committed Oct 24, 2019
1 parent c5ea335 commit 05cf792
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 76 deletions.
78 changes: 5 additions & 73 deletions js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,77 +19,9 @@
*/

(function() {
OCA.FilesAccessControl = OCA.FilesAccessControl || {};

/**
* @class OCA.FilesAccessControl.Operation
*/
OCA.FilesAccessControl.Operation =
OCA.WorkflowEngine.Operation.extend({
defaults: {
'class': 'OCA\\FilesAccessControl\\Operation',
'name': '',
'checks': [],
'operation': 'deny'
}
});

/**
* @class OCA.FilesAccessControl.OperationsCollection
*
* collection for all configurated operations
*/
OCA.FilesAccessControl.OperationsCollection =
OCA.WorkflowEngine.OperationsCollection.extend({
model: OCA.FilesAccessControl.Operation
});

/**
* @class OCA.FilesAccessControl.OperationView
*
* this creates the view for a single operation
*/
OCA.FilesAccessControl.OperationView =
OCA.WorkflowEngine.OperationView.extend({
model: OCA.FilesAccessControl.Operation,
render: function() {
var $el = OCA.WorkflowEngine.OperationView.prototype.render.apply(this);
$el.find('input.operation-operation').addClass('hidden');
}
});

/**
* @class OCA.FilesAccessControl.OperationsView
*
* this creates the view for configured operations
*/
OCA.FilesAccessControl.OperationsView =
OCA.WorkflowEngine.OperationsView.extend({
initialize: function() {
OCA.WorkflowEngine.OperationsView.prototype.initialize.apply(this, [
'OCA\\FilesAccessControl\\Operation'
]);
},
renderOperation: function(operation) {
var subView = new OCA.FilesAccessControl.OperationView({
model: operation
});

OCA.WorkflowEngine.OperationsView.prototype.renderOperation.apply(this, [
subView
]);
}
});
OCA.WorkflowEngine.registerOperator({
id: 'OCA\\FilesAccessControl\\Operation',
color: '#ca2b2b',
operation: 'deny',
})
})();


$(document).ready(function() {
OC.SystemTags.collection.fetch({
success: function() {
new OCA.FilesAccessControl.OperationsView({
el: '#files_accesscontrol .rules',
collection: new OCA.FilesAccessControl.OperationsCollection()
});
}
});
});
10 changes: 10 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
namespace OCA\FilesAccessControl\AppInfo;

use OC\Files\Filesystem;
use OCA\FilesAccessControl\Operation;
use OCA\FilesAccessControl\StorageWrapper;
use OCA\WorkflowEngine\Manager;
use OCP\Files\Storage\IStorage;
use OCP\Util;
use OCP\WorkflowEngine\IManager;
use Symfony\Component\EventDispatcher\GenericEvent;

class Application extends \OCP\AppFramework\App {

Expand All @@ -37,6 +41,12 @@ public function __construct() {
*/
public function registerHooksAndListeners() {
Util::connectHook('OC_Filesystem', 'preSetup', $this, 'addStorageWrapper');
\OC::$server->getEventDispatcher()->addListener(IManager::EVENT_NAME_REG_OPERATION, function (GenericEvent $event) {
$operation = \OC::$server->query(Operation::class);
$event->getSubject()->registerOperation($operation);
\OC_Util::addScript('files_accesscontrol', 'admin');
});

}

/**
Expand Down
108 changes: 105 additions & 3 deletions lib/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,38 @@
namespace OCA\FilesAccessControl;


use OCA\WorkflowEngine\Entity\File;
use OCP\Files\ForbiddenException;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\WorkflowEngine\IComplexOperation;
use OCP\WorkflowEngine\IManager;
use OCP\WorkflowEngine\IOperation;
use OCP\WorkflowEngine\ISpecificOperation;
use Symfony\Component\EventDispatcher\GenericEvent;

class Operation implements IOperation{
class Operation implements IOperation, IComplexOperation, ISpecificOperation {
/** @var IManager */
protected $manager;

/** @var IL10N */
protected $l;

/** @var IURLGenerator */
protected $urlGenerator;

/** @var int */
protected $nestingLevel = 0;

/**
* @param IManager $manager
* @param IL10N $l
*/
public function __construct(IManager $manager, IL10N $l) {
public function __construct(IManager $manager, IL10N $l, IURLGenerator $urlGenerator) {
$this->manager = $manager;
$this->l = $l;
$this->urlGenerator = $urlGenerator;
}

/**
Expand Down Expand Up @@ -166,9 +175,102 @@ protected function isCreatingSkeletonFiles() {
* @param string $operation
* @throws \UnexpectedValueException
*/
public function validateOperation($name, array $checks, $operation) {
public function validateOperation(string $name, array $checks, string $operation): void {
if (empty($checks)) {
throw new \UnexpectedValueException($this->l->t('No rule given'));
}
}

/**
* returns a translated name to be presented in the web interface
*
* Example: "Automated tagging" (en), "Aŭtomata etikedado" (eo)
*
* @since 18.0.0
*/
public function getDisplayName(): string {
return $this->l->t('Files access control');
}

/**
* returns a translated, descriptive text to be presented in the web interface.
*
* It should be short and precise.
*
* Example: "Tag based automatic deletion of files after a given time." (en)
*
* @since 18.0.0
*/
public function getDescription(): string {
return $this->l->t('Block access to a file');
}

/**
* returns the URL to the icon of the operator for display in the web interface.
*
* Usually, the implementation would utilize the `imagePath()` method of the
* `\OCP\IURLGenerator` instance and simply return its result.
*
* Example implementation: return $this->urlGenerator->imagePath('myApp', 'cat.svg');
*
* @since 18.0.0
*/
public function getIcon(): string {
return $this->urlGenerator->imagePath('files_accesscontrol', 'app.svg');
}

/**
* 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 {
return $scope === IManager::SCOPE_ADMIN;
}

/**
* returns the id of the entity the operator is designed for
*
* Example: 'WorkflowEngine_Entity_File'
*
* @since 18.0.0
*/
public function getEntityId(): string {
return File::class;
}

/**
* As IComplexOperation chooses the triggering events itself, a hint has
* to be shown to the user so make clear when this operation is becoming
* active. This method returns such a translated string.
*
* Example: "When a file is accessed" (en)
*
* @since 18.0.0
*/
public function getTriggerHint(): string {
return $this->l->t('File is accessed');
}

/**
* Is being called by the workflow engine when an event was triggered that
* is configured for this operation. An evaluation whether the event
* qualifies for this operation to run has still to be done by the
* implementor.
*
* If the implementor is an IComplexOpe ration, this method will not be
* called automatically. It can be used or left as no-op by the implementor.
*
* @since 18.0.0
*/
public function onEvent(string $eventName, GenericEvent $event): void {
// TODO: Implement onEvent() method.
}
}

0 comments on commit 05cf792

Please sign in to comment.