fix(files_sharing): phpunit & openapi fixes

Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
pull/46007/head
skjnldsv 1 year ago committed by John Molakvoæ
parent bc5839e5b5
commit 967b3848e0
  1. 10
      apps/files_sharing/lib/Controller/ShareAPIController.php
  2. 183
      apps/files_sharing/openapi.json
  3. 18
      apps/files_sharing/src/components/NewFileRequestDialog.vue
  4. 5
      apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogDatePassword.vue
  5. 2
      apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogFinish.vue
  6. 2
      apps/files_sharing/src/components/NewFileRequestDialog/NewFileRequestDialogIntro.vue
  7. 2
      apps/files_sharing/src/components/SharingEntryLink.vue
  8. 1
      apps/files_sharing/src/components/SharingInput.vue
  9. 1
      apps/files_sharing/src/models/Share.js
  10. 167
      apps/files_sharing/src/services/ConfigService.ts
  11. 6
      apps/files_sharing/tests/ApiTest.php
  12. 58
      apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
  13. 20
      apps/files_sharing/tests/MountProviderTest.php
  14. 47
      apps/sharebymail/lib/ShareByMailProvider.php
  15. 564
      apps/sharebymail/tests/ShareByMailProviderTest.php
  16. 14
      lib/private/Share20/DefaultShareProvider.php
  17. 2
      lib/public/Share/IManager.php
  18. 28
      tests/lib/Share20/DefaultShareProviderTest.php

