Skip to content
Prev Previous commit
Next Next commit
Fix creating a mail share with a password
When a mail share was created with a password the given password was not
hashed, so it was not possible to open the share with that password.
Moreover, if passwords were enforced the given password was ignored and
a new one was set (although in this case it was hashed so it worked as
expected). Now the given password is properly hashed and not overriden.

Signed-off-by: Daniel Calviño Sánchez <[email protected]>
  • Loading branch information
danxuliu authored and backportbot[bot] committed May 29, 2020
commit 9a5b51d43cf41163d23be30fb11cdaf5b815777d
10 changes: 6 additions & 4 deletions apps/sharebymail/lib/ShareByMailProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,16 @@ public function create(IShare $share) {

// if the admin enforces a password for all mail shares we create a
// random password and send it to the recipient
$password = '';
$password = $share->getPassword() ?: '';
$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
if ($passwordEnforced) {
if ($passwordEnforced && empty($password)) {
$password = $this->autoGeneratePassword($share);
}

if (!empty($password)) {
$share->setPassword($this->hasher->hash($password));
}

$shareId = $this->createMailShare($share);
$send = $this->sendPassword($share, $password);
if ($passwordEnforced && $send === false) {
Expand Down Expand Up @@ -233,8 +237,6 @@ protected function autoGeneratePassword($share) {

$password = $this->secureRandom->generate($passwordLength, $passwordCharset);

$share->setPassword($this->hasher->hash($password));

return $password;
}

Expand Down
98 changes: 98 additions & 0 deletions apps/sharebymail/tests/ShareByMailProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,51 @@ public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection()
);
}

public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtection() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('[email protected]');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');

$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');

$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);

$instance->expects($this->once())->method('getSharedWith')->willReturn([]);
$instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
$instance->expects($this->once())->method('createShareActivity')->with($share);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn('rawShare');
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
$share->expects($this->any())->method('getNode')->willReturn($node);

$share->expects($this->once())->method('getPassword')->willReturn('password');
$this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
$share->expects($this->once())->method('setPassword')->with('passwordHashed');

// The given password (but not the autogenerated password) should be
// mailed to the receiver of the share.
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(false);
$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(['[email protected]']);
$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' => '[email protected]',
]);
$this->mailer->expects($this->once())->method('send');

$this->assertSame('shareObject',
$instance->create($share)
);
}

public function testCreateSendPasswordByMailWithEnforcedPasswordProtection() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('[email protected]');
Expand All @@ -258,6 +303,10 @@ public function testCreateSendPasswordByMailWithEnforcedPasswordProtection() {
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
$share->expects($this->any())->method('getNode')->willReturn($node);

$share->expects($this->once())->method('getPassword')->willReturn(null);
$this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
$share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');

// The autogenerated password should be mailed to the receiver of the share.
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(true);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
Expand All @@ -280,6 +329,51 @@ public function testCreateSendPasswordByMailWithEnforcedPasswordProtection() {
);
}

public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordProtection() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('[email protected]');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');

$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');

$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);

$instance->expects($this->once())->method('getSharedWith')->willReturn([]);
$instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
$instance->expects($this->once())->method('createShareActivity')->with($share);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn('rawShare');
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
$share->expects($this->any())->method('getNode')->willReturn($node);

$share->expects($this->once())->method('getPassword')->willReturn('password');
$this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
$share->expects($this->once())->method('setPassword')->with('passwordHashed');

// The given password (but not the autogenerated password) should be
// mailed to the receiver of the share.
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->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(['[email protected]']);
$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' => '[email protected]',
]);
$this->mailer->expects($this->once())->method('send');

$this->assertSame('shareObject',
$instance->create($share)
);
}

public function testCreateSendPasswordByTalkWithEnforcedPasswordProtection() {
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('[email protected]');
Expand All @@ -298,6 +392,10 @@ public function testCreateSendPasswordByTalkWithEnforcedPasswordProtection() {
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
$share->expects($this->any())->method('getNode')->willReturn($node);

$share->expects($this->once())->method('getPassword')->willReturn(null);
$this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
$share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');

// The autogenerated password should be mailed to the owner of the share.
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(true);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
Expand Down