Skip to content

Commit

Permalink
Add "Password protect by Talk" to the menu of link shares
Browse files Browse the repository at this point in the history
When Talk is enabled the menu for link shares now shows a checkbox to
protect the password by Talk (that is, to show the "Request password by
Talk" UI in the authentication page for the link share).

Although in e-mail shares protecting the share with a password and
protecting the password by Talk are mutually exclusive actions (as when
the password is set it is sent to the sharee, so it must be set again
when protecting it by Talk to be able to verify the identity of the
sharee), in the case of link shares protecting the password by Talk is
an additional step to protecting the share with a password (as just
setting the password does not disclose it to anyone). As such, the
checkbox is shown only when there is a password set for the link share
(even if the field itself for the password is not shown, like when they
are enforced in the settings).

Note that the icon set for the field, "icon-passwordtalk", does not
currently exist; it is the same used for e-mail shares, and it is needed
simply to get the right padding in the menu.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
  • Loading branch information
danxuliu committed Nov 1, 2018
1 parent d0cbd1f commit f3addeb
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 7 deletions.
10 changes: 10 additions & 0 deletions core/js/share/sharedialoglinkshareview_popover_menu.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
</span>
</li>
{{/if}}
{{#if showPasswordByTalkCheckBox}}
<li>
<span class="shareOption menuitem">
<span class="icon-loading-small hidden"></span>
<input type="checkbox" name="passwordByTalk" id="passwordByTalk-{{cid}}" class="checkbox passwordByTalkCheckbox"
{{#if isPasswordByTalkSet}}checked="checked"{{/if}} />
<label for="passwordByTalk-{{cid}}">{{passwordByTalkLabel}}</label>
</span>
</li>
{{/if}}
<li>
<span class="shareOption menuitem">
<input id="expireDate-{{cid}}" type="checkbox" name="expirationDate" class="expireDate checkbox"
Expand Down
21 changes: 21 additions & 0 deletions core/js/sharedialoglinkshareview.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
'focusout input.linkPassText': 'onPasswordEntered',
'keyup input.linkPassText': 'onPasswordKeyUp',
'change .showPasswordCheckbox': 'onShowPasswordClick',
'change .passwordByTalkCheckbox': 'onPasswordByTalkChange',
'change .publicEditingCheckbox': 'onAllowPublicEditingChange',
// copy link url
'click .linkText': 'onLinkTextClick',
Expand Down Expand Up @@ -260,6 +261,20 @@
});
},

onPasswordByTalkChange: function() {
var $checkbox = this.$('.passwordByTalkCheckbox');
$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');

var sendPasswordByTalk = false;
if($checkbox.is(':checked')) {
sendPasswordByTalk = true;
}

this.model.saveLinkShare({
sendPasswordByTalk: sendPasswordByTalk
});
},

onAllowPublicEditingChange: function() {
var $checkbox = this.$('.publicEditingCheckbox');
$checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');
Expand Down Expand Up @@ -417,6 +432,9 @@
var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink')
? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL;

var isTalkEnabled = oc_appswebroots['spreed'] !== undefined;
var sendPasswordByTalk = this.model.get('linkShare').sendPasswordByTalk;

var showHideDownloadCheckbox = !this.model.isFolder();
var hideDownload = this.model.get('linkShare').hideDownload;

Expand Down Expand Up @@ -492,6 +510,9 @@
passwordPlaceholderInitial: passwordPlaceholderInitial,
isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced,
showPasswordCheckBox: showPasswordCheckBox,
showPasswordByTalkCheckBox: isTalkEnabled && isPasswordSet,
passwordByTalkLabel: t('core', 'Password protect by Talk'),
isPasswordByTalkSet: sendPasswordByTalk,
publicUpload: publicUpload && isLinkShare,
publicEditing: publicEditable,
publicEditingChecked: publicEditingChecked,
Expand Down
3 changes: 3 additions & 0 deletions core/js/shareitemmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* @property {string} token
* @property {bool} hideDownload
* @property {string|null} password
* @property {bool} sendPasswordByTalk
* @property {string} link
* @property {number} permissions
* @property {Date} expiration
Expand Down Expand Up @@ -140,6 +141,7 @@
hideDownload: false,
password: '',
passwordChanged: false,
sendPasswordByTalk: false,
permissions: OC.PERMISSION_READ,
expireDate: this.configModel.getDefaultExpirationDateString(),
shareType: OC.Share.SHARE_TYPE_LINK
Expand Down Expand Up @@ -878,6 +880,7 @@
// to a boolean
hideDownload: !!share.hide_download,
password: share.share_with,
sendPasswordByTalk: share.send_password_by_talk,
link: link,
permissions: share.permissions,
// currently expiration is only effective for link shares.
Expand Down
21 changes: 17 additions & 4 deletions core/js/sharetemplates.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions core/js/tests/specs/sharedialoglinkshareview.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,116 @@ describe('OC.Share.ShareDialogLinkShareView', function () {

});

describe('protect password by Talk', function () {

var $passwordByTalkCheckbox;
var $workingIcon;

beforeEach(function () {
// Needed to render the view
configModel.isShareWithLinkAllowed.returns(true);

// "Enable" Talk
window.oc_appswebroots['spreed'] = window.oc_webroot + '/apps/files/';

// Setting the share also triggers the rendering
shareModel.set({
linkShare: {
isLinkShare: true,
password: 'password'
}
});

$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
$workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');

sinon.stub(shareModel, 'saveLinkShare');

expect($workingIcon.hasClass('hidden')).toBeTruthy();
});

afterEach(function () {
shareModel.saveLinkShare.restore();
});

it('is shown if Talk is enabled and there is a password set', function() {
expect($passwordByTalkCheckbox.length).toBeTruthy();
});

it('is not shown if Talk is enabled but there is no password set', function() {
shareModel.set({
linkShare: {
isLinkShare: true
}
});

$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');

expect($passwordByTalkCheckbox.length).toBeFalsy();
});

it('is not shown if there is a password set but Talk is not enabled', function() {
// "Disable" Talk
delete window.oc_appswebroots['spreed'];

// Setting the model again in this case would not trigger the
// rendering, as the model would not have changed.
view.render();

$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');

expect($passwordByTalkCheckbox.length).toBeFalsy();
});

it('checkbox is checked when the setting is enabled', function () {
shareModel.set({
linkShare: {
isLinkShare: true,
password: 'password',
sendPasswordByTalk: true
}
});

$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');

expect($passwordByTalkCheckbox.is(':checked')).toEqual(true);
});

it('checkbox is not checked when the setting is disabled', function () {
expect($passwordByTalkCheckbox.is(':checked')).toEqual(false);
});

it('enables the setting if clicked when unchecked', function () {
// Simulate the click by checking the checkbox and then triggering
// the "change" event.
$passwordByTalkCheckbox.prop('checked', true);
$passwordByTalkCheckbox.change();

expect($workingIcon.hasClass('hidden')).toBeFalsy();
expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: true }).calledOnce).toBeTruthy();
});

it('disables the setting if clicked when checked', function () {
shareModel.set({
linkShare: {
isLinkShare: true,
password: 'password',
sendPasswordByTalk: true
}
});

$passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
$workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');

// Simulate the click by unchecking the checkbox and then triggering
// the "change" event.
$passwordByTalkCheckbox.prop('checked', false);
$passwordByTalkCheckbox.change();

expect($workingIcon.hasClass('hidden')).toBeFalsy();
expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: false }).calledOnce).toBeTruthy();
});

});

});
13 changes: 10 additions & 3 deletions core/js/tests/specs/shareitemmodelSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ describe('OC.Share.ShareItemModel', function() {
storage: 1,
token: 'tehtoken',
uid_owner: 'root',
hide_download: 1
hide_download: 1,
send_password_by_talk: true
}
]));

