Merge pull request #6670 from nextcloud/handle-encryption-state-in-web-interface

Handle encryption state in web interface
This commit is contained in:
Tobias Kaminsky 2017-12-06 16:19:17 +01:00 committed by GitHub
commit 430f60db21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 12 deletions

View file

@ -950,7 +950,8 @@
type: $el.attr('data-type'), type: $el.attr('data-type'),
etag: $el.attr('data-etag'), etag: $el.attr('data-etag'),
permissions: parseInt($el.attr('data-permissions'), 10), 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'); var size = $el.attr('data-size');
if (size) { if (size) {
@ -1152,7 +1153,10 @@
if (type === 'dir') { if (type === 'dir') {
mime = mime || 'httpd/unix-directory'; 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'); icon = OC.MimeType.getIconUrl('dir-external');
dataIcon = icon; dataIcon = icon;
} }
@ -1173,7 +1177,8 @@
"data-mtime": mtime, "data-mtime": mtime,
"data-etag": fileData.etag, "data-etag": fileData.etag,
"data-permissions": permissions, "data-permissions": permissions,
"data-has-preview": fileData.hasPreview !== false "data-has-preview": fileData.hasPreview !== false,
"data-e2eencrypted": fileData.isEncrypted === true
}); });
if (dataIcon) { if (dataIcon) {
@ -1444,7 +1449,9 @@
path = fileData.path || this.getCurrentDirectory(), path = fileData.path || this.getCurrentDirectory(),
permissions = parseInt(fileData.permissions, 10) || 0; permissions = parseInt(fileData.permissions, 10) || 0;
if (fileData.isShareMountPoint) { var isEndToEndEncrypted = (type === 'dir' && fileData.isEncrypted);
if (!isEndToEndEncrypted && fileData.isShareMountPoint) {
permissions = permissions | OC.PERMISSION_UPDATE; permissions = permissions | OC.PERMISSION_UPDATE;
} }

View file

@ -217,6 +217,7 @@ describe('OCA.Files.FileList tests', function() {
expect($tr.attr('data-permissions')).toEqual('31'); expect($tr.attr('data-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('text/plain'); expect($tr.attr('data-mime')).toEqual('text/plain');
expect($tr.attr('data-mtime')).toEqual('123456'); expect($tr.attr('data-mtime')).toEqual('123456');
expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('a.name').attr('href')) expect($tr.find('a.name').attr('href'))
.toEqual(OC.webroot + '/remote.php/webdav/subdir/testName.txt'); .toEqual(OC.webroot + '/remote.php/webdav/subdir/testName.txt');
expect($tr.find('.nametext').text().trim()).toEqual('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-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
expect($tr.attr('data-mtime')).toEqual('123456'); 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('.filesize').text()).toEqual('1 KB');
expect($tr.find('.date').text()).not.toEqual('?'); 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-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toBeUndefined(); expect($tr.attr('data-mime')).toBeUndefined();
expect($tr.attr('data-mtime')).toEqual('123456'); expect($tr.attr('data-mtime')).toEqual('123456');
expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('.filesize').text()).toEqual('Pending'); expect($tr.find('.filesize').text()).toEqual('Pending');
expect($tr.find('.date').text()).not.toEqual('?'); 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-permissions')).toEqual('31');
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
expect($tr.attr('data-mtime')).toEqual('123456'); expect($tr.attr('data-mtime')).toEqual('123456');
expect($tr.attr('data-e2eencrypted')).toEqual('false');
expect($tr.find('.filesize').text()).toEqual('Pending'); expect($tr.find('.filesize').text()).toEqual('Pending');
expect($tr.find('.date').text()).not.toEqual('?'); 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() { it('generates file element with no permissions when permissions are explicitly none', function() {
var fileData = { var fileData = {
type: 'dir', 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(OC.TestUtil.getImageUrl($td.find('.thumbnail'))).toEqual(OC.webroot + '/core/img/filetypes/folder.svg');
expect(previewLoadStub.notCalled).toEqual(true); 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() { it('render external storage icon for external storage root', function() {
var fileData = { var fileData = {
type: 'dir', type: 'dir',
@ -2086,7 +2125,8 @@ describe('OCA.Files.FileList tests', function() {
size: 12, size: 12,
etag: 'abc', etag: 'abc',
permissions: OC.PERMISSION_ALL, permissions: OC.PERMISSION_ALL,
hasPreview: true hasPreview: true,
isEncrypted: false
}); });
expect(files[1]).toEqual({ expect(files[1]).toEqual({
id: 3, id: 3,
@ -2097,7 +2137,8 @@ describe('OCA.Files.FileList tests', function() {
size: 58009, size: 58009,
etag: '123', etag: '123',
permissions: OC.PERMISSION_ALL, permissions: OC.PERMISSION_ALL,
hasPreview: true hasPreview: true,
isEncrypted: false
}); });
expect(files[2]).toEqual({ expect(files[2]).toEqual({
id: 4, id: 4,
@ -2108,7 +2149,8 @@ describe('OCA.Files.FileList tests', function() {
size: 250, size: 250,
etag: '456', etag: '456',
permissions: OC.PERMISSION_ALL, permissions: OC.PERMISSION_ALL,
hasPreview: true hasPreview: true,
isEncrypted: false
}); });
expect(files[0].id).toEqual(1); expect(files[0].id).toEqual(1);
expect(files[0].name).toEqual('One.txt'); expect(files[0].name).toEqual('One.txt');
@ -2130,7 +2172,8 @@ describe('OCA.Files.FileList tests', function() {
size: 12, size: 12,
etag: 'abc', etag: 'abc',
permissions: OC.PERMISSION_ALL, permissions: OC.PERMISSION_ALL,
hasPreview: true hasPreview: true,
isEncrypted: false
}); });
expect(files[1]).toEqual({ expect(files[1]).toEqual({
id: 4, id: 4,
@ -2141,7 +2184,8 @@ describe('OCA.Files.FileList tests', function() {
size: 250, size: 250,
etag: '456', etag: '456',
permissions: OC.PERMISSION_ALL, permissions: OC.PERMISSION_ALL,
hasPreview: true hasPreview: true,
isEncrypted: false
}); });
}); });
describe('Download', function() { describe('Download', function() {
@ -3231,6 +3275,16 @@ describe('OCA.Files.FileList tests', function() {
expect(fileInfo.mimetype).toEqual('text/plain'); expect(fileInfo.mimetype).toEqual('text/plain');
expect(fileInfo.type).toEqual('file'); expect(fileInfo.type).toEqual('file');
expect(fileInfo.path).not.toBeDefined(); 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() { it('adds path attribute if available', function() {
$tr.attr('data-path', '/subdir'); $tr.attr('data-path', '/subdir');

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1"><path fill-rule="evenodd" fill="#0082c9" d="m1.4609 2c-0.25 0-0.4609 0.2109-0.4609 0.4609v11.078c0 0.258 0.2029 0.461 0.4609 0.461h13.078c0.258 0 0.461-0.203 0.461-0.461v-9.0761c0-0.25-0.211-0.4649-0.461-0.4649h-6.539l-2-1.998h-4.5391zm6.5391 3.8008c0.8836 0 1.5996 0.7159 1.5996 1.5996v0.7988h0.4004v2.8008h-4v-2.8008h0.4004v-0.7988c0-0.8837 0.716-1.5996 1.5996-1.5996zm0 0.7988c-0.4419 0-0.8008 0.3589-0.8008 0.8008v0.7988h1.6016v-0.7988c0-0.4419-0.3589-0.8008-0.8008-0.8008z"/></svg>

After

Width:  |  Height:  |  Size: 562 B

View file

@ -74,6 +74,7 @@
Client.PROPERTY_PERMISSIONS = '{' + Client.NS_OWNCLOUD + '}permissions'; Client.PROPERTY_PERMISSIONS = '{' + Client.NS_OWNCLOUD + '}permissions';
Client.PROPERTY_SIZE = '{' + Client.NS_OWNCLOUD + '}size'; Client.PROPERTY_SIZE = '{' + Client.NS_OWNCLOUD + '}size';
Client.PROPERTY_GETCONTENTLENGTH = '{' + Client.NS_DAV + '}getcontentlength'; Client.PROPERTY_GETCONTENTLENGTH = '{' + Client.NS_DAV + '}getcontentlength';
Client.PROPERTY_ISENCRYPTED = '{' + Client.NS_DAV + '}is-encrypted';
Client.PROTOCOL_HTTP = 'http'; Client.PROTOCOL_HTTP = 'http';
Client.PROTOCOL_HTTPS = 'https'; Client.PROTOCOL_HTTPS = 'https';
@ -120,6 +121,10 @@
* Mount type * Mount type
*/ */
[Client.NS_NEXTCLOUD, 'mount-type'], [Client.NS_NEXTCLOUD, 'mount-type'],
/**
* Encryption state
*/
[Client.NS_NEXTCLOUD, 'is-encrypted'],
]; ];
/** /**
@ -305,6 +310,13 @@
data.hasPreview = true; 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]; var contentType = props[Client.PROPERTY_GETCONTENTTYPE];
if (!_.isUndefined(contentType)) { if (!_.isUndefined(contentType)) {
data.mimetype = contentType; data.mimetype = contentType;

View file

@ -44,6 +44,8 @@ OC.MimeType = {
// Generate path // Generate path
if (mimeType === 'dir' && $.inArray('folder', files) !== -1) { if (mimeType === 'dir' && $.inArray('folder', files) !== -1) {
return 'folder'; 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) { } else if (mimeType === 'dir-shared' && $.inArray('folder-shared', files) !== -1) {
return 'folder-shared'; return 'folder-shared';
} else if (mimeType === 'dir-public' && $.inArray('folder-public', files) !== -1) { } else if (mimeType === 'dir-public' && $.inArray('folder-public', files) !== -1) {

View file

@ -104,6 +104,7 @@ OC.MimeTypeList={
"file", "file",
"folder", "folder",
"folder-drag-accept", "folder-drag-accept",
"folder-encrypted",
"folder-external", "folder-external",
"folder-public", "folder-public",
"folder-shared", "folder-shared",

View file

@ -281,10 +281,14 @@ OC.Share = _.extend(OC.Share || {}, {
$tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')'); $tr.find('.filename .thumbnail').css('background-image', 'url(' + shareFolderIcon + ')');
$tr.attr('data-icon', shareFolderIcon); $tr.attr('data-icon', shareFolderIcon);
} else if (type === 'dir') { } else if (type === 'dir') {
var isEncrypted = $tr.attr('data-e2eencrypted');
var mountType = $tr.attr('data-mounttype'); var mountType = $tr.attr('data-mounttype');
// FIXME: duplicate of FileList._createRow logic for external folder, // FIXME: duplicate of FileList._createRow logic for external folder,
// need to refactor the icon logic into a single code path eventually // 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'); shareFolderIcon = OC.MimeType.getIconUrl('dir-external');
$tr.attr('data-icon', shareFolderIcon); $tr.attr('data-icon', shareFolderIcon);
} else { } else {

View file

@ -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}fileid');
expect(props).toContain('{http://owncloud.org/ns}size'); expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions'); 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() { it('sends PROPFIND to base url when empty path given', function() {
client.getFolderContents(''); client.getFolderContents('');
@ -262,6 +263,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436535485000); expect(info.mtime).toEqual(1436535485000);
expect(info.mimetype).toEqual('text/plain'); expect(info.mimetype).toEqual('text/plain');
expect(info.etag).toEqual('559fcabd79a38'); expect(info.etag).toEqual('559fcabd79a38');
expect(info.isEncrypted).toEqual(false);
// sub entry // sub entry
info = response[1]; info = response[1];
@ -274,6 +276,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436536800000); expect(info.mtime).toEqual(1436536800000);
expect(info.mimetype).toEqual('httpd/unix-directory'); expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('66cfcabd79abb'); expect(info.etag).toEqual('66cfcabd79abb');
expect(info.isEncrypted).toEqual(false);
}); });
}); });
it('returns parent node in result if specified', function() { 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.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory'); expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb'); expect(info.etag).toEqual('56cfcabd79abb');
expect(info.isEncrypted).toEqual(false);
// the two other entries follow // the two other entries follow
expect(response[1].id).toEqual(51); 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}fileid');
expect(props).toContain('{http://owncloud.org/ns}size'); expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions'); 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() { it('parses the result list into a FileInfo array', function() {
var promise = client.getFilteredFiles({ var promise = client.getFilteredFiles({
@ -473,7 +478,7 @@ describe('OC.Files.Client tests', function() {
describe('file info', function() { describe('file info', function() {
var responseXml = dav.Client.prototype.parseMultiStatus( var responseXml = dav.Client.prototype.parseMultiStatus(
'<?xml version="1.0" encoding="utf-8"?>' + '<?xml version="1.0" encoding="utf-8"?>' +
'<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns">' + '<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">' +
makeResponseBlock( makeResponseBlock(
'/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/', '/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:id': '00000011oc2d13a6a068',
'oc:fileid': '11', 'oc:fileid': '11',
'oc:permissions': 'GRDNVCK', 'oc:permissions': 'GRDNVCK',
'oc:size': '120' 'oc:size': '120',
'nc:is-encrypted': '1'
}, },
[ [
'd:getcontenttype', '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}fileid');
expect(props).toContain('{http://owncloud.org/ns}size'); expect(props).toContain('{http://owncloud.org/ns}size');
expect(props).toContain('{http://owncloud.org/ns}permissions'); 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() { it('parses the result into a FileInfo', function() {
var promise = client.getFileInfo('path/to space/文件夹'); var promise = client.getFileInfo('path/to space/文件夹');
@ -535,6 +542,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000); expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory'); expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb'); expect(info.etag).toEqual('56cfcabd79abb');
expect(info.isEncrypted).toEqual(true);
}); });
}); });
it('properly parses entry inside root', function() { it('properly parses entry inside root', function() {
@ -583,6 +591,7 @@ describe('OC.Files.Client tests', function() {
expect(info.mtime).toEqual(1436522405000); expect(info.mtime).toEqual(1436522405000);
expect(info.mimetype).toEqual('httpd/unix-directory'); expect(info.mimetype).toEqual('httpd/unix-directory');
expect(info.etag).toEqual('56cfcabd79abb'); expect(info.etag).toEqual('56cfcabd79abb');
expect(info.isEncrypted).toEqual(false);
}); });
}); });
it('rejects promise when an error occurred', function() { it('rejects promise when an error occurred', function() {

View file

@ -151,6 +151,13 @@ describe('OC.Share tests', function() {
checkIcon('filetypes/folder-external'); 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() { describe('displaying the recipients', function() {