Переглянути джерело

Add a setting to restrict returning a full match unless in phonebook or same group

Signed-off-by: Joas Schilling <coding@schilljs.com>
tags/v22.0.0beta1
Joas Schilling 3 роки тому
джерело
коміт
5b53b6f977
Аккаунт користувача з таким Email не знайдено

+ 23
- 13
apps/dav/lib/Connector/Sabre/Principal.php Переглянути файл

@@ -263,6 +263,7 @@ class Principal implements BackendInterface {
$allowEnumeration = $this->shareManager->allowEnumeration();
$limitEnumerationGroup = $this->shareManager->limitEnumerationToGroups();
$limitEnumerationPhone = $this->shareManager->limitEnumerationToPhone();
$allowEnumerationFullMatch = $this->shareManager->allowEnumerationFullMatch();

// If sharing is restricted to group members only,
// return only members that have groups in common
@@ -290,15 +291,19 @@ class Principal implements BackendInterface {
foreach ($searchProperties as $prop => $value) {
switch ($prop) {
case '{http://sabredav.org/ns}email-address':
$users = $this->userManager->getByEmail($value);

if (!$allowEnumeration) {
$users = \array_filter($users, static function (IUser $user) use ($value) {
return $user->getEMailAddress() === $value;
});
if ($allowEnumerationFullMatch) {
$users = $this->userManager->getByEmail($value);
$users = \array_filter($users, static function (IUser $user) use ($value) {
return $user->getEMailAddress() === $value;
});
} else {
$users = [];
}
} else {
$users = \array_filter($users, function (IUser $user) use ($currentUser, $value, $limitEnumerationPhone, $limitEnumerationGroup, $currentUserGroups) {
if ($user->getEMailAddress() === $value) {
$users = $this->userManager->getByEmail($value);
$users = \array_filter($users, function (IUser $user) use ($currentUser, $value, $limitEnumerationPhone, $limitEnumerationGroup, $allowEnumerationFullMatch, $currentUserGroups) {
if ($allowEnumerationFullMatch && $user->getEMailAddress() === $value) {
return true;
}

@@ -336,15 +341,20 @@ class Principal implements BackendInterface {
break;

case '{DAV:}displayname':
$users = $this->userManager->searchDisplayName($value, $searchLimit);

if (!$allowEnumeration) {
$users = \array_filter($users, static function (IUser $user) use ($value) {
return $user->getDisplayName() === $value;
});
if ($allowEnumerationFullMatch) {
$users = $this->userManager->searchDisplayName($value, $searchLimit);
$users = \array_filter($users, static function (IUser $user) use ($value) {
return $user->getDisplayName() === $value;
});
} else {
$users = [];
}
} else {
$users = \array_filter($users, function (IUser $user) use ($currentUser, $value, $limitEnumerationPhone, $limitEnumerationGroup, $currentUserGroups) {
if ($user->getDisplayName() === $value) {
$users = $this->userManager->searchDisplayName($value, $searchLimit);
$users = \array_filter($users, function (IUser $user) use ($currentUser, $value, $limitEnumerationPhone, $limitEnumerationGroup, $allowEnumerationFullMatch, $currentUserGroups) {
if ($allowEnumerationFullMatch && $user->getDisplayName() === $value) {
return true;
}


+ 51
- 0
apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php Переглянути файл

@@ -570,6 +570,10 @@ class PrincipalTest extends TestCase {
->method('shareWithGroupMembersOnly')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('allowEnumerationFullMatch')
->willReturn(true);

$user2 = $this->createMock(IUser::class);
$user2->method('getUID')->willReturn('user2');
$user2->method('getDisplayName')->willReturn('User 2');
@@ -592,6 +596,27 @@ class PrincipalTest extends TestCase {
['{DAV:}displayname' => 'User 2']));
}

public function testSearchPrincipalWithEnumerationDisabledDisplaynameOnFullMatch() {
$this->shareManager->expects($this->once())
->method('shareAPIEnabled')
->willReturn(true);

$this->shareManager->expects($this->once())
->method('allowEnumeration')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('shareWithGroupMembersOnly')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('allowEnumerationFullMatch')
->willReturn(false);

$this->assertEquals([], $this->connector->searchPrincipals('principals/users',
['{DAV:}displayname' => 'User 2']));
}

public function testSearchPrincipalWithEnumerationDisabledEmail() {
$this->shareManager->expects($this->once())
->method('shareAPIEnabled')
@@ -605,6 +630,10 @@ class PrincipalTest extends TestCase {
->method('shareWithGroupMembersOnly')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('allowEnumerationFullMatch')
->willReturn(true);

$user2 = $this->createMock(IUser::class);
$user2->method('getUID')->willReturn('user2');
$user2->method('getDisplayName')->willReturn('User 2');
@@ -627,6 +656,28 @@ class PrincipalTest extends TestCase {
['{http://sabredav.org/ns}email-address' => 'user2@foo.bar']));
}

public function testSearchPrincipalWithEnumerationDisabledEmailOnFullMatch() {
$this->shareManager->expects($this->once())
->method('shareAPIEnabled')
->willReturn(true);

$this->shareManager->expects($this->once())
->method('allowEnumeration')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('shareWithGroupMembersOnly')
->willReturn(false);

$this->shareManager->expects($this->once())
->method('allowEnumerationFullMatch')
->willReturn(false);


$this->assertEquals([], $this->connector->searchPrincipals('principals/users',
['{http://sabredav.org/ns}email-address' => 'user2@foo.bar']));
}

public function testSearchPrincipalWithEnumerationLimitedDisplayname() {
$this->shareManager->expects($this->at(0))
->method('shareAPIEnabled')

+ 1
- 0
apps/settings/lib/Settings/Admin/Sharing.php Переглянути файл

@@ -74,6 +74,7 @@ class Sharing implements ISettings {
'allowShareDialogUserEnumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'),
'restrictUserEnumerationToGroup' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no'),
'restrictUserEnumerationToPhone' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no'),
'restrictUserEnumerationFullMatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes'),
'enforceLinkPassword' => Util::isPublicLinkPasswordRequired(),
'onlyShareWithGroupMembers' => $this->shareManager->shareWithGroupMembersOnly(),
'shareAPIEnabled' => $this->config->getAppValue('core', 'shareapi_enabled', 'yes'),

+ 10
- 1
apps/settings/templates/settings/admin/sharing.php Переглянути файл

@@ -163,7 +163,7 @@
<?php if ($_['allowShareDialogUserEnumeration'] === 'yes') {
print_unescaped('checked="checked"');
} ?> />
<label for="shareapi_allow_share_dialog_user_enumeration"><?php p($l->t('Allow username autocompletion in share dialog (if this is disabled the full username or email address needs to be entered)'));?></label><br />
<label for="shareapi_allow_share_dialog_user_enumeration"><?php p($l->t('Allow username autocompletion in share dialog'));?></label><br />
</p>

<p id="shareapi_restrict_user_enumeration_to_group_setting" class="indent <?php if ($_['shareAPIEnabled'] === 'no' || $_['allowShareDialogUserEnumeration'] === 'no') {
@@ -190,6 +190,15 @@
}?>">
<em><?php p($l->t('If autocompletion "same group" and "phonebook matches" are enabled a match in either is enough to show the user.'));?></em><br />
</p>
<p id="shareapi_restrict_user_enumeration_full_match_setting" class="indent <?php if ($_['shareAPIEnabled'] === 'no') {
p('hidden');
}?>">
<input type="checkbox" name="shareapi_restrict_user_enumeration_full_match" value="1" id="shareapi_restrict_user_enumeration_full_match" class="checkbox"
<?php if ($_['restrictUserEnumerationFullMatch'] === 'yes') {
print_unescaped('checked="checked"');
} ?> />
<label for="shareapi_restrict_user_enumeration_full_match"><?php p($l->t('Allow username autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)'));?></label><br />
</p>

<p>
<input type="checkbox" id="publicShareDisclaimer" class="checkbox noJSAutoUpdate"

+ 4
- 0
apps/settings/tests/Settings/Admin/SharingTest.php Переглянути файл

@@ -74,6 +74,7 @@ class SharingTest extends TestCase {
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
['core', 'shareapi_enabled', 'yes', 'yes'],
['core', 'shareapi_default_expire_date', 'no', 'no'],
['core', 'shareapi_expire_after_n_days', '7', '7'],
@@ -98,6 +99,7 @@ class SharingTest extends TestCase {
'allowShareDialogUserEnumeration' => 'yes',
'restrictUserEnumerationToGroup' => 'no',
'restrictUserEnumerationToPhone' => 'no',
'restrictUserEnumerationFullMatch' => 'yes',
'enforceLinkPassword' => false,
'onlyShareWithGroupMembers' => false,
'shareAPIEnabled' => 'yes',
@@ -132,6 +134,7 @@ class SharingTest extends TestCase {
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
['core', 'shareapi_enabled', 'yes', 'yes'],
['core', 'shareapi_default_expire_date', 'no', 'no'],
['core', 'shareapi_expire_after_n_days', '7', '7'],
@@ -156,6 +159,7 @@ class SharingTest extends TestCase {
'allowShareDialogUserEnumeration' => 'yes',
'restrictUserEnumerationToGroup' => 'no',
'restrictUserEnumerationToPhone' => 'no',
'restrictUserEnumerationFullMatch' => 'yes',
'enforceLinkPassword' => false,
'onlyShareWithGroupMembers' => false,
'shareAPIEnabled' => 'yes',

+ 36
- 0
build/integration/collaboration_features/autocomplete.feature Переглянути файл

@@ -3,6 +3,7 @@ Feature: autocomplete
Given using api version "2"
And group "commongroup" exists
And user "admin" belongs to group "commongroup"
And user "auto" exists
And user "autocomplete" exists
And user "autocomplete2" exists
And user "autocomplete2" belongs to group "commongroup"
@@ -20,9 +21,15 @@ Feature: autocomplete
When parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" is set to "no"
Then get autocomplete for "auto"
| id | source |
| auto | users |
Then get autocomplete for "autocomplete"
| id | source |
| autocomplete | users |
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
Then get autocomplete for "auto"
| id | source |
Then get autocomplete for "autocomplete"
| id | source |


Scenario: getting autocomplete with limited enumeration by group
@@ -30,6 +37,7 @@ Feature: autocomplete
When parameter "shareapi_restrict_user_enumeration_to_group" of app "core" is set to "yes"
Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete2 | users |
Then get autocomplete for "autocomplete"
| id | source |
@@ -38,6 +46,13 @@ Feature: autocomplete
Then get autocomplete for "autocomplete2"
| id | source |
| autocomplete2 | users |
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
Then get autocomplete for "autocomplete"
| id | source |
| autocomplete2 | users |
Then get autocomplete for "autocomplete2"
| id | source |
| autocomplete2 | users |


Scenario: getting autocomplete with limited enumeration by phone
@@ -45,6 +60,7 @@ Feature: autocomplete
When parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
Then get autocomplete for "auto"
| id | source |
| auto | users |

# autocomplete stores their phone number
Given As an "autocomplete"
@@ -57,10 +73,17 @@ Feature: autocomplete
Given As an "admin"
Then get autocomplete for "auto"
| id | source |
| auto | users |

# admin populates they have the phone number
When search users by phone for region "DE" with
| random-string1 | 0711 / 252 428-90 |
Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete | users |

When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
Then get autocomplete for "auto"
| id | source |
| autocomplete | users |
@@ -83,6 +106,13 @@ Feature: autocomplete
When search users by phone for region "DE" with
| random-string1 | 0711 / 252 428-90 |

Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete | users |
| autocomplete2 | users |

When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
Then get autocomplete for "auto"
| id | source |
| autocomplete | users |
@@ -108,6 +138,7 @@ Feature: autocomplete

Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete | users |
| autocomplete2 | users |
When parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes"
@@ -121,6 +152,7 @@ Feature: autocomplete
When parameter "shareapi_restrict_user_enumeration_to_phone" of app "core" is set to "yes"
Then get autocomplete for "auto"
| id | source |
| auto | users |

# autocomplete stores their phone number
Given As an "autocomplete"
@@ -133,12 +165,14 @@ Feature: autocomplete
Given As an "admin"
Then get autocomplete for "auto"
| id | source |
| auto | users |

# admin populates they have the phone number
When search users by phone for region "DE" with
| random-string1 | 0711 / 252 428-90 |
Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete | users |

# autocomplete changes their phone number
@@ -152,12 +186,14 @@ Feature: autocomplete
Given As an "admin"
Then get autocomplete for "auto"
| id | source |
| auto | users |

# admin populates they have the new phone number
When search users by phone for region "DE" with
| random-string1 | 0711 / 252 428-91 |
Then get autocomplete for "auto"
| id | source |
| auto | users |
| autocomplete | users |



+ 1
- 0
build/integration/features/bootstrap/CollaborationContext.php Переглянути файл

@@ -66,6 +66,7 @@ class CollaborationContext implements Context {
$this->deleteServerConfig('core', 'shareapi_allow_share_dialog_user_enumeration');
$this->deleteServerConfig('core', 'shareapi_restrict_user_enumeration_to_group');
$this->deleteServerConfig('core', 'shareapi_restrict_user_enumeration_to_phone');
$this->deleteServerConfig('core', 'shareapi_restrict_user_enumeration_full_match');
$this->deleteServerConfig('core', 'shareapi_only_share_with_group_members');
}
}

+ 4
- 1
lib/private/Collaboration/Collaborators/MailPlugin.php Переглянути файл

@@ -49,6 +49,8 @@ class MailPlugin implements ISearchPlugin {
protected $shareeEnumerationInGroupOnly;
/* @var bool */
protected $shareeEnumerationPhone;
/* @var bool */
protected $shareeEnumerationFullMatch;

/** @var IManager */
private $contactsManager;
@@ -81,6 +83,7 @@ class MailPlugin implements ISearchPlugin {
$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
$this->shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
}

/**
@@ -137,7 +140,7 @@ class MailPlugin implements ISearchPlugin {
continue;
}
}
if ($exactEmailMatch) {
if ($exactEmailMatch && $this->shareeEnumerationFullMatch) {
try {
$cloud = $this->cloudIdManager->resolveCloudId($contact['CLOUD'][0]);
} catch (\InvalidArgumentException $e) {

+ 5
- 1
lib/private/Collaboration/Collaborators/UserPlugin.php Переглянути файл

@@ -53,6 +53,8 @@ class UserPlugin implements ISearchPlugin {
protected $shareeEnumerationInGroupOnly;
/* @var bool */
protected $shareeEnumerationPhone;
/* @var bool */
protected $shareeEnumerationFullMatch;

/** @var IConfig */
private $config;
@@ -85,6 +87,7 @@ class UserPlugin implements ISearchPlugin {
$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$this->shareeEnumerationPhone = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
$this->shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
}

public function search($search, $limit, $offset, ISearchResult $searchResult) {
@@ -150,6 +153,7 @@ class UserPlugin implements ISearchPlugin {


if (
$this->shareeEnumerationFullMatch &&
$lowerSearch !== '' && (strtolower($uid) === $lowerSearch ||
strtolower($userDisplayName) === $lowerSearch ||
strtolower($userEmail) === $lowerSearch)
@@ -202,7 +206,7 @@ class UserPlugin implements ISearchPlugin {
}
}

if ($offset === 0 && !$foundUserById) {
if ($this->shareeEnumerationFullMatch && $offset === 0 && !$foundUserById) {
// On page one we try if the search result has a direct hit on the
// user id and if so, we add that to the exact match list
$user = $this->userManager->get($search);

+ 6
- 1
lib/private/Contacts/ContactsMenu/ContactsStore.php Переглянути файл

@@ -124,6 +124,7 @@ class ContactsStore implements IContactsStore {
$disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
$restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
$restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
$allowEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';

// whether to filter out local users
@@ -146,7 +147,7 @@ class ContactsStore implements IContactsStore {

$selfUID = $self->getUID();

return array_values(array_filter($entries, function (IEntry $entry) use ($skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $restrictEnumerationGroup, $restrictEnumerationPhone, $filter) {
return array_values(array_filter($entries, function (IEntry $entry) use ($skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $restrictEnumerationGroup, $restrictEnumerationPhone, $allowEnumerationFullMatch, $filter) {
if ($entry->getProperty('UID') === $selfUID) {
return false;
}
@@ -160,6 +161,10 @@ class ContactsStore implements IContactsStore {

// Prevent enumerating local users
if ($disallowEnumeration) {
if (!$allowEnumerationFullMatch) {
return false;
}

$filterUser = true;

$mailAddresses = $entry->getEMailAddresses();

+ 4
- 0
lib/private/Share20/Manager.php Переглянути файл

@@ -1834,6 +1834,10 @@ class Manager implements IManager {
$this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
}

public function allowEnumerationFullMatch(): bool {
return $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
}

/**
* Copied from \OC_Util::isSharingDisabledForUser
*

+ 8
- 0
lib/public/Share/IManager.php Переглянути файл

@@ -392,6 +392,14 @@ interface IManager {
*/
public function limitEnumerationToPhone(): bool;

/**
* Check if user enumeration is allowed to return on full match
*
* @return bool
* @since 21.0.1
*/
public function allowEnumerationFullMatch(): bool;

/**
* Check if sharing is disabled for the given user
*

+ 90
- 3
tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php Переглянути файл

@@ -683,9 +683,12 @@ class ContactsStoreTest extends TestCase {
}

public function testGetContactsWithFilter() {
$this->config->expects($this->at(0))->method('getAppValue')
->with($this->equalTo('core'), $this->equalTo('shareapi_allow_share_dialog_user_enumeration'), $this->equalTo('yes'))
->willReturn('no');
$this->config
->method('getAppValue')
->willReturnMap([
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
]);

/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
$user = $this->createMock(IUser::class);
@@ -766,6 +769,90 @@ class ContactsStoreTest extends TestCase {
], $entry[0]->getEMailAddresses());
}

public function testGetContactsWithFilterWithoutFullMatch() {
$this->config
->method('getAppValue')
->willReturnMap([
['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'],
]);

/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
$user = $this->createMock(IUser::class);
$this->contactsManager->expects($this->any())
->method('search')
->willReturn([
[
'UID' => 'a567',
'FN' => 'Darren Roner',
'EMAIL' => [
'darren@roner.au',
],
'isLocalSystemBook' => true,
],
[
'UID' => 'john',
'FN' => 'John Doe',
'EMAIL' => [
'john@example.com',
],
'isLocalSystemBook' => true,
],
[
'FN' => 'Anne D',
'EMAIL' => [
'anne@example.com',
],
'isLocalSystemBook' => false,
],
]);
$user->expects($this->any())
->method('getUID')
->willReturn('user123');

// Complete match on UID should not match
$entry = $this->contactsStore->getContacts($user, 'a567');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());

// Partial match on UID should not match
$entry = $this->contactsStore->getContacts($user, 'a56');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());

// Complete match on email should not match
$entry = $this->contactsStore->getContacts($user, 'john@example.com');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());

// Partial match on email should not match
$entry = $this->contactsStore->getContacts($user, 'john@example.co');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());

// Match on FN should not match
$entry = $this->contactsStore->getContacts($user, 'Darren Roner');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());

// Don't filter users in local addressbook
$entry = $this->contactsStore->getContacts($user, 'Anne D');
$this->assertSame(1, count($entry));
$this->assertEquals([
'anne@example.com'
], $entry[0]->getEMailAddresses());
}

public function testFindOneUser() {
$this->config->expects($this->at(0))->method('getAppValue')
->with($this->equalTo('core'), $this->equalTo('shareapi_allow_share_dialog_user_enumeration'), $this->equalTo('yes'))

Завантаження…
Відмінити
Зберегти