Add repair step to fix file share permissions

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
This commit is contained in:
Vincent Petry 2016-11-07 12:25:05 +01:00 committed by Joas Schilling
parent d9035e2805
commit 7baa4ea1a4
No known key found for this signature in database
GPG Key ID: E166FD8976B3BAC8
2 changed files with 100 additions and 0 deletions

View File

@ -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
@ -91,6 +92,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
*/
@ -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);
}

View File

@ -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
*/