mirror of
https://github.com/nextcloud/server.git
synced 2026-03-09 09:51:03 -04:00
Merge pull request #34564 from nextcloud/backport/34559/stable25
[stable25] Require token for local editing
This commit is contained in:
commit
2a42dd4f4e
10 changed files with 435 additions and 6 deletions
|
|
@ -5,7 +5,7 @@
|
|||
<name>Files</name>
|
||||
<summary>File Management</summary>
|
||||
<description>File Management</description>
|
||||
<version>1.20.0</version>
|
||||
<version>1.20.1</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Robin Appelman</author>
|
||||
<author>Vincent Petry</author>
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
<job>OCA\Files\BackgroundJob\DeleteOrphanedItems</job>
|
||||
<job>OCA\Files\BackgroundJob\CleanupFileLocks</job>
|
||||
<job>OCA\Files\BackgroundJob\CleanupDirectEditingTokens</job>
|
||||
<job>OCA\Files\BackgroundJob\DeleteExpiredOpenLocalEditor</job>
|
||||
</background-jobs>
|
||||
|
||||
<commands>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Files\AppInfo;
|
||||
|
||||
use OCA\Files\Controller\OpenLocalEditorController;
|
||||
|
||||
/** @var Application $application */
|
||||
$application = \OC::$server->query(Application::class);
|
||||
$application->registerRoutes(
|
||||
|
|
@ -169,6 +171,18 @@ $application->registerRoutes(
|
|||
'url' => '/api/v1/transferownership/{id}',
|
||||
'verb' => 'DELETE',
|
||||
],
|
||||
[
|
||||
/** @see OpenLocalEditorController::create() */
|
||||
'name' => 'OpenLocalEditor#create',
|
||||
'url' => '/api/v1/openlocaleditor',
|
||||
'verb' => 'POST',
|
||||
],
|
||||
[
|
||||
/** @see OpenLocalEditorController::validate() */
|
||||
'name' => 'OpenLocalEditor#validate',
|
||||
'url' => '/api/v1/openlocaleditor/{token}',
|
||||
'verb' => 'POST',
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ return array(
|
|||
'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\\DeleteExpiredOpenLocalEditor' => $baseDir . '/../lib/BackgroundJob/DeleteExpiredOpenLocalEditor.php',
|
||||
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => $baseDir . '/../lib/BackgroundJob/DeleteOrphanedItems.php',
|
||||
'OCA\\Files\\BackgroundJob\\ScanFiles' => $baseDir . '/../lib/BackgroundJob/ScanFiles.php',
|
||||
'OCA\\Files\\BackgroundJob\\TransferOwnership' => $baseDir . '/../lib/BackgroundJob/TransferOwnership.php',
|
||||
|
|
@ -35,9 +36,12 @@ return array(
|
|||
'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\\OpenLocalEditorController' => $baseDir . '/../lib/Controller/OpenLocalEditorController.php',
|
||||
'OCA\\Files\\Controller\\TemplateController' => $baseDir . '/../lib/Controller/TemplateController.php',
|
||||
'OCA\\Files\\Controller\\TransferOwnershipController' => $baseDir . '/../lib/Controller/TransferOwnershipController.php',
|
||||
'OCA\\Files\\Controller\\ViewController' => $baseDir . '/../lib/Controller/ViewController.php',
|
||||
'OCA\\Files\\Db\\OpenLocalEditor' => $baseDir . '/../lib/Db/OpenLocalEditor.php',
|
||||
'OCA\\Files\\Db\\OpenLocalEditorMapper' => $baseDir . '/../lib/Db/OpenLocalEditorMapper.php',
|
||||
'OCA\\Files\\Db\\TransferOwnership' => $baseDir . '/../lib/Db/TransferOwnership.php',
|
||||
'OCA\\Files\\Db\\TransferOwnershipMapper' => $baseDir . '/../lib/Db/TransferOwnershipMapper.php',
|
||||
'OCA\\Files\\DirectEditingCapabilities' => $baseDir . '/../lib/DirectEditingCapabilities.php',
|
||||
|
|
@ -48,6 +52,7 @@ return array(
|
|||
'OCA\\Files\\Listener\\LegacyLoadAdditionalScriptsAdapter' => $baseDir . '/../lib/Listener/LegacyLoadAdditionalScriptsAdapter.php',
|
||||
'OCA\\Files\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
|
||||
'OCA\\Files\\Migration\\Version11301Date20191205150729' => $baseDir . '/../lib/Migration/Version11301Date20191205150729.php',
|
||||
'OCA\\Files\\Migration\\Version12101Date20221011153334' => $baseDir . '/../lib/Migration/Version12101Date20221011153334.php',
|
||||
'OCA\\Files\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Files\\Search\\FilesSearchProvider' => $baseDir . '/../lib/Search/FilesSearchProvider.php',
|
||||
'OCA\\Files\\Service\\DirectEditingService' => $baseDir . '/../lib/Service/DirectEditingService.php',
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class ComposerStaticInitFiles
|
|||
'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\\DeleteExpiredOpenLocalEditor' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteExpiredOpenLocalEditor.php',
|
||||
'OCA\\Files\\BackgroundJob\\DeleteOrphanedItems' => __DIR__ . '/..' . '/../lib/BackgroundJob/DeleteOrphanedItems.php',
|
||||
'OCA\\Files\\BackgroundJob\\ScanFiles' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScanFiles.php',
|
||||
'OCA\\Files\\BackgroundJob\\TransferOwnership' => __DIR__ . '/..' . '/../lib/BackgroundJob/TransferOwnership.php',
|
||||
|
|
@ -50,9 +51,12 @@ class ComposerStaticInitFiles
|
|||
'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\\OpenLocalEditorController' => __DIR__ . '/..' . '/../lib/Controller/OpenLocalEditorController.php',
|
||||
'OCA\\Files\\Controller\\TemplateController' => __DIR__ . '/..' . '/../lib/Controller/TemplateController.php',
|
||||
'OCA\\Files\\Controller\\TransferOwnershipController' => __DIR__ . '/..' . '/../lib/Controller/TransferOwnershipController.php',
|
||||
'OCA\\Files\\Controller\\ViewController' => __DIR__ . '/..' . '/../lib/Controller/ViewController.php',
|
||||
'OCA\\Files\\Db\\OpenLocalEditor' => __DIR__ . '/..' . '/../lib/Db/OpenLocalEditor.php',
|
||||
'OCA\\Files\\Db\\OpenLocalEditorMapper' => __DIR__ . '/..' . '/../lib/Db/OpenLocalEditorMapper.php',
|
||||
'OCA\\Files\\Db\\TransferOwnership' => __DIR__ . '/..' . '/../lib/Db/TransferOwnership.php',
|
||||
'OCA\\Files\\Db\\TransferOwnershipMapper' => __DIR__ . '/..' . '/../lib/Db/TransferOwnershipMapper.php',
|
||||
'OCA\\Files\\DirectEditingCapabilities' => __DIR__ . '/..' . '/../lib/DirectEditingCapabilities.php',
|
||||
|
|
@ -63,6 +67,7 @@ class ComposerStaticInitFiles
|
|||
'OCA\\Files\\Listener\\LegacyLoadAdditionalScriptsAdapter' => __DIR__ . '/..' . '/../lib/Listener/LegacyLoadAdditionalScriptsAdapter.php',
|
||||
'OCA\\Files\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
|
||||
'OCA\\Files\\Migration\\Version11301Date20191205150729' => __DIR__ . '/..' . '/../lib/Migration/Version11301Date20191205150729.php',
|
||||
'OCA\\Files\\Migration\\Version12101Date20221011153334' => __DIR__ . '/..' . '/../lib/Migration/Version12101Date20221011153334.php',
|
||||
'OCA\\Files\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
|
||||
'OCA\\Files\\Search\\FilesSearchProvider' => __DIR__ . '/..' . '/../lib/Search/FilesSearchProvider.php',
|
||||
'OCA\\Files\\Service\\DirectEditingService' => __DIR__ . '/..' . '/../lib/Service/DirectEditingService.php',
|
||||
|
|
|
|||
|
|
@ -2808,12 +2808,23 @@
|
|||
},
|
||||
|
||||
openLocalClient: function(path) {
|
||||
var scheme = 'nc://';
|
||||
var command = 'open';
|
||||
var uid = OC.getCurrentUser().uid;
|
||||
var url = scheme + command + '/' + uid + '@' + window.location.host + OC.encodePath(path);
|
||||
var link = OC.linkToOCS('apps/files/api/v1', 2) + 'openlocaleditor?format=json';
|
||||
|
||||
window.location.href = url;
|
||||
$.post(link, {
|
||||
path
|
||||
})
|
||||
.success(function(result) {
|
||||
var scheme = 'nc://';
|
||||
var command = 'open';
|
||||
var uid = OC.getCurrentUser().uid;
|
||||
var url = scheme + command + '/' + uid + '@' + window.location.host + OC.encodePath(path);
|
||||
url += '?token=' + result.ocs.data.token;
|
||||
|
||||
window.location.href = url;
|
||||
})
|
||||
.fail(function() {
|
||||
OC.Notification.show(t('files', 'Failed to redirect to client'))
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author 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 OCA\Files\BackgroundJob;
|
||||
|
||||
use OCA\Files\Controller\OpenLocalEditorController;
|
||||
use OCA\Files\Db\OpenLocalEditorMapper;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJob;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
|
||||
/**
|
||||
* Delete all expired "Open local editor" token
|
||||
*/
|
||||
class DeleteExpiredOpenLocalEditor extends TimedJob {
|
||||
protected OpenLocalEditorMapper $mapper;
|
||||
|
||||
public function __construct(
|
||||
ITimeFactory $time,
|
||||
OpenLocalEditorMapper $mapper
|
||||
) {
|
||||
parent::__construct($time);
|
||||
$this->mapper = $mapper;
|
||||
|
||||
// Run every 12h
|
||||
$this->interval = 12 * 3600;
|
||||
$this->setTimeSensitivity(IJob::TIME_INSENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the background job do its work
|
||||
*
|
||||
* @param array $argument unused argument
|
||||
*/
|
||||
public function run($argument): void {
|
||||
$this->mapper->deleteExpiredTokens($this->time->getTime());
|
||||
}
|
||||
}
|
||||
138
apps/files/lib/Controller/OpenLocalEditorController.php
Normal file
138
apps/files/lib/Controller/OpenLocalEditorController.php
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author 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 OCA\Files\Controller;
|
||||
|
||||
use OCA\Files\Db\OpenLocalEditor;
|
||||
use OCA\Files\Db\OpenLocalEditorMapper;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\DB\Exception;
|
||||
use OCP\IRequest;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class OpenLocalEditorController extends OCSController {
|
||||
public const TOKEN_LENGTH = 128;
|
||||
public const TOKEN_DURATION = 600; // 10 Minutes
|
||||
public const TOKEN_RETRIES = 50;
|
||||
|
||||
protected ITimeFactory $timeFactory;
|
||||
protected OpenLocalEditorMapper $mapper;
|
||||
protected ISecureRandom $secureRandom;
|
||||
protected LoggerInterface $logger;
|
||||
protected ?string $userId;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
ITimeFactory $timeFactory,
|
||||
OpenLocalEditorMapper $mapper,
|
||||
ISecureRandom $secureRandom,
|
||||
LoggerInterface $logger,
|
||||
?string $userId
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
$this->timeFactory = $timeFactory;
|
||||
$this->mapper = $mapper;
|
||||
$this->secureRandom = $secureRandom;
|
||||
$this->logger = $logger;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @UserRateThrottle(limit=10, period=120)
|
||||
*/
|
||||
public function create(string $path): DataResponse {
|
||||
$pathHash = sha1($path);
|
||||
|
||||
$entity = new OpenLocalEditor();
|
||||
$entity->setUserId($this->userId);
|
||||
$entity->setPathHash($pathHash);
|
||||
$entity->setExpirationTime($this->timeFactory->getTime() + self::TOKEN_DURATION); // Expire in 10 minutes
|
||||
|
||||
for ($i = 1; $i <= self::TOKEN_RETRIES; $i++) {
|
||||
$token = $this->secureRandom->generate(self::TOKEN_LENGTH, ISecureRandom::CHAR_ALPHANUMERIC);
|
||||
$entity->setToken($token);
|
||||
|
||||
try {
|
||||
$this->mapper->insert($entity);
|
||||
|
||||
return new DataResponse([
|
||||
'userId' => $this->userId,
|
||||
'pathHash' => $pathHash,
|
||||
'expirationTime' => $entity->getExpirationTime(),
|
||||
'token' => $entity->getToken(),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
if ($e->getCode() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
|
||||
// Only retry on unique constraint violation
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->error('Giving up after ' . self::TOKEN_RETRIES . ' retries to generate a unique local editor token for path hash: ' . $pathHash);
|
||||
return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @BruteForceProtection(action=openLocalEditor)
|
||||
*/
|
||||
public function validate(string $path, string $token): DataResponse {
|
||||
$pathHash = sha1($path);
|
||||
|
||||
try {
|
||||
$entity = $this->mapper->verifyToken($this->userId, $pathHash, $token);
|
||||
} catch (DoesNotExistException $e) {
|
||||
$response = new DataResponse([], Http::STATUS_NOT_FOUND);
|
||||
$response->throttle(['userId' => $this->userId, 'pathHash' => $pathHash]);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->mapper->delete($entity);
|
||||
|
||||
if ($entity->getExpirationTime() <= $this->timeFactory->getTime()) {
|
||||
$response = new DataResponse([], Http::STATUS_NOT_FOUND);
|
||||
$response->throttle(['userId' => $this->userId, 'pathHash' => $pathHash]);
|
||||
return $response;
|
||||
}
|
||||
|
||||
return new DataResponse([
|
||||
'userId' => $this->userId,
|
||||
'pathHash' => $pathHash,
|
||||
'expirationTime' => $entity->getExpirationTime(),
|
||||
'token' => $entity->getToken(),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
60
apps/files/lib/Db/OpenLocalEditor.php
Normal file
60
apps/files/lib/Db/OpenLocalEditor.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author 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 OCA\Files\Db;
|
||||
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
|
||||
/**
|
||||
* @method void setUserId(string $userId)
|
||||
* @method string getUserId()
|
||||
* @method void setPathHash(string $pathHash)
|
||||
* @method string getPathHash()
|
||||
* @method void setExpirationTime(int $expirationTime)
|
||||
* @method int getExpirationTime()
|
||||
* @method void setToken(string $token)
|
||||
* @method string getToken()
|
||||
*/
|
||||
class OpenLocalEditor extends Entity {
|
||||
/** @var string */
|
||||
protected $userId;
|
||||
|
||||
/** @var string */
|
||||
protected $pathHash;
|
||||
|
||||
/** @var int */
|
||||
protected $expirationTime;
|
||||
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
public function __construct() {
|
||||
$this->addType('userId', 'string');
|
||||
$this->addType('pathHash', 'string');
|
||||
$this->addType('expirationTime', 'integer');
|
||||
$this->addType('token', 'string');
|
||||
}
|
||||
}
|
||||
65
apps/files/lib/Db/OpenLocalEditorMapper.php
Normal file
65
apps/files/lib/Db/OpenLocalEditorMapper.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author 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 OCA\Files\Db;
|
||||
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
use OCP\DB\Exception;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
class OpenLocalEditorMapper extends QBMapper {
|
||||
public function __construct(IDBConnection $db) {
|
||||
parent::__construct($db, 'open_local_editor', OpenLocalEditor::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DoesNotExistException
|
||||
* @throws MultipleObjectsReturnedException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function verifyToken(string $userId, string $pathHash, string $token): OpenLocalEditor {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
->from($this->getTableName())
|
||||
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
|
||||
->andWhere($qb->expr()->eq('path_hash', $qb->createNamedParameter($pathHash)))
|
||||
->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
public function deleteExpiredTokens(int $time): void {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->delete($this->getTableName())
|
||||
->where($qb->expr()->lt('expiration_time', $qb->createNamedParameter($time)));
|
||||
|
||||
$qb->executeStatement();
|
||||
}
|
||||
}
|
||||
69
apps/files/lib/Migration/Version12101Date20221011153334.php
Normal file
69
apps/files/lib/Migration/Version12101Date20221011153334.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @author 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 OCA\Files\Migration;
|
||||
|
||||
use Closure;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
class Version12101Date20221011153334 extends SimpleMigrationStep {
|
||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
|
||||
$table = $schema->createTable('open_local_editor');
|
||||
$table->addColumn('id',Types::BIGINT, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 20,
|
||||
'unsigned' => true,
|
||||
]);
|
||||
$table->addColumn('user_id', Types::STRING, [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('path_hash', Types::STRING, [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('expiration_time', Types::BIGINT, [
|
||||
'notnull' => true,
|
||||
'unsigned' => true,
|
||||
]);
|
||||
$table->addColumn('token', Types::STRING, [
|
||||
'notnull' => true,
|
||||
'length' => 128,
|
||||
]);
|
||||
|
||||
$table->setPrimaryKey(['id']);
|
||||
$table->addUniqueIndex(['user_id', 'path_hash', 'token'], 'openlocal_user_path_token');
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue