diff options
-rw-r--r-- | apps/files_sharing/js/sharedfilelist.js | 73 | ||||
-rw-r--r-- | apps/files_sharing/tests/js/sharedfilelistSpec.js | 115 | ||||
-rw-r--r-- | apps/files_versions/lib/storage.php | 9 | ||||
-rw-r--r-- | core/js/mimetype.js | 2 | ||||
-rw-r--r-- | core/js/mimetypelist.js | 57 | ||||
-rw-r--r-- | core/js/sharedialogview.js | 9 | ||||
-rw-r--r-- | lib/private/files/type/detection.php | 2 | ||||
-rw-r--r-- | lib/private/files/view.php | 37 | ||||
-rw-r--r-- | lib/private/helper.php | 2 | ||||
-rw-r--r-- | lib/repair/repairmimetypes.php | 52 | ||||
-rw-r--r-- | resources/config/mimetypealiases.dist.json | 29 | ||||
-rw-r--r-- | resources/config/mimetypemapping.dist.json | 5 | ||||
-rw-r--r-- | tests/lib/files/view.php | 131 | ||||
-rw-r--r-- | tests/lib/repair/repairmimetypes.php | 72 | ||||
-rw-r--r-- | version.php | 2 |
15 files changed, 516 insertions, 81 deletions
diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index 98dbd4c6702..2e798a92578 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -122,7 +122,9 @@ if (this._reloadCall) { this._reloadCall.abort(); } - this._reloadCall = $.ajax({ + + var promises = []; + var shares = $.ajax({ url: OC.linkToOCS('apps/files_sharing/api/v1') + 'shares', /* jshint camelcase: false */ data: { @@ -132,25 +134,84 @@ type: 'GET', beforeSend: function(xhr) { xhr.setRequestHeader('OCS-APIREQUEST', 'true'); - } + }, }); + promises.push(shares); + + if (!!this._sharedWithUser) { + var remoteShares = $.ajax({ + url: OC.linkToOCS('apps/files_sharing/api/v1') + 'remote_shares', + /* jshint camelcase: false */ + data: { + format: 'json' + }, + type: 'GET', + beforeSend: function(xhr) { + xhr.setRequestHeader('OCS-APIREQUEST', 'true'); + }, + }); + promises.push(remoteShares); + } else { + //Push empty promise so callback gets called the same way + promises.push($.Deferred().resolve()); + } + + this._reloadCall = $.when.apply($, promises); var callBack = this.reloadCallback.bind(this); return this._reloadCall.then(callBack, callBack); }, - reloadCallback: function(result) { + reloadCallback: function(shares, remoteShares) { delete this._reloadCall; this.hideMask(); this.$el.find('#headerSharedWith').text( t('files_sharing', this._sharedWithUser ? 'Shared by' : 'Shared with') ); - if (result.ocs && result.ocs.data) { - this.setFiles(this._makeFilesFromShares(result.ocs.data)); + + var files = []; + + if (shares[0].ocs && shares[0].ocs.data) { + files = files.concat(this._makeFilesFromShares(shares[0].ocs.data)); + } else { + // TODO: error handling } - else { + + if (remoteShares && remoteShares[0].ocs && remoteShares[0].ocs.data) { + files = files.concat(this._makeFilesFromRemoteShares(remoteShares[0].ocs.data)); + } else { // TODO: error handling } + + this.setFiles(files); + }, + + _makeFilesFromRemoteShares: function(data) { + var self = this; + var files = data; + + files = _.chain(files) + // convert share data to file data + .map(function(share) { + var file = { + shareOwner: share.owner + '@' + share.remote.replace(/.*?:\/\//g, ""), + name: OC.basename(share.mountpoint), + mtime: share.mtime * 1000, + mimetype: share.mimetype, + type: share.type, + id: share.file_id, + path: OC.dirname(share.mountpoint), + permissions: share.permissions + }; + + file.shares = [{ + id: share.id, + type: OC.Share.SHARE_TYPE_REMOTE + }]; + return file; + }) + .value(); + return files; }, /** diff --git a/apps/files_sharing/tests/js/sharedfilelistSpec.js b/apps/files_sharing/tests/js/sharedfilelistSpec.js index 7fdc6345e38..90ae9c2d6da 100644 --- a/apps/files_sharing/tests/js/sharedfilelistSpec.js +++ b/apps/files_sharing/tests/js/sharedfilelistSpec.js @@ -57,6 +57,7 @@ describe('OCA.Sharing.FileList tests', function() { describe('loading file list for incoming shares', function() { var ocsResponse; + var ocsResponseRemote; beforeEach(function() { fileList = new OCA.Sharing.FileList( @@ -95,26 +96,64 @@ describe('OCA.Sharing.FileList tests', function() { }] } }; + + /* jshint camelcase: false */ + ocsResponseRemote = { + ocs: { + meta: { + status: 'ok', + statuscode: 100, + message: null + }, + data: [{ + id: 8, + remote: 'https://foo.bar/', + remote_id: 42, + share_token: 'abc', + name: '/a.txt', + owner: 'user3', + user: 'user1', + mountpoint: '/b.txt', + mountpoint_hash: 'def', + accepted: 1, + mimetype: 'text/plain', + mtime: 22222, + permissions: 31, + type: 'file', + file_id: 1337 + }] + } + }; + }); it('render file shares', function() { - var request; - - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( + expect(fakeServer.requests.length).toEqual(2); + expect(fakeServer.requests[0].url).toEqual( OC.linkToOCS('apps/files_sharing/api/v1') + 'shares?format=json&shared_with_me=true' ); + expect(fakeServer.requests[1].url).toEqual( + OC.linkToOCS('apps/files_sharing/api/v1') + + 'remote_shares?format=json' + ); + fakeServer.requests[0].respond( 200, { 'Content-Type': 'application/json' }, JSON.stringify(ocsResponse) ); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(ocsResponseRemote) + ); + var $rows = fileList.$el.find('tbody tr'); + expect($rows.length).toEqual(2); + var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); expect($tr.attr('data-id')).toEqual('49'); expect($tr.attr('data-type')).toEqual('file'); expect($tr.attr('data-file')).toEqual('local name.txt'); @@ -132,32 +171,66 @@ describe('OCA.Sharing.FileList tests', function() { '?dir=%2Flocal%20path&files=local%20name.txt' ); expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); + + $tr = $rows.eq(1); + expect($tr.attr('data-id')).toEqual('1337'); + expect($tr.attr('data-type')).toEqual('file'); + expect($tr.attr('data-file')).toEqual('b.txt'); + expect($tr.attr('data-path')).toEqual(''); + expect($tr.attr('data-size')).not.toBeDefined(); + expect(parseInt($tr.attr('data-permissions'), 10)) + .toEqual(OC.PERMISSION_ALL); // read and delete + expect($tr.attr('data-mime')).toEqual('text/plain'); + expect($tr.attr('data-mtime')).toEqual('22222000'); + expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/'); + expect($tr.attr('data-share-id')).toEqual('8'); + expect($tr.find('a.name').attr('href')).toEqual( + OC.webroot + + '/index.php/apps/files/ajax/download.php' + + '?dir=%2F&files=b.txt' + ); + expect($tr.find('.nametext').text().trim()).toEqual('b.txt'); }); it('render folder shares', function() { /* jshint camelcase: false */ - var request; ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], { item_type: 'folder', file_target: '/local path/local name', path: 'files/something shared', }); - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( + ocsResponseRemote.ocs.data[0] = _.extend(ocsResponseRemote.ocs.data[0], { + type: 'dir', + mimetype: 'httpd/unix-directory', + name: '/a', + mountpoint: '/b' + }); + + expect(fakeServer.requests.length).toEqual(2); + expect(fakeServer.requests[0].url).toEqual( OC.linkToOCS('apps/files_sharing/api/v1') + 'shares?format=json&shared_with_me=true' ); + expect(fakeServer.requests[1].url).toEqual( + OC.linkToOCS('apps/files_sharing/api/v1') + + 'remote_shares?format=json' + ); fakeServer.requests[0].respond( 200, { 'Content-Type': 'application/json' }, JSON.stringify(ocsResponse) ); + fakeServer.requests[1].respond( + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify(ocsResponseRemote) + ); var $rows = fileList.$el.find('tbody tr'); + expect($rows.length).toEqual(2); + var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); expect($tr.attr('data-id')).toEqual('49'); expect($tr.attr('data-type')).toEqual('dir'); expect($tr.attr('data-file')).toEqual('local name'); @@ -175,6 +248,26 @@ describe('OCA.Sharing.FileList tests', function() { '?dir=/local%20path/local%20name' ); expect($tr.find('.nametext').text().trim()).toEqual('local name'); + + $tr = $rows.eq(1); + expect($tr.attr('data-id')).toEqual('1337'); + expect($tr.attr('data-type')).toEqual('dir'); + expect($tr.attr('data-file')).toEqual('b'); + expect($tr.attr('data-path')).toEqual(''); + expect($tr.attr('data-size')).not.toBeDefined(); + expect(parseInt($tr.attr('data-permissions'), 10)) + .toEqual(OC.PERMISSION_ALL); // read and delete + expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); + expect($tr.attr('data-mtime')).toEqual('22222000'); + expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/'); + expect($tr.attr('data-share-id')).toEqual('8'); + expect($tr.find('a.name').attr('href')).toEqual( + OC.webroot + + '/index.php/apps/files' + + '?dir=/b' + ); + expect($tr.find('.nametext').text().trim()).toEqual('b'); + }); }); describe('loading file list for outgoing shares', function() { diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php index bdf1811c5f9..cd2077d2922 100644 --- a/apps/files_versions/lib/storage.php +++ b/apps/files_versions/lib/storage.php @@ -42,6 +42,7 @@ namespace OCA\Files_Versions; use OCA\Files_Versions\AppInfo\Application; use OCA\Files_Versions\Command\Expire; +use OCP\Lock\ILockingProvider; class Storage { @@ -337,11 +338,19 @@ class Storage { * @return bool true for success, false otherwise */ private static function copyFileContents($view, $path1, $path2) { + /** @var \OC\Files\Storage\Storage $storage1 */ list($storage1, $internalPath1) = $view->resolvePath($path1); + /** @var \OC\Files\Storage\Storage $storage2 */ list($storage2, $internalPath2) = $view->resolvePath($path2); + $view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); + $view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); + $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); + $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); + $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); + return ($result !== false); } diff --git a/core/js/mimetype.js b/core/js/mimetype.js index d22b0a2378a..b0de8eb8411 100644 --- a/core/js/mimetype.js +++ b/core/js/mimetype.js @@ -70,7 +70,7 @@ OC.MimeType = { return undefined; } - if (mimeType in OC.MimeTypeList.aliases) { + while (mimeType in OC.MimeTypeList.aliases) { mimeType = OC.MimeTypeList.aliases[mimeType]; } if (mimeType in OC.MimeType._mimeTypeIcons) { diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js index af2ad73c51b..43f01273f55 100644 --- a/core/js/mimetypelist.js +++ b/core/js/mimetypelist.js @@ -9,23 +9,26 @@ OC.MimeTypeList={ aliases: { "application/coreldraw": "image", - "application/font-sfnt": "font", - "application/font-woff": "font", - "application/illustrator": "image/vector", + "application/epub+zip": "text", + "application/font-sfnt": "image", + "application/font-woff": "image", + "application/illustrator": "image", + "application/javascript": "text/code", "application/json": "text/code", - "application/msaccess": "database", + "application/msaccess": "file", "application/msexcel": "x-office/spreadsheet", "application/mspowerpoint": "x-office/presentation", "application/msword": "x-office/document", "application/octet-stream": "file", - "application/postscript": "image/vector", + "application/postscript": "image", + "application/rss+xml": "application/xml", "application/vnd.android.package-archive": "package/x-generic", "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", "application/vnd.ms-excel.sheet.macroEnabled.12": "x-office/spreadsheet", "application/vnd.ms-excel.template.macroEnabled.12": "x-office/spreadsheet", - "application/vnd.ms-fontobject": "font", + "application/vnd.ms-fontobject": "image", "application/vnd.ms-powerpoint": "x-office/presentation", "application/vnd.ms-powerpoint.addin.macroEnabled.12": "x-office/presentation", "application/vnd.ms-powerpoint.presentation.macroEnabled.12": "x-office/presentation", @@ -49,10 +52,11 @@ OC.MimeTypeList={ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "x-office/document", "application/vnd.openxmlformats-officedocument.wordprocessingml.template": "x-office/document", "application/x-7z-compressed": "package/x-generic", + "application/x-cbr": "text", "application/x-compressed": "package/x-generic", "application/x-dcraw": "image", "application/x-deb": "package/x-generic", - "application/x-font": "font", + "application/x-font": "image", "application/x-gimp": "image", "application/x-gzip": "package/x-generic", "application/x-perl": "text/code", @@ -64,33 +68,40 @@ OC.MimeTypeList={ "application/xml": "text/html", "application/yaml": "text/code", "application/zip": "package/x-generic", + "database": "file", "httpd/unix-directory": "dir", - "image/svg+xml": "image/vector", "text/css": "text/code", "text/csv": "x-office/spreadsheet", - "text/x-shellscript": "text/code" + "text/html": "text/code", + "text/x-c": "text/code", + "text/x-c++src": "text/code", + "text/x-h": "text/code", + "text/x-java-source": "text/code", + "text/x-python": "text/code", + "text/x-shellscript": "text/code", + "web": "text/code" }, files: [ - "application-pdf", - "application", - "audio", - "file", + "video", "folder-drag-accept", - "folder-external", - "folder-public", - "folder-shared", "folder-starred", - "folder", - "image", + "folder-public", "package-x-generic", - "text-calendar", - "text-code", - "text-vcard", "text", - "video", + "folder-external", + "text-vcard", + "application", + "text-code", + "x-office-spreadsheet", + "application-pdf", + "folder", "x-office-document", + "text-calendar", "x-office-presentation", - "x-office-spreadsheet" + "file", + "folder-shared", + "image", + "audio" ], themes: [] }; diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index ee31ed33132..7b02e6a3a50 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -174,12 +174,19 @@ // only show the loading spinner for the first request (for now) if (!this._loadingOnce) { this._toggleLoading(true); - this._loadingOnce = true; } }, _onEndRequest: function() { + var self = this; this._toggleLoading(false); + if (!this._loadingOnce) { + this._loadingOnce = true; + // the first time, focus on the share field after the spinner disappeared + _.defer(function() { + self.$('#shareWith').focus(); + }); + } }, render: function() { diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php index 0c647ab44c6..dc8aff2f30c 100644 --- a/lib/private/files/type/detection.php +++ b/lib/private/files/type/detection.php @@ -269,7 +269,7 @@ class Detection implements IMimeTypeDetector { public function mimeTypeIcon($mimetype) { $this->loadAliases(); - if (isset($this->mimeTypeAlias[$mimetype])) { + while (isset($this->mimeTypeAlias[$mimetype])) { $mimetype = $this->mimeTypeAlias[$mimetype]; } if (isset($this->mimetypeIcons[$mimetype])) { diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 95b688fef5c..c8dbc001f2d 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -1602,25 +1602,46 @@ class View { /** * check if it is allowed to move a mount point to a given target. - * It is not allowed to move a mount point into a different mount point + * It is not allowed to move a mount point into a different mount point or + * into an already shared folder * * @param string $target path * @return boolean */ private function isTargetAllowed($target) { - $result = false; - - list($targetStorage,) = \OC\Files\Filesystem::resolvePath($target); - if ($targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) { - $result = true; - } else { + list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target); + if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) { \OCP\Util::writeLog('files', 'It is not allowed to move one mount point into another one', \OCP\Util::DEBUG); + return false; } - return $result; + // note: cannot use the view because the target is already locked + $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath); + if ($fileId === -1) { + // target might not exist, need to check parent instead + $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath)); + } + + // check if any of the parents were shared by the current owner (include collections) + $shares = \OCP\Share::getItemShared( + 'folder', + $fileId, + \OCP\Share::FORMAT_NONE, + null, + true + ); + + if (count($shares) > 0) { + \OCP\Util::writeLog('files', + 'It is not allowed to move one mount point into a shared folder', + \OCP\Util::DEBUG); + return false; + } + + return true; } /** diff --git a/lib/private/helper.php b/lib/private/helper.php index ba1240a5218..973960ca7a5 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -742,7 +742,7 @@ class OC_Helper { $freeSpace = max($freeSpace, 0); return $freeSpace; } else { - return INF; + return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188 } } diff --git a/lib/repair/repairmimetypes.php b/lib/repair/repairmimetypes.php index db11f526ad6..b9cd42f3136 100644 --- a/lib/repair/repairmimetypes.php +++ b/lib/repair/repairmimetypes.php @@ -250,6 +250,39 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { self::updateMimetypes($updatedMimetypes); } + private function introduceJavaMimeType() { + $updatedMimetypes = array( + 'class' => 'application/java', + 'java' => 'text/x-java-source', + ); + + self::updateMimetypes($updatedMimetypes); + } + + private function introduceHppMimeType() { + $updatedMimetypes = array( + 'hpp' => 'text/x-h', + ); + + self::updateMimetypes($updatedMimetypes); + } + + private function introduceRssMimeType() { + $updatedMimetypes = array( + 'rss' => 'application/rss+xml', + ); + + self::updateMimetypes($updatedMimetypes); + } + + private function introduceRtfMimeType() { + $updatedMimetypes = array( + 'rtf' => 'text/rtf', + ); + + self::updateMimetypes($updatedMimetypes); + } + /** * Fix mime types */ @@ -294,5 +327,24 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { $this->emit('\OC\Repair', 'info', array('Fixed Yaml/Yml mime types')); } } + + // Mimetype updates from #19272 + if (version_compare($ocVersionFromBeforeUpdate, '8.2.0.8', '<')) { + if ($this->introduceJavaMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed java/class mime types')); + } + + if ($this->introduceHppMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed hpp mime type')); + } + + if ($this->introduceRssMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed rss mime type')); + } + + if ($this->introduceRtfMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed rtf mime type')); + } + } } } diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json index 3d6c5edc132..ed471f228e2 100644 --- a/resources/config/mimetypealiases.dist.json +++ b/resources/config/mimetypealiases.dist.json @@ -9,23 +9,26 @@ "application/coreldraw": "image", - "application/font-sfnt": "font", - "application/font-woff": "font", - "application/illustrator": "image/vector", + "application/epub+zip": "text", + "application/font-sfnt": "image", + "application/font-woff": "image", + "application/illustrator": "image", + "application/javascript": "text/code", "application/json": "text/code", - "application/msaccess": "database", + "application/msaccess": "file", "application/msexcel": "x-office/spreadsheet", "application/mspowerpoint": "x-office/presentation", "application/msword": "x-office/document", "application/octet-stream": "file", - "application/postscript": "image/vector", + "application/postscript": "image", + "application/rss+xml": "application/xml", "application/vnd.android.package-archive": "package/x-generic", "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", "application/vnd.ms-excel.sheet.macroEnabled.12": "x-office/spreadsheet", "application/vnd.ms-excel.template.macroEnabled.12": "x-office/spreadsheet", - "application/vnd.ms-fontobject": "font", + "application/vnd.ms-fontobject": "image", "application/vnd.ms-powerpoint": "x-office/presentation", "application/vnd.ms-powerpoint.addin.macroEnabled.12": "x-office/presentation", "application/vnd.ms-powerpoint.presentation.macroEnabled.12": "x-office/presentation", @@ -49,10 +52,11 @@ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "x-office/document", "application/vnd.openxmlformats-officedocument.wordprocessingml.template": "x-office/document", "application/x-7z-compressed": "package/x-generic", + "application/x-cbr": "text", "application/x-compressed": "package/x-generic", "application/x-dcraw": "image", "application/x-deb": "package/x-generic", - "application/x-font": "font", + "application/x-font": "image", "application/x-gimp": "image", "application/x-gzip": "package/x-generic", "application/x-perl": "text/code", @@ -64,10 +68,17 @@ "application/xml": "text/html", "application/yaml": "text/code", "application/zip": "package/x-generic", + "database": "file", "httpd/unix-directory": "dir", - "image/svg+xml": "image/vector", "text/css": "text/code", "text/csv": "x-office/spreadsheet", - "text/x-shellscript": "text/code" + "text/html": "text/code", + "text/x-c": "text/code", + "text/x-c++src": "text/code", + "text/x-h": "text/code", + "text/x-java-source": "text/code", + "text/x-python": "text/code", + "text/x-shellscript": "text/code", + "web": "text/code" } diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json index 79b0ca65240..e26ec7038b1 100644 --- a/resources/config/mimetypemapping.dist.json +++ b/resources/config/mimetypemapping.dist.json @@ -27,6 +27,7 @@ "cbz": ["application/x-cbr"], "cc": ["text/x-c"], "cdr": ["application/coreldraw"], + "class": ["application/java"], "cnf": ["text/plain"], "conf": ["text/plain"], "cpp": ["text/x-c++src"], @@ -57,12 +58,14 @@ "gzip": ["application/x-gzip"], "h": ["text/x-h"], "hh": ["text/x-h"], + "hpp": ["text/x-h"], "html": ["text/html", "text/plain"], "htm": ["text/html", "text/plain"], "ical": ["text/calendar"], "ics": ["text/calendar"], "iiq": ["image/x-dcraw"], "impress": ["text/impress"], + "java": ["text/x-java-source"], "jpeg": ["image/jpeg"], "jpg": ["image/jpeg"], "jps": ["image/jpeg"], @@ -130,6 +133,8 @@ "raf": ["image/x-dcraw"], "rar": ["application/x-rar-compressed"], "reveal": ["text/reveal"], + "rss": ["application/rss+xml"], + "rtf": ["text/rtf"], "rw2": ["image/x-dcraw"], "sgf": ["application/sgf"], "sh-lib": ["text/x-shellscript"], diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ceeb9ba7a94..94f9e209152 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -104,6 +104,9 @@ class View extends \Test\TestCase { $this->userObject->delete(); $this->groupObject->delete(); + $mountProviderCollection = \OC::$server->getMountProviderCollection(); + \Test\TestCase::invokePrivate($mountProviderCollection, 'providers', [[]]); + parent::tearDown(); } @@ -1486,6 +1489,112 @@ class View extends \Test\TestCase { $this->assertEquals($shouldEmit, $result); } + /** + * Create test movable mount points + * + * @param array $mountPoints array of mount point locations + * @return array array of MountPoint objects + */ + private function createTestMovableMountPoints($mountPoints) { + $mounts = []; + foreach ($mountPoints as $mountPoint) { + $storage = $this->getMockBuilder('\OC\Files\Storage\Temporary') + ->setMethods([]) + ->getMock(); + + $mounts[] = $this->getMock( + '\Test\TestMoveableMountPoint', + ['moveMount'], + [$storage, $mountPoint] + ); + } + + $mountProvider = $this->getMock('\OCP\Files\Config\IMountProvider'); + $mountProvider->expects($this->any()) + ->method('getMountsForUser') + ->will($this->returnValue($mounts)); + + $mountProviderCollection = \OC::$server->getMountProviderCollection(); + $mountProviderCollection->registerProvider($mountProvider); + + return $mounts; + } + + /** + * Test mount point move + */ + public function testMountPointMove() { + $this->loginAsUser($this->user); + + list($mount1, $mount2) = $this->createTestMovableMountPoints([ + $this->user . '/files/mount1', + $this->user . '/files/mount2', + ]); + $mount1->expects($this->once()) + ->method('moveMount') + ->will($this->returnValue(true)); + + $mount2->expects($this->once()) + ->method('moveMount') + ->will($this->returnValue(true)); + + $view = new \OC\Files\View('/' . $this->user . '/files/'); + $view->mkdir('sub'); + + $this->assertTrue($view->rename('mount1', 'renamed_mount'), 'Can rename mount point'); + $this->assertTrue($view->rename('mount2', 'sub/moved_mount'), 'Can move a mount point into a subdirectory'); + } + /** + * Test that moving a mount point into another is forbidden + */ + public function testMoveMountPointIntoAnother() { + $this->loginAsUser($this->user); + + list($mount1, $mount2) = $this->createTestMovableMountPoints([ + $this->user . '/files/mount1', + $this->user . '/files/mount2', + ]); + + $mount1->expects($this->never()) + ->method('moveMount'); + + $mount2->expects($this->never()) + ->method('moveMount'); + + $view = new \OC\Files\View('/' . $this->user . '/files/'); + + $this->assertFalse($view->rename('mount1', 'mount2'), 'Cannot overwrite another mount point'); + $this->assertFalse($view->rename('mount1', 'mount2/sub'), 'Cannot move a mount point into another'); + } + /** + * Test that moving a mount point into a shared folder is forbidden + */ + public function testMoveMountPointIntoSharedFolder() { + $this->loginAsUser($this->user); + + list($mount1) = $this->createTestMovableMountPoints([ + $this->user . '/files/mount1', + ]); + + $mount1->expects($this->never()) + ->method('moveMount'); + + $view = new \OC\Files\View('/' . $this->user . '/files/'); + $view->mkdir('shareddir'); + $view->mkdir('shareddir/sub'); + $view->mkdir('shareddir/sub2'); + + $fileId = $view->getFileInfo('shareddir')->getId(); + $userObject = \OC::$server->getUserManager()->createUser('test2', 'IHateNonMockableStaticClasses'); + $this->assertTrue(\OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, 'test2', \OCP\Constants::PERMISSION_READ)); + + $this->assertFalse($view->rename('mount1', 'shareddir'), 'Cannot overwrite shared folder'); + $this->assertFalse($view->rename('mount1', 'shareddir/sub'), 'Cannot move mount point into shared folder'); + $this->assertFalse($view->rename('mount1', 'shareddir/sub/sub2'), 'Cannot move mount point into shared subfolder'); + + $this->assertTrue(\OCP\Share::unshare('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, 'test2')); + $userObject->delete(); + } public function basicOperationProviderForLocks() { return [ @@ -2042,23 +2151,9 @@ class View extends \Test\TestCase { public function testLockMoveMountPoint() { $this->loginAsUser('test'); - $subStorage = $this->getMockBuilder('\OC\Files\Storage\Temporary') - ->setMethods([]) - ->getMock(); - - $mount = $this->getMock( - '\Test\TestMoveableMountPoint', - ['moveMount'], - [$subStorage, $this->user . '/files/substorage'] - ); - - $mountProvider = $this->getMock('\OCP\Files\Config\IMountProvider'); - $mountProvider->expects($this->once()) - ->method('getMountsForUser') - ->will($this->returnValue([$mount])); - - $mountProviderCollection = \OC::$server->getMountProviderCollection(); - $mountProviderCollection->registerProvider($mountProvider); + list($mount) = $this->createTestMovableMountPoints([ + $this->user . '/files/substorage', + ]); $view = new \OC\Files\View('/' . $this->user . '/files/'); $view->mkdir('subdir'); @@ -2109,8 +2204,6 @@ class View extends \Test\TestCase { $this->assertNull($this->getFileLockType($view, $sourcePath, false), 'Shared storage root not locked after operation'); $this->assertNull($this->getFileLockType($view, $sourcePath, true), 'Source path not locked after operation'); $this->assertNull($this->getFileLockType($view, $targetPath, true), 'Target path not locked after operation'); - - \Test\TestCase::invokePrivate($mountProviderCollection, 'providers', [[]]); } /** diff --git a/tests/lib/repair/repairmimetypes.php b/tests/lib/repair/repairmimetypes.php index 3c100b808cf..0288a476ede 100644 --- a/tests/lib/repair/repairmimetypes.php +++ b/tests/lib/repair/repairmimetypes.php @@ -283,6 +283,68 @@ class RepairMimeTypes extends \Test\TestCase { } /** + * Test renaming the java mime types + */ + public function testRenameJavaMimeType() { + $currentMimeTypes = [ + ['test.java', 'application/octet-stream'], + ['test.class', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.java', 'text/x-java-source'], + ['test.class', 'application/java'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + + /** + * Test renaming the hpp mime type + */ + public function testRenameHppMimeType() { + $currentMimeTypes = [ + ['test.hpp', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.hpp', 'text/x-h'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + + /** + * Test renaming the rss mime type + */ + public function testRenameRssMimeType() { + $currentMimeTypes = [ + ['test.rss', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.rss', 'application/rss+xml'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + + /** + * Test renaming the hpp mime type + */ + public function testRenameRtfMimeType() { + $currentMimeTypes = [ + ['test.rtf', 'application/octet-stream'], + ]; + + $fixedMimeTypes = [ + ['test.rtf', 'text/rtf'], + ]; + + $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); + } + + /** * Test renaming and splitting old office mime types when * new ones already exist */ @@ -399,6 +461,11 @@ class RepairMimeTypes extends \Test\TestCase { ['test.cnf', 'text/plain'], ['test.yaml', 'application/yaml'], ['test.yml', 'application/yaml'], + ['test.java', 'text/x-java-source'], + ['test.class', 'application/java'], + ['test.hpp', 'text/x-h'], + ['test.rss', 'application/rss+xml'], + ['test.rtf', 'text/rtf'], ]; $fixedMimeTypes = [ @@ -438,6 +505,11 @@ class RepairMimeTypes extends \Test\TestCase { ['test.cnf', 'text/plain'], ['test.yaml', 'application/yaml'], ['test.yml', 'application/yaml'], + ['test.java', 'text/x-java-source'], + ['test.class', 'application/java'], + ['test.hpp', 'text/x-h'], + ['test.rss', 'application/rss+xml'], + ['test.rtf', 'text/rtf'], ]; $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); diff --git a/version.php b/version.php index 925e897d1ab..7ba6c3d93bc 100644 --- a/version.php +++ b/version.php @@ -23,7 +23,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(8, 2, 0, 7); +$OC_Version = array(8, 2, 0, 8); // The human readable string $OC_VersionString = '8.2 beta1'; |