Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
81761b8
DAV now returns file name with Content-Disposition header
Jun 10, 2016
9e3cf79
Use capped cache for encryption's user access list
Jun 13, 2016
3e846a4
Use an explicit version of sabre/dav to allow caching on the jenkins …
DeepDiver1975 Jun 14, 2016
a0215b1
decrease initial users to load to 50
butonic Jun 7, 2016
ea330df
Allow empty host when installing on oracle via CLI (#25034)
butonic Jun 10, 2016
173f732
Merge pull request #25106 from owncloud/stable9-allow-empty-host-when…
Jun 15, 2016
57d3bb3
Merge pull request #25105 from owncloud/stable9-initial-userloading-w…
Jun 15, 2016
c5a60c3
Merge pull request #25084 from owncloud/stable9-enc-cappedcache-getac…
Jun 15, 2016
a9c98da
Capped cache for cache info in UserMountCache
Jun 15, 2016
3da5d06
Merge pull request #25052 from owncloud/stable9-webdav-download-mimetype
Jun 15, 2016
ffec0f1
Merge pull request #25118 from owncloud/stable9-fs-usermountcache-capped
Jun 16, 2016
2656f68
load authentication apps first
ChristophWurst Jun 15, 2016
416d4c5
fix grouped input fields, make sure they take precedence
jancborchardt Jun 16, 2016
b1e60cc
Merge pull request #25143 from owncloud/stable9-fix-grouped-inputs
Jun 16, 2016
5e17e99
Convert Dropbox Forbidden exception to StorageNotAvailableException
Jun 16, 2016
d55ad77
Merge pull request #25148 from owncloud/stable9-dropbox-catchratelimit
Jun 16, 2016
f429be1
Merge pull request #25137 from owncloud/stable9-backport-25126
Jun 16, 2016
3ac02c9
–emit correct signal when disabling an app
butonic Jun 16, 2016
82384ab
Merge pull request #25149 from owncloud/backport25146
Jun 16, 2016
2ce078e
ownCloud 9.0.3 RC1
Jun 16, 2016
b5d3e87
Remove shares of the root folder (#25138)
Jun 17, 2016
7aa825f
Revert "[stable9] Remove shares of the root folder" (#25157)
Jun 17, 2016
2d7bbf4
Do not recurse link share fetching
rullzer Mar 8, 2016
0e3682d
Capped cache for user config
butonic Jun 17, 2016
a3111e8
Merge pull request #25160 from owncloud/fix-oracle-endless-loop-stable9
Jun 17, 2016
0129437
Make getShareFolder use given view instead of static FS (#25150)
Jun 20, 2016
2f61c29
Delay files_sharing's registerMountProviders
Jun 17, 2016
3e3c17a
Merge pull request #25187 from owncloud/share-app-initorder-stable9
Jun 20, 2016
826654b
Merge pull request #25165 from owncloud/stable9-capped-user-cache
Jun 20, 2016
11c1d39
Fix null pointer exception in user_ldap
butonic Jun 10, 2016
fa9ba64
Catch exceptions while creating shared mounts
icewind1991 Jun 20, 2016
bf7a08f
dd support to know where the storage test comes from (#25166)
jvillafanez Jun 21, 2016
ddd4f36
Merge pull request #25199 from owncloud/shared-mount-catch-9
Jun 21, 2016
54209ab
Merge pull request #25197 from owncloud/fix-npe-in-user-ldap-stable9
Jun 21, 2016
880ff12
Rollback version must also adjust cached size
Jun 22, 2016
3aaa33d
Merge pull request #25228 from owncloud/stable9-enc-revertversionsize
Jun 22, 2016
b6192c3
On mount make sure multiple shares with same target map to unique one…
rullzer Apr 14, 2016
eb8e151
Merge pull request #25248 from owncloud/stable9-unique_targets
Jun 23, 2016
e366ed6
Don't reload page in case of auth errors during setup checks
Jun 23, 2016
907c901
Merge pull request #25256 from owncloud/stable9-setupchecks-preventre…
ChristophWurst Jun 24, 2016
dcb5f00
Merge remote-tracking branch 'upstream/stable9' into stable9-upstream…
LukasReschke Jun 26, 2016
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
Prev Previous commit
Next Next commit
Remove shares of the root folder (#25138)
  • Loading branch information
Vincent Petry authored and DeepDiver1975 committed Jun 17, 2016
commit b5d3e877f1554a261da9d5a1fe0381f30607815b
2 changes: 2 additions & 0 deletions lib/private/repair.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
use OC\Repair\SearchLuceneTables;
use OC\Repair\UpdateOutdatedOcsIds;
use OC\Repair\RepairInvalidShares;
use OC\Repair\RemoveRootShares;

class Repair extends BasicEmitter {
/**
Expand Down Expand Up @@ -118,6 +119,7 @@ public static function getRepairSteps() {
new UpdateOutdatedOcsIds(\OC::$server->getConfig()),
new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
new AvatarPermissions(\OC::$server->getDatabaseConnection()),
new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getRootFolder()),
];
}

Expand Down
145 changes: 145 additions & 0 deletions lib/private/repair/removerootshares.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?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 OCP\Files\IRootFolder;
use OCP\IDBConnection;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Migration\IOutput;

/**
* Class RemoveRootShares
*
* @package OC\Repair
*/
class RemoveRootShares implements \OC\RepairStep {

/** @var IDBConnection */
protected $connection;

/** @var IUserManager */
protected $userManager;

/** @var IRootFolder */
protected $rootFolder;

/**
* RemoveRootShares constructor.
*
* @param IDBConnection $connection
* @param IUserManager $userManager
* @param IRootFolder $rootFolder
*/
public function __construct(IDBConnection $connection,
IUserManager $userManager,
IRootFolder $rootFolder) {
$this->connection = $connection;
$this->userManager = $userManager;
$this->rootFolder = $rootFolder;
}

/**
* @return string
*/
public function getName() {
return 'Remove shares of a users root folder';
}

public function run() {
if ($this->rootSharesExist()) {
$this->removeRootShares();
}
}

private function removeRootShares() {
$function = function(IUser $user) {
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
$fileId = $userFolder->getId();

$qb = $this->connection->getQueryBuilder();
$qb->delete('share')
->where($qb->expr()->eq('file_source', $qb->createNamedParameter($fileId)))
->andWhere($qb->expr()->orX(
$qb->expr()->eq('item_type', $qb->expr()->literal('file')),
$qb->expr()->eq('item_type', $qb->expr()->literal('folder'))
));

$qb->execute();
};

$userCount = $this->countUsers();

$this->userManager->callForAllUsers($function);
}

/**
* Count all the users
*
* @return int
*/
private function countUsers() {
$allCount = $this->userManager->countUsers();

$totalCount = 0;
foreach ($allCount as $backend => $count) {
$totalCount += $count;
}

return $totalCount;
}

/**
* Verify if this repair steps is required
* It *should* not be necessary in most cases and it can be very
* costly.
*
* @return bool
*/
private function rootSharesExist() {
$qb = $this->connection->getQueryBuilder();
$qb2 = $this->connection->getQueryBuilder();

$qb->select('fileid')
->from('filecache')
->where($qb->expr()->eq('path', $qb->expr()->literal('files')));

$qb2->select('id')
->from('share')
->where($qb2->expr()->in('file_source', $qb2->createFunction($qb->getSQL())))
->andWhere($qb2->expr()->orX(
$qb2->expr()->eq('item_type', $qb->expr()->literal('file')),
$qb2->expr()->eq('item_type', $qb->expr()->literal('folder'))
))
->setMaxResults(1);

$cursor = $qb2->execute();
$data = $cursor->fetch();
$cursor->closeCursor();

if ($data === false) {
return false;
}

return true;
}
}

194 changes: 194 additions & 0 deletions tests/lib/repair/removerootsharestest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
<?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;

use OC\Repair\RemoveRootShares;
use OCP\Files\IRootFolder;
use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\Migration\IOutput;
use Test\Traits\UserTrait;

/**
* Class RemoveOldSharesTest
*
* @package Test\Repair
* @group DB
*/
class RemoveRootSharesTest extends \Test\TestCase {
use UserTrait;

/** @var RemoveRootShares */
protected $repair;

/** @var IDBConnection */
protected $connection;

/** @var IOutput */
private $outputMock;

/** @var IUserManager */
private $userManager;

/** @var IRootFolder */
private $rootFolder;

protected function setUp() {
parent::setUp();

$this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput')
->disableOriginalConstructor()
->getMock();

$this->userManager = \OC::$server->getUserManager();
$this->rootFolder = \OC::$server->getRootFolder();

$this->connection = \OC::$server->getDatabaseConnection();
$this->repair = new RemoveRootShares($this->connection, $this->userManager, $this->rootFolder);
}

protected function tearDown() {
$qb = $this->connection->getQueryBuilder();
$qb->delete('share');
$qb->execute();

return parent::tearDown();
}

public function testRootSharesExist() {
//Add test user
$user = $this->userManager->createUser('test', 'test');
$userFolder = $this->rootFolder->getUserFolder('test');
$fileId = $userFolder->getId();

//Now insert cyclic share
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->createNamedParameter(0),
'share_with' => $qb->createNamedParameter('foo'),
'uid_owner' => $qb->createNamedParameter('owner'),
'item_type' => $qb->createNamedParameter('file'),
'item_source' => $qb->createNamedParameter($fileId),
'item_target' => $qb->createNamedParameter('/target'),
'file_source' => $qb->createNamedParameter($fileId),
'file_target' => $qb->createNamedParameter('/target'),
'permissions' => $qb->createNamedParameter(1),
]);
$qb->execute();

$res = $this->invokePrivate($this->repair, 'rootSharesExist', []);
$this->assertTrue($res);

$user->delete();
}

public function testRootSharesDontExist() {
//Add test user
$user = $this->userManager->createUser('test', 'test');
$userFolder = $this->rootFolder->getUserFolder('test');
$fileId = $userFolder->getId();

//Now insert cyclic share
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->createNamedParameter(0),
'share_with' => $qb->createNamedParameter('foo'),
'uid_owner' => $qb->createNamedParameter('owner'),
'item_type' => $qb->createNamedParameter('file'),
'item_source' => $qb->createNamedParameter($fileId+1),
'item_target' => $qb->createNamedParameter('/target'),
'file_source' => $qb->createNamedParameter($fileId+1),
'file_target' => $qb->createNamedParameter('/target'),
'permissions' => $qb->createNamedParameter(1),
]);
$qb->execute();

$res = $this->invokePrivate($this->repair, 'rootSharesExist', []);
$this->assertFalse($res);

$user->delete();
}

public function testRun() {
//Add test user
$user1 = $this->userManager->createUser('test1', 'test1');
$userFolder = $this->rootFolder->getUserFolder('test1');
$fileId = $userFolder->getId();

//Now insert cyclic share
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->createNamedParameter(0),
'share_with' => $qb->createNamedParameter('foo'),
'uid_owner' => $qb->createNamedParameter('owner'),
'item_type' => $qb->createNamedParameter('file'),
'item_source' => $qb->createNamedParameter($fileId),
'item_target' => $qb->createNamedParameter('/target'),
'file_source' => $qb->createNamedParameter($fileId),
'file_target' => $qb->createNamedParameter('/target'),
'permissions' => $qb->createNamedParameter(1),
]);
$qb->execute();

//Add test user
$user2 = $this->userManager->createUser('test2', 'test2');
$userFolder = $this->rootFolder->getUserFolder('test2');
$folder = $userFolder->newFolder('foo');
$fileId = $folder->getId();

//Now insert cyclic share
$qb = $this->connection->getQueryBuilder();
$qb->insert('share')
->values([
'share_type' => $qb->createNamedParameter(0),
'share_with' => $qb->createNamedParameter('foo'),
'uid_owner' => $qb->createNamedParameter('owner'),
'item_type' => $qb->createNamedParameter('file'),
'item_source' => $qb->createNamedParameter($fileId),
'item_target' => $qb->createNamedParameter('/target'),
'file_source' => $qb->createNamedParameter($fileId),
'file_target' => $qb->createNamedParameter('/target'),
'permissions' => $qb->createNamedParameter(1),
]);
$qb->execute();

$this->repair->run($this->outputMock);

//Verify
$qb = $this->connection->getQueryBuilder();
$qb->selectAlias($qb->createFunction('COUNT(*)'), 'count')
->from('share');

$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();

$count = (int)$data['count'];

$this->assertEquals(1, $count);

$user1->delete();
$user2->delete();
}
}