Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add repair step to fix file share permissions
  • Loading branch information
Vincent Petry committed Nov 14, 2016
commit a3dec9572673291243a198f747b84e6b2c0258b7
33 changes: 33 additions & 0 deletions lib/private/repair/repairinvalidshares.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace OC\Repair;

use OC\Hooks\BasicEmitter;
use Doctrine\DBAL\Platforms\OraclePlatform;

/**
* Repairs shares with invalid data
Expand Down Expand Up @@ -73,6 +74,35 @@ private function removeExpirationDateFromNonLinkShares() {
}
}

/**
* Adjust file share permissions
*/
private function adjustFileSharePermissions() {
$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) {
$this->emit('\OC\Repair', 'info', ['Fixed file share permissions for ' . $updatedEntries . ' shares']);
}
}

/**
* Remove shares where the parent share does not exist anymore
*/
Expand Down Expand Up @@ -115,6 +145,9 @@ public function run() {
// this situation was only possible before 8.2
$this->removeExpirationDateFromNonLinkShares();
}
if (version_compare($ocVersionFromBeforeUpdate, '9.0.6.6', '<')) {
$this->adjustFileSharePermissions();
}

$this->removeSharesNonExistingParent();
}
Expand Down
67 changes: 67 additions & 0 deletions tests/lib/repair/repairinvalidsharestest.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,73 @@ public function testSharesNonExistingParent() {
$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
*/
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
$OC_Version = array(9, 0, 6, 5);
$OC_Version = array(9, 0, 6, 6);

// The human readable string
$OC_VersionString = '9.0.6';
Expand Down