diff options
author | Vincent Petry <pvince81@owncloud.com> | 2016-11-07 12:25:05 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2017-01-05 14:30:22 +0100 |
commit | 7baa4ea1a48df31139fe6d36169cbc690208db62 (patch) | |
tree | 3e7e21f38910df629fc13b86fcb0fd2f0e1aa6b7 | |
parent | d9035e2805f2900cd1c78cc8ab22fdd1dfeb4b3e (diff) | |
download | nextcloud-server-7baa4ea1a48df31139fe6d36169cbc690208db62.tar.gz nextcloud-server-7baa4ea1a48df31139fe6d36169cbc690208db62.zip |
Add repair step to fix file share permissions
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
-rw-r--r-- | lib/private/Repair/RepairInvalidShares.php | 33 | ||||
-rw-r--r-- | tests/lib/Repair/RepairInvalidSharesTest.php | 67 |
2 files changed, 100 insertions, 0 deletions
diff --git a/lib/private/Repair/RepairInvalidShares.php b/lib/private/Repair/RepairInvalidShares.php index 6cb690057bb..05267be72cf 100644 --- a/lib/private/Repair/RepairInvalidShares.php +++ b/lib/private/Repair/RepairInvalidShares.php @@ -27,6 +27,7 @@ namespace OC\Repair; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; +use Doctrine\DBAL\Platforms\OraclePlatform; /** * Repairs shares with invalid data @@ -92,6 +93,35 @@ class RepairInvalidShares implements IRepairStep { } /** + * Adjust file share permissions + */ + private function adjustFileSharePermissions(IOutput $out) { + $mask = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE; + $builder = $this->connection->getQueryBuilder(); + + + if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { + $permsFunc = $builder->createFunction( + 'bitand(' . $builder->getColumnName('permissions') . ', ' . $mask . ')' + ); + } else { + $permsFunc = $builder->createFunction( + '(' . $builder->getColumnName('permissions') . ' & ' . $mask . ')' + ); + } + $builder + ->update('share') + ->set('permissions', $permsFunc) + ->where($builder->expr()->eq('item_type', $builder->expr()->literal('file'))) + ->andWhere($builder->expr()->neq('permissions', $permsFunc)); + + $updatedEntries = $builder->execute(); + if ($updatedEntries > 0) { + $out->info('Fixed file share permissions for ' . $updatedEntries . ' shares'); + } + } + + /** * Remove shares where the parent share does not exist anymore */ private function removeSharesNonExistingParent(IOutput $out) { @@ -137,6 +167,9 @@ class RepairInvalidShares implements IRepairStep { // this situation was only possible before 9.1 $this->addShareLinkDeletePermission($out); } + if (version_compare($ocVersionFromBeforeUpdate, '9.2.0.2', '<')) { + $this->adjustFileSharePermissions($out); + } $this->removeSharesNonExistingParent($out); } diff --git a/tests/lib/Repair/RepairInvalidSharesTest.php b/tests/lib/Repair/RepairInvalidSharesTest.php index 1ac42e53bf6..83dbed7d202 100644 --- a/tests/lib/Repair/RepairInvalidSharesTest.php +++ b/tests/lib/Repair/RepairInvalidSharesTest.php @@ -278,6 +278,73 @@ class RepairInvalidSharesTest extends TestCase { $result->closeCursor(); } + public function fileSharePermissionsProvider() { + return [ + // unchanged for folder + [ + 'folder', + 31, + 31, + ], + // unchanged for read-write + share + [ + 'file', + \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE, + \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE, + ], + // fixed for all perms + [ + 'file', + \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_SHARE, + \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_SHARE, + ], + ]; + } + + /** + * Test adjusting file share permissions + * + * @dataProvider fileSharePermissionsProvider + */ + public function testFileSharePermissions($itemType, $testPerms, $expectedPerms) { + $qb = $this->connection->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK), + 'uid_owner' => $qb->expr()->literal('user1'), + 'item_type' => $qb->expr()->literal($itemType), + 'item_source' => $qb->expr()->literal(123), + 'item_target' => $qb->expr()->literal('/123'), + 'file_source' => $qb->expr()->literal(123), + 'file_target' => $qb->expr()->literal('/test'), + 'permissions' => $qb->expr()->literal($testPerms), + 'stime' => $qb->expr()->literal(time()), + ]) + ->execute(); + + $shareId = $this->getLastShareId(); + + /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ + $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') + ->disableOriginalConstructor() + ->getMock(); + + $this->repair->run($outputMock); + + $results = $this->connection->getQueryBuilder() + ->select('*') + ->from('share') + ->orderBy('permissions', 'ASC') + ->execute() + ->fetchAll(); + + $this->assertCount(1, $results); + + $updatedShare = $results[0]; + + $this->assertEquals($expectedPerms, $updatedShare['permissions']); + } + /** * @return int */ |