Expand All @@ -188,6 +189,7 @@ describe('OC.Share.ShareItemModel', function() {
var linkShare = model.get('linkShare');
expect(linkShare.isLinkShare).toEqual(true);
expect(linkShare.hideDownload).toEqual(true);
expect(linkShare.sendPasswordByTalk).toEqual(true);

// TODO: check more attributes
});
Expand Down Expand Up @@ -292,7 +294,8 @@ describe('OC.Share.ShareItemModel', function() {
storage: 1,
token: 'tehtoken',
uid_owner: 'root',
hide_download: 0
hide_download: 0,
send_password_by_talk: false
}, {
displayname_owner: 'root',
expiration: '2015-10-15 00:00:00',
Expand All @@ -311,7 +314,8 @@ describe('OC.Share.ShareItemModel', function() {
storage: 1,
token: 'anothertoken',
uid_owner: 'root',
hide_download: 1
hide_download: 1,
send_password_by_talk: true
}]
));
OC.currentUser = 'root';
Expand All @@ -325,6 +329,7 @@ describe('OC.Share.ShareItemModel', function() {
expect(linkShare.isLinkShare).toEqual(true);
expect(linkShare.token).toEqual('tehtoken');
expect(linkShare.hideDownload).toEqual(false);
expect(linkShare.sendPasswordByTalk).toEqual(false);

// TODO: check child too
});
Expand Down Expand Up @@ -587,6 +592,7 @@ describe('OC.Share.ShareItemModel', function() {
hideDownload: false,
password: '',
passwordChanged: false,
sendPasswordByTalk: false,
permissions: OC.PERMISSION_READ,
expireDate: '',
shareType: OC.Share.SHARE_TYPE_LINK
Expand All @@ -612,6 +618,7 @@ describe('OC.Share.ShareItemModel', function() {
hideDownload: false,
password: '',
passwordChanged: false,
sendPasswordByTalk: false,
permissions: OC.PERMISSION_READ,
expireDate: '2015-07-24 00:00:00',
shareType: OC.Share.SHARE_TYPE_LINK
Expand Down

0 comments on commit f3addeb

Please sign in to comment.