diff options
49 files changed, 406 insertions, 181 deletions
diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php index dd4670da5fa..8822deb1661 100644 --- a/apps/dav/lib/connector/sabre/filesplugin.php +++ b/apps/dav/lib/connector/sabre/filesplugin.php @@ -246,6 +246,8 @@ class FilesPlugin extends ServerPlugin { */ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) { + $httpRequest = $this->server->httpRequest; + if ($node instanceof \OCA\DAV\Connector\Sabre\Node) { $propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) { @@ -265,8 +267,10 @@ class FilesPlugin extends ServerPlugin { return $perms; }); - $propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node) { - return $node->getSharePermissions(); + $propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) { + return $node->getSharePermissions( + $httpRequest->getRawServerValue('PHP_AUTH_USER') + ); }); $propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) { diff --git a/apps/dav/lib/connector/sabre/node.php b/apps/dav/lib/connector/sabre/node.php index 979149fc937..ccc035063cd 100644 --- a/apps/dav/lib/connector/sabre/node.php +++ b/apps/dav/lib/connector/sabre/node.php @@ -32,6 +32,8 @@ namespace OCA\DAV\Connector\Sabre; use OC\Files\Mount\MoveableMount; use OCA\DAV\Connector\Sabre\Exception\InvalidPath; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IManager; abstract class Node implements \Sabre\DAV\INode { @@ -61,15 +63,26 @@ abstract class Node implements \Sabre\DAV\INode { protected $info; /** + * @var IManager + */ + protected $shareManager; + + /** * Sets up the node, expects a full path name * * @param \OC\Files\View $view * @param \OCP\Files\FileInfo $info + * @param IManager $shareManager */ - public function __construct($view, $info) { + public function __construct($view, $info, IManager $shareManager = null) { $this->fileView = $view; $this->path = $this->fileView->getRelativePath($info->getPath()); $this->info = $info; + if ($shareManager) { + $this->shareManager = $shareManager; + } else { + $this->shareManager = \OC::$server->getShareManager(); + } } protected function refreshInfo() { @@ -215,9 +228,21 @@ abstract class Node implements \Sabre\DAV\INode { } /** + * @param string $user * @return int */ - public function getSharePermissions() { + public function getSharePermissions($user) { + + // check of we access a federated share + if ($user !== null) { + try { + $share = $this->shareManager->getShareByToken($user); + return $share->getPermissions(); + } catch (ShareNotFound $e) { + // ignore + } + } + $storage = $this->info->getStorage(); $path = $this->info->getInternalPath(); diff --git a/apps/dav/tests/unit/connector/sabre/node.php b/apps/dav/tests/unit/connector/sabre/node.php index 6fdf77adc21..f70d1ee3faf 100644 --- a/apps/dav/tests/unit/connector/sabre/node.php +++ b/apps/dav/tests/unit/connector/sabre/node.php @@ -23,6 +23,12 @@ namespace OCA\DAV\Tests\Unit\Connector\Sabre; +/** + * Class Node + * + * @group DB + * @package OCA\DAV\Tests\Unit\Connector\Sabre + */ class Node extends \Test\TestCase { public function davPermissionsProvider() { return array( @@ -66,52 +72,64 @@ class Node extends \Test\TestCase { public function sharePermissionsProvider() { return [ - [\OCP\Files\FileInfo::TYPE_FILE, 1, 1], - [\OCP\Files\FileInfo::TYPE_FILE, 3, 3], - [\OCP\Files\FileInfo::TYPE_FILE, 5, 1], - [\OCP\Files\FileInfo::TYPE_FILE, 7, 3], - [\OCP\Files\FileInfo::TYPE_FILE, 9, 1], - [\OCP\Files\FileInfo::TYPE_FILE, 11, 3], - [\OCP\Files\FileInfo::TYPE_FILE, 13, 1], - [\OCP\Files\FileInfo::TYPE_FILE, 15, 3], - [\OCP\Files\FileInfo::TYPE_FILE, 17, 17], - [\OCP\Files\FileInfo::TYPE_FILE, 19, 19], - [\OCP\Files\FileInfo::TYPE_FILE, 21, 17], - [\OCP\Files\FileInfo::TYPE_FILE, 23, 19], - [\OCP\Files\FileInfo::TYPE_FILE, 25, 17], - [\OCP\Files\FileInfo::TYPE_FILE, 27, 19], - [\OCP\Files\FileInfo::TYPE_FILE, 29, 17], - [\OCP\Files\FileInfo::TYPE_FILE, 30, 18], - [\OCP\Files\FileInfo::TYPE_FILE, 31, 19], - [\OCP\Files\FileInfo::TYPE_FOLDER, 1, 1], - [\OCP\Files\FileInfo::TYPE_FOLDER, 3, 3], - [\OCP\Files\FileInfo::TYPE_FOLDER, 5, 5], - [\OCP\Files\FileInfo::TYPE_FOLDER, 7, 7], - [\OCP\Files\FileInfo::TYPE_FOLDER, 9, 9], - [\OCP\Files\FileInfo::TYPE_FOLDER, 11, 11], - [\OCP\Files\FileInfo::TYPE_FOLDER, 13, 13], - [\OCP\Files\FileInfo::TYPE_FOLDER, 15, 15], - [\OCP\Files\FileInfo::TYPE_FOLDER, 17, 17], - [\OCP\Files\FileInfo::TYPE_FOLDER, 19, 19], - [\OCP\Files\FileInfo::TYPE_FOLDER, 21, 21], - [\OCP\Files\FileInfo::TYPE_FOLDER, 23, 23], - [\OCP\Files\FileInfo::TYPE_FOLDER, 25, 25], - [\OCP\Files\FileInfo::TYPE_FOLDER, 27, 27], - [\OCP\Files\FileInfo::TYPE_FOLDER, 29, 29], - [\OCP\Files\FileInfo::TYPE_FOLDER, 30, 30], - [\OCP\Files\FileInfo::TYPE_FOLDER, 31, 31], + [\OCP\Files\FileInfo::TYPE_FILE, null, 1, 1], + [\OCP\Files\FileInfo::TYPE_FILE, null, 3, 3], + [\OCP\Files\FileInfo::TYPE_FILE, null, 5, 1], + [\OCP\Files\FileInfo::TYPE_FILE, null, 7, 3], + [\OCP\Files\FileInfo::TYPE_FILE, null, 9, 1], + [\OCP\Files\FileInfo::TYPE_FILE, null, 11, 3], + [\OCP\Files\FileInfo::TYPE_FILE, null, 13, 1], + [\OCP\Files\FileInfo::TYPE_FILE, null, 15, 3], + [\OCP\Files\FileInfo::TYPE_FILE, null, 17, 17], + [\OCP\Files\FileInfo::TYPE_FILE, null, 19, 19], + [\OCP\Files\FileInfo::TYPE_FILE, null, 21, 17], + [\OCP\Files\FileInfo::TYPE_FILE, null, 23, 19], + [\OCP\Files\FileInfo::TYPE_FILE, null, 25, 17], + [\OCP\Files\FileInfo::TYPE_FILE, null, 27, 19], + [\OCP\Files\FileInfo::TYPE_FILE, null, 29, 17], + [\OCP\Files\FileInfo::TYPE_FILE, null, 30, 18], + [\OCP\Files\FileInfo::TYPE_FILE, null, 31, 19], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 1, 1], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 3, 3], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 5, 5], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 7, 7], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 9, 9], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 11, 11], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 13, 13], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 15, 15], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 17, 17], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 19, 19], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 21, 21], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 23, 23], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 25, 25], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 27, 27], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 29, 29], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 30, 30], + [\OCP\Files\FileInfo::TYPE_FOLDER, null, 31, 31], + [\OCP\Files\FileInfo::TYPE_FOLDER, 'shareToken', 7, 7], ]; } /** * @dataProvider sharePermissionsProvider */ - public function testSharePermissions($type, $permissions, $expected) { + public function testSharePermissions($type, $user, $permissions, $expected) { $storage = $this->getMock('\OCP\Files\Storage'); $storage->method('getPermissions')->willReturn($permissions); $mountpoint = $this->getMock('\OCP\Files\Mount\IMountPoint'); $mountpoint->method('getMountPoint')->willReturn('myPath'); + $shareManager = $this->getMockBuilder('OCP\Share\IManager')->disableOriginalConstructor()->getMock(); + $share = $this->getMockBuilder('OCP\Share\IShare')->disableOriginalConstructor()->getMock(); + + if ($user === null) { + $shareManager->expects($this->never())->method('getShareByToken'); + $share->expects($this->never())->method('getPermissions'); + } else { + $shareManager->expects($this->once())->method('getShareByToken')->with($user) + ->willReturn($share); + $share->expects($this->once())->method('getPermissions')->willReturn($permissions); + } $info = $this->getMockBuilder('\OC\Files\FileInfo') ->disableOriginalConstructor() @@ -125,6 +143,7 @@ class Node extends \Test\TestCase { $view = $this->getMock('\OC\Files\View'); $node = new \OCA\DAV\Connector\Sabre\File($view, $info); - $this->assertEquals($expected, $node->getSharePermissions()); + $this->invokePrivate($node, 'shareManager', [$shareManager]); + $this->assertEquals($expected, $node->getSharePermissions($user)); } } diff --git a/apps/files_sharing/ajax/shareinfo.php b/apps/files_sharing/ajax/shareinfo.php index e15e12fd287..47bc061c136 100644 --- a/apps/files_sharing/ajax/shareinfo.php +++ b/apps/files_sharing/ajax/shareinfo.php @@ -62,20 +62,25 @@ if (!$isWritable) { $rootInfo = \OC\Files\Filesystem::getFileInfo($path); $rootView = new \OC\Files\View(''); +$shareManager = \OC::$server->getShareManager(); +$share = $shareManager->getShareByToken($token); +$sharePermissions= (int)$share->getPermissions(); + /** * @param \OCP\Files\FileInfo $dir * @param \OC\Files\View $view * @return array */ -function getChildInfo($dir, $view) { +function getChildInfo($dir, $view, $sharePermissions) { $children = $view->getDirectoryContent($dir->getPath()); $result = array(); foreach ($children as $child) { $formatted = \OCA\Files\Helper::formatFileInfo($child); if ($child->getType() === 'dir') { - $formatted['children'] = getChildInfo($child, $view); + $formatted['children'] = getChildInfo($child, $view, $sharePermissions); } $formatted['mtime'] = $formatted['mtime'] / 1000; + $formatted['permissions'] = $sharePermissions & (int)$formatted['permissions']; $result[] = $formatted; } return $result; @@ -83,8 +88,11 @@ function getChildInfo($dir, $view) { $result = \OCA\Files\Helper::formatFileInfo($rootInfo); $result['mtime'] = $result['mtime'] / 1000; +$result['permissions'] = (int)$result['permissions'] & $sharePermissions; + + if ($rootInfo->getType() === 'dir') { - $result['children'] = getChildInfo($rootInfo, $rootView); + $result['children'] = getChildInfo($rootInfo, $rootView, $sharePermissions); } OCP\JSON::success(array('data' => $result)); diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index 8fe7af66044..4382dcab0c3 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -319,5 +319,21 @@ class Storage extends DAV implements ISharedStorage { } return ($this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE); } + + public function getPermissions($path) { + $response = $this->propfind($path); + if (isset($response['{http://open-collaboration-services.org/ns}share-permissions'])) { + $permissions = $response['{http://open-collaboration-services.org/ns}share-permissions']; + } else { + // use default permission if remote server doesn't provide the share permissions + if ($this->is_dir($path)) { + $permissions = \OCP\Constants::PERMISSION_ALL; + } else { + $permissions = \OCP\Constants::PERMISSION_ALL & ~\OCP\Constants::PERMISSION_CREATE; + } + } + + return $permissions; + } } diff --git a/apps/files_sharing/tests/encryptedsizepropagation.php b/apps/files_sharing/tests/encryptedsizepropagation.php new file mode 100644 index 00000000000..e341606abe4 --- /dev/null +++ b/apps/files_sharing/tests/encryptedsizepropagation.php @@ -0,0 +1,41 @@ +<?php +/** + * @author Robin Appelman <icewind@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 OCA\Files_sharing\Tests; + +use OC\Files\View; +use Test\Traits\EncryptionTrait; + +/** + * @group DB + */ +class EncryptedSizePropagation extends SizePropagation { + use EncryptionTrait; + + protected function setupUser($name, $password = '') { + $this->createUser($name, $password); + $tmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); + $this->setupForUser($name, $password); + $this->loginWithEncryption($name); + return new View('/' . $name . '/files'); + } +} diff --git a/apps/files_sharing/tests/sizepropagation.php b/apps/files_sharing/tests/sizepropagation.php index d4062e3a38c..c0f5696c16d 100644 --- a/apps/files_sharing/tests/sizepropagation.php +++ b/apps/files_sharing/tests/sizepropagation.php @@ -24,6 +24,8 @@ namespace OCA\Files_sharing\Tests; use OC\Files\View; +use Test\Traits\MountProviderTrait; +use Test\Traits\UserTrait; /** * Class SizePropagation @@ -33,13 +35,21 @@ use OC\Files\View; * @package OCA\Files_sharing\Tests */ class SizePropagation extends TestCase { + use UserTrait; + use MountProviderTrait; + + protected function setupUser($name, $password = '') { + $this->createUser($name, $password); + $tmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); + $this->loginAsUser($name); + return new View('/' . $name . '/files'); + } public function testSizePropagationWhenOwnerChangesFile() { - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); - $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); - $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->mkdir('/sharedfolder/subfolder'); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar'); @@ -52,31 +62,29 @@ class SizePropagation extends TestCase { ); $ownerRootInfo = $ownerView->getFileInfo('', false); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt')); $recipientRootInfo = $recipientView->getFileInfo('', false); // when file changed as owner - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar'); // size of recipient's root stays the same - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $newRecipientRootInfo = $recipientView->getFileInfo('', false); $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize()); // size of owner's root increases - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $newOwnerRootInfo = $ownerView->getFileInfo('', false); $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize()); } public function testSizePropagationWhenRecipientChangesFile() { - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); - $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); - $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2); $ownerView->mkdir('/sharedfolder/subfolder'); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar'); @@ -89,9 +97,10 @@ class SizePropagation extends TestCase { ); $ownerRootInfo = $ownerView->getFileInfo('', false); - $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt')); $recipientRootInfo = $recipientView->getFileInfo('', false); + $recipientRootInfoWithMounts = $recipientView->getFileInfo('', true); // when file changed as recipient $recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar'); @@ -100,8 +109,12 @@ class SizePropagation extends TestCase { $newRecipientRootInfo = $recipientView->getFileInfo('', false); $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize()); + // but the size including mountpoints increases + $newRecipientRootInfo = $recipientView->getFileInfo('', true); + $this->assertEquals($recipientRootInfoWithMounts->getSize() +3, $newRecipientRootInfo->getSize()); + // size of owner's root increases - $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $newOwnerRootInfo = $ownerView->getFileInfo('', false); $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize()); } diff --git a/core/Command/Maintenance/Repair.php b/core/Command/Maintenance/Repair.php index 95e2b872227..2da76143390 100644 --- a/core/Command/Maintenance/Repair.php +++ b/core/Command/Maintenance/Repair.php @@ -24,15 +24,14 @@ namespace OC\Core\Command\Maintenance; +use Exception; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Repair extends Command { - /** - * @var \OC\Repair $repair - */ + /** @var \OC\Repair $repair */ protected $repair; /** @var \OCP\IConfig */ protected $config; @@ -55,9 +54,7 @@ class Repair extends Command { 'include-expensive', null, InputOption::VALUE_NONE, - 'Use this option when you want to include resource and load expensive tasks' - ) - ; + 'Use this option when you want to include resource and load expensive tasks'); } protected function execute(InputInterface $input, OutputInterface $output) { @@ -68,6 +65,25 @@ class Repair extends Command { } } + $apps = \OC::$server->getAppManager()->getInstalledApps(); + foreach ($apps as $app) { + if (!\OC_App::isEnabled($app)) { + continue; + } + $info = \OC_App::getAppInfo($app); + if (!is_array($info)) { + continue; + } + $steps = $info['repair-steps']['post-migration']; + foreach ($steps as $step) { + try { + $this->repair->addStep($step); + } catch (Exception $ex) { + $output->writeln("<error>Failed to load repair step for $app: {$ex->getMessage()}</error>"); + } + } + } + $maintenanceMode = $this->config->getSystemValue('maintenance', false); $this->config->setSystemValue('maintenance', true); diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js index fd0b6d9d1bd..83fde154615 100644 --- a/core/js/sharedialogshareelistview.js +++ b/core/js/sharedialogshareelistview.js @@ -22,28 +22,25 @@ '<div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div>' + '{{/if}}' + '<span class="has-tooltip username" title="{{shareWith}}">{{shareWithDisplayName}}</span>' + - '{{#if mailNotificationEnabled}} {{#unless isRemoteShare}}' + + '{{#if mailNotificationEnabled}} {{#unless isRemoteShare}}' + '<span class="shareOption">' + '<input id="mail-{{cid}}-{{shareWith}}" type="checkbox" name="mailNotification" class="mailNotification checkbox" {{#if wasMailSent}}checked="checked"{{/if}} />' + '<label for="mail-{{cid}}-{{shareWith}}">{{notifyByMailLabel}}</label>' + '</span>' + '{{/unless}} {{/if}}' + - '{{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isRemoteShare}}' + + '{{#if isResharingAllowed}} {{#if sharePermissionPossible}}' + '<span class="shareOption">' + '<input id="canShare-{{cid}}-{{shareWith}}" type="checkbox" name="share" class="permissions checkbox" {{#if hasSharePermission}}checked="checked"{{/if}} data-permissions="{{sharePermission}}" />' + '<label for="canShare-{{cid}}-{{shareWith}}">{{canShareLabel}}</label>' + '</span>' + - '{{/unless}} {{/if}} {{/if}}' + + '{{/if}} {{/if}}' + '{{#if editPermissionPossible}}' + '<span class="shareOption">' + '<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" {{#if hasEditPermission}}checked="checked"{{/if}} />' + '<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' + - '{{#unless isRemoteShare}}' + '<a href="#" class="showCruds"><img class="svg" alt="{{crudsLabel}}" src="{{triangleSImage}}"/></a>' + - '{{/unless}}' + '</span>' + '{{/if}}' + - '{{#unless isRemoteShare}}' + '<div class="cruds hidden">' + '{{#if createPermissionPossible}}' + '<span class="shareOption">' + @@ -57,14 +54,13 @@ '<label for="canUpdate-{{cid}}-{{shareWith}}">{{updatePermissionLabel}}</label>' + '</span>' + '{{/if}}' + - '{{#if deletePermissionPossible}} {{#unless isRemoteShare}}' + + '{{#if deletePermissionPossible}}' + '<span class="shareOption">' + '<input id="canDelete-{{cid}}-{{shareWith}}" type="checkbox" name="delete" class="permissions checkbox" {{#if hasDeletePermission}}checked="checked"{{/if}} data-permissions="{{deletePermission}}"/>' + '<label for="canDelete-{{cid}}-{{shareWith}}">{{deletePermissionLabel}}</label>' + '</span>' + - '{{/unless}} {{/if}}' + + '{{/if}}' + '</div>' + - '{{/unless}}' + '</li>' + '{{/each}}' + '</ul>' @@ -125,10 +121,6 @@ shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'group') + ')'; } else if (shareType === OC.Share.SHARE_TYPE_REMOTE) { shareWithDisplayName = shareWithDisplayName + " (" + t('core', 'remote') + ')'; - hasPermissionOverride = { - createPermissionPossible: true, - updatePermissionPossible: true - }; } return _.extend(hasPermissionOverride, { diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index 292230d26d5..3ced66a1a78 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -154,21 +154,17 @@ // Default permissions are Edit (CRUD) and Share // Check if these permissions are possible var permissions = OC.PERMISSION_READ; - if (shareType === OC.Share.SHARE_TYPE_REMOTE) { - permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_READ; - } else { - if (this.updatePermissionPossible()) { - permissions = permissions | OC.PERMISSION_UPDATE; - } - if (this.createPermissionPossible()) { - permissions = permissions | OC.PERMISSION_CREATE; - } - if (this.deletePermissionPossible()) { - permissions = permissions | OC.PERMISSION_DELETE; - } - if (this.configModel.get('isResharingAllowed') && (this.sharePermissionPossible())) { - permissions = permissions | OC.PERMISSION_SHARE; - } + if (this.updatePermissionPossible()) { + permissions = permissions | OC.PERMISSION_UPDATE; + } + if (this.createPermissionPossible()) { + permissions = permissions | OC.PERMISSION_CREATE; + } + if (this.deletePermissionPossible()) { + permissions = permissions | OC.PERMISSION_DELETE; + } + if (this.configModel.get('isResharingAllowed') && (this.sharePermissionPossible())) { + permissions = permissions | OC.PERMISSION_SHARE; } attributes.permissions = permissions; @@ -411,12 +407,6 @@ if(!_.isObject(share)) { throw "Unknown Share"; } - if( share.share_type === OC.Share.SHARE_TYPE_REMOTE - && ( permission === OC.PERMISSION_SHARE - || permission === OC.PERMISSION_DELETE)) - { - return false; - } return (share.permissions & permission) === permission; }, diff --git a/core/register_command.php b/core/register_command.php index 90a54233e66..0b1a019f993 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -32,7 +32,7 @@ /** @var $application Symfony\Component\Console\Application */ $application->add(new OC\Core\Command\Status); $application->add(new OC\Core\Command\Check(\OC::$server->getConfig())); -$infoParser = new \OC\App\InfoParser(\OC::$server->getHTTPHelper(), \OC::$server->getURLGenerator()); +$infoParser = new \OC\App\InfoParser(\OC::$server->getURLGenerator()); $application->add(new OC\Core\Command\App\CheckCode($infoParser)); $application->add(new OC\Core\Command\L10n\CreateJs()); $application->add(new \OC\Core\Command\Integrity\SignApp( diff --git a/lib/base.php b/lib/base.php index 8ea164a5007..fb58177a432 100644 --- a/lib/base.php +++ b/lib/base.php @@ -341,10 +341,14 @@ class OC { $disableWebUpdater = $systemConfig->getValue('upgrade.disable-web', false); $tooBig = false; if (!$disableWebUpdater) { - // count users - $stats = \OC::$server->getUserManager()->countUsers(); - $totalUsers = array_sum($stats); - $tooBig = ($totalUsers > 50); + $apps = \OC::$server->getAppManager(); + $tooBig = $apps->isInstalled('user_ldap') || $apps->isInstalled('user_shibboleth'); + if (!$tooBig) { + // count users + $stats = \OC::$server->getUserManager()->countUsers(); + $totalUsers = array_sum($stats); + $tooBig = ($totalUsers > 50); + } } if ($disableWebUpdater || $tooBig) { // send http status 503 @@ -488,6 +492,9 @@ class OC { self::$CLI = (php_sapi_name() == 'cli'); + // Add default composer PSR-4 autoloader + require_once OC::$SERVERROOT . '/lib/composer/autoload.php'; + try { self::initPaths(); // setup 3rdparty autoloader @@ -507,9 +514,6 @@ class OC { exit(); } - // Add default composer PSR-4 autoloader - require_once OC::$SERVERROOT . '/lib/composer/autoload.php'; - // setup the basic server self::$server = new \OC\Server(\OC::$WEBROOT, self::$config); \OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd); diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php index c33e5349f3b..e763364e148 100644 --- a/lib/private/App/InfoParser.php +++ b/lib/private/App/InfoParser.php @@ -27,22 +27,14 @@ namespace OC\App; use OCP\IURLGenerator; class InfoParser { - /** - * @var \OC\HTTPHelper - */ - private $httpHelper; - /** - * @var IURLGenerator - */ + /** @var IURLGenerator */ private $urlGenerator; /** - * @param \OC\HTTPHelper $httpHelper * @param IURLGenerator $urlGenerator */ - public function __construct(\OC\HTTPHelper $httpHelper, IURLGenerator $urlGenerator) { - $this->httpHelper = $httpHelper; + public function __construct(IURLGenerator $urlGenerator) { $this->urlGenerator = $urlGenerator; } @@ -68,23 +60,32 @@ class InfoParser { return null; } if (!array_key_exists('info', $array)) { - $array['info'] = array(); + $array['info'] = []; } if (!array_key_exists('remote', $array)) { - $array['remote'] = array(); + $array['remote'] = []; } if (!array_key_exists('public', $array)) { - $array['public'] = array(); + $array['public'] = []; } if (!array_key_exists('types', $array)) { - $array['types'] = array(); + $array['types'] = []; + } + if (!array_key_exists('repair-steps', $array)) { + $array['repair-steps'] = []; + } + if (!array_key_exists('pre-migration', $array['repair-steps'])) { + $array['repair-steps']['pre-migration'] = []; + } + if (!array_key_exists('post-migration', $array['repair-steps'])) { + $array['repair-steps']['post-migration'] = []; } if (array_key_exists('documentation', $array) && is_array($array['documentation'])) { foreach ($array['documentation'] as $key => $url) { // If it is not an absolute URL we assume it is a key // i.e. admin-ldap will get converted to go.php?to=admin-ldap - if (!$this->httpHelper->isHTTPURL($url)) { + if (!$this->isHTTPURL($url)) { $url = $this->urlGenerator->linkToDocs($url); } @@ -100,10 +101,15 @@ class InfoParser { } } } else { - $array['types'] = array(); + $array['types'] = []; } } - + if (isset($array['repair-steps']['pre-migration']['step']) && is_array($array['repair-steps']['pre-migration']['step'])) { + $array['repair-steps']['pre-migration'] = $array['repair-steps']['pre-migration']['step']; + } + if (isset($array['repair-steps']['post-migration']['step']) && is_array($array['repair-steps']['post-migration']['step'])) { + $array['repair-steps']['post-migration'] = $array['repair-steps']['post-migration']['step']; + } return $array; } @@ -116,7 +122,7 @@ class InfoParser { return (string)$xml; } - $array = array(); + $array = []; foreach ($xml->children() as $element => $node) { $totalElement = count($xml->{$element}); @@ -129,9 +135,9 @@ class InfoParser { // Has attributes if ($attributes = $node->attributes()) { - $data = array( - '@attributes' => array(), - ); + $data = [ + '@attributes' => [], + ]; if (!count($node->children())){ $value = (string)$node; if (!empty($value)) { @@ -161,4 +167,8 @@ class InfoParser { return $array; } + + private function isHTTPURL($url) { + return stripos($url, 'https://') === 0 || stripos($url, 'http://') === 0; + } } diff --git a/lib/private/appframework/app.php b/lib/private/AppFramework/App.php index 376a8559454..376a8559454 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/AppFramework/App.php diff --git a/lib/private/appframework/core/api.php b/lib/private/AppFramework/Core/API.php index 67b696948f0..67b696948f0 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/AppFramework/Core/API.php diff --git a/lib/private/appframework/db/db.php b/lib/private/AppFramework/Db/Db.php index 0d17d7bc225..0d17d7bc225 100644 --- a/lib/private/appframework/db/db.php +++ b/lib/private/AppFramework/Db/Db.php diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index f74fe4aeb99..f74fe4aeb99 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php diff --git a/lib/private/appframework/http.php b/lib/private/AppFramework/Http.php index a99f7ea437f..a99f7ea437f 100644 --- a/lib/private/appframework/http.php +++ b/lib/private/AppFramework/Http.php diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/AppFramework/Http/Dispatcher.php index 641339c0d94..641339c0d94 100644 --- a/lib/private/appframework/http/dispatcher.php +++ b/lib/private/AppFramework/Http/Dispatcher.php diff --git a/lib/private/appframework/http/output.php b/lib/private/AppFramework/Http/Output.php index 469c809c21c..469c809c21c 100644 --- a/lib/private/appframework/http/output.php +++ b/lib/private/AppFramework/Http/Output.php diff --git a/lib/private/appframework/http/request.php b/lib/private/AppFramework/Http/Request.php index 7cd8cedcfdd..7cd8cedcfdd 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/AppFramework/Http/Request.php diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php index 4bd25f79bba..4bd25f79bba 100644 --- a/lib/private/appframework/middleware/middlewaredispatcher.php +++ b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php diff --git a/lib/private/appframework/middleware/security/corsmiddleware.php b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php index 258119b326a..258119b326a 100644 --- a/lib/private/appframework/middleware/security/corsmiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php diff --git a/lib/private/appframework/middleware/security/exceptions/appnotenabledexception.php b/lib/private/AppFramework/Middleware/Security/Exceptions/AppNotEnabledException.php index 59e247f3307..ce2d68054f2 100644 --- a/lib/private/appframework/middleware/security/exceptions/appnotenabledexception.php +++ b/lib/private/AppFramework/Middleware/Security/Exceptions/AppNotEnabledException.php @@ -21,7 +21,7 @@ * */ -namespace OC\Appframework\Middleware\Security\Exceptions; +namespace OC\AppFramework\Middleware\Security\Exceptions; use OCP\AppFramework\Http; @@ -29,7 +29,7 @@ use OCP\AppFramework\Http; * Class AppNotEnabledException is thrown when a resource for an application is * requested that is not enabled. * - * @package OC\Appframework\Middleware\Security\Exceptions + * @package OC\AppFramework\Middleware\Security\Exceptions */ class AppNotEnabledException extends SecurityException { public function __construct() { diff --git a/lib/private/appframework/middleware/security/exceptions/crosssiterequestforgeryexception.php b/lib/private/AppFramework/Middleware/Security/Exceptions/CrossSiteRequestForgeryException.php index 0eeb81730d4..251906bfca9 100644 --- a/lib/private/appframework/middleware/security/exceptions/crosssiterequestforgeryexception.php +++ b/lib/private/AppFramework/Middleware/Security/Exceptions/CrossSiteRequestForgeryException.php @@ -21,7 +21,7 @@ * */ -namespace OC\Appframework\Middleware\Security\Exceptions; +namespace OC\AppFramework\Middleware\Security\Exceptions; use OCP\AppFramework\Http; @@ -29,7 +29,7 @@ use OCP\AppFramework\Http; * Class CrossSiteRequestForgeryException is thrown when a CSRF exception has * been encountered. * - * @package OC\Appframework\Middleware\Security\Exceptions + * @package OC\AppFramework\Middleware\Security\Exceptions */ class CrossSiteRequestForgeryException extends SecurityException { public function __construct() { diff --git a/lib/private/appframework/middleware/security/exceptions/notadminexception.php b/lib/private/AppFramework/Middleware/Security/Exceptions/NotAdminException.php index be0f2f9d2a9..2a9fafa9f73 100644 --- a/lib/private/appframework/middleware/security/exceptions/notadminexception.php +++ b/lib/private/AppFramework/Middleware/Security/Exceptions/NotAdminException.php @@ -21,7 +21,7 @@ * */ -namespace OC\Appframework\Middleware\Security\Exceptions; +namespace OC\AppFramework\Middleware\Security\Exceptions; use OCP\AppFramework\Http; @@ -29,7 +29,7 @@ use OCP\AppFramework\Http; * Class NotAdminException is thrown when a resource has been requested by a * non-admin user that is not accessible to non-admin users. * - * @package OC\Appframework\Middleware\Security\Exceptions + * @package OC\AppFramework\Middleware\Security\Exceptions */ class NotAdminException extends SecurityException { public function __construct() { diff --git a/lib/private/appframework/middleware/security/exceptions/notloggedinexception.php b/lib/private/AppFramework/Middleware/Security/Exceptions/NotLoggedInException.php index f5b2e032032..54e78dc5a5b 100644 --- a/lib/private/appframework/middleware/security/exceptions/notloggedinexception.php +++ b/lib/private/AppFramework/Middleware/Security/Exceptions/NotLoggedInException.php @@ -21,7 +21,7 @@ * */ -namespace OC\Appframework\Middleware\Security\Exceptions; +namespace OC\AppFramework\Middleware\Security\Exceptions; use OCP\AppFramework\Http; @@ -29,7 +29,7 @@ use OCP\AppFramework\Http; * Class NotLoggedInException is thrown when a resource has been requested by a * guest user that is not accessible to the public. * - * @package OC\Appframework\Middleware\Security\Exceptions + * @package OC\AppFramework\Middleware\Security\Exceptions */ class NotLoggedInException extends SecurityException { public function __construct() { diff --git a/lib/private/appframework/middleware/security/exceptions/securityexception.php b/lib/private/AppFramework/Middleware/Security/Exceptions/SecurityException.php index c86614ec477..c86614ec477 100644 --- a/lib/private/appframework/middleware/security/exceptions/securityexception.php +++ b/lib/private/AppFramework/Middleware/Security/Exceptions/SecurityException.php diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php index 4afd29cd060..2c2f46a59f4 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php @@ -26,10 +26,10 @@ namespace OC\AppFramework\Middleware\Security; -use OC\Appframework\Middleware\Security\Exceptions\AppNotEnabledException; -use OC\Appframework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException; -use OC\Appframework\Middleware\Security\Exceptions\NotAdminException; -use OC\Appframework\Middleware\Security\Exceptions\NotLoggedInException; +use OC\AppFramework\Middleware\Security\Exceptions\AppNotEnabledException; +use OC\AppFramework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; +use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\CSP\ContentSecurityPolicyManager; use OCP\AppFramework\Http\ContentSecurityPolicy; diff --git a/lib/private/appframework/middleware/sessionmiddleware.php b/lib/private/AppFramework/Middleware/SessionMiddleware.php index b218b48ea11..b218b48ea11 100644 --- a/lib/private/appframework/middleware/sessionmiddleware.php +++ b/lib/private/AppFramework/Middleware/SessionMiddleware.php diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/AppFramework/Routing/RouteActionHandler.php index b282fc1b452..e8a7b8a1c61 100644 --- a/lib/private/appframework/routing/routeactionhandler.php +++ b/lib/private/AppFramework/Routing/RouteActionHandler.php @@ -21,7 +21,7 @@ * */ -namespace OC\AppFramework\routing; +namespace OC\AppFramework\Routing; use \OC\AppFramework\App; use \OC\AppFramework\DependencyInjection\DIContainer; diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/AppFramework/Routing/RouteConfig.php index dd029ba9a00..f2ec5c0c881 100644 --- a/lib/private/appframework/routing/routeconfig.php +++ b/lib/private/AppFramework/Routing/RouteConfig.php @@ -24,7 +24,7 @@ * */ -namespace OC\AppFramework\routing; +namespace OC\AppFramework\Routing; use OC\AppFramework\DependencyInjection\DIContainer; use OCP\Route\IRouter; diff --git a/lib/private/appframework/utility/controllermethodreflector.php b/lib/private/AppFramework/Utility/ControllerMethodReflector.php index de83749fbaf..de83749fbaf 100644 --- a/lib/private/appframework/utility/controllermethodreflector.php +++ b/lib/private/AppFramework/Utility/ControllerMethodReflector.php diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php index 78ded39735e..78ded39735e 100644 --- a/lib/private/appframework/utility/simplecontainer.php +++ b/lib/private/AppFramework/Utility/SimpleContainer.php diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/AppFramework/Utility/TimeFactory.php index 5241b367069..5241b367069 100644 --- a/lib/private/appframework/utility/timefactory.php +++ b/lib/private/AppFramework/Utility/TimeFactory.php diff --git a/lib/private/app.php b/lib/private/app.php index 8a8b97d2cd4..7bcbef32531 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -47,6 +47,7 @@ use OC\App\DependencyAnalyzer; use OC\App\Platform; use OC\OCSClient; +use OC\Repair; /** * This class manages the apps. It allows them to register and integrate in the @@ -626,7 +627,7 @@ class OC_App { $file = $appPath . '/appinfo/info.xml'; } - $parser = new \OC\App\InfoParser(\OC::$server->getHTTPHelper(), \OC::$server->getURLGenerator()); + $parser = new \OC\App\InfoParser(\OC::$server->getURLGenerator()); $data = $parser->parse($file); if (is_array($data)) { @@ -1031,7 +1032,6 @@ class OC_App { if (!empty($requireMax) && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>') ) { - return false; } @@ -1051,7 +1051,6 @@ class OC_App { return $versions; } - /** * @param string $app * @return bool @@ -1148,9 +1147,12 @@ class OC_App { if($appPath === false) { return false; } + $appData = self::getAppInfo($appId); + self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']); if (file_exists($appPath . '/appinfo/database.xml')) { OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml'); } + self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']); unset(self::$appVersion[$appId]); // run upgrade code if (file_exists($appPath . '/appinfo/update.php')) { @@ -1159,7 +1161,6 @@ class OC_App { } //set remote/public handlers - $appData = self::getAppInfo($appId); if (array_key_exists('ocsid', $appData)) { \OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']); } elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) { @@ -1182,6 +1183,34 @@ class OC_App { /** * @param string $appId + * @param string[] $steps + * @throws \OC\NeedsUpdateException + */ + private static function executeRepairSteps($appId, array $steps) { + if (empty($steps)) { + return; + } + // load the app + self::loadApp($appId, false); + + $dispatcher = OC::$server->getEventDispatcher(); + + // load the steps + $r = new Repair([], $dispatcher); + foreach ($steps as $step) { + try { + $r->addStep($step); + } catch (Exception $ex) { + $r->emit('\OC\Repair', 'error', [$ex->getMessage()]); + \OC::$server->getLogger()->logException($ex); + } + } + // run the steps + $r->run(); + } + + /** + * @param string $appId * @return \OC\Files\View|false */ public static function getStorage($appId) { diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index c16e8515b01..8730707f1c2 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -205,6 +205,10 @@ class Scanner extends BasicEmitter implements IScanner { $data['oldSize'] = 0; } + if (isset($cacheData['encrypted'])) { + $data['encrypted'] = $cacheData['encrypted']; + } + // post-emit only if it was a file. By that we avoid counting/treating folders as files if ($data['mimetype'] !== 'httpd/unix-directory') { $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId)); @@ -222,6 +226,9 @@ class Scanner extends BasicEmitter implements IScanner { } } + if ($data && !isset($data['encrypted'])) { + $data['encrypted'] = false; + } return $data; } diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php index 80ba704883e..3f80f2b6167 100644 --- a/lib/private/files/cache/updater.php +++ b/lib/private/files/cache/updater.php @@ -118,7 +118,10 @@ class Updater implements IUpdater { } $data = $this->scanner->scan($path, Scanner::SCAN_SHALLOW, -1, false); - if (isset($data['oldSize']) && isset($data['size'])) { + if ( + isset($data['oldSize']) && isset($data['size']) && + !$data['encrypted'] // encryption is a pita and touches the cache itself + ) { $sizeDifference = $data['size'] - $data['oldSize']; } else { // scanner didn't provide size info, fallback to full size calculation diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index df0f4c7e91d..8eebea1f3ba 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -246,7 +246,7 @@ class DAV extends Common { * * @throws NotFound */ - private function propfind($path) { + protected function propfind($path) { $path = $this->cleanPath($path); $cachedResponse = $this->statCache->get($path); if ($cachedResponse === false) { @@ -264,6 +264,7 @@ class DAV extends Common { '{DAV:}getcontentlength', '{DAV:}getcontenttype', '{http://owncloud.org/ns}permissions', + '{http://open-collaboration-services.org/ns}share-permissions', '{DAV:}resourcetype', '{DAV:}getetag', ) @@ -741,6 +742,9 @@ class DAV extends Common { } if (!empty($etag) && $cachedData['etag'] !== $etag) { return true; + } else if (isset($response['{http://open-collaboration-services.org/ns}share-permissions'])) { + $sharePermissions = (int)$response['{http://open-collaboration-services.org/ns}share-permissions']; + return $sharePermissions !== $cachedData['permissions']; } else if (isset($response['{http://owncloud.org/ns}permissions'])) { $permissions = $this->parsePermissions($response['{http://owncloud.org/ns}permissions']); return $permissions !== $cachedData['permissions']; diff --git a/lib/private/repair.php b/lib/private/repair.php index 779f09d42ec..28fe993db07 100644 --- a/lib/private/repair.php +++ b/lib/private/repair.php @@ -46,20 +46,24 @@ use OC\Repair\RepairMimeTypes; use OC\Repair\SearchLuceneTables; use OC\Repair\UpdateOutdatedOcsIds; use OC\Repair\RepairInvalidShares; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\GenericEvent; class Repair extends BasicEmitter { - /** - * @var RepairStep[] - **/ + /* @var RepairStep[] */ private $repairSteps; + /** @var EventDispatcher */ + private $dispatcher; /** * Creates a new repair step runner * - * @param array $repairSteps array of RepairStep instances + * @param RepairStep[] $repairSteps array of RepairStep instances + * @param EventDispatcher $dispatcher */ - public function __construct($repairSteps = array()) { + public function __construct($repairSteps = [], EventDispatcher $dispatcher = null) { $this->repairSteps = $repairSteps; + $this->dispatcher = $dispatcher; } /** @@ -91,10 +95,24 @@ class Repair extends BasicEmitter { /** * Add repair step * - * @param RepairStep $repairStep repair step + * @param RepairStep|string $repairStep repair step + * @throws \Exception */ public function addStep($repairStep) { - $this->repairSteps[] = $repairStep; + if (is_string($repairStep)) { + if (class_exists($repairStep)) { + $s = new $repairStep(); + if ($s instanceof RepairStep) { + $this->repairSteps[] = $s; + } else { + throw new \Exception("Repair step '$repairStep' is not of type \\OC\\RepairStep"); + } + } else { + throw new \Exception("Repair step '$repairStep' is unknown"); + } + } else { + $this->repairSteps[] = $repairStep; + } } /** @@ -159,10 +177,12 @@ class Repair extends BasicEmitter { /** * {@inheritDoc} - * - * Re-declared as public to allow invocation from within the closure above in php 5.3 */ - public function emit($scope, $method, array $arguments = array()) { + public function emit($scope, $method, array $arguments = []) { parent::emit($scope, $method, $arguments); + if (!is_null($this->dispatcher)) { + $this->dispatcher->dispatch("$scope::$method", + new GenericEvent("$scope::$method", $arguments)); + } } } diff --git a/lib/private/updater.php b/lib/private/updater.php index 627e01596bb..66f410b779f 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -40,6 +40,7 @@ use OC_Installer; use OCP\IConfig; use OC\Setup; use OCP\ILogger; +use Symfony\Component\EventDispatcher\GenericEvent; /** * Class that handles autoupdating of ownCloud @@ -361,6 +362,7 @@ class Updater extends BasicEmitter { * @throws NeedsUpdateException */ protected function doAppUpgrade() { + $this->emitRepairEvents(); $apps = \OC_App::getEnabledApps(); $priorityTypes = array('authentication', 'filesystem', 'logging'); $pseudoOtherType = 'other'; @@ -385,9 +387,9 @@ class Updater extends BasicEmitter { foreach ($stacks as $type => $stack) { foreach ($stack as $appId) { if (\OC_App::shouldUpgrade($appId)) { - $this->emit('\OC\Updater', 'appUpgradeStarted', array($appId, \OC_App::getAppVersion($appId))); + $this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OC_App::getAppVersion($appId)]); \OC_App::updateApp($appId); - $this->emit('\OC\Updater', 'appUpgrade', array($appId, \OC_App::getAppVersion($appId))); + $this->emit('\OC\Updater', 'appUpgrade', [$appId, \OC_App::getAppVersion($appId)]); } if($type !== $pseudoOtherType) { // load authentication, filesystem and logging apps after @@ -473,5 +475,33 @@ class Updater extends BasicEmitter { } } } + + /** + * Forward messages emitted by the repair routine + */ + private function emitRepairEvents() { + $dispatcher = \OC::$server->getEventDispatcher(); + $dispatcher->addListener('\OC\Repair::warning', function ($event) { + if ($event instanceof GenericEvent) { + $this->emit('\OC\Updater', 'repairWarning', $event->getArguments()); + } + }); + $dispatcher->addListener('\OC\Repair::error', function ($event) { + if ($event instanceof GenericEvent) { + $this->emit('\OC\Updater', 'repairError', $event->getArguments()); + } + }); + $dispatcher->addListener('\OC\Repair::info', function ($event) { + if ($event instanceof GenericEvent) { + $this->emit('\OC\Updater', 'repairInfo', $event->getArguments()); + } + }); + $dispatcher->addListener('\OC\Repair::step', function ($event) { + if ($event instanceof GenericEvent) { + $this->emit('\OC\Updater', 'repairStep', $event->getArguments()); + } + }); + } + } diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php index 09297d91ee8..e5069150765 100644 --- a/lib/public/appframework/app.php +++ b/lib/public/appframework/app.php @@ -29,7 +29,7 @@ */ namespace OCP\AppFramework; -use OC\AppFramework\routing\RouteConfig; +use OC\AppFramework\Routing\RouteConfig; /** diff --git a/settings/Middleware/SubadminMiddleware.php b/settings/Middleware/SubadminMiddleware.php index 8e138bdc1a8..a860bdcfbf1 100644 --- a/settings/Middleware/SubadminMiddleware.php +++ b/settings/Middleware/SubadminMiddleware.php @@ -23,7 +23,7 @@ namespace OC\Settings\Middleware; use OC\AppFramework\Http; -use OC\Appframework\Middleware\Security\Exceptions\NotAdminException; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Middleware; diff --git a/tests/data/app/expected-info.json b/tests/data/app/expected-info.json index d86ffed482b..e05d02f7641 100644 --- a/tests/data/app/expected-info.json +++ b/tests/data/app/expected-info.json @@ -67,5 +67,9 @@ "max-version": "8" } } + }, + "repair-steps": { + "pre-migration": [], + "post-migration": [] } } diff --git a/tests/lib/app/codechecker/infocheckertest.php b/tests/lib/app/codechecker/infocheckertest.php index b31c5fe3a7a..c6df5a715a1 100644 --- a/tests/lib/app/codechecker/infocheckertest.php +++ b/tests/lib/app/codechecker/infocheckertest.php @@ -43,7 +43,7 @@ class InfoCheckerTest extends TestCase { protected function setUp() { parent::setUp(); - $infoParser = new InfoParser(\OC::$server->getHTTPHelper(), \OC::$server->getURLGenerator()); + $infoParser = new InfoParser(\OC::$server->getURLGenerator()); $this->infoChecker = new InfoChecker($infoParser); } diff --git a/tests/lib/app/infoparser.php b/tests/lib/app/infoparser.php index 1e5257abec3..cb89dd0131c 100644 --- a/tests/lib/app/infoparser.php +++ b/tests/lib/app/infoparser.php @@ -10,35 +10,27 @@ namespace Test\App; use OC; +use OCP\IURLGenerator; use Test\TestCase; class InfoParser extends TestCase { - /** - * @var \OC\App\InfoParser - */ + /** @var \OC\App\InfoParser */ private $parser; public function setUp() { - $config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor()->getMock(); - $clientService = $this->getMock('\OCP\Http\Client\IClientService'); - $httpHelper = $this->getMockBuilder('\OC\HTTPHelper') - ->setConstructorArgs([$config, $clientService]) - ->setMethods(['getHeaders']) - ->getMock(); $urlGenerator = $this->getMockBuilder('\OCP\IURLGenerator') ->disableOriginalConstructor() ->getMock(); - //linkToDocs + /** @var IURLGenerator | \PHPUnit_Framework_MockObject_MockObject $urlGenerator */ $urlGenerator->expects($this->any()) ->method('linkToDocs') ->will($this->returnCallback(function ($url) { return "https://docs.example.com/server/go.php?to=$url"; })); - $this->parser = new \OC\App\InfoParser($httpHelper, $urlGenerator); + $this->parser = new \OC\App\InfoParser($urlGenerator); } /** diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index dd4ec3af96f..f70308dc731 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -26,10 +26,10 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; use OC\AppFramework\Http\Request; -use OC\Appframework\Middleware\Security\Exceptions\AppNotEnabledException; -use OC\Appframework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException; -use OC\Appframework\Middleware\Security\Exceptions\NotAdminException; -use OC\Appframework\Middleware\Security\Exceptions\NotLoggedInException; +use OC\AppFramework\Middleware\Security\Exceptions\AppNotEnabledException; +use OC\AppFramework\Middleware\Security\Exceptions\CrossSiteRequestForgeryException; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; +use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\CSP\ContentSecurityPolicy; diff --git a/tests/lib/appframework/routing/RoutingTest.php b/tests/lib/appframework/routing/RoutingTest.php index b063ef32835..3ceab1aac48 100644 --- a/tests/lib/appframework/routing/RoutingTest.php +++ b/tests/lib/appframework/routing/RoutingTest.php @@ -3,8 +3,6 @@ namespace OC\AppFramework\Routing; use OC\AppFramework\DependencyInjection\DIContainer; -use OC\AppFramework\routing\RouteConfig; - class RoutingTest extends \Test\TestCase { diff --git a/tests/settings/middleware/subadminmiddlewaretest.php b/tests/settings/middleware/subadminmiddlewaretest.php index 2b76e4beaa9..c16c21c9c10 100644 --- a/tests/settings/middleware/subadminmiddlewaretest.php +++ b/tests/settings/middleware/subadminmiddlewaretest.php @@ -10,7 +10,7 @@ namespace OC\Settings\Middleware; -use OC\Appframework\Middleware\Security\Exceptions\NotAdminException; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; @@ -42,7 +42,7 @@ class SubadminMiddlewareTest extends \Test\TestCase { } /** - * @expectedException \OC\Appframework\Middleware\Security\Exceptions\NotAdminException + * @expectedException \OC\AppFramework\Middleware\Security\Exceptions\NotAdminException */ public function testBeforeControllerAsUserWithExemption() { $this->reflector |