-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Delete orphaned shares in a background job
- Loading branch information
Vincent Petry
committed
Mar 28, 2015
1 parent
f4dc9e6
commit 8e25d90
Showing
3 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2015 Vincent Petry <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace OCA\Files_sharing\Lib; | ||
|
||
use OCP\IDBConnection; | ||
use OC\BackgroundJob\TimedJob; | ||
|
||
/** | ||
* Delete all share entries that have no matching entries in the file cache table. | ||
*/ | ||
class DeleteOrphanedSharesJob extends TimedJob { | ||
|
||
/** | ||
* Default interval in minutes | ||
* | ||
* @var int $defaultIntervalMin | ||
**/ | ||
protected $defaultIntervalMin = 15; | ||
|
||
/** | ||
* Makes the background job do its work | ||
* | ||
* @param array $argument unused argument | ||
*/ | ||
public function run($argument) { | ||
$connection = \OC::$server->getDatabaseConnection(); | ||
$config = \OC::$server->getConfig(); | ||
|
||
$dbType = $config->getSystemValue('dbtype', 'sqlite3'); | ||
|
||
if ($dbType === 'sqlite3') { | ||
// sqlite doesn't support left joints in update statements, | ||
// so do it slightly less efficiently... | ||
$sql = | ||
'DELETE FROM `*PREFIX*share` ' . | ||
'WHERE NOT EXISTS ' . | ||
'(SELECT `fileid` FROM `*PREFIX*filecache` WHERE `file_source` = `fileid`)'; | ||
} else { | ||
$sql = | ||
'DELETE `s` FROM `*PREFIX*share` `s` ' . | ||
'LEFT JOIN `*PREFIX*filecache` `f` ON `s`.`file_source`=`f`.`fileid` ' . | ||
'WHERE `f`.`fileid` IS NULL'; | ||
} | ||
$connection->executeUpdate($sql); | ||
} | ||
|
||
} |
102 changes: 102 additions & 0 deletions
102
apps/files_sharing/tests/deleteorphanedsharesjobtest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
/** | ||
* Copyright (c) 2015 Vincent Petry <[email protected]> | ||
* This file is licensed under the Affero General Public License version 3 or | ||
* later. | ||
* See the COPYING-README file. | ||
*/ | ||
|
||
namespace Test\BackgroundJob; | ||
|
||
use OCA\Files_sharing\Lib\DeleteOrphanedSharesJob; | ||
|
||
class DeleteOrphanedSharesJobTest extends \Test\TestCase { | ||
|
||
/** | ||
* @var DeleteOrphanedSharesJob | ||
*/ | ||
private $job; | ||
|
||
/** | ||
* @var \OCP\IDBConnection | ||
*/ | ||
private $connection; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $user1; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $user2; | ||
|
||
protected function setup() { | ||
parent::setUp(); | ||
|
||
$this->connection = \OC::$server->getDatabaseConnection(); | ||
|
||
$this->user1 = $this->getUniqueID('user1_'); | ||
$this->user2 = $this->getUniqueID('user2_'); | ||
\OC_User::createUser($this->user1, 'pass'); | ||
\OC_User::createUser($this->user2, 'pass'); | ||
|
||
\OC::registerShareHooks(); | ||
|
||
$this->job = new DeleteOrphanedSharesJob(); | ||
} | ||
|
||
protected function tearDown() { | ||
$this->connection->executeUpdate('DELETE FROM `*PREFIX*share` WHERE `item_type` in (\'file\', \'folder\')'); | ||
|
||
\OC_User::deleteUser($this->user1); | ||
\OC_User::deleteUser($this->user2); | ||
|
||
$this->logout(); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
private function getShares() { | ||
$shares = []; | ||
$result = $this->connection->executeQuery('SELECT * FROM `*PREFIX*share` WHERE `item_type` in (\'file\', \'folder\')'); | ||
while ($row = $result->fetch()) { | ||
$shares[] = $row; | ||
} | ||
$result->closeCursor(); | ||
return $shares; | ||
} | ||
|
||
/** | ||
* Test clearing orphaned shares | ||
*/ | ||
public function testClearShares() { | ||
$this->loginAsUser($this->user1); | ||
|
||
$view = new \OC\Files\View('/' . $this->user1 . '/'); | ||
$view->mkdir('files/test'); | ||
$view->mkdir('files/test/sub'); | ||
|
||
$fileInfo = $view->getFileInfo('files/test/sub'); | ||
$fileId = $fileInfo->getId(); | ||
|
||
$this->assertTrue( | ||
\OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ), | ||
'Failed asserting that user 1 successfully shared "test/sub" with user 2.' | ||
); | ||
|
||
$this->assertCount(1, $this->getShares()); | ||
|
||
$this->job->run([]); | ||
|
||
$this->assertCount(1, $this->getShares(), 'Linked shares not deleted'); | ||
|
||
$view->unlink('files/test'); | ||
|
||
$this->job->run([]); | ||
|
||
$this->assertCount(0, $this->getShares(), 'Orphaned shares deleted'); | ||
} | ||
} | ||
|