Avatars are now stored in appdata Signed-off-by: Robin Appelman <robin@icewind.nl>tags/v12.0.0beta1
'OC\\Repair' => $baseDir . '/lib/private/Repair.php', | 'OC\\Repair' => $baseDir . '/lib/private/Repair.php', | ||||
'OC\\RepairException' => $baseDir . '/lib/private/RepairException.php', | 'OC\\RepairException' => $baseDir . '/lib/private/RepairException.php', | ||||
'OC\\Repair\\AssetCache' => $baseDir . '/lib/private/Repair/AssetCache.php', | 'OC\\Repair\\AssetCache' => $baseDir . '/lib/private/Repair/AssetCache.php', | ||||
'OC\\Repair\\AvatarPermissions' => $baseDir . '/lib/private/Repair/AvatarPermissions.php', | |||||
'OC\\Repair\\CleanTags' => $baseDir . '/lib/private/Repair/CleanTags.php', | 'OC\\Repair\\CleanTags' => $baseDir . '/lib/private/Repair/CleanTags.php', | ||||
'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php', | 'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php', | ||||
'OC\\Repair\\DropOldJobs' => $baseDir . '/lib/private/Repair/DropOldJobs.php', | 'OC\\Repair\\DropOldJobs' => $baseDir . '/lib/private/Repair/DropOldJobs.php', |
'OC\\Repair' => __DIR__ . '/../../..' . '/lib/private/Repair.php', | 'OC\\Repair' => __DIR__ . '/../../..' . '/lib/private/Repair.php', | ||||
'OC\\RepairException' => __DIR__ . '/../../..' . '/lib/private/RepairException.php', | 'OC\\RepairException' => __DIR__ . '/../../..' . '/lib/private/RepairException.php', | ||||
'OC\\Repair\\AssetCache' => __DIR__ . '/../../..' . '/lib/private/Repair/AssetCache.php', | 'OC\\Repair\\AssetCache' => __DIR__ . '/../../..' . '/lib/private/Repair/AssetCache.php', | ||||
'OC\\Repair\\AvatarPermissions' => __DIR__ . '/../../..' . '/lib/private/Repair/AvatarPermissions.php', | |||||
'OC\\Repair\\CleanTags' => __DIR__ . '/../../..' . '/lib/private/Repair/CleanTags.php', | 'OC\\Repair\\CleanTags' => __DIR__ . '/../../..' . '/lib/private/Repair/CleanTags.php', | ||||
'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php', | 'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php', | ||||
'OC\\Repair\\DropOldJobs' => __DIR__ . '/../../..' . '/lib/private/Repair/DropOldJobs.php', | 'OC\\Repair\\DropOldJobs' => __DIR__ . '/../../..' . '/lib/private/Repair/DropOldJobs.php', |
namespace OC; | namespace OC; | ||||
use OC\Repair\AssetCache; | use OC\Repair\AssetCache; | ||||
use OC\Repair\AvatarPermissions; | |||||
use OC\Repair\CleanTags; | use OC\Repair\CleanTags; | ||||
use OC\Repair\Collation; | use OC\Repair\Collation; | ||||
use OC\Repair\DropOldJobs; | use OC\Repair\DropOldJobs; | ||||
new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), | new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), | ||||
new SharePropagation(\OC::$server->getConfig()), | new SharePropagation(\OC::$server->getConfig()), | ||||
new RemoveOldShares(\OC::$server->getDatabaseConnection()), | new RemoveOldShares(\OC::$server->getDatabaseConnection()), | ||||
new AvatarPermissions(\OC::$server->getDatabaseConnection()), | |||||
new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()), | new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()), | ||||
new RepairUnmergedShares( | new RepairUnmergedShares( | ||||
\OC::$server->getConfig(), | \OC::$server->getConfig(), |
<?php | |||||
/** | |||||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||||
* | |||||
* @author Roeland Jago Douma <roeland@famdouma.nl> | |||||
* | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* 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, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace OC\Repair; | |||||
use Doctrine\DBAL\Platforms\OraclePlatform; | |||||
use OCP\IDBConnection; | |||||
use OCP\Migration\IOutput; | |||||
use OCP\Migration\IRepairStep; | |||||
/** | |||||
* Class AvatarPermissions | |||||
* | |||||
* @package OC\Repair | |||||
*/ | |||||
class AvatarPermissions implements IRepairStep { | |||||
/** @var IDBConnection */ | |||||
private $connection; | |||||
/** | |||||
* AvatarPermissions constructor. | |||||
* | |||||
* @param IDBConnection $connection | |||||
*/ | |||||
public function __construct(IDBConnection $connection) { | |||||
$this->connection = $connection; | |||||
} | |||||
/** | |||||
* @return string | |||||
*/ | |||||
public function getName() { | |||||
return 'Fix permissions so avatars can be stored again'; | |||||
} | |||||
/** | |||||
* @param IOutput $output | |||||
*/ | |||||
public function run(IOutput $output) { | |||||
$output->startProgress(2); | |||||
$this->fixUserRootPermissions(); | |||||
$output->advance(); | |||||
$this->fixAvatarPermissions(); | |||||
$output->finishProgress(); | |||||
} | |||||
/** | |||||
* Make sure all user roots have permissions 23 (all but share) | |||||
*/ | |||||
protected function fixUserRootPermissions() { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb2 = $this->connection->getQueryBuilder(); | |||||
$qb->select('numeric_id') | |||||
->from('storages') | |||||
->where($qb->expr()->like('id', $qb2->createParameter('like'))); | |||||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { | |||||
// '' is null on oracle | |||||
$path = $qb2->expr()->isNull('path'); | |||||
} else { | |||||
$path = $qb2->expr()->eq('path', $qb2->createNamedParameter('')); | |||||
} | |||||
$qb2->update('filecache') | |||||
->set('permissions', $qb2->createNamedParameter(23)) | |||||
->where($path) | |||||
->andWhere($qb2->expr()->in('storage', $qb2->createFunction($qb->getSQL()))) | |||||
->andWhere($qb2->expr()->neq('permissions', $qb2->createNamedParameter(23))) | |||||
->setParameter('like', 'home::%'); | |||||
$qb2->execute(); | |||||
} | |||||
/** | |||||
* Make sure all avatar files in the user roots have permission 27 | |||||
*/ | |||||
protected function fixAvatarPermissions() { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb2 = $this->connection->getQueryBuilder(); | |||||
$qb->select('numeric_id') | |||||
->from('storages') | |||||
->where($qb->expr()->like('id', $qb2->createParameter('like'))); | |||||
$qb2->update('filecache') | |||||
->set('permissions', $qb2->createNamedParameter(27)) | |||||
->where($qb2->expr()->like('path', $qb2->createNamedParameter('avatar.%'))) | |||||
->andWhere($qb2->expr()->in('storage', $qb2->createFunction($qb->getSQL()))) | |||||
->andWhere($qb2->expr()->neq('permissions', $qb2->createNamedParameter(27))) | |||||
->setParameter('like', 'home::%'); | |||||
$qb2->execute(); | |||||
} | |||||
} | |||||
<?php | |||||
/** | |||||
* @author Roeland Jago Douma <rullzer@owncloud.com> | |||||
* | |||||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||||
* @license AGPL-3.0 | |||||
* | |||||
* This code is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Affero General Public License, version 3, | |||||
* as published by the Free Software Foundation. | |||||
* | |||||
* 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, version 3, | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||||
* | |||||
*/ | |||||
namespace Test\Repair; | |||||
/** | |||||
* Test for fixing the userRoot and avatar permissions | |||||
* | |||||
* @group DB | |||||
* | |||||
* @see \OC\Repair\AvatarPermissionsTest | |||||
*/ | |||||
class AvatarPermissionsTest extends \Test\TestCase { | |||||
/** @var \OC\Repair\AvatarPermissions */ | |||||
protected $repair; | |||||
/** @var \OCP\IDBConnection */ | |||||
protected $connection; | |||||
protected function setUp() { | |||||
parent::setUp(); | |||||
$this->connection = \OC::$server->getDatabaseConnection(); | |||||
$this->repair = new \OC\Repair\AvatarPermissions($this->connection); | |||||
$this->cleanUpTables(); | |||||
} | |||||
protected function tearDown() { | |||||
$this->cleanUpTables(); | |||||
parent::tearDown(); | |||||
} | |||||
protected function cleanUpTables() { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb->delete('filecache')->execute(); | |||||
$qb->delete('storages')->execute(); | |||||
} | |||||
public function dataFixUserRootPermissions() { | |||||
return [ | |||||
['home::user', '', 0, 23], | |||||
['home::user', 'foo', 0, 0], | |||||
['home::user', 'avatar.jpg', 0, 0], | |||||
['ABC::user', '', 0, 0], | |||||
['ABC::user', 'foo', 0, 0], | |||||
]; | |||||
} | |||||
/** | |||||
* @dataProvider dataFixUserRootPermissions | |||||
* | |||||
* @param string $storageId | |||||
* @param string $path | |||||
* @param int $permissionsBefore | |||||
* @param int $permissionsAfter | |||||
*/ | |||||
public function testFixUserRootPermissions($storageId, $path, $permissionsBefore, $permissionsAfter) { | |||||
$userStorage = $this->addStorage($storageId); | |||||
$userHome = $this->addFileCacheEntry($userStorage, $path, $permissionsBefore); | |||||
$this->invokePrivate($this->repair, 'fixUserRootPermissions', []); | |||||
$this->verifyPermissions($userHome, $permissionsAfter); | |||||
} | |||||
public function dataFixAvatarPermissions() { | |||||
return [ | |||||
['home::user', '', 0, 0], | |||||
['home::user', 'avatar.jpg', 0, 27], | |||||
['home::user', 'avatar.png', 0, 27], | |||||
['home::user', 'avatar.32.png', 0, 27], | |||||
['home::user', 'mine.txt', 0, 0], | |||||
['ABC::user', '', 0, 0], | |||||
['ABC::user', 'avatar.jpg', 0, 0], | |||||
['ABC::user', 'avatar.png', 0, 0], | |||||
['ABC::user', 'avatar.32.png', 0, 0], | |||||
['ABC::user', 'mine.txt', 0, 0], | |||||
]; | |||||
} | |||||
/** | |||||
* @dataProvider dataFixAvatarPermissions | |||||
* | |||||
* @param string $storageId | |||||
* @param string $path | |||||
* @param int $permissionsBefore | |||||
* @param int $permissionsAfter | |||||
*/ | |||||
public function testFixAvatarPermissions($storageId, $path, $permissionsBefore, $permissionsAfter) { | |||||
$userStorage = $this->addStorage($storageId); | |||||
$userHome = $this->addFileCacheEntry($userStorage, $path, $permissionsBefore); | |||||
$this->invokePrivate($this->repair, 'fixAvatarPermissions', []); | |||||
$this->verifyPermissions($userHome, $permissionsAfter); | |||||
} | |||||
/** | |||||
* Add a new storage | |||||
* | |||||
* @param string $id | |||||
* @return int The numeric id | |||||
*/ | |||||
protected function addStorage($id) { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb->insert('storages') | |||||
->values([ | |||||
'id' => $qb->createNamedParameter($id) | |||||
]); | |||||
$qb->execute(); | |||||
return $qb->getLastInsertId(); | |||||
} | |||||
/** | |||||
* Add a filecache entry | |||||
* | |||||
* @param int $storage | |||||
* @param string $path | |||||
* @param int $permissions | |||||
* | |||||
* @return int The fileid | |||||
*/ | |||||
protected function addFileCacheEntry($storage, $path, $permissions) { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb->insert('filecache') | |||||
->values([ | |||||
'path' => $qb->createNamedParameter($path), | |||||
'path_hash' => $qb->createNamedParameter(md5($path)), | |||||
'parent' => $qb->createNamedParameter(42), | |||||
'mimetype' => $qb->createNamedParameter(23), | |||||
'mimepart' => $qb->createNamedParameter(32), | |||||
'size' => $qb->createNamedParameter(16), | |||||
'mtime' => $qb->createNamedParameter(1), | |||||
'storage_mtime' => $qb->createNamedParameter(2), | |||||
'encrypted' => $qb->createNamedParameter(0), | |||||
'unencrypted_size' => $qb->createNamedParameter(0), | |||||
'storage' => $qb->createNamedParameter($storage), | |||||
'permissions' => $qb->createNamedParameter($permissions), | |||||
]); | |||||
$qb->execute(); | |||||
return $qb->getLastInsertId(); | |||||
} | |||||
/** | |||||
* @param int $fileId | |||||
* @param int $permissions | |||||
*/ | |||||
protected function verifyPermissions($fileId, $permissions) { | |||||
$qb = $this->connection->getQueryBuilder(); | |||||
$qb->select('permissions') | |||||
->from('filecache') | |||||
->where($qb->expr()->eq('fileid', $qb->createNamedParameter($fileId))); | |||||
$cursor = $qb->execute(); | |||||
$data = $cursor->fetch(); | |||||
$cursor->closeCursor(); | |||||
$this->assertSame($permissions, (int)$data['permissions']); | |||||
} | |||||
} |