diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 10efa54496..fa9819b78b 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -950,7 +950,8 @@
type: $el.attr('data-type'),
etag: $el.attr('data-etag'),
permissions: parseInt($el.attr('data-permissions'), 10),
- hasPreview: $el.attr('data-has-preview') === 'true'
+ hasPreview: $el.attr('data-has-preview') === 'true',
+ isEncrypted: $el.attr('data-e2eencrypted') === 'true'
};
var size = $el.attr('data-size');
if (size) {
@@ -1152,7 +1153,10 @@
if (type === 'dir') {
mime = mime || 'httpd/unix-directory';
- if (fileData.mountType && fileData.mountType.indexOf('external') === 0) {
+ if (fileData.isEncrypted) {
+ icon = OC.MimeType.getIconUrl('dir-encrypted');
+ dataIcon = icon;
+ } else if (fileData.mountType && fileData.mountType.indexOf('external') === 0) {
icon = OC.MimeType.getIconUrl('dir-external');
dataIcon = icon;
}
@@ -1173,7 +1177,8 @@
"data-mtime": mtime,
"data-etag": fileData.etag,
"data-permissions": permissions,
- "data-has-preview": fileData.hasPreview !== false
+ "data-has-preview": fileData.hasPreview !== false,
+ "data-e2eencrypted": fileData.isEncrypted === true
});
if (dataIcon) {
@@ -1444,7 +1449,9 @@
path = fileData.path || this.getCurrentDirectory(),
permissions = parseInt(fileData.permissions, 10) || 0;
- if (fileData.isShareMountPoint) {
+ var isEndToEndEncrypted = (type === 'dir' && fileData.isEncrypted);
+
+ if (!isEndToEndEncrypted && fileData.isShareMountPoint) {
permissions = permissions | OC.PERMISSION_UPDATE;
}
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 64fc687649..83926b24fe 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -217,6 +217,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('text/plain');
expect($tr.attr('data-mtime')).toEqual('123456');
+ expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('a.name').attr('href'))
.toEqual(OC.webroot + '/remote.php/webdav/subdir/testName.txt');
expect($tr.find('.nametext').text().trim()).toEqual('testName.txt');
@@ -246,6 +247,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
expect($tr.attr('data-mtime')).toEqual('123456');
+ expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('.filesize').text()).toEqual('1 KB');
expect($tr.find('.date').text()).not.toEqual('?');
@@ -271,6 +273,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toBeUndefined();
expect($tr.attr('data-mtime')).toEqual('123456');
+ expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('.filesize').text()).toEqual('Pending');
expect($tr.find('.date').text()).not.toEqual('?');
@@ -293,10 +296,20 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
expect($tr.attr('data-mtime')).toEqual('123456');
+ expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('.filesize').text()).toEqual('Pending');
expect($tr.find('.date').text()).not.toEqual('?');
});
+ it('generates dir element with true e2eencrypted attribute when calling add() with minimal data including isEncrypted', function() {
+ var fileData = {
+ type: 'dir',
+ name: 'testFolder',
+ isEncrypted: true
+ };
+ var $tr = fileList.add(fileData);
+ expect($tr.attr('data-e2eencrypted')).toEqual('true');
+ });
it('generates file element with no permissions when permissions are explicitly none', function() {
var fileData = {
type: 'dir',
@@ -1442,6 +1455,32 @@ describe('OCA.Files.FileList tests', function() {
expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder.svg');
expect(previewLoadStub.notCalled).toEqual(true);
});
+ it('render encrypted folder icon for encrypted root', function() {
+ var fileData = {
+ type: 'dir',
+ mimetype: 'httpd/unix-directory',
+ name: 'test dir',
+ isEncrypted: true
+ };
+ var $tr = fileList.add(fileData);
+ var $td = $tr.find('td.filename');
+ expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder-encrypted.svg');
+ expect(previewLoadStub.notCalled).toEqual(true);
+ });
+ it('render encrypted folder icon for encrypted subdir', function() {
+ var fileData = {
+ type: 'dir',
+ mimetype: 'httpd/unix-directory',
+ name: 'test dir',
+ isEncrypted: true
+ };
+ var $tr = fileList.add(fileData);
+ var $td = $tr.find('td.filename');
+ expect(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder-encrypted.svg');
+ expect(previewLoadStub.notCalled).toEqual(true);
+ // default icon override
+ expect($tr.attr('data-icon')).toEqual(OC.webroot + '/core/img/filetypes/folder-encrypted.svg');
+ });
it('render external storage icon for external storage root', function() {
var fileData = {
type: 'dir',
@@ -2086,7 +2125,8 @@ describe('OCA.Files.FileList tests', function() {
size: 12,
etag: 'abc',
permissions: OC.PERMISSION_ALL,
- hasPreview: true
+ hasPreview: true,
+ isEncrypted: false
});
expect(files[1]).toEqual({
id: 3,
@@ -2097,7 +2137,8 @@ describe('OCA.Files.FileList tests', function() {
size: 58009,
etag: '123',
permissions: OC.PERMISSION_ALL,
- hasPreview: true
+ hasPreview: true,
+ isEncrypted: false
});
expect(files[2]).toEqual({
id: 4,
@@ -2108,7 +2149,8 @@ describe('OCA.Files.FileList tests', function() {
size: 250,
etag: '456',
permissions: OC.PERMISSION_ALL,
- hasPreview: true
+ hasPreview: true,
+ isEncrypted: false
});
expect(files[0].id).toEqual(1);
expect(files[0].name).toEqual('One.txt');
@@ -2130,7 +2172,8 @@ describe('OCA.Files.FileList tests', function() {
size: 12,
etag: 'abc',
permissions: OC.PERMISSION_ALL,
- hasPreview: true
+ hasPreview: true,
+ isEncrypted: false
});
expect(files[1]).toEqual({
id: 4,
@@ -2141,7 +2184,8 @@ describe('OCA.Files.FileList tests', function() {
size: 250,
etag: '456',
permissions: OC.PERMISSION_ALL,
- hasPreview: true
+ hasPreview: true,
+ isEncrypted: false
});
});
describe('Download', function() {
@@ -3231,6 +3275,16 @@ describe('OCA.Files.FileList tests', function() {
expect(fileInfo.mimetype).toEqual('text/plain');
expect(fileInfo.type).toEqual('file');
expect(fileInfo.path).not.toBeDefined();
+ expect(fileInfo.isEncrypted).toEqual(false);
+ });
+ it('sets isEncrypted attribute if data includes true e2eencrypted', function() {
+ testFiles[3].isEncrypted = true;
+
+ fileList.setFiles(testFiles);
+ $tr = fileList.findFileEl('somedir');
+
+ var fileInfo = fileList.elementToFile($tr);
+ expect(fileInfo.isEncrypted).toEqual(true);
});
it('adds path attribute if available', function() {
$tr.attr('data-path', '/subdir');
diff --git a/core/img/filetypes/folder-encrypted.svg b/core/img/filetypes/folder-encrypted.svg
new file mode 100644
index 0000000000..e2b62a99b0
--- /dev/null
+++ b/core/img/filetypes/folder-encrypted.svg
@@ -0,0 +1 @@
+
diff --git a/core/js/files/client.js b/core/js/files/client.js
index fa3d795d41..dc842a9d3b 100644
--- a/core/js/files/client.js
+++ b/core/js/files/client.js
@@ -74,6 +74,7 @@
Client.PROPERTY_PERMISSIONS = '{' + Client.NS_OWNCLOUD + '}permissions';
Client.PROPERTY_SIZE = '{' + Client.NS_OWNCLOUD + '}size';
Client.PROPERTY_GETCONTENTLENGTH = '{' + Client.NS_DAV + '}getcontentlength';
+ Client.PROPERTY_ISENCRYPTED = '{' + Client.NS_DAV + '}is-encrypted';
Client.PROTOCOL_HTTP = 'http';
Client.PROTOCOL_HTTPS = 'https';
@@ -120,6 +121,10 @@
* Mount type
*/
[Client.NS_NEXTCLOUD, 'mount-type'],
+ /**
+ * Encryption state
+ */
+ [Client.NS_NEXTCLOUD, 'is-encrypted'],
];
/**
@@ -305,6 +310,13 @@
data.hasPreview = true;
}
+ var isEncryptedProp = props['{' + Client.NS_NEXTCLOUD + '}is-encrypted'];
+ if (!_.isUndefined(isEncryptedProp)) {
+ data.isEncrypted = isEncryptedProp === '1';
+ } else {
+ data.isEncrypted = false;
+ }
+
var contentType = props[Client.PROPERTY_GETCONTENTTYPE];
if (!_.isUndefined(contentType)) {
data.mimetype = contentType;
diff --git a/core/js/mimetype.js b/core/js/mimetype.js
index ed4fedc7f8..e5a07abc95 100644
--- a/core/js/mimetype.js
+++ b/core/js/mimetype.js
@@ -44,6 +44,8 @@ OC.MimeType = {
// Generate path
if (mimeType === 'dir' && $.inArray('folder', files) !== -1) {
return 'folder';
+ } else if (mimeType === 'dir-encrypted' && $.inArray('folder-encrypted', files) !== -1) {
+ return 'folder-encrypted';
} else if (mimeType === 'dir-shared' && $.inArray('folder-shared', files) !== -1) {
return 'folder-shared';
} else if (mimeType === 'dir-public' && $.inArray('folder-public', files) !== -1) {
diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js
index ea513131d8..13db16c5a2 100644
--- a/core/js/mimetypelist.js
+++ b/core/js/mimetypelist.js
@@ -104,6 +104,7 @@ OC.MimeTypeList={
"file",
"folder",
"folder-drag-accept",
+ "folder-encrypted",
"folder-external",
"folder-public",
"folder-shared",
diff --git a/core/js/share.js b/core/js/share.js
index 7662d6cffb..f301de2541 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -281,10 +281,14 @@ OC.Share = _.extend(OC.Share || {}, {
$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')');
$tr.attr('data-icon', shareFolderIcon);
} else if (type === 'dir') {
+ var isEncrypted = $tr.attr('data-e2eencrypted');
var mountType = $tr.attr('data-mounttype');
// FIXME: duplicate of FileList._createRow logic for external folder,
// need to refactor the icon logic into a single code path eventually
- if (mountType && mountType.indexOf('external') === 0) {
+ if (isEncrypted === 'true') {
+ shareFolderIcon = OC.MimeType.getIconUrl('dir-encrypted');
+ $tr.attr('data-icon', shareFolderIcon);
+ } else if (mountType && mountType.indexOf('external') === 0) {
shareFolderIcon = OC.MimeType.getIconUrl('dir-external');
$tr.attr('data-icon', shareFolderIcon);
} else {
diff --git a/core/js/tests/specs/files/clientSpec.js b/core/js/tests/specs/files/clientSpec.js
index 6593372144..ec0a0fbda4 100644
--- a/core/js/tests/specs/files/clientSpec.js
+++ b/core/js/tests/specs/files/clientSpec.js
@@ -224,6 +224,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('sends PROPFIND to base url when empty path given', function() {
client.getFolderContents('');
@@ -262,6 +263,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436535485000);
expect(info.mimetype).toEqual('text/plain');
expect(info.etag).toEqual('559fcabd79a38');
+ expect(info.isEncrypted).toEqual(false);
// sub entry
info = response[1];
@@ -274,6 +276,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436536800000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('66cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
});
});
it('returns parent node in result if specified', function() {
@@ -303,6 +306,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
// the two other entries follow
expect(response[1].id).toEqual(51);
@@ -422,6 +426,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('parses the result list into a FileInfo array', function() {
var promise = client.getFilteredFiles({
@@ -473,7 +478,7 @@ describe('OC.Files.Client tests', function() {
describe('file info', function() {
var responseXml = dav.Client.prototype.parseMultiStatus(
'' +
- '' +
+ '' +
makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/',
{
@@ -483,7 +488,8 @@ describe('OC.Files.Client tests', function() {
'oc:id': '00000011oc2d13a6a068',
'oc:fileid': '11',
'oc:permissions': 'GRDNVCK',
- 'oc:size': '120'
+ 'oc:size': '120',
+ 'nc:is-encrypted': '1'
},
[
'd:getcontenttype',
@@ -510,6 +516,7 @@ describe('OC.Files.Client tests', function() {
expect(props).toContain('{http://owncloud.org/ns}fileid');
expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions');
+ expect(props).toContain('{http://nextcloud.org/ns}is-encrypted');
});
it('parses the result into a FileInfo', function() {
var promise = client.getFileInfo('path/to space/文件夹');
@@ -535,6 +542,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(true);
});
});
it('properly parses entry inside root', function() {
@@ -583,6 +591,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb');
+ expect(info.isEncrypted).toEqual(false);
});
});
it('rejects promise when an error occurred', function() {
diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js
index 05057692e9..2006f29bc0 100644
--- a/core/js/tests/specs/shareSpec.js
+++ b/core/js/tests/specs/shareSpec.js
@@ -151,6 +151,13 @@ describe('OC.Share tests', function() {
checkIcon('filetypes/folder-external');
});
+ it('shows encrypted icon if encrypted folder', function() {
+ $file.attr('data-type', 'dir');
+ $file.attr('data-e2eencrypted', true);
+ OC.Share.markFileAsShared($file, false, false);
+
+ checkIcon('filetypes/folder-encrypted');
+ });
});
describe('displaying the recipients', function() {