diff options
31 files changed, 909 insertions, 163 deletions
diff --git a/apps/dav/lib/comments/commentnode.php b/apps/dav/lib/comments/commentnode.php index a5d508dd198..d3cd53bceb1 100644 --- a/apps/dav/lib/comments/commentnode.php +++ b/apps/dav/lib/comments/commentnode.php @@ -27,6 +27,7 @@ use OCP\Comments\ICommentsManager; use OCP\ILogger; use OCP\IUserManager; use OCP\IUserSession; +use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\MethodNotAllowed; use Sabre\DAV\PropPatch; @@ -112,12 +113,23 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties { ]; } + protected function checkWriteAccessOnComment() { + $user = $this->userSession->getUser(); + if( $this->comment->getActorType() !== 'users' + || is_null($user) + || $this->comment->getActorId() !== $user->getUID() + ) { + throw new Forbidden('Only authors are allowed to edit their comment.'); + } + } + /** * Deleted the current node * * @return void */ function delete() { + $this->checkWriteAccessOnComment(); $this->commentsManager->delete($this->comment->getId()); } @@ -156,8 +168,10 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties { * * @param $propertyValue * @return bool + * @throws Forbidden */ public function updateComment($propertyValue) { + $this->checkWriteAccessOnComment(); try { $this->comment->setMessage($propertyValue); $this->commentsManager->save($this->comment); diff --git a/apps/dav/tests/unit/comments/commentnode.php b/apps/dav/tests/unit/comments/commentnode.php index 44ac54ae937..8d1bf06ab60 100644 --- a/apps/dav/tests/unit/comments/commentnode.php +++ b/apps/dav/tests/unit/comments/commentnode.php @@ -51,10 +51,28 @@ class CommentsNode extends \Test\TestCase { } public function testDelete() { + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('alice')); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->comment->expects($this->once()) ->method('getId') ->will($this->returnValue('19')); + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->comment->expects($this->any()) + ->method('getActorId') + ->will($this->returnValue('alice')); + $this->commentsManager->expects($this->once()) ->method('delete') ->with('19'); @@ -62,6 +80,37 @@ class CommentsNode extends \Test\TestCase { $this->node->delete(); } + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testDeleteForbidden() { + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('mallory')); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $this->comment->expects($this->never()) + ->method('getId'); + + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->comment->expects($this->any()) + ->method('getActorId') + ->will($this->returnValue('alice')); + + $this->commentsManager->expects($this->never()) + ->method('delete'); + + $this->node->delete(); + } + public function testGetName() { $id = '19'; $this->comment->expects($this->once()) @@ -85,10 +134,28 @@ class CommentsNode extends \Test\TestCase { public function testUpdateComment() { $msg = 'Hello Earth'; + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('alice')); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->comment->expects($this->once()) ->method('setMessage') ->with($msg); + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->comment->expects($this->any()) + ->method('getActorId') + ->will($this->returnValue('alice')); + $this->commentsManager->expects($this->once()) ->method('save') ->with($this->comment); @@ -96,14 +163,32 @@ class CommentsNode extends \Test\TestCase { $this->assertTrue($this->node->updateComment($msg)); } - public function testUpdateCommentException() { + public function testUpdateCommentLogException() { $msg = null; + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('alice')); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + $this->comment->expects($this->once()) ->method('setMessage') ->with($msg) ->will($this->throwException(new \Exception('buh!'))); + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->comment->expects($this->any()) + ->method('getActorId') + ->will($this->returnValue('alice')); + $this->commentsManager->expects($this->never()) ->method('save'); @@ -113,6 +198,90 @@ class CommentsNode extends \Test\TestCase { $this->assertFalse($this->node->updateComment($msg)); } + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testUpdateForbiddenByUser() { + $msg = 'HaXX0r'; + + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('mallory')); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $this->comment->expects($this->never()) + ->method('setMessage'); + + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->comment->expects($this->any()) + ->method('getActorId') + ->will($this->returnValue('alice')); + + $this->commentsManager->expects($this->never()) + ->method('save'); + + $this->node->updateComment($msg); + } + + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testUpdateForbiddenByType() { + $msg = 'HaXX0r'; + + $user = $this->getMock('\OCP\IUser'); + + $user->expects($this->never()) + ->method('getUID'); + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + + $this->comment->expects($this->never()) + ->method('setMessage'); + + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('bots')); + + $this->commentsManager->expects($this->never()) + ->method('save'); + + $this->node->updateComment($msg); + } + + /** + * @expectedException \Sabre\DAV\Exception\Forbidden + */ + public function testUpdateForbiddenByNotLoggedIn() { + $msg = 'HaXX0r'; + + $this->userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue(null)); + + $this->comment->expects($this->never()) + ->method('setMessage'); + + $this->comment->expects($this->any()) + ->method('getActorType') + ->will($this->returnValue('users')); + + $this->commentsManager->expects($this->never()) + ->method('save'); + + $this->node->updateComment($msg); + } + public function testPropPatch() { $propPatch = $this->getMockBuilder('Sabre\DAV\PropPatch') ->disableOriginalConstructor() diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 1bf258c48b4..d6552fa680c 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -110,6 +110,7 @@ class Application extends App { $container->query('OCA\Files_External\Lib\Auth\Password\SessionCredentials'), $container->query('OCA\Files_External\Lib\Auth\Password\LoginCredentials'), $container->query('OCA\Files_External\Lib\Auth\Password\UserProvided'), + $container->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'), // AuthMechanism::SCHEME_OAUTH1 mechanisms $container->query('OCA\Files_External\Lib\Auth\OAuth1\OAuth1'), diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php index c3149a300cf..d5b927c0227 100644 --- a/apps/files_external/appinfo/routes.php +++ b/apps/files_external/appinfo/routes.php @@ -44,7 +44,12 @@ namespace OCA\Files_External\AppInfo; 'url' => '/ajax/public_key.php', 'verb' => 'POST', 'requirements' => array() - ) + ), + [ + 'name' => 'Ajax#saveGlobalCredentials', + 'url' => '/globalcredentials', + 'verb' => 'POST' + ] ) ) ); diff --git a/apps/files_external/controller/ajaxcontroller.php b/apps/files_external/controller/ajaxcontroller.php index cfccacb03ea..86c1b657c91 100644 --- a/apps/files_external/controller/ajaxcontroller.php +++ b/apps/files_external/controller/ajaxcontroller.php @@ -23,6 +23,7 @@ namespace OCA\Files_External\Controller; +use OCA\Files_External\Lib\Auth\Password\GlobalAuth; use OCP\AppFramework\Controller; use OCP\IRequest; use OCP\AppFramework\Http\JSONResponse; @@ -31,10 +32,13 @@ use OCA\Files_External\Lib\Auth\PublicKey\RSA; class AjaxController extends Controller { /** @var RSA */ private $rsaMechanism; + /** @var GlobalAuth */ + private $globalAuth; - public function __construct($appName, IRequest $request, RSA $rsaMechanism) { + public function __construct($appName, IRequest $request, RSA $rsaMechanism, GlobalAuth $globalAuth) { parent::__construct($appName, $request); $this->rsaMechanism = $rsaMechanism; + $this->globalAuth = $globalAuth; } private function generateSshKeys() { @@ -61,4 +65,8 @@ class AjaxController extends Controller { )); } + public function saveGlobalCredentials($uid, $user, $password) { + $this->globalAuth->saveAuth($uid, $user, $password); + return true; + } } diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 26df203091e..0837555f534 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -1338,6 +1338,33 @@ $(document).ready(function() { } }); + $('#global_credentials').on('submit', function() { + var $form = $(this); + var uid = $form.find('[name=uid]').val(); + var user = $form.find('[name=username]').val(); + var password = $form.find('[name=password]').val(); + var $submit = $form.find('[type=submit]'); + $submit.val(t('files_external', 'Saving...')); + $.ajax({ + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({ + uid: uid, + user: user, + password: password + }), + url: OC.generateUrl('apps/files_external/globalcredentials'), + dataType: 'json', + success: function() { + $submit.val(t('files_external', 'Saved')); + setTimeout(function(){ + $submit.val(t('files_external', 'Save')); + }, 2500); + } + }); + return false; + }); + // global instance OCA.External.Settings.mountConfig = mountConfigListView; diff --git a/apps/files_external/lib/auth/password/globalauth.php b/apps/files_external/lib/auth/password/globalauth.php new file mode 100644 index 00000000000..dcfea65b555 --- /dev/null +++ b/apps/files_external/lib/auth/password/globalauth.php @@ -0,0 +1,85 @@ +<?php +/** + * @author Robin Appelman <icewind@owncloud.com> + * + * @copyright Copyright (c) 2015, 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_External\Lib\Auth\Password; + +use OCA\Files_External\Lib\Auth\IUserProvided; +use OCA\Files_External\Lib\DefinitionParameter; +use OCA\Files_External\Service\BackendService; +use OCP\IL10N; +use OCP\IUser; +use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\StorageConfig; +use OCP\Security\ICredentialsManager; +use OCP\Files\Storage; +use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; + +/** + * Global Username and Password + */ +class GlobalAuth extends AuthMechanism { + + const CREDENTIALS_IDENTIFIER = 'password::global'; + + /** @var ICredentialsManager */ + protected $credentialsManager; + + public function __construct(IL10N $l, ICredentialsManager $credentialsManager) { + $this->credentialsManager = $credentialsManager; + + $this + ->setIdentifier('password::global') + ->setVisibility(BackendService::VISIBILITY_DEFAULT) + ->setScheme(self::SCHEME_PASSWORD) + ->setText($l->t('Global Credentails')); + } + + public function getAuth($uid) { + $auth = $this->credentialsManager->retrieve($uid, self::CREDENTIALS_IDENTIFIER); + if (!is_array($auth)) { + return []; + } else { + return $auth; + } + } + + public function saveAuth($uid, $user, $password) { + $this->credentialsManager->store($uid, self::CREDENTIALS_IDENTIFIER, [ + 'user' => $user, + 'password' => $password + ]); + } + + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { + if ($storage->getType() === StorageConfig::MOUNT_TYPE_ADMIN) { + $uid = ''; + } else { + $uid = $user->getUID(); + } + $credentials = $this->credentialsManager->retrieve($uid, self::CREDENTIALS_IDENTIFIER); + + if (is_array($credentials)) { + $storage->setBackendOption('user', $credentials['user']); + $storage->setBackendOption('password', $credentials['password']); + } + } + +} diff --git a/apps/files_external/lib/failedcache.php b/apps/files_external/lib/failedcache.php index 9e24c12f4b5..f9866f43058 100644 --- a/apps/files_external/lib/failedcache.php +++ b/apps/files_external/lib/failedcache.php @@ -60,6 +60,10 @@ class FailedCache implements ICache { return; } + public function insert($file, array $data) { + return; + } + public function update($id, array $data) { return; } diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index 4d8f480ecc0..f180b7e8f5c 100644 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -30,6 +30,7 @@ use \OCA\Files_External\Service\BackendService; $appContainer = \OC_Mount_Config::$app->getContainer(); $backendService = $appContainer->query('OCA\Files_External\Service\BackendService'); $userStoragesService = $appContainer->query('OCA\Files_external\Service\UserStoragesService'); +$globalAuth = $appContainer->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'); $tmpl = new OCP\Template('files_external', 'settings'); $tmpl->assign('encryptionEnabled', \OC::$server->getEncryptionManager()->isEnabled()); @@ -38,4 +39,7 @@ $tmpl->assign('storages', $userStoragesService->getStorages()); $tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); $tmpl->assign('backends', $backendService->getAvailableBackends()); $tmpl->assign('authMechanisms', $backendService->getAuthMechanisms()); +$uid = \OC::$server->getUserSession()->getUser()->getUID(); +$tmpl->assign('globalCredentials', $globalAuth->getAuth($uid)); +$tmpl->assign('globalCredentialsUid', $uid); return $tmpl->fetchPage(); diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index 0d83d26ff97..a5265c500d9 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -32,6 +32,7 @@ use \OCA\Files_External\Service\BackendService; $appContainer = \OC_Mount_Config::$app->getContainer(); $backendService = $appContainer->query('OCA\Files_External\Service\BackendService'); $globalStoragesService = $appContainer->query('OCA\Files_external\Service\GlobalStoragesService'); +$globalAuth = $appContainer->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'); \OC_Util::addVendorScript('select2/select2'); \OC_Util::addVendorStyle('select2/select2'); @@ -44,4 +45,7 @@ $tmpl->assign('backends', $backendService->getAvailableBackends()); $tmpl->assign('authMechanisms', $backendService->getAuthMechanisms()); $tmpl->assign('dependencies', OC_Mount_Config::dependencyMessage($backendService->getBackends())); $tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); +$tmpl->assign('allowUserMounting', $backendService->isUserMountingAllowed()); +$tmpl->assign('globalCredentials', $globalAuth->getAuth('')); +$tmpl->assign('globalCredentialsUid', ''); return $tmpl->fetchPage(); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index f7caf3d2caa..8b453fe77c3 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -68,8 +68,23 @@ } } ?> -<form id="files_external" class="section" data-encryption-enabled="<?php echo $_['encryptionEnabled']?'true': 'false'; ?>"> +<form autocomplete="false" class="section" action="#" + id="global_credentials"> <h2><?php p($l->t('External Storage')); ?></h2> + <p><?php p($l->t('Global Credentials')); ?></p> + <input type="text" name="username" + autocomplete="false" + value="<?php p($_['globalCredentials']['user']); ?>" + placeholder="<?php p($l->t('Username')) ?>"/> + <input type="password" name="password" + autocomplete="false" + value="<?php p($_['globalCredentials']['password']); ?>" + placeholder="<?php p($l->t('Password')) ?>"/> + <input type="hidden" name="uid" + value="<?php p($_['globalCredentialsUid']); ?>"/> + <input type="submit" value="<?php p($l->t('Save')) ?>"/> +</form> +<form id="files_external" class="section" data-encryption-enabled="<?php echo $_['encryptionEnabled']?'true': 'false'; ?>"> <?php if (isset($_['dependencies']) and ($_['dependencies']<>'')) print_unescaped(''.$_['dependencies'].''); ?> <table id="externalStorage" class="grid" data-admin='<?php print_unescaped(json_encode($_['visibilityType'] === BackendService::VISIBILITY_ADMIN)); ?>'> <thead> diff --git a/core/command/integrity/signcore.php b/core/command/integrity/signcore.php index 531a4d33aa3..e5c2de73e00 100644 --- a/core/command/integrity/signcore.php +++ b/core/command/integrity/signcore.php @@ -59,7 +59,8 @@ class SignCore extends Command { ->setName('integrity:sign-core') ->setDescription('Sign core using a private key.') ->addOption('privateKey', null, InputOption::VALUE_REQUIRED, 'Path to private key to use for signing') - ->addOption('certificate', null, InputOption::VALUE_REQUIRED, 'Path to certificate to use for signing'); + ->addOption('certificate', null, InputOption::VALUE_REQUIRED, 'Path to certificate to use for signing') + ->addOption('path', null, InputOption::VALUE_REQUIRED, 'Path of core to sign'); } /** @@ -68,8 +69,9 @@ class SignCore extends Command { protected function execute(InputInterface $input, OutputInterface $output) { $privateKeyPath = $input->getOption('privateKey'); $keyBundlePath = $input->getOption('certificate'); - if(is_null($privateKeyPath) || is_null($keyBundlePath)) { - $output->writeln('--privateKey and --certificate are required.'); + $path = $input->getOption('path'); + if(is_null($privateKeyPath) || is_null($keyBundlePath) || is_null($path)) { + $output->writeln('--privateKey, --certificate and --path are required.'); return null; } @@ -91,7 +93,7 @@ class SignCore extends Command { $x509 = new X509(); $x509->loadX509($keyBundle); $x509->setPrivateKey($rsa); - $this->checker->writeCoreSignature($x509, $rsa); + $this->checker->writeCoreSignature($x509, $rsa, $path); $output->writeln('Successfully signed "core"'); } diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js index dea065814d1..89c6e8c4d4e 100644 --- a/core/js/mimetypelist.js +++ b/core/js/mimetypelist.js @@ -17,12 +17,14 @@ OC.MimeTypeList={ "application/json": "text/code", "application/msaccess": "file", "application/msexcel": "x-office/spreadsheet", + "application/msonenote": "x-office/document", "application/mspowerpoint": "x-office/presentation", "application/msword": "x-office/document", "application/octet-stream": "file", "application/postscript": "image", "application/rss+xml": "application/xml", "application/vnd.android.package-archive": "package/x-generic", + "application/vnd.lotus-wordpro": "x-office/document", "application/vnd.ms-excel": "x-office/spreadsheet", "application/vnd.ms-excel.addin.macroEnabled.12": "x-office/spreadsheet", "application/vnd.ms-excel.sheet.binary.macroEnabled.12": "x-office/spreadsheet", @@ -51,6 +53,8 @@ OC.MimeTypeList={ "application/vnd.openxmlformats-officedocument.spreadsheetml.template": "x-office/spreadsheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "x-office/document", "application/vnd.openxmlformats-officedocument.wordprocessingml.template": "x-office/document", + "application/vnd.visio": "x-office/document", + "application/vnd.wordperfect": "x-office/document", "application/x-7z-compressed": "package/x-generic", "application/x-cbr": "text", "application/x-compressed": "package/x-generic", diff --git a/lib/private/integritycheck/checker.php b/lib/private/integritycheck/checker.php index c256fe66d32..e6f9f9a1457 100644 --- a/lib/private/integritycheck/checker.php +++ b/lib/private/integritycheck/checker.php @@ -90,6 +90,8 @@ class Checker { // FIXME: Once the signing server is instructed to sign daily, beta and // RCs as well these need to be included also. $signedChannels = [ + 'daily', + 'testing', 'stable', ]; if(!in_array($this->environmentHelper->getChannel(), $signedChannels, true)) { @@ -113,16 +115,22 @@ class Checker { * Enumerates all files belonging to the folder. Sensible defaults are excluded. * * @param string $folderToIterate + * @param string $root * @return \RecursiveIteratorIterator * @throws \Exception */ - private function getFolderIterator($folderToIterate) { + private function getFolderIterator($folderToIterate, $root = '') { $dirItr = new \RecursiveDirectoryIterator( $folderToIterate, \RecursiveDirectoryIterator::SKIP_DOTS ); + if($root === '') { + $root = \OC::$SERVERROOT; + } + $root = rtrim($root, '/'); + $excludeGenericFilesIterator = new ExcludeFileByNameFilterIterator($dirItr); - $excludeFoldersIterator = new ExcludeFoldersByPathFilterIterator($excludeGenericFilesIterator); + $excludeFoldersIterator = new ExcludeFoldersByPathFilterIterator($excludeGenericFilesIterator, $root); return new \RecursiveIteratorIterator( $excludeFoldersIterator, @@ -234,14 +242,16 @@ class Checker { * * @param X509 $certificate * @param RSA $rsa + * @param string $path */ public function writeCoreSignature(X509 $certificate, - RSA $rsa) { - $iterator = $this->getFolderIterator($this->environmentHelper->getServerRoot()); - $hashes = $this->generateHashes($iterator, $this->environmentHelper->getServerRoot()); + RSA $rsa, + $path) { + $iterator = $this->getFolderIterator($path, $path); + $hashes = $this->generateHashes($iterator, $path); $signatureData = $this->createSignatureData($hashes, $certificate, $rsa); $this->fileAccessHelper->file_put_contents( - $this->environmentHelper->getServerRoot() . '/core/signature.json', + $path . '/core/signature.json', json_encode($signatureData, JSON_PRETTY_PRINT) ); } diff --git a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php index c3994197fc6..67bcd423b68 100644 --- a/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php +++ b/lib/private/integritycheck/iterator/excludefoldersbypathfilteriterator.php @@ -24,7 +24,7 @@ namespace OC\IntegrityCheck\Iterator; class ExcludeFoldersByPathFilterIterator extends \RecursiveFilterIterator { private $excludedFolders = []; - public function __construct(\RecursiveIterator $iterator) { + public function __construct(\RecursiveIterator $iterator, $root = '') { parent::__construct($iterator); $appFolders = \OC::$APPSROOTS; @@ -33,9 +33,10 @@ class ExcludeFoldersByPathFilterIterator extends \RecursiveFilterIterator { } $this->excludedFolders = array_merge([ - rtrim(\OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data'), '/'), - rtrim(\OC::$SERVERROOT.'/themes', '/'), - rtrim(\OC::$SERVERROOT.'/config', '/'), + rtrim($root . '/data', '/'), + rtrim($root .'/themes', '/'), + rtrim($root.'/config', '/'), + rtrim($root.'/apps', '/'), ], $appFolders); } diff --git a/lib/private/repair/repairmimetypes.php b/lib/private/repair/repairmimetypes.php index 692a7120a63..b84f19a3082 100644 --- a/lib/private/repair/repairmimetypes.php +++ b/lib/private/repair/repairmimetypes.php @@ -293,6 +293,17 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { self::updateMimetypes($updatedMimetypes); } + private function introduceRichDocumentsMimeTypes() { + $updatedMimetypes = array( + 'lwp' => 'application/vnd.lotus-wordpro', + 'one' => 'application/msonenote', + 'vsd' => 'application/vnd.visio', + 'wpd' => 'application/vnd.wordperfect', + ); + + self::updateMimetypes($updatedMimetypes); + } + /** * Fix mime types */ @@ -356,5 +367,11 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { $this->emit('\OC\Repair', 'info', array('Fixed rtf mime type')); } } + + if (version_compare($ocVersionFromBeforeUpdate, '9.0.0.10', '<')) { + if ($this->introduceRichDocumentsMimeTypes()) { + $this->emit('\OC\Repair', 'info', array('Fixed richdocuments additional office mime types')); + } + } } } diff --git a/lib/private/server.php b/lib/private/server.php index 69406c2203f..55ac64a0c2d 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -618,7 +618,8 @@ class Server extends ServerContainer implements IServerContainer { $c->getGroupManager(), $c->getL10N('core'), $factory, - $c->getUserManager() + $c->getUserManager(), + $c->getRootFolder() ); return $manager; diff --git a/lib/private/share20/defaultshareprovider.php b/lib/private/share20/defaultshareprovider.php index 38d1dae316d..0ab0dc81fa7 100644 --- a/lib/private/share20/defaultshareprovider.php +++ b/lib/private/share20/defaultshareprovider.php @@ -711,7 +711,7 @@ class DefaultShareProvider implements IShareProvider { * @throws InvalidShare */ private function createShare($data) { - $share = new Share(); + $share = new Share($this->rootFolder); $share->setId((int)$data['id']) ->setShareType((int)$data['share_type']) ->setPermissions((int)$data['permissions']) @@ -744,8 +744,8 @@ class DefaultShareProvider implements IShareProvider { $share->setShareOwner($data['uid_owner']); } - $path = $this->getNode($share->getShareOwner(), (int)$data['file_source']); - $share->setNode($path); + $share->setNodeId((int)$data['file_source']); + $share->setNodeType($data['item_type']); if ($data['expiration'] !== null) { $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']); diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index db42f76d7a2..6ea638b84e6 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -21,6 +21,7 @@ namespace OC\Share20; +use OCP\Files\IRootFolder; use OCP\IUserManager; use OCP\Share\IManager; use OCP\Share\IProviderFactory; @@ -45,30 +46,24 @@ class Manager implements IManager { /** @var IProviderFactory */ private $factory; - /** @var ILogger */ private $logger; - /** @var IConfig */ private $config; - /** @var ISecureRandom */ private $secureRandom; - /** @var IHasher */ private $hasher; - /** @var IMountManager */ private $mountManager; - /** @var IGroupManager */ private $groupManager; - /** @var IL10N */ private $l; - /** @var IUserManager */ private $userManager; + /** @var IRootFolder */ + private $rootFolder; /** * Manager constructor. @@ -92,7 +87,8 @@ class Manager implements IManager { IGroupManager $groupManager, IL10N $l, IProviderFactory $factory, - IUserManager $userManager + IUserManager $userManager, + IRootFolder $rootFolder ) { $this->logger = $logger; $this->config = $config; @@ -103,6 +99,7 @@ class Manager implements IManager { $this->l = $l; $this->factory = $factory; $this->userManager = $userManager; + $this->rootFolder = $rootFolder; } /** @@ -666,13 +663,13 @@ class Manager implements IManager { $hookParams = [ 'id' => $share->getId(), - 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getNode()->getId(), + 'itemType' => $share->getNodeType(), + 'itemSource' => $share->getNodeId(), 'shareType' => $shareType, 'shareWith' => $sharedWith, 'itemparent' => $share->getParent(), 'uidOwner' => $share->getSharedBy(), - 'fileSource' => $share->getNode()->getId(), + 'fileSource' => $share->getNodeId(), 'fileTarget' => $share->getTarget() ]; return $hookParams; @@ -888,7 +885,7 @@ class Manager implements IManager { * @return \OCP\Share\IShare; */ public function newShare() { - return new \OC\Share20\Share(); + return new \OC\Share20\Share($this->rootFolder); } /** diff --git a/lib/private/share20/share.php b/lib/private/share20/share.php index db91ad4a91d..448b05d20a3 100644 --- a/lib/private/share20/share.php +++ b/lib/private/share20/share.php @@ -20,7 +20,10 @@ */ namespace OC\Share20; +use OCP\Files\File; +use OCP\Files\IRootFolder; use OCP\Files\Node; +use OCP\Files\NotFoundException; use OCP\IUser; use OCP\IGroup; @@ -31,14 +34,18 @@ class Share implements \OCP\Share\IShare { /** @var string */ private $providerId; /** @var Node */ - private $path; + private $node; + /** @var int */ + private $fileId; + /** @var string */ + private $nodeType; /** @var int */ private $shareType; - /** @var IUser|IGroup */ + /** @var string */ private $sharedWith; - /** @var IUser */ + /** @var string */ private $sharedBy; - /** @var IUser */ + /** @var string */ private $shareOwner; /** @var int */ private $permissions; @@ -57,6 +64,13 @@ class Share implements \OCP\Share\IShare { /** @var bool */ private $mailSend; + /** @var IRootFolder */ + private $rootFolder; + + public function __construct(IRootFolder $rootFolder) { + $this->rootFolder = $rootFolder; + } + /** * @inheritdoc */ @@ -90,8 +104,8 @@ class Share implements \OCP\Share\IShare { /** * @inheritdoc */ - public function setNode(Node $path) { - $this->path = $path; + public function setNode(Node $node) { + $this->node = $node; return $this; } @@ -99,7 +113,66 @@ class Share implements \OCP\Share\IShare { * @inheritdoc */ public function getNode() { - return $this->path; + if ($this->node === null) { + + if ($this->shareOwner === null || $this->fileId === null) { + throw new NotFoundException(); + } + + $userFolder = $this->rootFolder->getUserFolder($this->shareOwner); + + $nodes = $userFolder->getById($this->fileId); + if (empty($nodes)) { + throw new NotFoundException(); + } + + $this->node = $nodes[0]; + } + + return $this->node; + } + + /** + * @inheritdoc + */ + public function setNodeId($fileId) { + $this->node = null; + $this->fileId = $fileId; + return $this; + } + + /** + * @inheritdoc + */ + public function getNodeId() { + if ($this->fileId === null) { + $this->fileId = $this->getNode()->getId(); + } + + return $this->fileId; + } + + /** + * @inheritdoc + */ + public function setNodeType($type) { + if ($type !== 'file' && $type !== 'folder') { + throw new \InvalidArgumentException(); + } + + $this->nodeType = $type; + } + + /** + * @inheritdoc + */ + public function getNodeType() { + if ($this->nodeType === null) { + $node = $this->getNode(); + $this->nodeType = $node instanceof File ? 'file' : 'folder'; + } + + return $this->nodeType; } /** diff --git a/lib/public/share/ishare.php b/lib/public/share/ishare.php index 5a82436c720..5054a886af5 100644 --- a/lib/public/share/ishare.php +++ b/lib/public/share/ishare.php @@ -24,8 +24,7 @@ namespace OCP\Share; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\Node; -use OCP\IUser; -use OCP\IGroup; +use OCP\Files\NotFoundException; /** * Interface IShare @@ -55,21 +54,56 @@ interface IShare { /** * Set the node of the file/folder that is shared * - * @param File|Folder $path + * @param Node $node * @return \OCP\Share\IShare The modified object * @since 9.0.0 */ - public function setNode(Node $path); + public function setNode(Node $node); /** * Get the node of the file/folder that is shared * * @return File|Folder * @since 9.0.0 + * @throws NotFoundException */ public function getNode(); /** + * Set file id for lazy evaluation of the node + * @param int $fileId + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setNodeId($fileId); + + /** + * Get the fileid of the node of this share + * @return int + * @since 9.0.0 + * @throws NotFoundException + */ + public function getNodeId(); + + /** + * Set the type of node (file/folder) + * + * @param string $type + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setNodeType($type); + + /** + * Get the type of node (file/folder) + * + * @return string + * @since 9.0.0 + * @throws NotFoundException + */ + public function getNodeType(); + + /** * Set the shareType * * @param int $shareType diff --git a/resources/codesigning/core.crt b/resources/codesigning/core.crt index 0692e940186..62f87c9d30c 100644 --- a/resources/codesigning/core.crt +++ b/resources/codesigning/core.crt @@ -1,24 +1,24 @@ -----BEGIN CERTIFICATE----- -MIID/TCCAeUCAhAAMA0GCSqGSIb3DQEBCwUAMHkxFjAUBgNVBAoTDW93bkNsb3Vk -IEluYy4xEjAQBgNVBAcTCUxleGluZ3RvbjEPMA0GA1UECBMGQm9zdG9uMQswCQYD -VQQGEwJVUzEtMCsGA1UEAxMkb3duQ2xvdWQgQ29kZSBTaWduaW5nIFJvb3QgQXV0 -aG9yaXR5MB4XDTE2MDIwMzE3MTM0NVoXDTI2MDEzMTE3MTM0NVowDzENMAsGA1UE -AwwEY29yZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKzP4ujnvS9l -otPJ7zHZMD8IGgcuYVtZ40n4pWSArhJboazhMdadpfxEZAghZtzkK+AKz4V+92GV -UOf+FgFRMcsaaBFr9INE4tdYKPVfHq19sDZVhYySfg7/z9qWc9XTMAm1lWpFyDQb -CC0i1YFogk0JdPr5Ay2Ftgbbr+TtMduL0RshdClqoiwntLnFhu8VRZi3+/yHH2cN -M5ANjm/MXT8Ae6KMVOzsYhBcxMLNVL08Ih1ubtu4LbKgyT5ShYzxqRnJ8U1KlmVT -w/wsSGMvVTEJkozkQEyg88vkxwvqLLYs5bOvXY93S6YKb2gO7RAA2c/IaEDbL32t -TJJhRoPif9cCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAiRhcef1Tc0Lj4BWIxYDV -Fjkrd4HHe3FyZRdD1+NU4LSb/4xXknmrwu5tITrnoGqNfUGn9BlP5Ek7Iu15PMPi -8Us8xszvgMZ7BG3x4zTMHwUseLT56/+qE76VN2vXusQBuEhOll/WN2qHvPi8BOCk -fOL6/EIUdqfMh9FKGNKOJ5f95eKogyVVxVcUpGWoqZRQTJaNMBTdT8Zwv1aTLRgp -Vf8JFzmxG9Atc/00w7cg4tV4lUpZafn1RYaIi4DWZhI43yR+Z8CKQBXt7iufu0QD -VwWOqYjmK7aKB2bL3+8I2bL9pm9DUKrAPYSObdmasJQGFVNCILisWJjX5wlUC2IL -FtMfZ4egyWZTLeQ+VQt92cJeVZYins5GECm1SqgXGnmQWv01/wNIqUhLuVFoLyVv -aPhCYcjNcbwJm8m++kz/G6+5AhRv2JrZq3i1Cw/yRQuiotXrJE+ukIvvSEjlLJ0C -Njm7EMy1mNfhIi1Xel/aUaf0y92GMsfnCuzI+tRG50HHupLEXHItlg2RILmNQNpo -woqHpUZs5G5HZlE5ZnffJlZpJyqA1EpQDh1XXJqcVwV50V9o+CMvxXO8s2lUA+i6 -Kay+t3mz2dX6qflRUPLsPS4XLdB9MUiIHCOgMJfsK+9SZ+i1VymhV5UYx8rqglC7 -8crw8NpiIuOqQZW8LcZXZBU= ------END CERTIFICATE-----
\ No newline at end of file +MIID8TCCAdkCAhAAMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ8wDQYD +VQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4xNTAzBgNVBAMMLG93 +bkNsb3VkIENvZGUgU2lnbmluZyBJbnRlcm1lZGlhdGUgQXV0aG9yaXR5MB4XDTE2 +MDIwMzE3NTE0OVoXDTI2MDEzMTE3NTE0OVowDzENMAsGA1UEAwwEY29yZTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPHdSljnHI+ueQd27UyWPO9n4Lqt +bK0kdekiC3si7Mee7uXXJaGuqXJozHEZYB1LIFLdCU/itCxEk9hyLcyNzeT+nRT/ +zDuOYdbLgCj7/A5bX+u3jc29UlCYybSFchfMdvn7a0njCna4dE+73b4yEj16tS2h +S1EUygSzgicWlJqMD3Z9Qc+zLEpdhq9oDdDB8HURi2NW4KzIraVncSH+zF1QduOh +nERDnF8x48D3FLdTxGA0W/Kg4gYsq4NRvU6g3DJNdp4YfqRSFMmLFDCgzDuhan7D +wgRlI9NAeHbnyoUPtrDBUceI7shIbC/i87xk9ptqV0AyFonkJtK6lWwZjNkCAwEA +ATANBgkqhkiG9w0BAQsFAAOCAgEAAMgymqZE1YaHYlRGwvTE7gGDY3gmFOMaxQL4 +E5m0CnkBz4BdIPRsQFFdOv3l/MIWkw5ED3vUB925VpQZYFSiEuv5NbnlPaHZlIMI +n8AV/sTP5jue3LhtAN4EM63xNBhudAT6wVsvGwOuQOx9Xv+ptO8Po7sTuNYP0CMH +EOQN+/q8tYlSm2VW+dAlaJ+zVZwZldhVjL+lSH4E9ktWn3PmgNQeKfcnJISUbus6 +ZtsYDF/X96/Z2ZQvMXOKksgvU6XlvIxllcyebC9Bxe/h0D63GCO2tqN5CWQzIIqn +apUynPX8BlLaaExqYGERwlUi/yOGaUVPUjEPVehviOQYgAqxlrkJk1dWeCrwUori +CXpi+IUYkidfgiJ9F88M3ElpwqIaXp7G3/4oHBuE2u6M+L+1/vqPJeTCAWUxxpJE +yYmM+db6D4TySFpQPENNzPS8bpR6T8w2hRumkldC42HrnyJJbpjOieTXhXzjdPvZ +IEP9JGtkhB2du6nBF2MNAq2TqRXpcfQrQEbnQ13aV9bl+roTwwO+SOWK/wgvdOMI +STQ0Xk0sTGlmQjPYPkibVceaWMR3sX4cNt5c33YhJys5jxHoAh42km4nN9tfykR5 +crl5lBlKjXh2GP0+omSO3x1jX4+iQPCW2TWoyKkUdLu/hGHG2w8RrTeme+kATECH +YSu356M= +-----END CERTIFICATE----- diff --git a/resources/codesigning/root.crt b/resources/codesigning/root.crt index 201164feb0c..cbd82898bab 100644 --- a/resources/codesigning/root.crt +++ b/resources/codesigning/root.crt @@ -1,36 +1,66 @@ -----BEGIN CERTIFICATE----- -MIIGVDCCBDygAwIBAgIJAJGMJhEr5q3dMA0GCSqGSIb3DQEBCwUAMHkxFjAUBgNV -BAoTDW93bkNsb3VkIEluYy4xEjAQBgNVBAcTCUxleGluZ3RvbjEPMA0GA1UECBMG -Qm9zdG9uMQswCQYDVQQGEwJVUzEtMCsGA1UEAxMkb3duQ2xvdWQgQ29kZSBTaWdu -aW5nIFJvb3QgQXV0aG9yaXR5MB4XDTE2MDIwMzE3MDYyOVoXDTI2MDEzMTE3MDYy -OVoweTEWMBQGA1UEChMNb3duQ2xvdWQgSW5jLjESMBAGA1UEBxMJTGV4aW5ndG9u -MQ8wDQYDVQQIEwZCb3N0b24xCzAJBgNVBAYTAlVTMS0wKwYDVQQDEyRvd25DbG91 -ZCBDb2RlIFNpZ25pbmcgUm9vdCBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDGAqfV+pZuKD9rKsny6PxQWYV35bJYo2xdYxFpd8oI/Fco -Ygjv5iZc9U4/iY0mN3wSDjYXJtMQnO96qthSI/bqsxrD9wutRKXYo/VEZALWL8vR -F+cRpgmCrq98tF7fNEhEX2PdVlmwEWV8c7wL+QAd+qXrVz+MyJyw6jlh5JzEEqAR -kNNRFm2d5+FPgWZeBNE0tbj7XxBTFTn/OMAOndhLo2dwhTXu6t2Caq15IZt6YoPM -Ibn/Y3c2E76vpfWCznB4uEsEx4C4Hkdmzu5BwjPjcnPoFGobHaURMnwrEOI1s0cn -V7kl2120I2Dr29NTL4vgnxRM2SQp3253NVmy9EbabszwfHy9bGH5G6IKQyTLyJHG -AIAN3QHfr86N3t/ELekNb8bbh+2OBzuytMbTPlauKny7isVfciGUfnJgU54mMbIc -1XBiYEgKjdkq/IEiYkjtOToS29AvCnDkH82piEeW0TMmcNN7/Vq79S1YR4ceZ4PQ -d0Qm0y59nXPVZMso5em39TJH1PRwe93RPDN8NM434sfbdjqMqDi+3E+urG01AzwT -BZj8lUvD/FvDB1no2p4/JKeHmlR/AQmfWFA0c6dv5DlzeIldwar4paDER9McGXvy -GSTDVEhdEJrbK8pQh2pIkHZ6WkuMyTXDMTvyRtuPwlk68MVmYic/AHUSLrGT0wID -AQABo4HeMIHbMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFM2KMEEv31J4fR3ufEH6 -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 ++Dr25NoOcuqjCWRw2T3SBPSXBxjlhRTQ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIJALFuk51OGp2KMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNV +BAYTAlVTMQ8wDQYDVQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4x +LTArBgNVBAMMJG93bkNsb3VkIENvZGUgU2lnbmluZyBSb290IEF1dGhvcml0eTAe +Fw0xNjAyMDMxNzM5NThaFw0yNjAxMzExNzM5NThaMGUxCzAJBgNVBAYTAlVTMQ8w +DQYDVQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4xLTArBgNVBAMM +JG93bkNsb3VkIENvZGUgU2lnbmluZyBSb290IEF1dGhvcml0eTCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAJmTnGtGaB0cDtQPxWr2r5FyXFzJ6GIkm4Lb +7iY/DYpIEarbRFwqDCDZ00V+PWsTBBF6qXW5W7eZ+fOOdIEGoNaDuGtIlGVjj3Dz +TZtmcFg0euimfLNYVvYZlPPh4kS3zDRZs30AgAdgq4RHWC4qjElWcVKTwERNQ2ln +gRFRQEv+i2DI7sEK9ZpK7B1SfJ1o1fm/kPL7bVfiYda+QKp0vOxBecDnGV+rfz4t +DT6mBOgwAiZnwojuiigfUJxSisv3roWri+0O+0TiXglV+oUtkIRrs0etkQGWAlgn +H4CC+sZ5N2TiGPH1hksLkXP4mymlio8/x7ax0WfcxeTZu3ok9eK5fwIQVWam6dd9 +klCqZVttKodZYspvdFfwqMlf4lPEIY+r2PIdGjUhKu4FsDhORaGj8WMYRJUR44ls +/r2ktCB/TOsh8DW2Pi9HAgxI4mrdmvL0WMSOBFZRcSC/nTz977oi1iiB2T+s7V0Z +Y0AHMQYiIn83MFB7rb+mVlEoLID/evVSTfUaUaO8DqcfeQN/OFM/zcJY9YHv8AlJ +3b8CPdeX9edMnyZWNdrhOSawjAbOBIna3o66RXdeC3oWg7FuckJmy7JLtRCJ2Owu +losRAxe0z5mQmjFzMczxCYJQ4A+4U5UZwbd/MQJg508StcOumroYqruDic/Wbc3C +v6DupG8dAgMBAAGjYzBhMB0GA1UdDgQWBBRxl2IGIav5j44fYOuU3ArTfNYf5jAf +BgNVHSMEGDAWgBRxl2IGIav5j44fYOuU3ArTfNYf5jAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAR6IZBOBw3KzRxvUP ++46RZYayMrdLyAgMzbDvQe7WCaeuA2UoPVL8jN7X2Lvw12Mz84+EKs1voR0OBxlY +6muuyl0SETa2k4UtklVscMvcokG+m5aVNJ7/HHGFmKsTyJDMxSzDA/r3KRPXZOwV +CLUVTkr5fQbIaVljA89U2p3pN/X7gNq89xi/XiszNCEIvvSscRmBGlRmx4XbjXHK +XKO74+HiM/ahqUI792ae97jlsy9jG4OIelse3+e1KBWNsGtU90asnUHgyMXVL8gp +ocznGvWceAhkcogUCUCXq1Rh/mKcGQdi2z0g/X+MGzfA9Ij4NQZLnNPh2UjgxCtG +KWPUzs0t/xoCtJh1WpwqTrOUcYqFAaBa282sD/O8tX4t076aGKdbhfo6tvaOFwDU +iRPgdMol++BFnfCld53Yivg2+S6+xo1wzuPkNjVFXHjx9vMyiov/HHKqJoBsuCwU +7VegzM/6Cvh32lSZfUHsfynCab/7vv923KyaANWxb0QsHZSSt+mmOK3ZmC96vCEa +55IGNckOvOGW9yCIz3Q0kEj2hoJs1bw0SkwGWs7N1TkugQjM/S7/Im1LJUxdtqQK +Zjn+8U6U3TR1aKLYEdqHCGcVoRXKDG/S40FHxyeV/9buTI7SSvhzZfj+qasmJe1L +Kd08UdS/im8RwbVSS1mih5hbAHg= -----END CERTIFICATE-----
\ No newline at end of file diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json index ed471f228e2..545d4b0c399 100644 --- a/resources/config/mimetypealiases.dist.json +++ b/resources/config/mimetypealiases.dist.json @@ -17,12 +17,14 @@ "application/json": "text/code", "application/msaccess": "file", "application/msexcel": "x-office/spreadsheet", + "application/msonenote": "x-office/document", "application/mspowerpoint": "x-office/presentation", "application/msword": "x-office/document", "application/octet-stream": "file", "application/postscript": "image", "application/rss+xml": "application/xml", "application/vnd.android.package-archive": "package/x-generic", + "application/vnd.lotus-wordpro": "x-office/document", "application/vnd.ms-excel": "x-office/spreadsheet", "application/vnd.ms-excel.addin.macroEnabled.12": "x-office/spreadsheet", "application/vnd.ms-excel.sheet.binary.macroEnabled.12": "x-office/spreadsheet", @@ -51,6 +53,8 @@ "application/vnd.openxmlformats-officedocument.spreadsheetml.template": "x-office/spreadsheet", "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "x-office/document", "application/vnd.openxmlformats-officedocument.wordprocessingml.template": "x-office/document", + "application/vnd.visio": "x-office/document", + "application/vnd.wordperfect": "x-office/document", "application/x-7z-compressed": "package/x-generic", "application/x-cbr": "text", "application/x-compressed": "package/x-generic", diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json index e26ec7038b1..d08a46bb017 100644 --- a/resources/config/mimetypemapping.dist.json +++ b/resources/config/mimetypemapping.dist.json @@ -76,6 +76,7 @@ "key": ["application/x-iwork-keynote-sffkey"], "keynote": ["application/x-iwork-keynote-sffkey"], "kra": ["application/x-krita"], + "lwp": ["application/vnd.lotus-wordpro"], "m2t": ["video/mp2t"], "m4v": ["video/mp4"], "markdown": ["text/markdown"], @@ -106,6 +107,7 @@ "oga": ["audio/ogg"], "ogg": ["audio/ogg"], "ogv": ["video/ogg"], + "one": ["application/msonenote"], "opus": ["audio/ogg"], "orf": ["image/x-dcraw"], "otf": ["application/font-sfnt"], @@ -154,9 +156,11 @@ "vcard": ["text/vcard"], "vcf": ["text/vcard"], "vob": ["video/dvd"], + "vsd": ["application/vnd.visio"], "wav": ["audio/wav"], "webm": ["video/webm"], "woff": ["application/font-woff"], + "wpd": ["application/vnd.wordperfect"], "wmv": ["video/x-ms-wmv"], "xcf": ["application/x-gimp"], "xla": ["application/vnd.ms-excel"], diff --git a/tests/lib/command/integrity/SignCoreTest.php b/tests/lib/command/integrity/SignCoreTest.php index 885c6fc664e..ff1f6b23a95 100644 --- a/tests/lib/command/integrity/SignCoreTest.php +++ b/tests/lib/command/integrity/SignCoreTest.php @@ -63,7 +63,7 @@ class SignCoreTest extends TestCase { $outputInterface ->expects($this->at(0)) ->method('writeln') - ->with('--privateKey and --certificate are required.'); + ->with('--privateKey, --certificate and --path are required.'); $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]); } @@ -86,7 +86,7 @@ class SignCoreTest extends TestCase { $outputInterface ->expects($this->at(0)) ->method('writeln') - ->with('--privateKey and --certificate are required.'); + ->with('--privateKey, --certificate and --path are required.'); $this->invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]); } @@ -105,6 +105,11 @@ class SignCoreTest extends TestCase { ->method('getOption') ->with('certificate') ->will($this->returnValue('certificate')); + $inputInterface + ->expects($this->at(2)) + ->method('getOption') + ->with('path') + ->will($this->returnValue('certificate')); $this->fileAccessHelper ->expects($this->at(0)) @@ -134,6 +139,11 @@ class SignCoreTest extends TestCase { ->method('getOption') ->with('certificate') ->will($this->returnValue('certificate')); + $inputInterface + ->expects($this->at(2)) + ->method('getOption') + ->with('path') + ->will($this->returnValue('certificate')); $this->fileAccessHelper ->expects($this->at(0)) @@ -168,6 +178,11 @@ class SignCoreTest extends TestCase { ->method('getOption') ->with('certificate') ->will($this->returnValue('certificate')); + $inputInterface + ->expects($this->at(2)) + ->method('getOption') + ->with('path') + ->will($this->returnValue('certificate')); $this->fileAccessHelper ->expects($this->at(0)) diff --git a/tests/lib/integritycheck/checkertest.php b/tests/lib/integritycheck/checkertest.php index dec3ea84a64..fac60b0c123 100644 --- a/tests/lib/integritycheck/checkertest.php +++ b/tests/lib/integritycheck/checkertest.php @@ -465,7 +465,7 @@ class CheckerTest extends TestCase { $rsa->loadKey($rsaPrivateKey); $x509 = new X509(); $x509->loadX509($keyBundle); - $this->checker->writeCoreSignature($x509, $rsa); + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/'); } public function testWriteCoreSignatureWithUnmodifiedHtaccess() { @@ -495,7 +495,7 @@ class CheckerTest extends TestCase { $rsa->loadKey($rsaPrivateKey); $x509 = new X509(); $x509->loadX509($keyBundle); - $this->checker->writeCoreSignature($x509, $rsa); + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/'); } public function testWriteCoreSignatureWithInvalidModifiedHtaccess() { @@ -506,10 +506,6 @@ class CheckerTest extends TestCase { "signature": "qpDddYGgAKNR3TszOgjPXRphUl2P9Ym5OQaetltocgZASGDkOun5D64+1D0QJRKb4SG2+48muxGOHyL2Ngos4NUrrSR+SIkywZacay82YQBCEdr7\/4MjW1WHRPjvboLwEJwViw0EdAjsWRpD68aPnzUGrGsy2BsCo06P5iwjk9cXcHxdjC9R39npvoC3QNvQ2jmNIbh1Lc4U97dbb+CsXEQCLU1OSa9p3q6cEFV98Easwt7uF\/DzHK+CbeZlxVZ0DwLh2\/ylT1PyGou8QC1b3vKAnPjLWMO+UsCPpCKhk3C5pV+5etQ8puGd+0x2t5tEU+qXxLzek91zWNC+rqgC\/WlqLKbwPb\/BCHs4zLGV55Q2fEQmT21x0KCUELdPs4dBnYP4Ox5tEDugtJujWFzOHzoY6gGa\/BY\/78pSZXmq9o8dWkBEtioWWvaNZ1rM0ddE83GBlBTgjigi9Ay1D++bUW\/FCBB7CMk6qyNlV81H+cBuIEODw2aymmkM9LLDD2Qbmvo8gHEPRjiQxPC5OpDlcdSNiL+zcxVxeuX4FpT+9xzz\/\/DRONhufxRpsbuCOMxd96RW7y9U2N2Uxb3Bzn\/BIqEayUUsdgZjfaGcXXYKR+chu\/LOwNYN6RlnLsgqL\/dhGKwlRVKXw1RA2\/af\/CpqyR7uVP6al1YJo\/YJ+5XJ6zE=", "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; - $this->environmentHelper - ->expects($this->any()) - ->method('getServerRoot') - ->will($this->returnValue(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/')); $this->fileAccessHelper ->expects($this->once()) ->method('file_put_contents') @@ -524,7 +520,7 @@ class CheckerTest extends TestCase { $rsa->loadKey($rsaPrivateKey); $x509 = new X509(); $x509->loadX509($keyBundle); - $this->checker->writeCoreSignature($x509, $rsa); + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/'); } public function testWriteCoreSignatureWithValidModifiedHtaccess() { @@ -554,7 +550,7 @@ class CheckerTest extends TestCase { $rsa->loadKey($rsaPrivateKey); $x509 = new X509(); $x509->loadX509($keyBundle); - $this->checker->writeCoreSignature($x509, $rsa); + $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent'); } public function testVerifyCoreSignatureWithoutSignatureData() { diff --git a/tests/lib/repair/repairmimetypes.php b/tests/lib/repair/repairmimetypes.php index 1bdaa9a2dbf..a9ebb7bc88a 100644 --- a/tests/lib/repair/repairmimetypes.php +++ b/tests/lib/repair/repairmimetypes.php @@ -347,6 +347,27 @@ class RepairMimeTypes extends \Test\TestCase { } /** + * Test renaming the richdocuments additional office mime types + */ + public function testRenameRichDocumentsMimeTypes() { + $currentMimeTypes = [ + ['test.lwp', 'application/octet-stream'], + ['test.one', 'application/octet-stream'], + ['test.vsd', 'application/octet-stream'], + ['test.wpd', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.lwp', 'application/vnd.lotus-wordpro'], + ['test.one', 'application/msonenote'], + ['test.vsd', 'application/vnd.visio'], + ['test.wpd', 'application/vnd.wordperfect'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + + /** * Test renaming and splitting old office mime types when * new ones already exist */ @@ -468,6 +489,10 @@ class RepairMimeTypes extends \Test\TestCase { ['test.hpp', 'text/x-h'], ['test.rss', 'application/rss+xml'], ['test.rtf', 'text/rtf'], + ['test.lwp', 'application/vnd.lotus-wordpro'], + ['test.one', 'application/msonenote'], + ['test.vsd', 'application/vnd.visio'], + ['test.wpd', 'application/vnd.wordperfect'], ]; $fixedMimeTypes = [ @@ -512,6 +537,10 @@ class RepairMimeTypes extends \Test\TestCase { ['test.hpp', 'text/x-h'], ['test.rss', 'application/rss+xml'], ['test.rtf', 'text/rtf'], + ['test.lwp', 'application/vnd.lotus-wordpro'], + ['test.one', 'application/msonenote'], + ['test.vsd', 'application/vnd.visio'], + ['test.wpd', 'application/vnd.wordperfect'], ]; $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); diff --git a/tests/lib/share20/defaultshareprovidertest.php b/tests/lib/share20/defaultshareprovidertest.php index 19f21fba7b1..60024989681 100644 --- a/tests/lib/share20/defaultshareprovidertest.php +++ b/tests/lib/share20/defaultshareprovidertest.php @@ -171,6 +171,85 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals('myTarget', $share->getTarget()); } + public function testGetShareByIdLazy() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + $id = $qb->getLastInsertId(); + + $this->rootFolder->expects($this->never())->method('getUserFolder'); + + $share = $this->provider->getShareById($id); + + // We do not fetch the node so the rootfolder is never called. + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + + public function testGetShareByIdLazy2() { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $qb->execute(); + + $id = $qb->getLastInsertId(); + + $ownerPath = $this->getMock('\OCP\Files\File'); + + $shareOwnerFolder = $this->getMock('\OCP\Files\Folder'); + $shareOwnerFolder->method('getById')->with(42)->willReturn([$ownerPath]); + + $this->rootFolder + ->method('getUserFolder') + ->with('shareOwner') + ->willReturn($shareOwnerFolder); + + $share = $this->provider->getShareById($id); + + // We fetch the node so the root folder is eventually called + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_USER, $share->getShareType()); + $this->assertEquals('sharedWith', $share->getSharedWith()); + $this->assertEquals('sharedBy', $share->getSharedBy()); + $this->assertEquals('shareOwner', $share->getShareOwner()); + $this->assertEquals($ownerPath, $share->getNode()); + $this->assertEquals(13, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('myTarget', $share->getTarget()); + } + public function testGetShareByIdGroupShare() { $qb = $this->dbConn->getQueryBuilder(); @@ -370,6 +449,39 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEmpty($result); } + public function testDeleteSingleShareLazy() { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), + 'share_with' => $qb->expr()->literal('sharedWith'), + 'uid_owner' => $qb->expr()->literal('shareOwner'), + 'uid_initiator' => $qb->expr()->literal('sharedBy'), + 'item_type' => $qb->expr()->literal('file'), + 'file_source' => $qb->expr()->literal(42), + 'file_target' => $qb->expr()->literal('myTarget'), + 'permissions' => $qb->expr()->literal(13), + ]); + $this->assertEquals(1, $qb->execute()); + + $id = $qb->getLastInsertId(); + + $this->rootFolder->expects($this->never())->method($this->anything()); + + $share = $this->provider->getShareById($id); + $this->provider->delete($share); + + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('share'); + + $cursor = $qb->execute(); + $result = $cursor->fetchAll(); + $cursor->closeCursor(); + + $this->assertEmpty($result); + } + public function testDeleteGroupShareWithUserGroupShares() { $qb = $this->dbConn->getQueryBuilder(); $qb->insert('share') @@ -561,7 +673,7 @@ class DefaultShareProviderTest extends \Test\TestCase { } public function testCreateUserShare() { - $share = new \OC\Share20\Share(); + $share = new \OC\Share20\Share($this->rootFolder); $shareOwner = $this->getMock('OCP\IUser'); $shareOwner->method('getUID')->WillReturn('shareOwner'); @@ -609,7 +721,7 @@ class DefaultShareProviderTest extends \Test\TestCase { } public function testCreateGroupShare() { - $share = new \OC\Share20\Share(); + $share = new \OC\Share20\Share($this->rootFolder); $shareOwner = $this->getMock('\OCP\IUser'); $shareOwner->method('getUID')->willReturn('shareOwner'); @@ -657,7 +769,7 @@ class DefaultShareProviderTest extends \Test\TestCase { } public function testCreateLinkShare() { - $share = new \OC\Share20\Share(); + $share = new \OC\Share20\Share($this->rootFolder); $shareOwner = $this->getMock('\OCP\IUser'); $shareOwner->method('getUID')->willReturn('shareOwner'); diff --git a/tests/lib/share20/managertest.php b/tests/lib/share20/managertest.php index aa286cc4719..270f5da33cd 100644 --- a/tests/lib/share20/managertest.php +++ b/tests/lib/share20/managertest.php @@ -20,6 +20,7 @@ */ namespace Test\Share20; +use OCP\Files\IRootFolder; use OCP\IUserManager; use OCP\Share\IProviderFactory; use OCP\Share\IShare; @@ -35,7 +36,6 @@ use OCP\Security\ISecureRandom; use OCP\Security\IHasher; use OCP\Files\Mount\IMountManager; use OCP\IGroupManager; -use Sabre\VObject\Property\VCard\DateTime; /** * Class ManagerTest @@ -47,36 +47,28 @@ class ManagerTest extends \Test\TestCase { /** @var Manager */ protected $manager; - /** @var ILogger */ protected $logger; - /** @var IConfig */ protected $config; - /** @var ISecureRandom */ protected $secureRandom; - /** @var IHasher */ protected $hasher; - /** @var IShareProvider | \PHPUnit_Framework_MockObject_MockObject */ protected $defaultProvider; - /** @var IMountManager */ protected $mountManager; - /** @var IGroupManager */ protected $groupManager; - /** @var IL10N */ protected $l; - /** @var DummyFactory */ protected $factory; - /** @var IUserManager */ protected $userManager; + /** @var IRootFolder | \PHPUnit_Framework_MockObject_MockObject */ + protected $rootFolder; public function setUp() { @@ -87,6 +79,7 @@ class ManagerTest extends \Test\TestCase { $this->mountManager = $this->getMock('\OCP\Files\Mount\IMountManager'); $this->groupManager = $this->getMock('\OCP\IGroupManager'); $this->userManager = $this->getMock('\OCP\IUserManager'); + $this->rootFolder = $this->getMock('\OCP\Files\IRootFolder'); $this->l = $this->getMock('\OCP\IL10N'); $this->l->method('t') @@ -105,7 +98,8 @@ class ManagerTest extends \Test\TestCase { $this->groupManager, $this->l, $this->factory, - $this->userManager + $this->userManager, + $this->rootFolder ); $this->defaultProvider = $this->getMockBuilder('\OC\Share20\DefaultShareProvider') @@ -131,7 +125,8 @@ class ManagerTest extends \Test\TestCase { $this->groupManager, $this->l, $this->factory, - $this->userManager + $this->userManager, + $this->rootFolder ]); } @@ -247,6 +242,86 @@ class ManagerTest extends \Test\TestCase { $manager->deleteShare($share); } + public function testDeleteLazyShare() { + $manager = $this->createManagerMock() + ->setMethods(['getShareById', 'deleteChildren']) + ->getMock(); + + $share = $this->manager->newShare(); + $share->setId(42) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith('sharedWith') + ->setSharedBy('sharedBy') + ->setShareOwner('shareOwner') + ->setTarget('myTarget') + ->setNodeId(1) + ->setNodeType('file'); + + $this->rootFolder->expects($this->never())->method($this->anything()); + + $manager->expects($this->once())->method('getShareById')->with('prov:42')->willReturn($share); + $manager->expects($this->once())->method('deleteChildren')->with($share); + + $this->defaultProvider + ->expects($this->once()) + ->method('delete') + ->with($share); + + $hookListner = $this->getMockBuilder('Dummy')->setMethods(['pre', 'post'])->getMock(); + \OCP\Util::connectHook('OCP\Share', 'pre_unshare', $hookListner, 'pre'); + \OCP\Util::connectHook('OCP\Share', 'post_unshare', $hookListner, 'post'); + + $hookListnerExpectsPre = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ]; + + $hookListnerExpectsPost = [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + 'deletedShares' => [ + [ + 'id' => 42, + 'itemType' => 'file', + 'itemSource' => 1, + 'shareType' => \OCP\Share::SHARE_TYPE_USER, + 'shareWith' => 'sharedWith', + 'itemparent' => null, + 'uidOwner' => 'sharedBy', + 'fileSource' => 1, + 'fileTarget' => 'myTarget', + ], + ], + ]; + + + $hookListner + ->expects($this->exactly(1)) + ->method('pre') + ->with($hookListnerExpectsPre); + $hookListner + ->expects($this->exactly(1)) + ->method('post') + ->with($hookListnerExpectsPost); + + $manager->deleteShare($share); + } + public function testDeleteNested() { $manager = $this->createManagerMock() ->setMethods(['getShareById']) @@ -792,7 +867,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Only sharing with group members is allowed */ public function testUserCreateChecksShareWithGroupMembersOnlyDifferentGroups() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $sharedBy = $this->getMock('\OCP\IUser'); $sharedWith = $this->getMock('\OCP\IUser'); @@ -822,7 +897,7 @@ class ManagerTest extends \Test\TestCase { } public function testUserCreateChecksShareWithGroupMembersOnlySharedGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $sharedBy = $this->getMock('\OCP\IUser'); $sharedWith = $this->getMock('\OCP\IUser'); @@ -904,8 +979,7 @@ class ManagerTest extends \Test\TestCase { ->setProviderId('foo') ->setId('bar'); - $share2 = new \OC\Share20\Share(); - $owner2 = $this->getMock('\OCP\IUser'); + $share2 = $this->manager->newShare(); $share2->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setShareOwner('shareOwner2') ->setProviderId('foo') @@ -928,7 +1002,7 @@ class ManagerTest extends \Test\TestCase { } public function testUserCreateChecksIdenticalPathNotSharedWithUser() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $sharedWith = $this->getMock('\OCP\IUser'); $path = $this->getMock('\OCP\Files\Node'); $share->setSharedWith('sharedWith') @@ -939,7 +1013,7 @@ class ManagerTest extends \Test\TestCase { $this->userManager->method('get')->with('sharedWith')->willReturn($sharedWith); - $share2 = new \OC\Share20\Share(); + $share2 = $this->manager->newShare(); $share2->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setShareOwner('shareOwner2') ->setProviderId('foo') @@ -967,7 +1041,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Only sharing within your own groups is allowed */ public function testGroupCreateChecksShareWithGroupMembersOnlyNotInGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $user = $this->getMock('\OCP\IUser'); $group = $this->getMock('\OCP\IGroup'); @@ -988,7 +1062,7 @@ class ManagerTest extends \Test\TestCase { } public function testGroupCreateChecksShareWithGroupMembersOnlyInGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $user = $this->getMock('\OCP\IUser'); $group = $this->getMock('\OCP\IGroup'); @@ -1028,7 +1102,7 @@ class ManagerTest extends \Test\TestCase { ->setProviderId('foo') ->setId('bar'); - $share2 = new \OC\Share20\Share(); + $share2 = $this->manager->newShare(); $share2->setSharedWith('sharedWith') ->setProviderId('foo') ->setId('baz'); @@ -1041,14 +1115,14 @@ class ManagerTest extends \Test\TestCase { } public function testGroupCreateChecksPathAlreadySharedWithDifferentGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setSharedWith('sharedWith'); $path = $this->getMock('\OCP\Files\Node'); $share->setNode($path); - $share2 = new \OC\Share20\Share(); + $share2 = $this->manager->newShare(); $share2->setSharedWith('sharedWith2'); $this->defaultProvider->method('getSharesByPath') @@ -1063,7 +1137,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Link sharing not allowed */ public function testLinkCreateChecksNoLinkSharesAllowed() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $this->config ->method('getAppValue') @@ -1079,7 +1153,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Link shares can't have reshare permissions */ public function testLinkCreateChecksSharePermissions() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_SHARE); @@ -1097,7 +1171,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Link shares can't have delete permissions */ public function testLinkCreateChecksDeletePermissions() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_DELETE); @@ -1115,7 +1189,7 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Public upload not allowed */ public function testLinkCreateChecksNoPublicUpload() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); @@ -1130,7 +1204,7 @@ class ManagerTest extends \Test\TestCase { } public function testLinkCreateChecksPublicUpload() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); @@ -1145,7 +1219,7 @@ class ManagerTest extends \Test\TestCase { } public function testLinkCreateChecksReadOnly() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_READ); @@ -1316,7 +1390,7 @@ class ManagerTest extends \Test\TestCase { ->getMock(); $manager->expects($this->once())->method('canShare')->willReturn(false); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $manager->createShare($share); } @@ -1610,7 +1684,8 @@ class ManagerTest extends \Test\TestCase { $this->groupManager, $this->l, $factory, - $this->userManager + $this->userManager, + $this->rootFolder ); $share = $this->getMock('\OCP\Share\IShare'); @@ -1695,7 +1770,7 @@ class ManagerTest extends \Test\TestCase { ->getMock(); $manager->expects($this->once())->method('canShare')->willReturn(false); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $manager->updateShare($share); } @@ -1711,13 +1786,13 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP); $manager->expects($this->once())->method('canShare')->willReturn(true); $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setProviderId('foo') ->setId('42') ->setShareType(\OCP\Share::SHARE_TYPE_USER); @@ -1737,14 +1812,14 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setSharedWith('origGroup'); $manager->expects($this->once())->method('canShare')->willReturn(true); $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setProviderId('foo') ->setId('42') ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) @@ -1765,14 +1840,14 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_USER) ->setSharedWith('sharedWith'); $manager->expects($this->once())->method('canShare')->willReturn(true); $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setProviderId('foo') ->setId('42') ->setShareType(\OCP\Share::SHARE_TYPE_USER) @@ -1793,19 +1868,22 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_USER) ->setSharedWith('origUser'); $manager->expects($this->once())->method('canShare')->willReturn(true); $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); - $share = new \OC\Share20\Share(); + $node = $this->getMock('\OCP\Files\File'); + + $share = $this->manager->newShare(); $share->setProviderId('foo') ->setId('42') ->setShareType(\OCP\Share::SHARE_TYPE_USER) ->setSharedWith('origUser') - ->setShareOwner('newUser'); + ->setShareOwner('newUser') + ->setNode($node); $this->defaultProvider->expects($this->once()) ->method('update') @@ -1831,19 +1909,22 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setSharedWith('origUser'); $manager->expects($this->once())->method('canShare')->willReturn(true); $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); - $share = new \OC\Share20\Share(); + $node = $this->getMock('\OCP\Files\File'); + + $share = $this->manager->newShare(); $share->setProviderId('foo') ->setId('42') ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) ->setSharedWith('origUser') - ->setShareOwner('owner'); + ->setShareOwner('owner') + ->setNode($node); $this->defaultProvider->expects($this->once()) ->method('update') @@ -1871,7 +1952,7 @@ class ManagerTest extends \Test\TestCase { ]) ->getMock(); - $originalShare = new \OC\Share20\Share(); + $originalShare = $this->manager->newShare(); $originalShare->setShareType(\OCP\Share::SHARE_TYPE_LINK); $tomorrow = new \DateTime(); diff --git a/version.php b/version.php index f807b01d7d0..44bddca0700 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,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, 0, 9); +$OC_Version = array(9, 0, 0, 10); // The human readable string $OC_VersionString = '9.0 pre alpha'; |