mobile apps Signed-off-by: Julius Härtl <jus@bitgrid.net>tags/v18.0.0beta1
<name>Files</name> | <name>Files</name> | ||||
<summary>File Management</summary> | <summary>File Management</summary> | ||||
<description>File Management</description> | <description>File Management</description> | ||||
<version>1.13.0</version> | |||||
<version>1.13.1</version> | |||||
<licence>agpl</licence> | <licence>agpl</licence> | ||||
<author>Robin Appelman</author> | <author>Robin Appelman</author> | ||||
<author>Vincent Petry</author> | <author>Vincent Petry</author> |
'url' => '/api/v1/quickaccess/get/NodeType', | 'url' => '/api/v1/quickaccess/get/NodeType', | ||||
'verb' => 'GET', | 'verb' => 'GET', | ||||
], | ], | ||||
[ | |||||
'name' => 'DirectEditingView#edit', | |||||
'url' => '/directEditing/{token}', | |||||
'verb' => 'GET' | |||||
], | |||||
], | |||||
'ocs' => [ | |||||
[ | |||||
'name' => 'DirectEditing#get', | |||||
'url' => '/api/v1/directEditing', | |||||
'verb' => 'GET' | |||||
], | |||||
[ | |||||
'name' => 'DirectEditing#templates', | |||||
'url' => '/api/v1/directEditing/templates/{editorId}/{creatorId}', | |||||
'verb' => 'GET' | |||||
], | |||||
[ | |||||
'name' => 'DirectEditing#open', | |||||
'url' => '/api/v1/directEditing/open', | |||||
'verb' => 'POST' | |||||
], | |||||
[ | |||||
'name' => 'DirectEditing#create', | |||||
'url' => '/api/v1/directEditing/create', | |||||
'verb' => 'POST' | |||||
], | |||||
] | ] | ||||
] | ] | ||||
); | ); |
'OCA\\Files\\Activity\\Settings\\FileRestored' => $baseDir . '/../lib/Activity/Settings/FileRestored.php', | 'OCA\\Files\\Activity\\Settings\\FileRestored' => $baseDir . '/../lib/Activity/Settings/FileRestored.php', | ||||
'OCA\\Files\\App' => $baseDir . '/../lib/App.php', | 'OCA\\Files\\App' => $baseDir . '/../lib/App.php', | ||||
'OCA\\Files\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php', | 'OCA\\Files\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php', | ||||
'OCA\\Files\\BackgroundJob\\CleanupDirectEditingTokens' => $baseDir . '/../lib/BackgroundJob/CleanupDirectEditingTokens.php', | |||||
'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => $baseDir . '/../lib/BackgroundJob/CleanupFileLocks.php', | 'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => $baseDir . '/../lib/BackgroundJob/CleanupFileLocks.php', | ||||
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => $baseDir . '/../lib/BackgroundJob/DeleteOrphanedItems.php', | 'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => $baseDir . '/../lib/BackgroundJob/DeleteOrphanedItems.php', | ||||
'OCA\\Files\\BackgroundJob\\ScanFiles' => $baseDir . '/../lib/BackgroundJob/ScanFiles.php', | 'OCA\\Files\\BackgroundJob\\ScanFiles' => $baseDir . '/../lib/BackgroundJob/ScanFiles.php', | ||||
'OCA\\Files\\Command\\TransferOwnership' => $baseDir . '/../lib/Command/TransferOwnership.php', | 'OCA\\Files\\Command\\TransferOwnership' => $baseDir . '/../lib/Command/TransferOwnership.php', | ||||
'OCA\\Files\\Controller\\AjaxController' => $baseDir . '/../lib/Controller/AjaxController.php', | 'OCA\\Files\\Controller\\AjaxController' => $baseDir . '/../lib/Controller/AjaxController.php', | ||||
'OCA\\Files\\Controller\\ApiController' => $baseDir . '/../lib/Controller/ApiController.php', | 'OCA\\Files\\Controller\\ApiController' => $baseDir . '/../lib/Controller/ApiController.php', | ||||
'OCA\\Files\\Controller\\DirectEditingController' => $baseDir . '/../lib/Controller/DirectEditingController.php', | |||||
'OCA\\Files\\Controller\\DirectEditingViewController' => $baseDir . '/../lib/Controller/DirectEditingViewController.php', | |||||
'OCA\\Files\\Controller\\ViewController' => $baseDir . '/../lib/Controller/ViewController.php', | 'OCA\\Files\\Controller\\ViewController' => $baseDir . '/../lib/Controller/ViewController.php', | ||||
'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => $baseDir . '/../lib/Event/LoadAdditionalScriptsEvent.php', | 'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => $baseDir . '/../lib/Event/LoadAdditionalScriptsEvent.php', | ||||
'OCA\\Files\\Event\\LoadSidebar' => $baseDir . '/../lib/Event/LoadSidebar.php', | 'OCA\\Files\\Event\\LoadSidebar' => $baseDir . '/../lib/Event/LoadSidebar.php', |
'OCA\\Files\\Activity\\Settings\\FileRestored' => __DIR__ . '/..' . '/../lib/Activity/Settings/FileRestored.php', | 'OCA\\Files\\Activity\\Settings\\FileRestored' => __DIR__ . '/..' . '/../lib/Activity/Settings/FileRestored.php', | ||||
'OCA\\Files\\App' => __DIR__ . '/..' . '/../lib/App.php', | 'OCA\\Files\\App' => __DIR__ . '/..' . '/../lib/App.php', | ||||
'OCA\\Files\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php', | 'OCA\\Files\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php', | ||||
'OCA\\Files\\BackgroundJob\\CleanupDirectEditingTokens' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectEditingTokens.php', | |||||
'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupFileLocks.php', | 'OCA\\Files\\BackgroundJob\\CleanupFileLocks' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupFileLocks.php', | ||||
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOrphanedItems.php', | 'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOrphanedItems.php', | ||||
'OCA\\Files\\BackgroundJob\\ScanFiles' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScanFiles.php', | 'OCA\\Files\\BackgroundJob\\ScanFiles' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScanFiles.php', | ||||
'OCA\\Files\\Command\\TransferOwnership' => __DIR__ . '/..' . '/../lib/Command/TransferOwnership.php', | 'OCA\\Files\\Command\\TransferOwnership' => __DIR__ . '/..' . '/../lib/Command/TransferOwnership.php', | ||||
'OCA\\Files\\Controller\\AjaxController' => __DIR__ . '/..' . '/../lib/Controller/AjaxController.php', | 'OCA\\Files\\Controller\\AjaxController' => __DIR__ . '/..' . '/../lib/Controller/AjaxController.php', | ||||
'OCA\\Files\\Controller\\ApiController' => __DIR__ . '/..' . '/../lib/Controller/ApiController.php', | 'OCA\\Files\\Controller\\ApiController' => __DIR__ . '/..' . '/../lib/Controller/ApiController.php', | ||||
'OCA\\Files\\Controller\\DirectEditingController' => __DIR__ . '/..' . '/../lib/Controller/DirectEditingController.php', | |||||
'OCA\\Files\\Controller\\DirectEditingViewController' => __DIR__ . '/..' . '/../lib/Controller/DirectEditingViewController.php', | |||||
'OCA\\Files\\Controller\\ViewController' => __DIR__ . '/..' . '/../lib/Controller/ViewController.php', | 'OCA\\Files\\Controller\\ViewController' => __DIR__ . '/..' . '/../lib/Controller/ViewController.php', | ||||
'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => __DIR__ . '/..' . '/../lib/Event/LoadAdditionalScriptsEvent.php', | 'OCA\\Files\\Event\\LoadAdditionalScriptsEvent' => __DIR__ . '/..' . '/../lib/Event/LoadAdditionalScriptsEvent.php', | ||||
'OCA\\Files\\Event\\LoadSidebar' => __DIR__ . '/..' . '/../lib/Event/LoadSidebar.php', | 'OCA\\Files\\Event\\LoadSidebar' => __DIR__ . '/..' . '/../lib/Event/LoadSidebar.php', |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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 OCA\Files\Controller; | |||||
use Exception; | |||||
use OCP\AppFramework\Http; | |||||
use OCP\AppFramework\Http\DataResponse; | |||||
use OCP\AppFramework\OCSController; | |||||
use OCP\DirectEditing\ACreateEmpty; | |||||
use OCP\DirectEditing\ACreateFromTemplate; | |||||
use OCP\DirectEditing\IEditor; | |||||
use OCP\DirectEditing\IManager; | |||||
use OCP\DirectEditing\RegisterDirectEditorEvent; | |||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OCP\ILogger; | |||||
use OCP\IRequest; | |||||
use OCP\IURLGenerator; | |||||
class DirectEditingController extends OCSController { | |||||
/** @var IEventDispatcher */ | |||||
private $eventDispatcher; | |||||
/** @var IManager */ | |||||
private $directEditingManager; | |||||
/** @var IURLGenerator */ | |||||
private $urlGenerator; | |||||
/** @var ILogger */ | |||||
private $logger; | |||||
public function __construct($appName, IRequest $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge, | |||||
IEventDispatcher $eventDispatcher, IURLGenerator $urlGenerator, IManager $manager, ILogger $logger) { | |||||
parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge); | |||||
$this->eventDispatcher = $eventDispatcher; | |||||
$this->directEditingManager = $manager; | |||||
$this->logger = $logger; | |||||
$this->urlGenerator = $urlGenerator; | |||||
} | |||||
/** | |||||
* @NoAdminRequired | |||||
* | |||||
* @return DataResponse | |||||
*/ | |||||
public function get(): DataResponse { | |||||
$this->eventDispatcher->dispatch(RegisterDirectEditorEvent::class, new RegisterDirectEditorEvent($this->directEditingManager)); | |||||
$capabilities = [ | |||||
'editors' => [], | |||||
'creators' => [] | |||||
]; | |||||
/** | |||||
* @var string $id | |||||
* @var IEditor $editor | |||||
*/ | |||||
foreach ($this->directEditingManager->getEditors() as $id => $editor) { | |||||
$capabilities['editors'][$id] = [ | |||||
'name' => $editor->getName(), | |||||
'mimetypes' => $editor->getMimetypes(), | |||||
'optionalMimetypes' => $editor->getMimetypesOptional(), | |||||
'secure' => $editor->isSecure(), | |||||
]; | |||||
/** @var ACreateEmpty|ACreateFromTemplate $creator */ | |||||
foreach ($editor->getCreators() as $creator) { | |||||
$id = $creator->getId(); | |||||
$capabilities['creators'][$id] = [ | |||||
'id' => $id, | |||||
'name' => $creator->getName(), | |||||
'extension' => $creator->getExtension(), | |||||
'templates' => false | |||||
]; | |||||
if ($creator instanceof ACreateFromTemplate) { | |||||
$capabilities['creators'][$id]['templates'] = true; | |||||
} | |||||
} | |||||
} | |||||
return new DataResponse($capabilities); | |||||
} | |||||
/** | |||||
* @NoAdminRequired | |||||
*/ | |||||
public function create(string $path, string $editorId, string $creatorId, string $templateId = null): DataResponse { | |||||
$this->eventDispatcher->dispatch(RegisterDirectEditorEvent::class, new RegisterDirectEditorEvent($this->directEditingManager)); | |||||
try { | |||||
$token = $this->directEditingManager->create($path, $editorId, $creatorId, $templateId); | |||||
return new DataResponse([ | |||||
'url' => $this->urlGenerator->linkToRouteAbsolute('files.DirectEditingView.edit', ['token' => $token]) | |||||
]); | |||||
} catch (Exception $e) { | |||||
$this->logger->logException($e, ['message' => 'Exception when creating a new file through direct editing']); | |||||
return new DataResponse('Failed to create file', Http::STATUS_FORBIDDEN); | |||||
} | |||||
} | |||||
/** | |||||
* @NoAdminRequired | |||||
*/ | |||||
public function open(int $fileId, string $editorId = null): DataResponse { | |||||
$this->eventDispatcher->dispatch(RegisterDirectEditorEvent::class, new RegisterDirectEditorEvent($this->directEditingManager)); | |||||
try { | |||||
$token = $this->directEditingManager->open($fileId, $editorId); | |||||
return new DataResponse([ | |||||
'url' => $this->urlGenerator->linkToRouteAbsolute('files.DirectEditingView.edit', ['token' => $token]) | |||||
]); | |||||
} catch (Exception $e) { | |||||
$this->logger->logException($e, ['message' => 'Exception when opening a file through direct editing']); | |||||
return new DataResponse('Failed to open file', Http::STATUS_FORBIDDEN); | |||||
} | |||||
} | |||||
/** | |||||
* @NoAdminRequired | |||||
*/ | |||||
public function templates(string $editorId, string $creatorId): DataResponse { | |||||
$this->eventDispatcher->dispatch(RegisterDirectEditorEvent::class, new RegisterDirectEditorEvent($this->directEditingManager)); | |||||
try { | |||||
return new DataResponse($this->directEditingManager->getTemplates($editorId, $creatorId)); | |||||
} catch (Exception $e) { | |||||
$this->logger->logException($e); | |||||
return new DataResponse('Failed to open file', Http::STATUS_INTERNAL_SERVER_ERROR); | |||||
} | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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 OCA\Files\Controller; | |||||
use Exception; | |||||
use OCP\AppFramework\Controller; | |||||
use OCP\AppFramework\Http\NotFoundResponse; | |||||
use OCP\AppFramework\Http\Response; | |||||
use OCP\DirectEditing\IManager; | |||||
use OCP\DirectEditing\RegisterDirectEditorEvent; | |||||
use OCP\EventDispatcher\IEventDispatcher; | |||||
use OCP\ILogger; | |||||
use OCP\IRequest; | |||||
class DirectEditingViewController extends Controller { | |||||
/** @var IEventDispatcher */ | |||||
private $eventDispatcher; | |||||
/** @var IManager */ | |||||
private $directEditingManager; | |||||
/** @var ILogger */ | |||||
private $logger; | |||||
public function __construct($appName, IRequest $request, IEventDispatcher $eventDispatcher, IManager $manager, ILogger $logger) { | |||||
parent::__construct($appName, $request); | |||||
$this->eventDispatcher = $eventDispatcher; | |||||
$this->directEditingManager = $manager; | |||||
$this->logger = $logger; | |||||
} | |||||
/** | |||||
* @PublicPage | |||||
* @NoCSRFRequired | |||||
* | |||||
* @param string $token | |||||
* @return Response | |||||
*/ | |||||
public function edit(string $token): Response { | |||||
$this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager)); | |||||
try { | |||||
return $this->directEditingManager->edit($token); | |||||
} catch (Exception $e) { | |||||
$this->logger->logException($e); | |||||
return new NotFoundResponse(); | |||||
} | |||||
} | |||||
} |
<?php | |||||
declare(strict_types=1); | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\Core\Migrations; | |||||
use Closure; | |||||
use Doctrine\DBAL\Types\Type; | |||||
use OCP\DB\ISchemaWrapper; | |||||
use OCP\IDBConnection; | |||||
use OCP\Migration\SimpleMigrationStep; | |||||
use OCP\Migration\IOutput; | |||||
class Version18000Date20191014105105 extends SimpleMigrationStep { | |||||
/** @var IDBConnection */ | |||||
protected $connection; | |||||
public function __construct(IDBConnection $connection) { | |||||
$this->connection = $connection; | |||||
} | |||||
/** | |||||
* @param IOutput $output | |||||
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` | |||||
* @param array $options | |||||
* @return null|ISchemaWrapper | |||||
*/ | |||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { | |||||
/** @var ISchemaWrapper $schema */ | |||||
$schema = $schemaClosure(); | |||||
if (!$schema->hasTable('direct_edit')) { | |||||
$table = $schema->createTable('direct_edit'); | |||||
$table->addColumn('id', Type::BIGINT, [ | |||||
'autoincrement' => true, | |||||
'notnull' => true, | |||||
]); | |||||
$table->addColumn('editor_id', Type::STRING, [ | |||||
'notnull' => true, | |||||
'length' => 64, | |||||
]); | |||||
$table->addColumn('token', Type::STRING, [ | |||||
'notnull' => true, | |||||
'length' => 64, | |||||
]); | |||||
$table->addColumn('file_id', Type::BIGINT, [ | |||||
'notnull' => true, | |||||
]); | |||||
$table->addColumn('user_id', Type::STRING, [ | |||||
'notnull' => false, | |||||
'length' => 64, | |||||
]); | |||||
$table->addColumn('share_id', Type::BIGINT, [ | |||||
'notnull' => false | |||||
]); | |||||
$table->addColumn('timestamp', Type::BIGINT, [ | |||||
'notnull' => true, | |||||
'length' => 20, | |||||
'unsigned' => true, | |||||
]); | |||||
$table->addColumn('accessed', Type::BOOLEAN, [ | |||||
'notnull' => true, | |||||
'default' => false | |||||
]); | |||||
$table->setPrimaryKey(['id']); | |||||
$table->addIndex(['token']); | |||||
} | |||||
return $schema; | |||||
} | |||||
} |
['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'], | ['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'], | ||||
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'], | ['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'], | ||||
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'], | |||||
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'] | |||||
], | ], | ||||
]); | ]); | ||||
'OCP\\Diagnostics\\IEventLogger' => $baseDir . '/lib/public/Diagnostics/IEventLogger.php', | 'OCP\\Diagnostics\\IEventLogger' => $baseDir . '/lib/public/Diagnostics/IEventLogger.php', | ||||
'OCP\\Diagnostics\\IQuery' => $baseDir . '/lib/public/Diagnostics/IQuery.php', | 'OCP\\Diagnostics\\IQuery' => $baseDir . '/lib/public/Diagnostics/IQuery.php', | ||||
'OCP\\Diagnostics\\IQueryLogger' => $baseDir . '/lib/public/Diagnostics/IQueryLogger.php', | 'OCP\\Diagnostics\\IQueryLogger' => $baseDir . '/lib/public/Diagnostics/IQueryLogger.php', | ||||
'OCP\\DirectEditing\\ACreateEmpty' => $baseDir . '/lib/public/DirectEditing/ACreateEmpty.php', | |||||
'OCP\\DirectEditing\\ACreateFromTemplate' => $baseDir . '/lib/public/DirectEditing/ACreateFromTemplate.php', | |||||
'OCP\\DirectEditing\\ATemplate' => $baseDir . '/lib/public/DirectEditing/ATemplate.php', | |||||
'OCP\\DirectEditing\\IEditor' => $baseDir . '/lib/public/DirectEditing/IEditor.php', | |||||
'OCP\\DirectEditing\\IManager' => $baseDir . '/lib/public/DirectEditing/IManager.php', | |||||
'OCP\\DirectEditing\\IToken' => $baseDir . '/lib/public/DirectEditing/IToken.php', | |||||
'OCP\\DirectEditing\\RegisterDirectEditorEvent' => $baseDir . '/lib/public/DirectEditing/RegisterDirectEditorEvent.php', | |||||
'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => $baseDir . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php', | 'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => $baseDir . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php', | ||||
'OCP\\Encryption\\IEncryptionModule' => $baseDir . '/lib/public/Encryption/IEncryptionModule.php', | 'OCP\\Encryption\\IEncryptionModule' => $baseDir . '/lib/public/Encryption/IEncryptionModule.php', | ||||
'OCP\\Encryption\\IFile' => $baseDir . '/lib/public/Encryption/IFile.php', | 'OCP\\Encryption\\IFile' => $baseDir . '/lib/public/Encryption/IFile.php', | ||||
'OC\\Core\\Migrations\\Version16000Date20190428150708' => $baseDir . '/core/Migrations/Version16000Date20190428150708.php', | 'OC\\Core\\Migrations\\Version16000Date20190428150708' => $baseDir . '/core/Migrations/Version16000Date20190428150708.php', | ||||
'OC\\Core\\Migrations\\Version17000Date20190514105811' => $baseDir . '/core/Migrations/Version17000Date20190514105811.php', | 'OC\\Core\\Migrations\\Version17000Date20190514105811' => $baseDir . '/core/Migrations/Version17000Date20190514105811.php', | ||||
'OC\\Core\\Migrations\\Version18000Date20190920085628' => $baseDir . '/core/Migrations/Version18000Date20190920085628.php', | 'OC\\Core\\Migrations\\Version18000Date20190920085628' => $baseDir . '/core/Migrations/Version18000Date20190920085628.php', | ||||
'OC\\Core\\Migrations\\Version18000Date20191014105105' => $baseDir . '/core/Migrations/Version18000Date20191014105105.php', | |||||
'OC\\Core\\Notification\\RemoveLinkSharesNotifier' => $baseDir . '/core/Notification/RemoveLinkSharesNotifier.php', | 'OC\\Core\\Notification\\RemoveLinkSharesNotifier' => $baseDir . '/core/Notification/RemoveLinkSharesNotifier.php', | ||||
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php', | 'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php', | ||||
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', | 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', | ||||
'OC\\Diagnostics\\EventLogger' => $baseDir . '/lib/private/Diagnostics/EventLogger.php', | 'OC\\Diagnostics\\EventLogger' => $baseDir . '/lib/private/Diagnostics/EventLogger.php', | ||||
'OC\\Diagnostics\\Query' => $baseDir . '/lib/private/Diagnostics/Query.php', | 'OC\\Diagnostics\\Query' => $baseDir . '/lib/private/Diagnostics/Query.php', | ||||
'OC\\Diagnostics\\QueryLogger' => $baseDir . '/lib/private/Diagnostics/QueryLogger.php', | 'OC\\Diagnostics\\QueryLogger' => $baseDir . '/lib/private/Diagnostics/QueryLogger.php', | ||||
'OC\\DirectEditing\\Manager' => $baseDir . '/lib/private/DirectEditing/Manager.php', | |||||
'OC\\DirectEditing\\Token' => $baseDir . '/lib/private/DirectEditing/Token.php', | |||||
'OC\\Encryption\\DecryptAll' => $baseDir . '/lib/private/Encryption/DecryptAll.php', | 'OC\\Encryption\\DecryptAll' => $baseDir . '/lib/private/Encryption/DecryptAll.php', | ||||
'OC\\Encryption\\EncryptionWrapper' => $baseDir . '/lib/private/Encryption/EncryptionWrapper.php', | 'OC\\Encryption\\EncryptionWrapper' => $baseDir . '/lib/private/Encryption/EncryptionWrapper.php', | ||||
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => $baseDir . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php', | 'OC\\Encryption\\Exceptions\\DecryptionFailedException' => $baseDir . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php', |
'OCP\\Diagnostics\\IEventLogger' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IEventLogger.php', | 'OCP\\Diagnostics\\IEventLogger' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IEventLogger.php', | ||||
'OCP\\Diagnostics\\IQuery' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IQuery.php', | 'OCP\\Diagnostics\\IQuery' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IQuery.php', | ||||
'OCP\\Diagnostics\\IQueryLogger' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IQueryLogger.php', | 'OCP\\Diagnostics\\IQueryLogger' => __DIR__ . '/../../..' . '/lib/public/Diagnostics/IQueryLogger.php', | ||||
'OCP\\DirectEditing\\ACreateEmpty' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/ACreateEmpty.php', | |||||
'OCP\\DirectEditing\\ACreateFromTemplate' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/ACreateFromTemplate.php', | |||||
'OCP\\DirectEditing\\ATemplate' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/ATemplate.php', | |||||
'OCP\\DirectEditing\\IEditor' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/IEditor.php', | |||||
'OCP\\DirectEditing\\IManager' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/IManager.php', | |||||
'OCP\\DirectEditing\\IToken' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/IToken.php', | |||||
'OCP\\DirectEditing\\RegisterDirectEditorEvent' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/RegisterDirectEditorEvent.php', | |||||
'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => __DIR__ . '/../../..' . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php', | 'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => __DIR__ . '/../../..' . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php', | ||||
'OCP\\Encryption\\IEncryptionModule' => __DIR__ . '/../../..' . '/lib/public/Encryption/IEncryptionModule.php', | 'OCP\\Encryption\\IEncryptionModule' => __DIR__ . '/../../..' . '/lib/public/Encryption/IEncryptionModule.php', | ||||
'OCP\\Encryption\\IFile' => __DIR__ . '/../../..' . '/lib/public/Encryption/IFile.php', | 'OCP\\Encryption\\IFile' => __DIR__ . '/../../..' . '/lib/public/Encryption/IFile.php', | ||||
'OC\\Core\\Migrations\\Version16000Date20190428150708' => __DIR__ . '/../../..' . '/core/Migrations/Version16000Date20190428150708.php', | 'OC\\Core\\Migrations\\Version16000Date20190428150708' => __DIR__ . '/../../..' . '/core/Migrations/Version16000Date20190428150708.php', | ||||
'OC\\Core\\Migrations\\Version17000Date20190514105811' => __DIR__ . '/../../..' . '/core/Migrations/Version17000Date20190514105811.php', | 'OC\\Core\\Migrations\\Version17000Date20190514105811' => __DIR__ . '/../../..' . '/core/Migrations/Version17000Date20190514105811.php', | ||||
'OC\\Core\\Migrations\\Version18000Date20190920085628' => __DIR__ . '/../../..' . '/core/Migrations/Version18000Date20190920085628.php', | 'OC\\Core\\Migrations\\Version18000Date20190920085628' => __DIR__ . '/../../..' . '/core/Migrations/Version18000Date20190920085628.php', | ||||
'OC\\Core\\Migrations\\Version18000Date20191014105105' => __DIR__ . '/../../..' . '/core/Migrations/Version18000Date20191014105105.php', | |||||
'OC\\Core\\Notification\\RemoveLinkSharesNotifier' => __DIR__ . '/../../..' . '/core/Notification/RemoveLinkSharesNotifier.php', | 'OC\\Core\\Notification\\RemoveLinkSharesNotifier' => __DIR__ . '/../../..' . '/core/Notification/RemoveLinkSharesNotifier.php', | ||||
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php', | 'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php', | ||||
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', | 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', | ||||
'OC\\Diagnostics\\EventLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/EventLogger.php', | 'OC\\Diagnostics\\EventLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/EventLogger.php', | ||||
'OC\\Diagnostics\\Query' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/Query.php', | 'OC\\Diagnostics\\Query' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/Query.php', | ||||
'OC\\Diagnostics\\QueryLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/QueryLogger.php', | 'OC\\Diagnostics\\QueryLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/QueryLogger.php', | ||||
'OC\\DirectEditing\\Manager' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Manager.php', | |||||
'OC\\DirectEditing\\Token' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Token.php', | |||||
'OC\\Encryption\\DecryptAll' => __DIR__ . '/../../..' . '/lib/private/Encryption/DecryptAll.php', | 'OC\\Encryption\\DecryptAll' => __DIR__ . '/../../..' . '/lib/private/Encryption/DecryptAll.php', | ||||
'OC\\Encryption\\EncryptionWrapper' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionWrapper.php', | 'OC\\Encryption\\EncryptionWrapper' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionWrapper.php', | ||||
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php', | 'OC\\Encryption\\Exceptions\\DecryptionFailedException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php', |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use Doctrine\DBAL\FetchMode; | |||||
use OCP\AppFramework\Http\NotFoundResponse; | |||||
use OCP\AppFramework\Http\Response; | |||||
use OCP\AppFramework\Http\TemplateResponse; | |||||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||||
use OCP\DirectEditing\ACreateFromTemplate; | |||||
use OCP\DirectEditing\IEditor; | |||||
use \OCP\DirectEditing\IManager; | |||||
use OCP\DirectEditing\IToken; | |||||
use OCP\Files\File; | |||||
use OCP\Files\IRootFolder; | |||||
use OCP\Files\NotFoundException; | |||||
use OCP\IDBConnection; | |||||
use OCP\IUserSession; | |||||
use OCP\Security\ISecureRandom; | |||||
use OCP\Share\IShare; | |||||
class Manager implements IManager { | |||||
private const TOKEN_CLEANUP_TIME = 12 * 60 * 60 ; | |||||
public const TABLE_TOKENS = 'direct_edit'; | |||||
/** @var IEditor[] */ | |||||
private $editors; | |||||
/** @var IDBConnection */ | |||||
private $connection; | |||||
/** | |||||
* @var ISecureRandom | |||||
*/ | |||||
private $random; | |||||
private $userId; | |||||
private $rootFolder; | |||||
public function __construct( | |||||
ISecureRandom $random, | |||||
IDBConnection $connection, | |||||
IUserSession $userSession, | |||||
IRootFolder $rootFolder | |||||
) { | |||||
$this->random = $random; | |||||
$this->connection = $connection; | |||||
$this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null; | |||||
$this->rootFolder = $rootFolder; | |||||
} | |||||
public function registerDirectEditor(IEditor $directEditor): void { | |||||
$this->editors[$directEditor->getId()] = $directEditor; | |||||
} | |||||
public function getEditors(): array { | |||||
return $this->editors; | |||||
} | |||||
public function getTemplates(string $editor, string $type): array { | |||||
if (!array_key_exists($editor, $this->editors)) { | |||||
throw new \RuntimeException('No matching editor found'); | |||||
} | |||||
$templates = []; | |||||
foreach ($this->editors[$editor]->getCreators() as $creator) { | |||||
if ($creator instanceof ACreateFromTemplate && $creator->getId() === $type) { | |||||
$templates = $creator->getTemplates(); | |||||
} | |||||
} | |||||
return $templates; | |||||
} | |||||
public function create(string $path, string $editorId, string $creatorId, $templateId = null): string { | |||||
$userFolder = $this->rootFolder->getUserFolder($this->userId); | |||||
$file = $userFolder->newFile($path); | |||||
$editor = $this->getEditor($editorId); | |||||
$creators = $editor->getCreators(); | |||||
foreach ($creators as $creator) { | |||||
if ($creator->getId() === $creatorId) { | |||||
$creator->create($file, $creatorId, $templateId); | |||||
return $this->createToken($editorId, $file); | |||||
} | |||||
} | |||||
throw new \RuntimeException('No creator found'); | |||||
} | |||||
public function open(int $fileId, string $editorId = null): string { | |||||
$file = $this->rootFolder->getUserFolder($this->userId)->getById($fileId); | |||||
if (count($file) === 0 || !($file[0] instanceof File) || $file === null) { | |||||
throw new NotFoundException(); | |||||
} | |||||
/** @var File $file */ | |||||
$file = $file[0]; | |||||
if ($editorId === null) { | |||||
$editorId = $this->findEditorForFile($file); | |||||
} | |||||
return $this->createToken($editorId, $file); | |||||
} | |||||
private function findEditorForFile(File $file) { | |||||
foreach ($this->editors as $editor) { | |||||
if (in_array($file->getMimeType(), $editor->getMimetypes())) { | |||||
return $editor->getId(); | |||||
} | |||||
} | |||||
throw new \RuntimeException('No default editor found for files mimetype'); | |||||
} | |||||
public function edit(string $token): Response { | |||||
try { | |||||
/** @var IEditor $editor */ | |||||
$tokenObject = $this->getToken($token); | |||||
if ($tokenObject->hasBeenAccessed()) { | |||||
throw new \RuntimeException('Token has already been used and can only be used for followup requests'); | |||||
} | |||||
$editor = $this->getEditor($tokenObject->getEditor()); | |||||
$this->accessToken($token); | |||||
} catch (\Throwable $throwable) { | |||||
$this->invalidateToken($token); | |||||
return new NotFoundResponse(); | |||||
} | |||||
return $editor->open($tokenObject); | |||||
} | |||||
public function editSecure(File $file, string $editorId): TemplateResponse { | |||||
// TODO: Implementation in follow up | |||||
} | |||||
private function getEditor($editorId): IEditor { | |||||
if (!array_key_exists($editorId, $this->editors)) { | |||||
throw new \RuntimeException('No editor found'); | |||||
} | |||||
return $this->editors[$editorId]; | |||||
} | |||||
public function getToken(string $token): IToken { | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->select('*')->from(self::TABLE_TOKENS) | |||||
->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR))); | |||||
$result = $query->execute(); | |||||
if ($tokenRow = $result->fetch(FetchMode::ASSOCIATIVE)) { | |||||
return new Token($this, $tokenRow); | |||||
} | |||||
throw new \RuntimeException('Failed to validate the token'); | |||||
} | |||||
public function cleanup(): int { | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->delete(self::TABLE_TOKENS) | |||||
->where($query->expr()->lt('timestamp', $query->createNamedParameter(time() - self::TOKEN_CLEANUP_TIME))); | |||||
return $query->execute(); | |||||
} | |||||
public function refreshToken(string $token): bool { | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->update(self::TABLE_TOKENS) | |||||
->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT)) | |||||
->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR))); | |||||
$result = $query->execute(); | |||||
return $result !== 0; | |||||
} | |||||
public function invalidateToken(string $token): bool { | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->delete(self::TABLE_TOKENS) | |||||
->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR))); | |||||
$result = $query->execute(); | |||||
return $result !== 0; | |||||
} | |||||
public function accessToken(string $token): bool { | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->update(self::TABLE_TOKENS) | |||||
->set('accessed', $query->createNamedParameter(true, IQueryBuilder::PARAM_BOOL)) | |||||
->set('timestamp', $query->createNamedParameter(time(), IQueryBuilder::PARAM_INT)) | |||||
->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR))); | |||||
$result = $query->execute(); | |||||
return $result !== 0; | |||||
} | |||||
public function invokeTokenScope($userId): void { | |||||
\OC_User::setIncognitoMode(true); | |||||
\OC_User::setUserId($userId); | |||||
} | |||||
public function createToken($editorId, File $file, IShare $share = null): string { | |||||
$token = $this->random->generate(64, ISecureRandom::CHAR_HUMAN_READABLE); | |||||
$query = $this->connection->getQueryBuilder(); | |||||
$query->insert(self::TABLE_TOKENS) | |||||
->values([ | |||||
'token' => $query->createNamedParameter($token), | |||||
'editor_id' => $query->createNamedParameter($editorId), | |||||
'file_id' => $query->createNamedParameter($file->getId()), | |||||
'user_id' => $query->createNamedParameter($this->userId), | |||||
'share_id' => $query->createNamedParameter($share !== null ? $share->getId(): null), | |||||
'timestamp' => $query->createNamedParameter(time()) | |||||
]); | |||||
$query->execute(); | |||||
return $token; | |||||
} | |||||
public function getFileForToken($userId, $fileId) { | |||||
$userFolder = $this->rootFolder->getUserFolder($userId); | |||||
return $userFolder->getById($fileId)[0]; | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\DirectEditing\IToken; | |||||
use OCP\Files\File; | |||||
class Token implements IToken { | |||||
/** @var Manager */ | |||||
private $manager; | |||||
private $data; | |||||
public function __construct(Manager $manager, $data) { | |||||
$this->manager = $manager; | |||||
$this->data = $data; | |||||
} | |||||
public function extend(): void { | |||||
$this->manager->refreshToken($this->data['token']); | |||||
} | |||||
public function invalidate(): void { | |||||
$this->manager->invalidateToken($this->data['token']); | |||||
} | |||||
public function getFile(): File { | |||||
if ($this->data['share_id'] !== null) { | |||||
return $this->manager->getShareForToken($this->data['share_id']); | |||||
} | |||||
return $this->manager->getFileForToken($this->data['user_id'], $this->data['file_id']); | |||||
} | |||||
public function getToken(): string { | |||||
return $this->data['token']; | |||||
} | |||||
public function useTokenScope(): void { | |||||
$this->manager->invokeTokenScope($this->data['user_id']); | |||||
} | |||||
public function hasBeenAccessed(): bool { | |||||
return $this->data['accessed'] === '1'; | |||||
} | |||||
public function getEditor(): string { | |||||
return $this->data['editor_id']; | |||||
} | |||||
public function getUser(): string { | |||||
return $this->data['user_id']; | |||||
} | |||||
} |
$this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class); | $this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class); | ||||
$this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class); | $this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class); | ||||
$this->registerAlias(\OCP\DirectEditing\IManager::class, \OC\DirectEditing\Manager::class); | |||||
$this->registerAlias(IActionFactory::class, ActionFactory::class); | $this->registerAlias(IActionFactory::class, ActionFactory::class); | ||||
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\Files\File; | |||||
/** | |||||
* @since 18.0.0 | |||||
*/ | |||||
abstract class ACreateEmpty { | |||||
/** | |||||
* Unique id for the creator to filter templates | |||||
* | |||||
* e.g. document/spreadsheet/presentation | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getId(): string; | |||||
/** | |||||
* Descriptive name for the create action | |||||
* | |||||
* e.g Create a new document | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getName(): string; | |||||
/** | |||||
* Default file extension for the new file | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getExtension(): string; | |||||
/** | |||||
* Add content when creating empty files | |||||
* | |||||
* @since 18.0.0 | |||||
* @param File $file | |||||
*/ | |||||
public function create(File $file, string $creatorId = null, string $templateId = null): void { | |||||
} | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
/** | |||||
* @since 18.0.0 | |||||
*/ | |||||
abstract class ACreateFromTemplate extends ACreateEmpty { | |||||
/** | |||||
* List of available templates for the create from template action | |||||
* | |||||
* @since 18.0.0 | |||||
* @return array | |||||
*/ | |||||
abstract public function getTemplates(): array; | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use JsonSerializable; | |||||
/** | |||||
* Class ATemplate | |||||
* | |||||
* @package OCP\DirectEditing | |||||
* @since 18.0.0 | |||||
*/ | |||||
abstract class ATemplate implements JsonSerializable { | |||||
/** | |||||
* Return a unique id so the app can identify the template | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getId(): string; | |||||
/** | |||||
* Return a title that is displayed to the user | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getTitle(): string; | |||||
/** | |||||
* Return a link to the template preview image | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
abstract public function getPreview(): string; | |||||
/** | |||||
* @since 18.0.0 | |||||
* @return array|mixed | |||||
*/ | |||||
public function jsonSerialize() { | |||||
return [ | |||||
'id' => $this->getId(), | |||||
'title' => $this->getTitle(), | |||||
'preview' => $this->getPreview(), | |||||
]; | |||||
} | |||||
} |
<?php | |||||
declare(strict_types=1); | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\AppFramework\Http\Response; | |||||
/** | |||||
* @since 18.0.0 | |||||
*/ | |||||
interface IEditor { | |||||
/** | |||||
* Return a unique identifier for the editor | |||||
* | |||||
* e.g. richdocuments | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
public function getId(): string; | |||||
/** | |||||
* Return a readable name for the editor | |||||
* | |||||
* e.g. Collabora Online | |||||
* | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
public function getName(): string; | |||||
/** | |||||
* A list of mimetypes that should open the editor by default | |||||
* | |||||
* @since 18.0.0 | |||||
* @return array | |||||
*/ | |||||
public function getMimetypes(): array; | |||||
/** | |||||
* A list of mimetypes that can be opened in the editor optionally | |||||
* | |||||
* @since 18.0.0 | |||||
* @return array | |||||
*/ | |||||
public function getMimetypesOptional(): array; | |||||
/** | |||||
* Return a list of file creation options to be presented to the user | |||||
* | |||||
* @since 18.0.0 | |||||
* @return array of ICreateFromTemplate|ICreateEmpty | |||||
*/ | |||||
public function getCreators(): array; | |||||
/** | |||||
* Return if the view is able to securely view a file without downloading it to the browser | |||||
* | |||||
* @since 18.0.0 | |||||
* @return bool | |||||
*/ | |||||
public function isSecure(): bool; | |||||
/** | |||||
* Return a template response for displaying the editor | |||||
* | |||||
* open can only be called once when the client requests the editor with a one-time-use token | |||||
* For handling editing and later requests, editors need to impelement their own token handling and take care of invalidation | |||||
* | |||||
* This behavior is similar to the current direct editing implementation in collabora where we generate a one-time token and switch over to the regular wopi token for the actual editing/saving process | |||||
* | |||||
* @since 18.0.0 | |||||
* @return Response | |||||
*/ | |||||
public function open(IToken $token): Response; | |||||
} |
<?php | |||||
declare(strict_types=1); | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\AppFramework\Http\Response; | |||||
use OCP\Files\NotPermittedException; | |||||
use RuntimeException; | |||||
/** | |||||
* Interface IManager | |||||
* | |||||
* @package OCP\DirectEditing | |||||
* @since 18.0.0 | |||||
*/ | |||||
interface IManager { | |||||
/** | |||||
* Register a new editor | |||||
* | |||||
* @since 18.0.0 | |||||
* @param IEditor $directEditor | |||||
*/ | |||||
public function registerDirectEditor(IEditor $directEditor): void; | |||||
/** | |||||
* Open the editing page for a provided token | |||||
* | |||||
* @since 18.0.0 | |||||
* @param string $token | |||||
* @return Response | |||||
*/ | |||||
public function edit(string $token): Response; | |||||
/** | |||||
* Create a new token based on the file path and editor details | |||||
* | |||||
* @since 18.0.0 | |||||
* @param string $path | |||||
* @param string $editorId | |||||
* @param string $creatorId | |||||
* @param null $templateId | |||||
* @return string | |||||
* @throws NotPermittedException | |||||
* @throws RuntimeException | |||||
*/ | |||||
public function create(string $path, string $editorId, string $creatorId, $templateId = null): string; | |||||
/** | |||||
* Get the token details for a given token | |||||
* | |||||
* @since 18.0.0 | |||||
* @param string $token | |||||
* @return IToken | |||||
*/ | |||||
public function getToken(string $token): IToken; | |||||
/** | |||||
* Cleanup expired tokens | |||||
* | |||||
* @since 18.0.0 | |||||
* @return int number of deleted tokens | |||||
*/ | |||||
public function cleanup(): int; | |||||
} | |||||
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\Files\File; | |||||
/** | |||||
* @since 18.0.0 | |||||
*/ | |||||
interface IToken { | |||||
/** | |||||
* Extend the token validity time | |||||
* | |||||
* @since 18.0.0 | |||||
*/ | |||||
public function extend(): void; | |||||
/** | |||||
* Invalidate the token | |||||
* | |||||
* @since 18.0.0 | |||||
*/ | |||||
public function invalidate(): void; | |||||
/** | |||||
* Check if the token has already been used | |||||
* | |||||
* @since 18.0.0 | |||||
* @return bool | |||||
*/ | |||||
public function hasBeenAccessed(): bool; | |||||
/** | |||||
* Change to the user scope of the token | |||||
* | |||||
* @since 18.0.0 | |||||
*/ | |||||
public function useTokenScope(): void; | |||||
/** | |||||
* Get the file that is related to the token | |||||
* | |||||
* @since 18.0.0 | |||||
* @return File | |||||
*/ | |||||
public function getFile(): File; | |||||
/** | |||||
* @since 18.0.0 | |||||
* @return string | |||||
*/ | |||||
public function getEditor(): string; | |||||
} |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @author Julius Härtl <jus@bitgrid.net> | |||||
* | |||||
* @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\DirectEditing; | |||||
use OCP\EventDispatcher\Event; | |||||
/** | |||||
* @since 18.0.0 | |||||
*/ | |||||
class RegisterDirectEditorEvent extends Event { | |||||
/** | |||||
* @var IManager | |||||
*/ | |||||
private $manager; | |||||
/** | |||||
* RegisterDirectEditorEvent constructor. | |||||
* | |||||
* @param IManager $manager | |||||
* @since 18.0.0 | |||||
*/ | |||||
public function __construct(IManager $manager) { | |||||
parent::__construct(); | |||||
$this->manager = $manager; | |||||
} | |||||
/** | |||||
* @since 18.0.0 | |||||
* @param IEditor $editor | |||||
*/ | |||||
public function register(IEditor $editor): void { | |||||
$this->manager->registerDirectEditor($editor); | |||||
} | |||||
} |
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel | ||||
// when updating major/minor version number. | // when updating major/minor version number. | ||||
$OC_Version = array(18, 0, 0, 1); | |||||
$OC_Version = array(18, 0, 0, 2); | |||||
// The human readable string | // The human readable string | ||||
$OC_VersionString = '18.0.0 Alpha'; | $OC_VersionString = '18.0.0 Alpha'; |