Skip to content

Commit

Permalink
Merge branch 'stable9' into stable9-sscpac-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
rwakida committed Jun 13, 2016
2 parents 5379c6f + d41d5c4 commit fa95062
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 5 deletions.
12 changes: 10 additions & 2 deletions apps/files_sharing/api/share20ocs.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,16 @@ protected function formatShare(\OCP\Share\IShare $share) {
'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
];

$node = $share->getNode();
$result['path'] = $this->rootFolder->getUserFolder($share->getShareOwner())->getRelativePath($node->getPath());
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
$nodes = $userFolder->getById($share->getNodeId());

if (empty($nodes)) {
throw new NotFoundException();
}

$node = $nodes[0];
$result['path'] = $userFolder->getRelativePath($node->getPath());

if ($node instanceOf \OCP\Files\Folder) {
$result['item_type'] = 'folder';
} else {
Expand Down
21 changes: 18 additions & 3 deletions apps/files_sharing/tests/api/share20ocstest.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,12 @@ public function testGetShare(\OCP\Share\IShare $share, array $result) {
->method('getRelativePath')
->will($this->returnArgument(0));

$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);

$this->rootFolder->method('getUserFolder')
->with($share->getShareOwner())
->with($this->currentUser->getUID())
->willReturn($userFolder);

$this->urlGenerator
Expand Down Expand Up @@ -1869,8 +1873,19 @@ public function testFormatShare(array $expects, \OCP\Share\IShare $share, array
->willReturn('myLink');


$this->rootFolder->method('getUserFolder')->with($share->getShareOwner())->will($this->returnSelf());
$this->rootFolder->method('getRelativePath')->will($this->returnArgument(0));
$this->rootFolder->method('getUserFolder')
->with($this->currentUser->getUID())
->will($this->returnSelf());

if (!$exception) {
$this->rootFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);

$this->rootFolder->method('getRelativePath')
->with($share->getNode()->getPath())
->will($this->returnArgument(0));
}

try {
$result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
Expand Down
2 changes: 2 additions & 0 deletions lib/private/repair.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OC\Hooks\BasicEmitter;
use OC\Hooks\Emitter;
use OC\Repair\AssetCache;
use OC\Repair\AvatarPermissions;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
use OC\Repair\CopyRewriteBaseToConfig;
Expand Down Expand Up @@ -116,6 +117,7 @@ public static function getRepairSteps() {
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
new UpdateOutdatedOcsIds(\OC::$server->getConfig()),
new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
new AvatarPermissions(\OC::$server->getDatabaseConnection()),
];
}

Expand Down
108 changes: 108 additions & 0 deletions lib/private/repair/avatarpermissions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php
/**
* @author Roeland Jago Douma <[email protected]>
*
* @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 OC\Repair;

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

/**
* Class AvatarPermissions
*
* @package OC\Repair
*/
class AvatarPermissions extends BasicEmitter implements \OC\RepairStep {
/** @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';
}

public function run() {
$this->fixUserRootPermissions();
$this->fixAvatarPermissions();
}

/**
* 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();
}

}

189 changes: 189 additions & 0 deletions tests/lib/repair/avatarpermissions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php
/**
* @author Roeland Jago Douma <[email protected]>
*
* @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']);
}


}

0 comments on commit fa95062

Please sign in to comment.