@ -2065,8 +2065,14 @@ class ShareAPIController extends OCSController {
/**
* Send a mail notification again for a share.
* The mail_send option must be enabled for the given share.
* @param string $id
* @param string $id the share ID
* @param string $password optional, the password to check against. Necessary for password protected shares.
* @throws OCSNotFoundException Share not found
* @throws OCSForbiddenException You are not allowed to send mail notifications
* @throws OCSBadRequestException Invalid request or wrong password
* @throws OCSException Error while sending mail notification
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* 200: The email notification was sent successfully
*/
#[NoAdminRequired]
#[UserRateLimit(limit: 5, period: 120)]
@ -2110,7 +2116,7 @@ class ShareAPIController extends OCSController {
}
$provider->sendMailNotification($share);
return new DataResponse(['message' => 'ok']);
return new DataResponse();
} catch(OCSBadRequestException $e) {
throw $e;
} catch (Exception $e) {

@ -1755,6 +1755,15 @@
"type": "string",
"nullable": true,
"description": "Additional attributes for the share"
},
"sendMail": {
"type": "string",
"nullable": true,
"enum": [
"false",
"true"
],
"description": "Send a mail to the recipient"
}
}
}
@ -2256,6 +2265,11 @@
"type": "string",
"nullable": true,
"description": "New additional attributes"
},
"sendMail": {
"type": "string",
"nullable": true,
"description": "if the share should be send by mail.\n Considering the share already exists, no mail will be send after the share is updated.\n \t\t\t\t You will have to use the sendMail action to send the mail."
}
}
}
@ -2523,6 +2537,175 @@
}
}
},
"/ocs/v2.php/apps/files_sharing/api/v1/shares/{id}/send-email": {
"post": {
"operationId": "shareapi-send-share-email",
"summary": "Send a mail notification again for a share. The mail_send option must be enabled for the given share.",
"tags": [
"shareapi"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"password": {
"type": "string",
"default": "",
"description": "optional, the password to check against. Necessary for password protected shares."
}
}
}
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"description": "the share ID",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"404": {
"description": "Share not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "You are not allowed to send mail notifications",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"400": {
"description": "Invalid request or wrong password",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"200": {
"description": "The email notification was sent successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/files_sharing/api/v1/shares/pending/{id}": {
"post": {
"operationId": "shareapi-accept-share",

@ -41,7 +41,7 @@
<FileRequestFinish v-if="share"
v-show="currentStep === STEP.LAST"
:emails="emails"
:isShareByMailEnabled="isShareByMailEnabled"
:is-share-by-mail-enabled="isShareByMailEnabled"
:share="share"
@add-email="email => emails.push(email)"
@remove-email="onRemoveEmail" />
@ -103,8 +103,9 @@
</template>
<script lang="ts">
// eslint-disable-next-line n/no-extraneous-import
import type { AxiosError } from 'axios'
import { Permission, type Folder, type Node } from '@nextcloud/files'
import type { Folder, Node } from '@nextcloud/files'
import type { OCSResponse } from '@nextcloud/typings/ocs'
import type { PropType } from 'vue'
@ -112,9 +113,10 @@ import { defineComponent } from 'vue'
import { emit } from '@nextcloud/event-bus'
import { generateOcsUrl } from '@nextcloud/router'
import { getCapabilities } from '@nextcloud/capabilities'
import { Permission } from '@nextcloud/files'
import { ShareType } from '@nextcloud/sharing'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { translate, translatePlural } from '@nextcloud/l10n'
import { Type } from '@nextcloud/sharing'
import axios from '@nextcloud/axios'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
@ -170,7 +172,7 @@ export default defineComponent({
n: translatePlural,
t: translate,
isShareByMailEnabled: getCapabilities()?.files_sharing?.sharebymail?.enabled === true
isShareByMailEnabled: getCapabilities()?.files_sharing?.sharebymail?.enabled === true,
}
},
@ -254,9 +256,9 @@ export default defineComponent({
const shareUrl = generateOcsUrl('apps/files_sharing/api/v1/shares')
try {
const request = await axios.post<OCSResponse>(shareUrl, {
shareType: Type.SHARE_TYPE_EMAIL,
shareType: ShareType.Email,
permissions: Permission.CREATE,
label: this.label,
path: this.destination,
note: this.note,
@ -331,7 +333,7 @@ export default defineComponent({
}
},
async sendEmails () {
async sendEmails() {
this.loading = true
// This should never happen
@ -358,7 +360,7 @@ export default defineComponent({
}
},
onEmailSendError(error: AxiosError<OCSResponse>|any) {
onEmailSendError(error: AxiosError<OCSResponse>) {
const errorMessage = error.response?.data?.ocs?.meta?.message
showError(
errorMessage

@ -37,7 +37,7 @@
:value="expirationDate"
name="expirationDate"
type="date"
@update:value="$emit('update:expirationDate', $event)"/>
@update:value="$emit('update:expirationDate', $event)" />
</fieldset>
<!-- Password -->
@ -96,7 +96,7 @@ import GeneratePassword from '../../utils/GeneratePassword'
const sharingConfig = new Config()
export default defineComponent({
name: 'FileRequestDatePassword',
name: 'NewFileRequestDialogDatePassword',
components: {
IconPasswordGen,
@ -207,7 +207,6 @@ export default defineComponent({
this.$emit('update:password', null)
},
async onGeneratePassword() {
await this.generatePassword()
this.showPassword()

@ -73,7 +73,7 @@ import IconCheck from 'vue-material-design-icons/Check.vue'
import IconClipboard from 'vue-material-design-icons/Clipboard.vue'
export default defineComponent({
name: 'FileRequestFinish',
name: 'NewFileRequestDialogFinish',
components: {
IconCheck,

@ -73,7 +73,7 @@ import NcTextArea from '@nextcloud/vue/dist/Components/NcTextArea.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
export default defineComponent({
name: 'FileRequestIntro',
name: 'NewFileRequestDialogIntro',
components: {
IconFolder,

@ -564,7 +564,7 @@ export default {
},
canChangeHideDownload() {
const hasDisabledDownload = (shareAttribute) => shareAttribute.scope === 'permissions' && shareAttribute.key === 'download'&& shareAttribute.value === false
const hasDisabledDownload = (shareAttribute) => shareAttribute.scope === 'permissions' && shareAttribute.key === 'download' && shareAttribute.value === false
return this.fileInfo.shareAttributes.some(hasDisabledDownload)
},

@ -35,7 +35,6 @@ import debounce from 'debounce'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import Config from '../services/ConfigService.ts'
import GeneratePassword from '../utils/GeneratePassword.ts'
import Share from '../models/Share.js'
import ShareRequests from '../mixins/ShareRequests.js'
import ShareTypes from '../mixins/ShareTypes.js'

@ -552,7 +552,6 @@ export default class Share {
return this.attributes.some(isFileRequest)
}
set hasDownloadPermission(enabled) {
this.setAttribute('permissions', 'download', !!enabled)
}

@ -4,7 +4,91 @@
*/
import { getCapabilities } from '@nextcloud/capabilities'
type PasswordPolicyCapabilities = {
enforceNonCommonPassword: boolean
enforceNumericCharacters: boolean
enforceSpecialCharacters: boolean
enforceUpperLowerCase: boolean
minLength: number
}
type FileSharingCapabilities = {
api_enabled: boolean,
public: {
enabled: boolean,
password: {
enforced: boolean,
askForOptionalPassword: boolean
},
expire_date: {
enabled: boolean,
days: number,
enforced: boolean
},
multiple_links: boolean,
expire_date_internal: {
enabled: boolean
},
expire_date_remote: {
enabled: boolean
},
send_mail: boolean,
upload: boolean,
upload_files_drop: boolean
},
resharing: boolean,
user: {
send_mail: boolean,
expire_date: {
enabled: boolean
}
},
group_sharing: boolean,
group: {
enabled: boolean,
expire_date: {
enabled: true
}
},
default_permissions: number,
federation: {
outgoing: boolean,
incoming: boolean,
expire_date: {
enabled: boolean
},
expire_date_supported: {
enabled: boolean
}
},
sharee: {
query_lookup_default: boolean,
always_show_unique: boolean
},
sharebymail: {
enabled: boolean,
send_password_by_mail: boolean,
upload_files_drop: {
enabled: boolean
},
password: {
enabled: boolean,
enforced: boolean
},
expire_date: {
enabled: boolean,
enforced: boolean
}
}
}
type Capabilities = {
files_sharing: FileSharingCapabilities
password_policy: PasswordPolicyCapabilities
}
export default class Config {
_capabilities: Capabilities
constructor() {
@ -208,86 +292,3 @@ export default class Config {
}
}
type PasswordPolicyCapabilities = {
enforceNonCommonPassword: boolean
enforceNumericCharacters: boolean
enforceSpecialCharacters: boolean
enforceUpperLowerCase: boolean
minLength: number
}
type FileSharingCapabilities = {
api_enabled: boolean,
public: {
enabled: boolean,
password: {
enforced: boolean,
askForOptionalPassword: boolean
},
expire_date: {
enabled: boolean,
days: number,
enforced: boolean
},
multiple_links: boolean,
expire_date_internal: {
enabled: boolean
},
expire_date_remote: {
enabled: boolean
},
send_mail: boolean,
upload: boolean,
upload_files_drop: boolean
},
resharing: boolean,
user: {
send_mail: boolean,
expire_date: {
enabled: boolean
}
},
group_sharing: boolean,
group: {
enabled: boolean,
expire_date: {
enabled: true
}
},
default_permissions: number,
federation: {
outgoing: boolean,
incoming: boolean,
expire_date: {
enabled: boolean
},
expire_date_supported: {
enabled: boolean
}
},
sharee: {
query_lookup_default: boolean,
always_show_unique: boolean
},
sharebymail: {
enabled: boolean,
send_password_by_mail: boolean,
upload_files_drop: {
enabled: boolean
},
password: {
enabled: boolean,
enforced: boolean
},
expire_date: {
enabled: boolean,
enforced: boolean
}
}
}
type Capabilities = {
files_sharing: FileSharingCapabilities
password_policy: PasswordPolicyCapabilities
}

@ -19,6 +19,8 @@ use OCP\IDateTimeZone;
use OCP\IL10N;
use OCP\IPreview;
use OCP\IRequest;
use OCP\Mail\IMailer;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\UserStatus\IManager as IUserStatusManager;
use Psr\Container\ContainerInterface;
@ -97,6 +99,8 @@ class ApiTest extends TestCase {
$previewManager = $this->createMock(IPreview::class);
$dateTimeZone = $this->createMock(IDateTimeZone::class);
$logger = $this->createMock(LoggerInterface::class);
$providerFactory = $this->createMock(IProviderFactory::class);
$mailer = $this->createMock(IMailer::class);
$dateTimeZone->method('getTimeZone')->willReturn(new \DateTimeZone(date_default_timezone_get()));
return new ShareAPIController(
@ -115,6 +119,8 @@ class ApiTest extends TestCase {
$previewManager,
$dateTimeZone,
$logger,
$providerFactory,
$mailer,
$userId,
);
}

@ -28,9 +28,11 @@ use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Lock\LockedException;
use OCP\Mail\IMailer;
use OCP\Share\Exceptions\GenericShareException;
use OCP\Share\IAttributes as IShareAttributes;
use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\UserStatus\IManager as IUserStatusManager;
use Psr\Container\ContainerInterface;
@ -62,6 +64,8 @@ class ShareAPIControllerTest extends TestCase {
private IPreview|\PHPUnit\Framework\MockObject\MockObject $previewManager;
private IDateTimeZone|\PHPUnit\Framework\MockObject\MockObject $dateTimeZone;
private LoggerInterface $logger;
private IProviderFactory|\PHPUnit\Framework\MockObject\MockObject $factory;
private IMailer|\PHPUnit\Framework\MockObject\MockObject $mailer;
protected function setUp(): void {
$this->shareManager = $this->createMock(IManager::class);
@ -95,6 +99,8 @@ class ShareAPIControllerTest extends TestCase {
});
$this->dateTimeZone = $this->createMock(IDateTimeZone::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->factory = $this->createMock(IProviderFactory::class);
$this->mailer = $this->createMock(IMailer::class);
$this->ocs = new ShareAPIController(
$this->appName,
@ -112,6 +118,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
);
}
@ -137,6 +145,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -152,7 +162,7 @@ class ShareAPIControllerTest extends TestCase {
[
'scope' => 'permissions',
'key' => 'download',
'enabled' => true
'value' => true
]
];
@ -360,7 +370,7 @@ class ShareAPIControllerTest extends TestCase {
// canDeleteShareFromSelf
$user = $this->createMock(IUser::class);
$group = $this->getMockBuilder('OCP\IGroup')->getMock();
$group = $this->getMockBuilder(IGroup::class)->getMock();
$this->groupManager
->method('get')
->with('group')
@ -377,7 +387,7 @@ class ShareAPIControllerTest extends TestCase {
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
@ -423,7 +433,7 @@ class ShareAPIControllerTest extends TestCase {
// canDeleteShareFromSelf
$user = $this->createMock(IUser::class);
$group = $this->getMockBuilder('OCP\IGroup')->getMock();
$group = $this->getMockBuilder(IGroup::class)->getMock();
$this->groupManager
->method('get')
->with('group')
@ -440,7 +450,7 @@ class ShareAPIControllerTest extends TestCase {
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
@ -522,7 +532,7 @@ class ShareAPIControllerTest extends TestCase {
$storage->method('getId')->willReturn('STORAGE');
$storage->method('getCache')->willReturn($cache);
$parentFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$parentFolder = $this->getMockBuilder(Folder::class)->getMock();
$parentFolder->method('getId')->willReturn(3);
$file = $this->getMockBuilder('OCP\Files\File')->getMock();
@ -534,7 +544,7 @@ class ShareAPIControllerTest extends TestCase {
$file->method('getMTime')->willReturn(1234567890);
$file->method('getMimeType')->willReturn('myMimeType');
$folder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$folder = $this->getMockBuilder(Folder::class)->getMock();
$folder->method('getId')->willReturn(2);
$folder->method('getPath')->willReturn('folder');
$folder->method('getStorage')->willReturn($storage);
@ -739,6 +749,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['canAccessShare'])
@ -754,7 +766,7 @@ class ShareAPIControllerTest extends TestCase {
->with($share->getFullId(), 'currentUser')
->willReturn($share);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$userFolder
->method('getRelativePath')
->willReturnArgument(0);
@ -788,7 +800,7 @@ class ShareAPIControllerTest extends TestCase {
$user->method('getDisplayName')->willReturn('userDisplay');
$user->method('getSystemEMailAddress')->willReturn('userId@example.com');
$group = $this->getMockBuilder('OCP\IGroup')->getMock();
$group = $this->getMockBuilder(IGroup::class)->getMock();
$group->method('getGID')->willReturn('groupId');
$this->userManager->method('get')->willReturnMap([
@ -822,7 +834,7 @@ class ShareAPIControllerTest extends TestCase {
->with('ocinternal:42', 'currentUser')
->willReturn($share);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
@ -1371,6 +1383,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -1385,7 +1399,7 @@ class ShareAPIControllerTest extends TestCase {
}
);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$userFolder->method('get')
->with('path')
->willReturn($getSharesParameters['path']);
@ -1447,7 +1461,7 @@ class ShareAPIControllerTest extends TestCase {
$file = $this->getMockBuilder(File::class)->getMock();
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
@ -1480,9 +1494,9 @@ class ShareAPIControllerTest extends TestCase {
->with($this->currentUser)
->willReturn($user);
$group = $this->getMockBuilder('OCP\IGroup')->getMock();
$group = $this->getMockBuilder(IGroup::class)->getMock();
$group->method('inGroup')->with($user)->willReturn(true);
$group2 = $this->getMockBuilder('OCP\IGroup')->getMock();
$group2 = $this->getMockBuilder(IGroup::class)->getMock();
$group2->method('inGroup')->with($user)->willReturn(false);
$this->groupManager->method('get')->willReturnMap([
@ -1543,7 +1557,7 @@ class ShareAPIControllerTest extends TestCase {
* @param bool canAccessShareByHelper
*/
public function testCanAccessRoomShare(bool $expected, \OCP\Share\IShare $share, bool $helperAvailable, bool $canAccessShareByHelper) {
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$userFolder = $this->getMockBuilder(Folder::class)->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
@ -1712,6 +1726,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -1808,6 +1824,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -2228,6 +2246,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -2296,6 +2316,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -2537,6 +2559,8 @@ class ShareAPIControllerTest extends TestCase {
$this->previewManager,
$this->dateTimeZone,
$this->logger,
$this->factory,
$this->mailer,
$this->currentUser,
])->setMethods(['formatShare'])
->getMock();
@ -3806,7 +3830,7 @@ class ShareAPIControllerTest extends TestCase {
'can_delete' => false,
'item_size' => 123456,
'item_mtime' => 1234567890,
'attributes' => '[{"scope":"permissions","key":"download","enabled":true}]',
'attributes' => '[{"scope":"permissions","key":"download","value":true}]',
], $share, [], false
];
// User backend up
@ -3845,7 +3869,7 @@ class ShareAPIControllerTest extends TestCase {
'can_delete' => false,
'item_size' => 123456,
'item_mtime' => 1234567890,
'attributes' => '[{"scope":"permissions","key":"download","enabled":true}]',
'attributes' => '[{"scope":"permissions","key":"download","value":true}]',
], $share, [
['owner', $owner],
['initiator', $initiator],

@ -70,7 +70,7 @@ class MountProviderTest extends \Test\TestCase {
$result = null;
foreach ($attrs as $attr) {
if ($attr['key'] === $key && $attr['scope'] === $scope) {
$result = $attr['enabled'];
$result = $attr['value'];
}
}
return $result;
@ -117,7 +117,7 @@ class MountProviderTest extends \Test\TestCase {
$rootFolder = $this->createMock(IRootFolder::class);
$userManager = $this->createMock(IUserManager::class);
$attr1 = [];
$attr2 = [['scope' => 'permission', 'key' => 'download', 'enabled' => true]];
$attr2 = [['scope' => 'permission', 'key' => 'download', 'value' => true]];
$userShares = [
$this->makeMockShare(1, 100, 'user2', '/share2', 0, $attr1),
$this->makeMockShare(2, 100, 'user2', '/share2', 31, $attr2),
@ -221,14 +221,14 @@ class MountProviderTest extends \Test\TestCase {
// #1: share as outsider with "group1" and "user1" with different permissions
[
[
[1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'enabled' => true], ['scope' => 'app', 'key' => 'attribute1', 'enabled' => true]]],
[1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true], ['scope' => 'app', 'key' => 'attribute1', 'value' => true]]],
],
[
[2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'enabled' => false], ['scope' => 'app', 'key' => 'attribute2', 'enabled' => false]]],
[2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => false], ['scope' => 'app', 'key' => 'attribute2', 'value' => false]]],
],
[
// use highest permissions
['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'enabled' => true], ['scope' => 'app', 'key' => 'attribute1', 'enabled' => true], ['scope' => 'app', 'key' => 'attribute2', 'enabled' => false]]],
['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true], ['scope' => 'app', 'key' => 'attribute1', 'value' => true], ['scope' => 'app', 'key' => 'attribute2', 'value' => false]]],
],
],
// #2: share as outsider with "group1" and "group2" with same permissions
@ -249,12 +249,12 @@ class MountProviderTest extends \Test\TestCase {
[
],
[
[1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'enabled' => false]]],
[2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'enabled' => true]]],
[1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => false]]],
[2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
],
[
// use higher permissions (most permissive)
['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'enabled' => true]]],
['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
],
],
// #4: share as insider with "group1"
@ -273,8 +273,8 @@ class MountProviderTest extends \Test\TestCase {
[
],
[
[1, 100, 'user1', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'enabled' => true]]],
[2, 100, 'user1', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'enabled' => false]]],
[1, 100, 'user1', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
[2, 100, 'user1', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => false]]],
],
[
// no received share since "user1" is the sharer/owner

@ -106,7 +106,11 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
$data = $this->getRawShare($shareId);
// Temporary set the clear password again to send it by mail
$data['password'] = $password;
// This need to be done after the share was created in the database
// as the password is hashed in between.
if (!empty($password)) {
$data['password'] = $password;
}
return $this->createShareObject($data);
}
@ -257,8 +261,11 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
// If we have a password set, we send it to the recipient
if ($share->getPassword() !== null) {
// 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 share-by-talk password is enabled, we do not send the notification
// to the recipient. They will have to request it to the owner after opening the link.
// Secondly, if the password expiration is disabled, we send the notification to the recipient
// Lastly, if the mail to recipient failed, we send the password to the owner as a fallback.
// If a password expires, the recipient will still be able to request a new one via talk.
$passwordExpire = $this->config->getSystemValue('sharing.enable_mail_link_password_expiration', false);
$passwordEnforced = $this->shareManager->shareApiLinkEnforcePassword();
if ($passwordExpire === false || $share->getSendPasswordByTalk()) {
@ -283,8 +290,12 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
'exception' => $e,
]);
$this->removeShareFromTable((int)$shareId);
throw new HintException('Failed to send share by mail',
$this->l->t('Failed to send share by email'));
throw new HintException(
'Failed to send share by mail',
$this->l->t('Failed to send share by email'),
0,
$e,
);
}
return false;
}
@ -359,10 +370,14 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
// The "Reply-To" is set to the sharer if an mail address is configured
// also the default footer contains a "Do not reply" which needs to be adjusted.
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
if ($initiatorUser && $this->settingsManager->replyToInitiator()) {
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
} else {
$emailTemplate->addFooter();
}
} else {
$emailTemplate->addFooter();
}
@ -451,10 +466,14 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
// The "Reply-To" is set to the sharer if an mail address is configured
// also the default footer contains a "Do not reply" which needs to be adjusted.
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
if ($initiatorUser && $this->settingsManager->replyToInitiator()) {
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
} else {
$emailTemplate->addFooter();
}
} else {
$emailTemplate->addFooter();
}
@ -714,7 +733,7 @@ class ShareByMailProvider extends DefaultShareProvider implements IShareProvider
->set('note', $qb->createNamedParameter($share->getNote()))
->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
->set('attributes', $qb->createNamedParameter($shareAttributes))
->set('mail_send', $qb->createNamedParameter($share->getMailSend(), IQueryBuilder::PARAM_INT))
->set('mail_send', $qb->createNamedParameter((int)$share->getMailSend(), IQueryBuilder::PARAM_INT))
->executeStatement();
if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {

@ -24,6 +24,7 @@ use OCP\Mail\IMessage;
use OCP\Security\Events\GenerateSecurePasswordEvent;
use OCP\Security\IHasher;
use OCP\Security\ISecureRandom;
use OCP\Share\IAttributes;
use OCP\Share\IManager;
use OCP\Share\IShare;
use Psr\Log\LoggerInterface;
@ -110,6 +111,7 @@ class ShareByMailProviderTest extends TestCase {
$this->shareManager = $this->getMockBuilder(IManager::class)->getMock();
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
$this->config->expects($this->any())->method('getAppValue')->with('core', 'enforce_strict_email_check')->willReturn('yes');
}
/**
@ -119,9 +121,9 @@ class ShareByMailProviderTest extends TestCase {
* @return \PHPUnit\Framework\MockObject\MockObject | ShareByMailProvider
*/
private function getInstance(array $mockedMethods = []) {
$instance = $this->getMockBuilder('OCA\ShareByMail\ShareByMailProvider')
->setConstructorArgs(
[
if (!empty($mockedMethods)) {
return $this->getMockBuilder('OCA\ShareByMail\ShareByMailProvider')
->setConstructorArgs([
$this->config,
$this->connection,
$this->secureRandom,
@ -137,12 +139,9 @@ class ShareByMailProviderTest extends TestCase {
$this->hasher,
$this->eventDispatcher,
$this->shareManager
]
);
if (!empty($mockedMethods)) {
$instance->setMethods($mockedMethods);
return $instance->getMock();
])
->setMethods($mockedMethods)
->getMock();
}
return new ShareByMailProvider(
@ -179,17 +178,22 @@ class ShareByMailProviderTest extends TestCase {
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'sendPassword']);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'sendEmail', 'sendPassword']);
$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($expectedShare);
$instance->expects($this->any())->method('sendPassword')->willReturn(true);
$share->expects($this->any())->method('getNode')->willReturn($node);
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
// As share api link password is not enforced, the password will not be generated.
$this->shareManager->expects($this->once())->method('shareApiLinkEnforcePassword')->willReturn(false);
$this->settingsManager->expects($this->never())->method('sendPasswordByMail');
// Mail notification is triggered by the share manager.
$instance->expects($this->never())->method('sendEmail');
$instance->expects($this->never())->method('sendPassword');
$this->assertSame($expectedShare, $instance->create($share));
}
@ -197,16 +201,22 @@ class ShareByMailProviderTest extends TestCase {
public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@examplelölöl.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
$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);
@ -219,32 +229,45 @@ class ShareByMailProviderTest extends TestCase {
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
$instance->expects($this->never())->method('autoGeneratePassword');
$this->mailer->expects($this->never())->method('send');
// No password is set and no password sent via talk is requested
$instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@examplelölöl.com']);
$instance->expects($this->never())->method('sendPassword');
$instance->expects($this->never())->method('sendPasswordToOwner');
// The manager sends the mail notification.
// For the sake of testing simplicity, we will handle it ourselves.
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
$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($expectedShare);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->once())->method('getPassword')->willReturn('password');
$share->expects($this->any())->method('getPassword')->willReturn('password');
$this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
$share->expects($this->once())->method('setPassword')->with('passwordHashed');
@ -254,60 +277,82 @@ class ShareByMailProviderTest extends TestCase {
$this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
$instance->expects($this->never())->method('autoGeneratePassword');
// A password is set but no password sent via talk has been requested
$instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']);
$instance->expects($this->once())->method('sendPassword')->with($share, 'password');
$instance->expects($this->never())->method('sendPasswordToOwner');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithoutPermanentPassword() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
$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($expectedShare);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->once())->method('getPassword')->willReturn('password');
$share->expects($this->any())->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 because permanent passwords are enforced.
// No password is generated, so no emails need to be sent
// aside from the main email notification.
$this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
$instance->expects($this->never())->method('autoGeneratePassword');
$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->config->expects($this->once())->method('getSystemValue')
->with('sharing.enable_mail_link_password_expiration')
->willReturn(true);
// No password has been set and no password sent via talk has been requested,
// but password has been enforced for the whole instance and will be generated.
$instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']);
$instance->expects($this->never())->method('sendPassword');
$instance->expects($this->never())->method('sendPasswordToOwner');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPermanentPassword() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$this->secureRandom->expects($this->once())
->method('generate')
@ -317,16 +362,19 @@ class ShareByMailProviderTest extends TestCase {
->method('dispatchTyped')
->with(new GenerateSecurePasswordEvent());
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity']);
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity', 'sendPasswordToOwner']);
$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($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare);
$share->expects($this->once())->method('getPassword')->willReturn(null);
// Initially not set, but will be set by the autoGeneratePassword method.
$share->expects($this->exactly(3))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword');
$this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
$share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');
@ -336,41 +384,69 @@ class ShareByMailProviderTest extends TestCase {
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
$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' => 'autogeneratedPassword',
'initiator' => 'owner',
'initiatorEmail' => null,
'shareWith' => 'receiver@example.com',
]);
$this->mailer->expects($this->once())->method('send');
$message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']);
$this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
$this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
->withConsecutive([
'sharebymail.RecipientNotification', [
'filename' => 'filename',
'link' => 'https://example.com/file.txt',
'initiator' => 'owner',
'expiration' => null,
'shareWith' => 'receiver@example.com',
'note' => ''
]
],
[
'sharebymail.RecipientPasswordNotification', [
'filename' => 'filename',
'password' => 'autogeneratedPassword',
'initiator' => 'owner',
'initiatorEmail' => null,
'shareWith' => 'receiver@example.com',
]
]);
// Main email notification is sent as well as the password
// to the recipient because shareApiLinkEnforcePassword is enabled.
$this->mailer->expects($this->exactly(2))->method('send');
$instance->expects($this->never())->method('sendPasswordToOwner');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordProtectionWithPermanentPassword() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendPasswordToOwner']);
$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($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
$share->expects($this->once())->method('getPassword')->willReturn('password');
$share->expects($this->exactly(3))->method('getPassword')->willReturn('password');
$this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
$share->expects($this->once())->method('setPassword')->with('passwordHashed');
@ -382,41 +458,75 @@ class ShareByMailProviderTest extends TestCase {
$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');
$message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']);
$this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
$this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
->withConsecutive([
'sharebymail.RecipientNotification', [
'filename' => 'filename',
'link' => 'https://example.com/file.txt',
'initiator' => 'owner',
'expiration' => null,
'shareWith' => 'receiver@example.com',
'note' => ''
]
],
[
'sharebymail.RecipientPasswordNotification', [
'filename' => 'filename',
'password' => 'password',
'initiator' => 'owner',
'initiatorEmail' => null,
'shareWith' => 'receiver@example.com',
]
]);
// Main email notification is sent as well as the password
// to the recipient because the password is set.
$this->mailer->expects($this->exactly(2))->method('send');
$instance->expects($this->never())->method('sendPasswordToOwner');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPermanentPassword() {
$expectedShare = $this->createMock(IShare::class);
// The owner of the share.
$owner = $this->getMockBuilder(IUser::class)->getMock();
$this->userManager->expects($this->any())->method('get')->with('owner')->willReturn($owner);
$owner->expects($this->any())->method('getEMailAddress')->willReturn('owner@example.com');
$owner->expects($this->any())->method('getDisplayName')->willReturn('owner');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(true);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$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($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare);
$share->expects($this->once())->method('getPassword')->willReturn(null);
$share->expects($this->exactly(4))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword', 'autogeneratedPassword');
$this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
$share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');
@ -427,26 +537,103 @@ class ShareByMailProviderTest extends TestCase {
$instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('autogeneratedPassword');
$message = $this->createMock(IMessage::class);
$message->expects($this->once())->method('setTo')->with(['owner@example.com' => 'Owner display name']);
$this->mailer->expects($this->once())->method('createMessage')->willReturn($message);
$this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.OwnerPasswordNotification', [
'filename' => 'filename',
'password' => 'autogeneratedPassword',
'initiator' => 'Owner display name',
'initiatorEmail' => 'owner@example.com',
'shareWith' => 'receiver@example.com',
$message->expects($this->exactly(2))->method('setTo')->withConsecutive([['receiver@example.com']], [['owner@example.com' => 'owner']]);
$this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
$this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
->withConsecutive([
'sharebymail.RecipientNotification', [
'filename' => 'filename',
'link' => 'https://example.com/file.txt',
'initiator' => 'owner',
'expiration' => null,
'shareWith' => 'receiver@example.com',
'note' => ''
]
],
[
'sharebymail.OwnerPasswordNotification', [
'filename' => 'filename',
'password' => 'autogeneratedPassword',
'initiator' => 'owner',
'initiatorEmail' => 'owner@example.com',
'shareWith' => 'receiver@example.com',
]
]);
// Main email notification is sent as well as the password to owner
// because the password is set and SendPasswordByTalk is enabled.
$this->mailer->expects($this->exactly(2))->method('send');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
// If attributes is set to multiple emails, use them as BCC
public function sendNotificationToMultipleEmails() {
$expectedShare = $this->createMock(IShare::class);
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('filename');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedWith')->willReturn('');
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
$attributes = $this->getMockBuilder(IAttributes::class)->getMock();
$share->expects($this->any())->method('getAttributes')->willReturn($attributes);
$attributes->expects($this->any())->method('getAttribute')->with('shareWith', 'emails')->willReturn([
'receiver1@example.com',
'receiver2@example.com',
'receiver3@example.com',
]);
$this->mailer->expects($this->once())->method('send');
$user = $this->createMock(IUser::class);
$this->userManager->expects($this->once())->method('get')->with('owner')->willReturn($user);
$user->expects($this->once())->method('getDisplayName')->willReturn('Owner display name');
$user->expects($this->once())->method('getEMailAddress')->willReturn('owner@example.com');
// Assume the mail address is valid.
$this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
$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', 'password' => 'password']);
$instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->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 not be
// mailed to the receiver of the share because permanent passwords are not 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(false);
$instance->expects($this->never())->method('autoGeneratePassword');
// A password is set but no password sent via talk has been requested
$instance->expects($this->once())->method('sendEmail')
->with($share, ['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']);
$instance->expects($this->once())->method('sendPassword')->with($share, 'password');
$instance->expects($this->never())->method('sendPasswordToOwner');
$message = $this->createMock(IMessage::class);
$message->expects($this->never())->method('setTo');
$message->expects($this->exactly(2))->method('setBcc')->with(['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']);
$this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
// Main email notification is sent as well as the password
// to recipients because the password is set.
$this->mailer->expects($this->exactly(2))->method('send');
$this->assertSame($expectedShare, $instance->create($share));
$instance->sendMailNotification($share);
}
public function testCreateFailed() {
$this->expectException(\Exception::class);
@ -473,33 +660,8 @@ class ShareByMailProviderTest extends TestCase {
$this->share->expects($this->any())->method('getSharedBy')->willReturn('validby@valid.com');
$this->share->expects($this->any())->method('getSharedWith')->willReturn('validwith@valid.com');
$this->share->expects($this->any())->method('getNote')->willReturn('Check this!');
$node = $this->getMockBuilder('OCP\Files\Node')->getMock();
$node->expects($this->any())->method('getName')->willReturn('fileName');
$this->share->expects($this->any())->method('getNode')->willReturn($node);
$this->share->expects($this->any())->method('getMailSend')->willReturn(true);
$instance = $this->getInstance(['generateToken', 'addShareToDB', 'sendMailNotification']);
$instance->expects($this->once())->method('generateToken')->willReturn('token');
$instance->expects($this->once())->method('addShareToDB')->willReturn(42);
$instance->expects($this->once())->method('sendMailNotification');
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token']);
$instance->expects($this->once())->method('sendMailNotification');
$this->assertSame(42,
$this->invokePrivate($instance, 'createMailShare', [$this->share])
);
}
public function testCreateMailShareFailed() {
$this->expectException(\OCP\HintException::class);
$this->share->expects($this->any())->method('getToken')->willReturn('token');
$this->share->expects($this->once())->method('setToken')->with('token');
$this->share->expects($this->any())->method('getSharedBy')->willReturn('validby@valid.com');
$this->share->expects($this->any())->method('getSharedWith')->willReturn('validwith@valid.com');
$this->share->expects($this->any())->method('getNote')->willReturn('Check this!');
$node = $this->getMockBuilder('OCP\Files\Node')->getMock();
$node->expects($this->any())->method('getName')->willReturn('fileName');
$this->share->expects($this->any())->method('getNode')->willReturn($node);
@ -508,15 +670,9 @@ class ShareByMailProviderTest extends TestCase {
$instance->expects($this->once())->method('generateToken')->willReturn('token');
$instance->expects($this->once())->method('addShareToDB')->willReturn(42);
$instance->expects($this->once())->method('sendMailNotification');
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token']);
$instance->expects($this->once())->method('sendMailNotification')
->willReturnCallback(
function () {
throw new \Exception('should be converted to a hint exception');
}
);
// The manager handle the mail sending
$instance->expects($this->never())->method('sendMailNotification');
$this->assertSame(42,
$this->invokePrivate($instance, 'createMailShare', [$this->share])
@ -1195,22 +1351,35 @@ class ShareByMailProviderTest extends TestCase {
->expects($this->once())
->method('useTemplate')
->with($template);
$this->mailer->expects($this->once())
->method('validateMailAddress')
->willReturn(true);
$this->mailer
->expects($this->once())
->method('send')
->with($message);
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('file.txt');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
$share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
self::invokePrivate(
$provider,
'sendMailNotification',
[
'file.txt',
'https://example.com/file.txt',
'OwnerUser',
'john@doe.com',
null,
''
]);
[$share]
);
}
public function testSendMailNotificationWithSameUserAndUserEmailAndNote() {
@ -1295,22 +1464,35 @@ class ShareByMailProviderTest extends TestCase {
->expects($this->once())
->method('useTemplate')
->with($template);
$this->mailer->expects($this->once())
->method('validateMailAddress')
->willReturn(true);
$this->mailer
->expects($this->once())
->method('send')
->with($message);
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('file.txt');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
$share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('This is a note to the recipient');
$share->expects($this->any())->method('getToken')->willReturn('token');
self::invokePrivate(
$provider,
'sendMailNotification',
[
'file.txt',
'https://example.com/file.txt',
'OwnerUser',
'john@doe.com',
null,
'This is a note to the recipient'
]);
[$share]
);
}
public function testSendMailNotificationWithDifferentUserAndNoUserEmail() {
@ -1386,21 +1568,35 @@ class ShareByMailProviderTest extends TestCase {
->expects($this->once())
->method('useTemplate')
->with($template);
$this->mailer->expects($this->once())
->method('validateMailAddress')
->willReturn(true);
$this->mailer
->expects($this->once())
->method('send')
->with($message);
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('file.txt');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser');
$share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
self::invokePrivate(
$provider,
'sendMailNotification',
[
'file.txt',
'https://example.com/file.txt',
'InitiatorUser',
'john@doe.com',
null,
]);
[$share]
);
}
public function testSendMailNotificationWithSameUserAndUserEmailAndReplyToDesactivate() {
@ -1461,10 +1657,10 @@ class ShareByMailProviderTest extends TestCase {
->with([
\OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud'
]);
// Since replyToInitiator is false, we never get the initiator email address
$user
->expects($this->once())
->method('getEMailAddress')
->willReturn('owner@example.com');
->expects($this->never())
->method('getEMailAddress');
$message
->expects($this->never())
->method('setReplyTo');
@ -1480,21 +1676,35 @@ class ShareByMailProviderTest extends TestCase {
->expects($this->once())
->method('useTemplate')
->with($template);
$this->mailer->expects($this->once())
->method('validateMailAddress')
->willReturn(true);
$this->mailer
->expects($this->once())
->method('send')
->with($message);
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('file.txt');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
$share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
self::invokePrivate(
$provider,
'sendMailNotification',
[
'file.txt',
'https://example.com/file.txt',
'OwnerUser',
'john@doe.com',
null,
]);
[$share]
);
}
public function testSendMailNotificationWithDifferentUserAndNoUserEmailAndReplyToDesactivate() {
@ -1570,20 +1780,34 @@ class ShareByMailProviderTest extends TestCase {
->expects($this->once())
->method('useTemplate')
->with($template);
$this->mailer->expects($this->once())
->method('validateMailAddress')
->willReturn(true);
$this->mailer
->expects($this->once())
->method('send')
->with($message);
$this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
->willReturn('https://example.com/file.txt');
$node = $this->getMockBuilder(File::class)->getMock();
$node->expects($this->any())->method('getName')->willReturn('file.txt');
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser');
$share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
$share->expects($this->any())->method('getNode')->willReturn($node);
$share->expects($this->any())->method('getId')->willReturn(42);
$share->expects($this->any())->method('getNote')->willReturn('');
$share->expects($this->any())->method('getToken')->willReturn('token');
self::invokePrivate(
$provider,
'sendMailNotification',
[
'file.txt',
'https://example.com/file.txt',
'InitiatorUser',
'john@doe.com',
null,
]);
[$share]
);
}
}

@ -1488,12 +1488,16 @@ class DefaultShareProvider implements IShareProviderWithNotification {
// The "Reply-To" is set to the sharer if an mail address is configured
// also the default footer contains a "Do not reply" which needs to be adjusted.
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
if ($initiatorUser) {
$initiatorEmail = $initiatorUser->getEMailAddress();
if ($initiatorEmail !== null) {
$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
} else {
$emailTemplate->addFooter();
}
} else {
$emailTemplate->addFooter('', $l->getLanguageCode());
$emailTemplate->addFooter();
}
$message->useTemplate($emailTemplate);

@ -300,7 +300,7 @@ interface IManager {
public function shareApiAllowLinks();
/**
* Is password on public link requires
* Is password on public link required
*
* @param bool $checkGroupMembership Check group membership exclusion
* @return bool

@ -27,6 +27,7 @@ use OCP\Mail\IMailer;
use OCP\Share\IManager as IShareManager;
use OCP\Share\IShare;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
/**
* Class DefaultShareProviderTest
@ -68,6 +69,9 @@ class DefaultShareProviderTest extends \Test\TestCase {
/** @var ITimeFactory|MockObject */
protected $timeFactory;
/** @var LoggerInterface|MockObject */
protected $logger;
protected function setUp(): void {
$this->dbConn = \OC::$server->getDatabaseConnection();
$this->userManager = $this->createMock(IUserManager::class);
@ -79,6 +83,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock();
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->userManager->expects($this->any())->method('userExists')->willReturn(true);
$this->timeFactory->expects($this->any())->method('now')->willReturn(new \DateTimeImmutable("2023-05-04 00:00 Europe/Berlin"));
@ -95,7 +100,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
);
}
@ -355,6 +361,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
$node = $this->createMock(Folder::class);
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myTarget');
$this->rootFolder->method('getUserFolder')->with('user0')->willReturnSelf();
$this->rootFolder->method('getFirstNodeById')->willReturn($node);
@ -456,7 +463,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
])
->setMethods(['getShareById'])
->getMock();
@ -551,7 +559,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
])
->setMethods(['getShareById'])
->getMock();
@ -722,7 +731,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
[
'scope' => 'permissions',
'key' => 'download',
'enabled' => true
'value' => true
]
],
$share->getAttributes()->toArray()
@ -792,7 +801,7 @@ class DefaultShareProviderTest extends \Test\TestCase {
[
'scope' => 'permissions',
'key' => 'download',
'enabled' => true
'value' => true
]
],
$share->getAttributes()->toArray()
@ -2519,7 +2528,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
);
$password = md5(time());
@ -2617,7 +2627,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
);
$u1 = $userManager->createUser('testShare1', 'test');
@ -2713,7 +2724,8 @@ class DefaultShareProviderTest extends \Test\TestCase {
$this->defaults,
$this->l10nFactory,
$this->urlGenerator,
$this->timeFactory
$this->timeFactory,
$this->logger
);
$u1 = $userManager->createUser('testShare1', 'test');

Loading…
Cancel
Save