Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporary passwords fixes 31952 #31981

Merged
merged 1 commit into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/files_sharing/lib/Controller/ShareAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array
} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
$result['share_with'] = $share->getSharedWith();
$result['password'] = $share->getPassword();
$result['password_expiration_time'] = $share->getPasswordExpirationTime();
$result['password_expiration_time'] = $share->getPasswordExpirationTime() !== null ? $share->getPasswordExpirationTime()->format(\DateTime::ATOM) : null;
$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
$result['token'] = $share->getToken();
Expand Down
20 changes: 20 additions & 0 deletions apps/files_sharing/src/components/SharingEntryLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@
@submit="onPasswordSubmit">
{{ t('files_sharing', 'Enter a password') }}
</ActionInput>
<ActionText v-if="isEmailShareType && passwordExpirationTime" icon="icon-info">
{{ t('files_sharing', 'Password expires {passwordExpirationTime}', {passwordExpirationTime}) }}
</ActionText>
<ActionText v-else-if="isEmailShareType && passwordExpirationTime !== null" icon="icon-error">
{{ t('files_sharing', 'Password expired') }}
</ActionText>

<!-- password protected by Talk -->
<ActionCheckbox v-if="isPasswordProtectedByTalkAvailable"
Expand Down Expand Up @@ -461,6 +467,20 @@ export default {
},
},

passwordExpirationTime() {
if (this.share.passwordExpirationTime === null) {
return null
}

const expirationTime = moment(this.share.passwordExpirationTime)

if (expirationTime.diff(moment()) < 0) {
return false
}

return expirationTime.fromNow()
},

/**
* Is Talk enabled?
*
Expand Down
3 changes: 2 additions & 1 deletion apps/files_sharing/src/mixins/ShareRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ export default {
const request = await axios.put(shareUrl + `/${id}`, properties)
if (!request?.data?.ocs) {
throw request
} else {
return request.data.ocs.data
}
return true
} catch (error) {
console.error('Error while updating share', error)
if (error.response.status !== 400) {
Expand Down
5 changes: 4 additions & 1 deletion apps/files_sharing/src/mixins/SharesMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,14 @@ export default {
this.saving = true
this.errors = {}
try {
await this.updateShare(this.share.id, properties)
const updatedShare = await this.updateShare(this.share.id, properties)

if (propertyNames.indexOf('password') >= 0) {
// reset password state after sync
this.$delete(this.share, 'newPassword')

// updates password expiration time after sync
this.share.passwordExpirationTime = updatedShare.password_expiration_time
}

// clear any previous errors
Expand Down
21 changes: 21 additions & 0 deletions apps/files_sharing/src/models/Share.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,27 @@ export default class Share {
this._share.password = password
}

/**
* Password expiration time
*
* @return {string}
* @readonly
* @memberof Share
*/
get passwordExpirationTime() {
return this._share.password_expiration_time
}

/**
* Password expiration time
*
* @param {string} password exipration time
* @memberof Share
*/
set passwordExpirationTime(passwordExpirationTime) {
this._share.password_expiration_time = passwordExpirationTime
}

