mirror of
https://github.com/nextcloud/server.git
synced 2026-06-09 08:44:07 -04:00
Merge pull request #59610 from nextcloud/feat/versions-wfe
feat(files_versions): allow to block version creation using WFE
This commit is contained in:
commit
f8f5e9e7f9
14 changed files with 215 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ return array(
|
|||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'OCA\\Files_Versions\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\Files_Versions\\BackgroundJob\\ExpireVersions' => $baseDir . '/../lib/BackgroundJob/ExpireVersions.php',
|
||||
'OCA\\Files_Versions\\BlockVersioningOperation' => $baseDir . '/../lib/BlockVersioningOperation.php',
|
||||
'OCA\\Files_Versions\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
|
||||
'OCA\\Files_Versions\\Command\\CleanUp' => $baseDir . '/../lib/Command/CleanUp.php',
|
||||
'OCA\\Files_Versions\\Command\\Expire' => $baseDir . '/../lib/Command/Expire.php',
|
||||
|
|
@ -20,10 +21,12 @@ return array(
|
|||
'OCA\\Files_Versions\\Events\\VersionCreatedEvent' => $baseDir . '/../lib/Events/VersionCreatedEvent.php',
|
||||
'OCA\\Files_Versions\\Events\\VersionRestoredEvent' => $baseDir . '/../lib/Events/VersionRestoredEvent.php',
|
||||
'OCA\\Files_Versions\\Expiration' => $baseDir . '/../lib/Expiration.php',
|
||||
'OCA\\Files_Versions\\Listener\\CreateVersionListenerForWorkflow' => $baseDir . '/../lib/Listener/CreateVersionListenerForWorkflow.php',
|
||||
'OCA\\Files_Versions\\Listener\\FileEventsListener' => $baseDir . '/../lib/Listener/FileEventsListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LegacyRollbackListener' => $baseDir . '/../lib/Listener/LegacyRollbackListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => $baseDir . '/../lib/Listener/LoadAdditionalListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\RegisterWorkflowIntegrationListener' => $baseDir . '/../lib/Listener/RegisterWorkflowIntegrationListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\VersionAuthorListener' => $baseDir . '/../lib/Listener/VersionAuthorListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\VersionStorageMoveListener' => $baseDir . '/../lib/Listener/VersionStorageMoveListener.php',
|
||||
'OCA\\Files_Versions\\Migration\\Version1020Date20221114144058' => $baseDir . '/../lib/Migration/Version1020Date20221114144058.php',
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class ComposerStaticInitFiles_Versions
|
|||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'OCA\\Files_Versions\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
|
||||
'OCA\\Files_Versions\\BackgroundJob\\ExpireVersions' => __DIR__ . '/..' . '/../lib/BackgroundJob/ExpireVersions.php',
|
||||
'OCA\\Files_Versions\\BlockVersioningOperation' => __DIR__ . '/..' . '/../lib/BlockVersioningOperation.php',
|
||||
'OCA\\Files_Versions\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
|
||||
'OCA\\Files_Versions\\Command\\CleanUp' => __DIR__ . '/..' . '/../lib/Command/CleanUp.php',
|
||||
'OCA\\Files_Versions\\Command\\Expire' => __DIR__ . '/..' . '/../lib/Command/Expire.php',
|
||||
|
|
@ -35,10 +36,12 @@ class ComposerStaticInitFiles_Versions
|
|||
'OCA\\Files_Versions\\Events\\VersionCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/VersionCreatedEvent.php',
|
||||
'OCA\\Files_Versions\\Events\\VersionRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/VersionRestoredEvent.php',
|
||||
'OCA\\Files_Versions\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
|
||||
'OCA\\Files_Versions\\Listener\\CreateVersionListenerForWorkflow' => __DIR__ . '/..' . '/../lib/Listener/CreateVersionListenerForWorkflow.php',
|
||||
'OCA\\Files_Versions\\Listener\\FileEventsListener' => __DIR__ . '/..' . '/../lib/Listener/FileEventsListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LegacyRollbackListener' => __DIR__ . '/..' . '/../lib/Listener/LegacyRollbackListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\RegisterWorkflowIntegrationListener' => __DIR__ . '/..' . '/../lib/Listener/RegisterWorkflowIntegrationListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\VersionAuthorListener' => __DIR__ . '/..' . '/../lib/Listener/VersionAuthorListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\VersionStorageMoveListener' => __DIR__ . '/..' . '/../lib/Listener/VersionStorageMoveListener.php',
|
||||
'OCA\\Files_Versions\\Migration\\Version1020Date20221114144058' => __DIR__ . '/..' . '/../lib/Migration/Version1020Date20221114144058.php',
|
||||
|
|
|
|||
|
|
@ -12,11 +12,14 @@ use OCA\DAV\Connector\Sabre\Principal;
|
|||
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
||||
use OCA\Files\Event\LoadSidebar;
|
||||
use OCA\Files_Versions\Capabilities;
|
||||
use OCA\Files_Versions\Events\CreateVersionEvent;
|
||||
use OCA\Files_Versions\Events\VersionRestoredEvent;
|
||||
use OCA\Files_Versions\Listener\CreateVersionListenerForWorkflow;
|
||||
use OCA\Files_Versions\Listener\FileEventsListener;
|
||||
use OCA\Files_Versions\Listener\LegacyRollbackListener;
|
||||
use OCA\Files_Versions\Listener\LoadAdditionalListener;
|
||||
use OCA\Files_Versions\Listener\LoadSidebarListener;
|
||||
use OCA\Files_Versions\Listener\RegisterWorkflowIntegrationListener;
|
||||
use OCA\Files_Versions\Listener\VersionAuthorListener;
|
||||
use OCA\Files_Versions\Listener\VersionStorageMoveListener;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
|
|
@ -37,6 +40,8 @@ use OCP\Files\Events\Node\NodeDeletedEvent;
|
|||
use OCP\Files\Events\Node\NodeRenamedEvent;
|
||||
use OCP\Files\Events\Node\NodeTouchedEvent;
|
||||
use OCP\Files\Events\Node\NodeWrittenEvent;
|
||||
use OCP\WorkflowEngine\Events\LoadSettingsScriptsEvent;
|
||||
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
|
@ -86,8 +91,12 @@ class Application extends App implements IBootstrap {
|
|||
|
||||
// we add the version author listener with lower priority to make sure new versions already are created by FileEventsListener
|
||||
$context->registerEventListener(NodeWrittenEvent::class, VersionAuthorListener::class, -1);
|
||||
|
||||
$context->registerEventListener(VersionRestoredEvent::class, LegacyRollbackListener::class);
|
||||
|
||||
// WFE integration
|
||||
$context->registerEventListener(RegisterOperationsEvent::class, RegisterWorkflowIntegrationListener::class);
|
||||
$context->registerEventListener(LoadSettingsScriptsEvent::class, RegisterWorkflowIntegrationListener::class);
|
||||
$context->registerEventListener(CreateVersionEvent::class, CreateVersionListenerForWorkflow::class);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
|
|
|
|||
95
apps/files_versions/lib/BlockVersioningOperation.php
Normal file
95
apps/files_versions/lib/BlockVersioningOperation.php
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Files_Versions;
|
||||
|
||||
use OCA\Files_Versions\Events\CreateVersionEvent;
|
||||
use OCA\WorkflowEngine\Entity\File as FileEntity;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\WorkflowEngine\IComplexOperation;
|
||||
use OCP\WorkflowEngine\IManager;
|
||||
use OCP\WorkflowEngine\IRuleMatcher;
|
||||
use OCP\WorkflowEngine\ISpecificOperation;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class BlockVersioningOperation implements ISpecificOperation, IComplexOperation {
|
||||
|
||||
public function __construct(
|
||||
private readonly IL10N $l10n,
|
||||
private readonly FileEntity $fileEntity,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly IURLGenerator $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getEntityId(): string {
|
||||
return FileEntity::class;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getDisplayName(): string {
|
||||
return $this->l10n->t('Block file versioning');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getDescription(): string {
|
||||
return $this->l10n->t('Automatic tag based blocking of file version creation.');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getIcon(): string {
|
||||
return $this->urlGenerator->imagePath('files_versions', 'app.svg');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function isAvailableForScope(int $scope): bool {
|
||||
return $scope === IManager::SCOPE_ADMIN;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function validateOperation(string $name, array $checks, string $operation): void {
|
||||
if (empty($checks)) {
|
||||
throw new \UnexpectedValueException($this->l10n->t('No rule given'));
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function onEvent(string $eventName, Event $event, IRuleMatcher $ruleMatcher): void {
|
||||
if ($eventName !== CreateVersionEvent::class || !($event instanceof CreateVersionEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $event->getNode();
|
||||
$path = $node->getInternalPath();
|
||||
|
||||
$ruleMatcher->setFileInfo(
|
||||
$node->getStorage(),
|
||||
$path,
|
||||
$node instanceof Folder,
|
||||
);
|
||||
$ruleMatcher->setEntitySubject($this->fileEntity, $node);
|
||||
$ruleMatcher->setOperation($this);
|
||||
$flows = $ruleMatcher->getFlows();
|
||||
|
||||
if ($flows !== []) {
|
||||
$this->logger->debug('Blocking version creation due to matching workflow rules', [
|
||||
'path' => $path,
|
||||
]);
|
||||
$event->disableVersions();
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getTriggerHint(): string {
|
||||
return $this->l10n->t('A new version is created'); // TRANSLATORS: This will be shown as "When: " "A new version is created"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Files_Versions\Listener;
|
||||
|
||||
use OCA\Files_Versions\BlockVersioningOperation;
|
||||
use OCA\Files_Versions\Events\CreateVersionEvent;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\WorkflowEngine\IManager;
|
||||
|
||||
/** @template-implements IEventListener<CreateVersionEvent> */
|
||||
class CreateVersionListenerForWorkflow implements IEventListener {
|
||||
|
||||
public function __construct(
|
||||
private IManager $manager,
|
||||
private BlockVersioningOperation $operation,
|
||||
) {
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function handle(Event $event): void {
|
||||
if (!($event instanceof CreateVersionEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->operation->onEvent(
|
||||
$event::class,
|
||||
$event,
|
||||
$this->manager->getRuleMatcher(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Files_Versions\Listener;
|
||||
|
||||
use OCA\Files_Versions\BlockVersioningOperation;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
use OCP\Util;
|
||||
use OCP\WorkflowEngine\Events\LoadSettingsScriptsEvent;
|
||||
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;
|
||||
|
||||
/** @template-implements IEventListener<RegisterOperationsEvent|LoadSettingsScriptsEvent> */
|
||||
class RegisterWorkflowIntegrationListener implements IEventListener {
|
||||
|
||||
public function __construct(
|
||||
private readonly BlockVersioningOperation $operation,
|
||||
) {
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function handle(Event $event): void {
|
||||
if ($event instanceof RegisterOperationsEvent) {
|
||||
$event->registerOperation($this->operation);
|
||||
} elseif ($event instanceof LoadSettingsScriptsEvent) {
|
||||
Util::addScript('files_versions', 'workflow', 'workflowengine');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -205,6 +205,7 @@ class Storage {
|
|||
}
|
||||
|
||||
$event = new CreateVersionEvent($file);
|
||||
$eventDispatcher->dispatchTyped($event);
|
||||
$eventDispatcher->dispatch('OCA\Files_Versions::createVersion', $event);
|
||||
if ($event->shouldCreateVersion() === false) {
|
||||
return false;
|
||||
|
|
|
|||
12
apps/files_versions/src/workflow.ts
Normal file
12
apps/files_versions/src/workflow.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
globalThis.OCA.WorkflowEngine.registerOperator({
|
||||
id: 'OCA\\Files_Versions\\BlockVersioningOperation',
|
||||
color: '#ff5900',
|
||||
operation: 'deny',
|
||||
})
|
||||
})
|
||||
|
|
@ -48,6 +48,7 @@ const modules = {
|
|||
},
|
||||
files_versions: {
|
||||
'sidebar-tab': resolve(import.meta.dirname, 'apps/files_versions/src', 'sidebar_tab.ts'),
|
||||
workflow: resolve(import.meta.dirname, 'apps/files_versions/src', 'workflow.ts'),
|
||||
},
|
||||
oauth2: {
|
||||
'settings-admin': resolve(import.meta.dirname, 'apps/oauth2/src', 'settings-admin.ts'),
|
||||
|
|
|
|||
1
dist/files_versions-workflow.css
vendored
Normal file
1
dist/files_versions-workflow.css
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/* extracted by css-entry-points-plugin */
|
||||
2
dist/files_versions-workflow.mjs
vendored
Normal file
2
dist/files_versions-workflow.mjs
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
window.addEventListener("DOMContentLoaded",()=>{globalThis.OCA.WorkflowEngine.registerOperator({id:"OCA\\Files_Versions\\BlockVersioningOperation",color:"#ff5900",operation:"deny"})});
|
||||
//# sourceMappingURL=files_versions-workflow.mjs.map
|
||||
7
dist/files_versions-workflow.mjs.license
vendored
Normal file
7
dist/files_versions-workflow.mjs.license
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
||||
|
||||
This file is generated from multiple sources. Included packages:
|
||||
- nextcloud-ui
|
||||
- version: 1.0.0
|
||||
- license: AGPL-3.0-or-later
|
||||
1
dist/files_versions-workflow.mjs.map
vendored
Normal file
1
dist/files_versions-workflow.mjs.map
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"files_versions-workflow.mjs","sources":["../build/frontend/apps/files_versions/src/workflow.ts"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nwindow.addEventListener('DOMContentLoaded', () => {\n\tglobalThis.OCA.WorkflowEngine.registerOperator({\n\t\tid: 'OCA\\\\Files_Versions\\\\BlockVersioningOperation',\n\t\tcolor: '#ff5900',\n\t\toperation: 'deny',\n\t})\n})\n"],"names":[],"mappings":"AAKA,OAAO,iBAAiB,mBAAoB,IAAM,CACjD,WAAW,IAAI,eAAe,iBAAiB,CAC9C,GAAI,gDACJ,MAAO,UACP,UAAW,MAAA,CACX,CACF,CAAC"}
|
||||
7
dist/files_versions-workflow.mjs.map.license
vendored
Normal file
7
dist/files_versions-workflow.mjs.map.license
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
||||
|
||||
This file is generated from multiple sources. Included packages:
|
||||
- nextcloud-ui
|
||||
- version: 1.0.0
|
||||
- license: AGPL-3.0-or-later
|
||||
Loading…
Reference in a new issue