/**
* Password protection by Talk of the share
*
Expand Down
18 changes: 17 additions & 1 deletion apps/sharebymail/lib/ShareByMailProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public function create(IShare $share) {

// Sends share password to receiver when it's a permanent one (otherwise she will have to request it via the showShare UI)
// or to owner when the password shall be given during a Talk session
if ($this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false) === true || $share->getSendPasswordByTalk()) {
if ($this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false) === false || $share->getSendPasswordByTalk()) {
$send = $this->sendPassword($share, $password);
if ($passwordEnforced && $send === false) {
$this->sendPasswordToOwner($share, $password);
Expand Down Expand Up @@ -503,6 +503,13 @@ protected function sendPassword(IShare $share, $password) {
$emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
$emailTemplate->addBodyText($password);

if ($this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false) === true) {
$expirationTime = new \DateTime();
$expirationInterval = $this->config->getSystemValue('sharing.mail_link_password_expiration_interval', 3600);
$expirationTime = $expirationTime->add(new \DateInterval('PT' . $expirationInterval . 'S'));
$emailTemplate->addBodyText($this->l->t('This password will expire at %s', [$expirationTime->format('r')]));
}

// The "From" contains the sharers name
$instanceName = $this->defaults->getName();
$senderName = $instanceName;
Expand Down Expand Up @@ -627,7 +634,16 @@ protected function sendPasswordToOwner(IShare $share, $password) {
$emailTemplate->addBodyText($bodyPart);
$emailTemplate->addBodyText($this->l->t('This is the password:'));
$emailTemplate->addBodyText($password);

if ($this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false) === true) {
$expirationTime = new \DateTime();
$expirationInterval = $this->config->getSystemValue('sharing.mail_link_password_expiration_interval', 3600);
$expirationTime = $expirationTime->add(new \DateInterval('PT' . $expirationInterval . 'S'));
$emailTemplate->addBodyText($this->l->t('This password will expire at %s', [$expirationTime->format('r')]));
}

$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));

$emailTemplate->addFooter();

$instanceName = $this->defaults->getName();
Expand Down
35 changes: 15 additions & 20 deletions apps/sharebymail/tests/ShareByMailProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection()
);
}

public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtection() {
public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
Expand Down Expand Up @@ -285,7 +285,7 @@ public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswo
);
}

public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword() {
public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithoutPermanentPassword() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
Expand All @@ -310,21 +310,16 @@ public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswo
// The given password (but not the autogenerated password) should be
// mailed to the receiver of the share because permanent passwords are enforced.
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
$this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(true);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
$instance->expects($this->never())->method('autoGeneratePassword');

$message = $this->createMock(IMessage::class);
$message->expects($this->once())->method('setTo')->with(['receiver@example.com']);
$this->mailer->expects($this->once())->method('createMessage')->willReturn($message);
$this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.RecipientPasswordNotification', [
'filename' => 'filename',
'password' => 'password',
'initiator' => 'owner',
'initiatorEmail' => null,
'shareWith' => 'receiver@example.com',
]);
$this->mailer->expects($this->once())->method('send');
$this->config->expects($this->any())->method('getSystemValue')->withConsecutive(
['sharing.enable_mail_link_password_expiration'],
['sharing.enable_mail_link_password_expiration'],
['sharing.mail_link_password_expiration_interval']
)->willReturnOnConsecutiveCalls(
true,
true,
3600
);

$this->assertSame('shareObject',
$instance->create($share)
Expand Down Expand Up @@ -363,7 +358,7 @@ public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPe

// The autogenerated password should be mailed to the receiver of the share because permanent passwords are enforced.
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
$this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(true);
$this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);

$message = $this->createMock(IMessage::class);
Expand Down Expand Up @@ -408,7 +403,7 @@ public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordP
// The given password (but not the autogenerated password) should be
// mailed to the receiver of the share.
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
$this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(true);
$this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
$instance->expects($this->never())->method('autoGeneratePassword');

Expand All @@ -429,7 +424,7 @@ public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordP
);
}

public function testCreateSendPasswordByTalkWithEnforcedPasswordProtection() {
public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPermanentPassword() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(true);
Expand All @@ -453,7 +448,7 @@ public function testCreateSendPasswordByTalkWithEnforcedPasswordProtection() {

// The autogenerated password should be mailed to the owner of the share.
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
$this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
$this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
$instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('autogeneratedPassword');

Expand Down
15 changes: 6 additions & 9 deletions core/templates/publicshareauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,20 @@ class="svg icon-confirm input-button-inline" value="" disabled="disabled" />

<!-- request password button -->
<?php if (!isset($_['identityOk']) && $_['share']->getShareType() === $_['share']::TYPE_EMAIL && !$_['share']->getSendPasswordByTalk()): ?>
<input type="button"
id="request-password-button-not-talk"
value="<?php p($l->t('Request password')); ?>"
class="primary" />
<a id="request-password-button-not-talk"><?php p($l->t('Forgot password?')); ?></a>
<?php endif; ?>

<!-- back to showShare button -->
<form method="get">
<fieldset>
<input type="submit"
<a
href=""
id="request-password-back-button"
value="<?php p($l->t('Back')); ?>"
class="primary"
<?php if (isset($_['identityOk'])): ?>
style="display:block;" />
style="display:block;">
<?php else: ?>
style="display:none;" />
style="display:none;">
<?php endif; ?>
<?php p($l->t('Back')); ?></a>
</fieldset>
</form>
4 changes: 2 additions & 2 deletions dist/files_sharing-files_sharing_tab.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_sharing-files_sharing_tab.js.map

Large diffs are not rendered by default.