summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2021-03-11 08:29:21 +0100
committerGitHub <noreply@github.com>2021-03-11 08:29:21 +0100
commit56b08c04c739dc5ad1cc0e924004fa8acc2ce3ac (patch)
tree35470a9943cea2b9238ea29971228d27b0dc1c3c /apps
parent31cc0741cb247b0f1a4a6bb2eac2d24aa643eabe (diff)
parentb4f6aca62485d80367984be7a141983598114bec (diff)
downloadnextcloud-server-56b08c04c739dc5ad1cc0e924004fa8acc2ce3ac.tar.gz
nextcloud-server-56b08c04c739dc5ad1cc0e924004fa8acc2ce3ac.zip
Merge pull request #26031 from nextcloud/feature/noid/allow-autocomplete-based-on-phone-sync
Allow autocomplete based on phone sync
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/appinfo/v1/caldav.php2
-rw-r--r--apps/dav/appinfo/v1/carddav.php2
-rw-r--r--apps/dav/lib/CardDAV/SystemAddressbook.php5
-rw-r--r--apps/dav/lib/Command/CreateCalendar.php2
-rw-r--r--apps/dav/lib/Connector/Sabre/Principal.php116
-rw-r--r--apps/dav/lib/RootCollection.php2
-rw-r--r--apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php2
-rw-r--r--apps/dav/tests/unit/CardDAV/CardDavBackendTest.php2
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php59
-rw-r--r--apps/files_versions/lib/AppInfo/Application.php2
-rw-r--r--apps/provisioning_api/composer/composer/autoload_classmap.php1
-rw-r--r--apps/provisioning_api/composer/composer/autoload_static.php1
-rw-r--r--apps/provisioning_api/lib/AppInfo/Application.php4
-rw-r--r--apps/provisioning_api/lib/Controller/UsersController.php17
-rw-r--r--apps/provisioning_api/lib/Listener/UserDeletedListener.php54
-rw-r--r--apps/provisioning_api/tests/Controller/UsersControllerTest.php23
-rw-r--r--apps/settings/js/admin.js2
-rw-r--r--apps/settings/lib/Controller/UsersController.php24
-rw-r--r--apps/settings/lib/Settings/Admin/Sharing.php2
-rw-r--r--apps/settings/templates/settings/admin/sharing.php28
-rw-r--r--apps/settings/tests/Controller/UsersControllerTest.php6
-rw-r--r--apps/settings/tests/Settings/Admin/SharingTest.php225
22 files changed, 356 insertions, 225 deletions
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php
index e04653ddea1..236d81f66f8 100644
--- a/apps/dav/appinfo/v1/caldav.php
+++ b/apps/dav/appinfo/v1/caldav.php
@@ -27,6 +27,7 @@
*/
// Backends
+use OC\KnownUser\KnownUserService;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\Connector\LegacyDAVACL;
use OCA\DAV\CalDAV\CalendarRoot;
@@ -50,6 +51,7 @@ $principalBackend = new Principal(
\OC::$server->getUserSession(),
\OC::$server->getAppManager(),
\OC::$server->query(\OCA\DAV\CalDAV\Proxy\ProxyMapper::class),
+ \OC::$server->get(KnownUserService::class),
\OC::$server->getConfig(),
'principals/'
);
diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php
index dbab1ae9681..bb766bbaeca 100644
--- a/apps/dav/appinfo/v1/carddav.php
+++ b/apps/dav/appinfo/v1/carddav.php
@@ -27,6 +27,7 @@
*/
// Backends
+use OC\KnownUser\KnownUserService;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CardDAV\AddressBookRoot;
use OCA\DAV\CardDAV\CardDavBackend;
@@ -53,6 +54,7 @@ $principalBackend = new Principal(
\OC::$server->getUserSession(),
\OC::$server->getAppManager(),
\OC::$server->query(\OCA\DAV\CalDAV\Proxy\ProxyMapper::class),
+ \OC::$server->get(KnownUserService::class),
\OC::$server->getConfig(),
'principals/'
);
diff --git a/apps/dav/lib/CardDAV/SystemAddressbook.php b/apps/dav/lib/CardDAV/SystemAddressbook.php
index c7190c81319..5b952152711 100644
--- a/apps/dav/lib/CardDAV/SystemAddressbook.php
+++ b/apps/dav/lib/CardDAV/SystemAddressbook.php
@@ -43,8 +43,9 @@ class SystemAddressbook extends AddressBook {
public function getChildren() {
$shareEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
- $restrictShareEnumeration = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
- if (!$shareEnumeration || ($shareEnumeration && $restrictShareEnumeration)) {
+ $shareEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
+ $shareEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
+ if (!$shareEnumeration || $shareEnumerationGroup || $shareEnumerationPhone) {
return [];
}
diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php
index 58c6a8c63fb..1d543c71bc2 100644
--- a/apps/dav/lib/Command/CreateCalendar.php
+++ b/apps/dav/lib/Command/CreateCalendar.php
@@ -27,6 +27,7 @@
namespace OCA\DAV\Command;
+use OC\KnownUser\KnownUserService;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Connector\Sabre\Principal;
@@ -86,6 +87,7 @@ class CreateCalendar extends Command {
\OC::$server->getUserSession(),
\OC::$server->getAppManager(),
\OC::$server->query(ProxyMapper::class),
+ \OC::$server->get(KnownUserService::class),
\OC::$server->getConfig()
);
$random = \OC::$server->getSecureRandom();
diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php
index 2351094a917..b74747b1163 100644
--- a/apps/dav/lib/Connector/Sabre/Principal.php
+++ b/apps/dav/lib/Connector/Sabre/Principal.php
@@ -36,6 +36,7 @@
namespace OCA\DAV\Connector\Sabre;
+use OC\KnownUser\KnownUserService;
use OCA\Circles\Exceptions\CircleDoesNotExistException;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Traits\PrincipalProxyTrait;
@@ -82,27 +83,19 @@ class Principal implements BackendInterface {
/** @var ProxyMapper */
private $proxyMapper;
+ /** @var KnownUserService */
+ private $knownUserService;
+
/** @var IConfig */
private $config;
- /**
- * Principal constructor.
- *
- * @param IUserManager $userManager
- * @param IGroupManager $groupManager
- * @param IShareManager $shareManager
- * @param IUserSession $userSession
- * @param IAppManager $appManager
- * @param ProxyMapper $proxyMapper
- * @param IConfig $config
- * @param string $principalPrefix
- */
public function __construct(IUserManager $userManager,
IGroupManager $groupManager,
IShareManager $shareManager,
IUserSession $userSession,
IAppManager $appManager,
ProxyMapper $proxyMapper,
+ KnownUserService $knownUserService,
IConfig $config,
string $principalPrefix = 'principals/users/') {
$this->userManager = $userManager;
@@ -113,6 +106,7 @@ class Principal implements BackendInterface {
$this->principalPrefix = trim($principalPrefix, '/');
$this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/');
$this->proxyMapper = $proxyMapper;
+ $this->knownUserService = $knownUserService;
$this->config = $config;
}
@@ -267,24 +261,25 @@ class Principal implements BackendInterface {
}
$allowEnumeration = $this->shareManager->allowEnumeration();
- $limitEnumeration = $this->shareManager->limitEnumerationToGroups();
+ $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
$restrictGroups = false;
+ $currentUser = $this->userSession->getUser();
if ($this->shareManager->shareWithGroupMembersOnly()) {
- $user = $this->userSession->getUser();
- if (!$user) {
+ if (!$currentUser instanceof IUser) {
return [];
}
- $restrictGroups = $this->groupManager->getUserGroupIds($user);
+ $restrictGroups = $this->groupManager->getUserGroupIds($currentUser);
}
$currentUserGroups = [];
- if ($limitEnumeration) {
- $currentUser = $this->userSession->getUser();
- if ($currentUser) {
+ if ($limitEnumerationGroup) {
+ if ($currentUser instanceof IUser) {
$currentUserGroups = $this->groupManager->getUserGroupIds($currentUser);
}
}
@@ -296,20 +291,38 @@ 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 = $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;
+ }
- if ($limitEnumeration) {
- $users = \array_filter($users, function (IUser $user) use ($currentUserGroups, $value) {
- return !empty(array_intersect(
- $this->groupManager->getUserGroupIds($user),
- $currentUserGroups
- )) || $user->getEMailAddress() === $value;
+ if ($limitEnumerationPhone
+ && $currentUser instanceof IUser
+ && $this->knownUserService->isKnownToUser($currentUser->getUID(), $user->getUID())) {
+ // Synced phonebook match
+ return true;
+ }
+
+ if (!$limitEnumerationGroup) {
+ // No limitation on enumeration, all allowed
+ return true;
+ }
+
+ return !empty($currentUserGroups) && !empty(array_intersect(
+ $this->groupManager->getUserGroupIds($user),
+ $currentUserGroups
+ ));
});
}
@@ -328,20 +341,39 @@ 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 = $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;
+ }
+
+ if ($limitEnumerationPhone
+ && $currentUser instanceof IUser
+ && $this->knownUserService->isKnownToUser($currentUser->getUID(), $user->getUID())) {
+ // Synced phonebook match
+ return true;
+ }
+
+ if (!$limitEnumerationGroup) {
+ // No limitation on enumeration, all allowed
+ return true;
+ }
- if ($limitEnumeration) {
- $users = \array_filter($users, function (IUser $user) use ($currentUserGroups, $value) {
- return !empty(array_intersect(
- $this->groupManager->getUserGroupIds($user),
- $currentUserGroups
- )) || $user->getDisplayName() === $value;
+ return !empty($currentUserGroups) && !empty(array_intersect(
+ $this->groupManager->getUserGroupIds($user),
+ $currentUserGroups
+ ));
});
}
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php
index 18874ecf748..16a209a98f0 100644
--- a/apps/dav/lib/RootCollection.php
+++ b/apps/dav/lib/RootCollection.php
@@ -28,6 +28,7 @@
namespace OCA\DAV;
+use OC\KnownUser\KnownUserService;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\CalendarRoot;
@@ -70,6 +71,7 @@ class RootCollection extends SimpleCollection {
\OC::$server->getUserSession(),
\OC::$server->getAppManager(),
$proxyMapper,
+ \OC::$server->get(KnownUserService::class),
\OC::$server->getConfig()
);
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager, $userSession, $shareManager, $config);
diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
index 85efd0fd369..51ba8c1867a 100644
--- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
+++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php
@@ -27,6 +27,7 @@
namespace OCA\DAV\Tests\unit\CalDAV;
+use OC\KnownUser\KnownUserService;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Connector\Sabre\Principal;
@@ -92,6 +93,7 @@ abstract class AbstractCalDavBackend extends TestCase {
$this->createMock(IUserSession::class),
$this->createMock(IAppManager::class),
$this->createMock(ProxyMapper::class),
+ $this->createMock(KnownUserService::class),
$this->createMock(IConfig::class),
])
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
index a8c7a781724..60f46ce8fac 100644
--- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
+++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php
@@ -33,6 +33,7 @@
namespace OCA\DAV\Tests\unit\CardDAV;
+use OC\KnownUser\KnownUserService;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\CardDAV\AddressBook;
use OCA\DAV\CardDAV\CardDavBackend;
@@ -139,6 +140,7 @@ class CardDavBackendTest extends TestCase {
$this->createMock(IUserSession::class),
$this->createMock(IAppManager::class),
$this->createMock(ProxyMapper::class),
+ $this->createMock(KnownUserService::class),
$this->createMock(IConfig::class),
])
->setMethods(['getPrincipalByPath', 'getGroupMembership'])
diff --git a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
index 117707eaf2a..c9e3d44bf88 100644
--- a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php
@@ -30,6 +30,7 @@
namespace OCA\DAV\Tests\unit\Connector\Sabre;
+use OC\KnownUser\KnownUserService;
use OC\User\User;
use OCA\DAV\CalDAV\Proxy\Proxy;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
@@ -41,6 +42,7 @@ use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Share\IManager;
+use PHPUnit\Framework\MockObject\MockObject;
use Sabre\DAV\PropPatch;
use Test\TestCase;
@@ -67,6 +69,8 @@ class PrincipalTest extends TestCase {
/** @var ProxyMapper | \PHPUnit\Framework\MockObject\MockObject */
private $proxyMapper;
+ /** @var KnownUserService|MockObject */
+ private $knownUserService;
/** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */
private $config;
@@ -77,6 +81,7 @@ class PrincipalTest extends TestCase {
$this->userSession = $this->createMock(IUserSession::class);
$this->appManager = $this->createMock(IAppManager::class);
$this->proxyMapper = $this->createMock(ProxyMapper::class);
+ $this->knownUserService = $this->createMock(KnownUserService::class);
$this->config = $this->createMock(IConfig::class);
$this->connector = new \OCA\DAV\Connector\Sabre\Principal(
@@ -86,6 +91,7 @@ class PrincipalTest extends TestCase {
$this->userSession,
$this->appManager,
$this->proxyMapper,
+ $this->knownUserService,
$this->config
);
parent::setUp();
@@ -442,7 +448,7 @@ class PrincipalTest extends TestCase {
if ($groupsOnly) {
$user = $this->createMock(IUser::class);
- $this->userSession->expects($this->once())
+ $this->userSession->expects($this->atLeastOnce())
->method('getUser')
->willReturn($user);
@@ -564,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');
@@ -586,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')
@@ -599,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');
@@ -621,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')
diff --git a/apps/files_versions/lib/AppInfo/Application.php b/apps/files_versions/lib/AppInfo/Application.php
index afbd42ffc3f..e09ad7e90ae 100644
--- a/apps/files_versions/lib/AppInfo/Application.php
+++ b/apps/files_versions/lib/AppInfo/Application.php
@@ -27,6 +27,7 @@
namespace OCA\Files_Versions\AppInfo;
+use OC\KnownUser\KnownUserService;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
@@ -72,6 +73,7 @@ class Application extends App implements IBootstrap {
$server->getUserSession(),
$server->getAppManager(),
$server->get(ProxyMapper::class),
+ $server->get(KnownUserService::class),
$server->getConfig()
);
});
diff --git a/apps/provisioning_api/composer/composer/autoload_classmap.php b/apps/provisioning_api/composer/composer/autoload_classmap.php
index 0383fddbefd..e94a97c1949 100644
--- a/apps/provisioning_api/composer/composer/autoload_classmap.php
+++ b/apps/provisioning_api/composer/composer/autoload_classmap.php
@@ -14,6 +14,7 @@ return array(
'OCA\\Provisioning_API\\Controller\\GroupsController' => $baseDir . '/../lib/Controller/GroupsController.php',
'OCA\\Provisioning_API\\Controller\\UsersController' => $baseDir . '/../lib/Controller/UsersController.php',
'OCA\\Provisioning_API\\FederatedShareProviderFactory' => $baseDir . '/../lib/FederatedShareProviderFactory.php',
+ 'OCA\\Provisioning_API\\Listener\\UserDeletedListener' => $baseDir . '/../lib/Listener/UserDeletedListener.php',
'OCA\\Provisioning_API\\Middleware\\Exceptions\\NotSubAdminException' => $baseDir . '/../lib/Middleware/Exceptions/NotSubAdminException.php',
'OCA\\Provisioning_API\\Middleware\\ProvisioningApiMiddleware' => $baseDir . '/../lib/Middleware/ProvisioningApiMiddleware.php',
);
diff --git a/apps/provisioning_api/composer/composer/autoload_static.php b/apps/provisioning_api/composer/composer/autoload_static.php
index 2c1682641a1..b982f203211 100644
--- a/apps/provisioning_api/composer/composer/autoload_static.php
+++ b/apps/provisioning_api/composer/composer/autoload_static.php
@@ -29,6 +29,7 @@ class ComposerStaticInitProvisioning_API
'OCA\\Provisioning_API\\Controller\\GroupsController' => __DIR__ . '/..' . '/../lib/Controller/GroupsController.php',
'OCA\\Provisioning_API\\Controller\\UsersController' => __DIR__ . '/..' . '/../lib/Controller/UsersController.php',
'OCA\\Provisioning_API\\FederatedShareProviderFactory' => __DIR__ . '/..' . '/../lib/FederatedShareProviderFactory.php',
+ 'OCA\\Provisioning_API\\Listener\\UserDeletedListener' => __DIR__ . '/..' . '/../lib/Listener/UserDeletedListener.php',
'OCA\\Provisioning_API\\Middleware\\Exceptions\\NotSubAdminException' => __DIR__ . '/..' . '/../lib/Middleware/Exceptions/NotSubAdminException.php',
'OCA\\Provisioning_API\\Middleware\\ProvisioningApiMiddleware' => __DIR__ . '/..' . '/../lib/Middleware/ProvisioningApiMiddleware.php',
);
diff --git a/apps/provisioning_api/lib/AppInfo/Application.php b/apps/provisioning_api/lib/AppInfo/Application.php
index 863f8861d8b..7ec21c3329e 100644
--- a/apps/provisioning_api/lib/AppInfo/Application.php
+++ b/apps/provisioning_api/lib/AppInfo/Application.php
@@ -29,6 +29,7 @@
namespace OCA\Provisioning_API\AppInfo;
use OC\Group\Manager as GroupManager;
+use OCA\Provisioning_API\Listener\UserDeletedListener;
use OCA\Provisioning_API\Middleware\ProvisioningApiMiddleware;
use OCA\Settings\Mailer\NewUserMailHelper;
use OCP\AppFramework\App;
@@ -47,6 +48,7 @@ use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
+use OCP\User\Events\UserDeletedEvent;
use OCP\Util;
use Psr\Container\ContainerInterface;
@@ -56,6 +58,8 @@ class Application extends App implements IBootstrap {
}
public function register(IRegistrationContext $context): void {
+ $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class);
+
$context->registerService(NewUserMailHelper::class, function (ContainerInterface $c) {
return new NewUserMailHelper(
$c->get(Defaults::class),
diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php
index 11c3a85db9b..579f9ae522a 100644
--- a/apps/provisioning_api/lib/Controller/UsersController.php
+++ b/apps/provisioning_api/lib/Controller/UsersController.php
@@ -49,6 +49,7 @@ use libphonenumber\PhoneNumberUtil;
use OC\Accounts\AccountManager;
use OC\Authentication\Token\RemoteWipe;
use OC\HintException;
+use OC\KnownUser\KnownUserService;
use OCA\Provisioning_API\FederatedShareProviderFactory;
use OCA\Settings\Mailer\NewUserMailHelper;
use OCP\Accounts\IAccountManager;
@@ -90,6 +91,8 @@ class UsersController extends AUserData {
private $secureRandom;
/** @var RemoteWipe */
private $remoteWipe;
+ /** @var KnownUserService */
+ private $knownUserService;
/** @var IEventDispatcher */
private $eventDispatcher;
@@ -108,6 +111,7 @@ class UsersController extends AUserData {
FederatedShareProviderFactory $federatedShareProviderFactory,
ISecureRandom $secureRandom,
RemoteWipe $remoteWipe,
+ KnownUserService $knownUserService,
IEventDispatcher $eventDispatcher) {
parent::__construct($appName,
$request,
@@ -126,6 +130,7 @@ class UsersController extends AUserData {
$this->federatedShareProviderFactory = $federatedShareProviderFactory;
$this->secureRandom = $secureRandom;
$this->remoteWipe = $remoteWipe;
+ $this->knownUserService = $knownUserService;
$this->eventDispatcher = $eventDispatcher;
}
@@ -231,6 +236,13 @@ class UsersController extends AUserData {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
+ /** @var IUser $user */
+ $user = $this->userSession->getUser();
+ $knownTo = $user->getUID();
+
+ // Cleanup all previous entries and only allow new matches
+ $this->knownUserService->deleteKnownTo($knownTo);
+
$normalizedNumberToKey = [];
foreach ($search as $key => $phoneNumbers) {
foreach ($phoneNumbers as $phone) {
@@ -268,6 +280,7 @@ class UsersController extends AUserData {
foreach ($userMatches as $phone => $userId) {
// Not using the ICloudIdManager as that would run a search for each contact to find the display name in the address book
$matches[$normalizedNumberToKey[$phone]] = $userId . '@' . $cloudUrl;
+ $this->knownUserService->storeIsKnownToUser($knownTo, $userId);
}
return new DataResponse($matches);
@@ -677,6 +690,10 @@ class UsersController extends AUserData {
$userAccount[$key]['value'] = $value;
try {
$this->accountManager->updateUser($targetUser, $userAccount, true);
+
+ if ($key === IAccountManager::PROPERTY_PHONE) {
+ $this->knownUserService->deleteByContactUserId($targetUser->getUID());
+ }
} catch (\InvalidArgumentException $e) {
throw new OCSException('Invalid ' . $e->getMessage(), 102);
}
diff --git a/apps/provisioning_api/lib/Listener/UserDeletedListener.php b/apps/provisioning_api/lib/Listener/UserDeletedListener.php
new file mode 100644
index 00000000000..1e021177bb4
--- /dev/null
+++ b/apps/provisioning_api/lib/Listener/UserDeletedListener.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Provisioning_API\Listener;
+
+use OC\KnownUser\KnownUserService;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\User\Events\UserDeletedEvent;
+
+class UserDeletedListener implements IEventListener {
+
+ /** @var KnownUserService */
+ private $service;
+
+ public function __construct(KnownUserService $service) {
+ $this->service = $service;
+ }
+
+ public function handle(Event $event): void {
+ if (!($event instanceof UserDeletedEvent)) {
+ // Unrelated
+ return;
+ }
+
+ $user = $event->getUser();
+
+ // Delete all entries of this user
+ $this->service->deleteKnownTo($user->getUID());
+
+ // Delete all entries that other users know this user
+ $this->service->deleteByContactUserId($user->getUID());
+ }
+}
diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
index 3130fce3e9c..d65e3d07913 100644
--- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php
+++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php
@@ -44,6 +44,7 @@ use Exception;
use OC\Accounts\AccountManager;
use OC\Authentication\Token\RemoteWipe;
use OC\Group\Manager;
+use OC\KnownUser\KnownUserService;
use OC\SubAdmin;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\Provisioning_API\Controller\UsersController;
@@ -102,6 +103,8 @@ class UsersControllerTest extends TestCase {
private $secureRandom;
/** @var RemoteWipe|MockObject */
private $remoteWipe;
+ /** @var KnownUserService|MockObject */
+ private $knownUserService;
/** @var IEventDispatcher */
private $eventDispatcher;
@@ -122,6 +125,7 @@ class UsersControllerTest extends TestCase {
$this->federatedShareProviderFactory = $this->createMock(FederatedShareProviderFactory::class);
$this->secureRandom = $this->createMock(ISecureRandom::class);
$this->remoteWipe = $this->createMock(RemoteWipe::class);
+ $this->knownUserService = $this->createMock(KnownUserService::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->api = $this->getMockBuilder(UsersController::class)
@@ -141,6 +145,7 @@ class UsersControllerTest extends TestCase {
$this->federatedShareProviderFactory,
$this->secureRandom,
$this->remoteWipe,
+ $this->knownUserService,
$this->eventDispatcher,
])
->setMethods(['fillStorageInfo'])
@@ -405,6 +410,7 @@ class UsersControllerTest extends TestCase {
$this->federatedShareProviderFactory,
$this->secureRandom,
$this->remoteWipe,
+ $this->knownUserService,
$this->eventDispatcher,
])
->setMethods(['editUser'])
@@ -1400,6 +1406,13 @@ class UsersControllerTest extends TestCase {
* @param array $expected
*/
public function testSearchByPhoneNumbers(string $location, array $search, int $status, ?array $searchUsers, ?array $userMatches, array $expected) {
+ $knownTo = 'knownTo';
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')
+ ->willReturn($knownTo);
+ $this->userSession->method('getUser')
+ ->willReturn($user);
+
if ($searchUsers === null) {
$this->accountManager->expects($this->never())
->method('searchUsers');
@@ -1408,6 +1421,14 @@ class UsersControllerTest extends TestCase {
->method('searchUsers')
->with(IAccountManager::PROPERTY_PHONE, $searchUsers)
->willReturn($userMatches);
+
+ $this->knownUserService->expects($this->once())
+ ->method('deleteKnownTo')
+ ->with($knownTo);
+
+ $this->knownUserService->expects($this->exactly(count($expected)))
+ ->method('storeIsKnownToUser')
+ ->with($knownTo, $this->anything());
}
$this->urlGenerator->method('getAbsoluteURL')
@@ -3229,6 +3250,7 @@ class UsersControllerTest extends TestCase {
$this->federatedShareProviderFactory,
$this->secureRandom,
$this->remoteWipe,
+ $this->knownUserService,
$this->eventDispatcher,
])
->setMethods(['getUserData'])
@@ -3295,6 +3317,7 @@ class UsersControllerTest extends TestCase {
$this->federatedShareProviderFactory,
$this->secureRandom,
$this->remoteWipe,
+ $this->knownUserService,
$this->eventDispatcher,
])
->setMethods(['getUserData'])
diff --git a/apps/settings/js/admin.js b/apps/settings/js/admin.js
index cffaefa3821..ba6b480c79d 100644
--- a/apps/settings/js/admin.js
+++ b/apps/settings/js/admin.js
@@ -144,6 +144,8 @@ window.addEventListener('DOMContentLoaded', function(){
$('#shareapi_allow_share_dialog_user_enumeration').on('change', function() {
$('#shareapi_restrict_user_enumeration_to_group_setting').toggleClass('hidden', !this.checked);
+ $('#shareapi_restrict_user_enumeration_to_phone_setting').toggleClass('hidden', !this.checked);
+ $('#shareapi_restrict_user_enumeration_combinewarning_setting').toggleClass('hidden', !this.checked);
})
$('#allowLinks').change(function() {
diff --git a/apps/settings/lib/Controller/UsersController.php b/apps/settings/lib/Controller/UsersController.php
index bdb3236c2df..46de0b4cd96 100644
--- a/apps/settings/lib/Controller/UsersController.php
+++ b/apps/settings/lib/Controller/UsersController.php
@@ -42,6 +42,7 @@ use OC\AppFramework\Http;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\ForbiddenException;
use OC\Group\Manager as GroupManager;
+use OC\KnownUser\KnownUserService;
use OC\L10N\Factory;
use OC\Security\IdentityProof\Manager;
use OC\User\Manager as UserManager;
@@ -96,6 +97,8 @@ class UsersController extends Controller {
private $jobList;
/** @var IManager */
private $encryptionManager;
+ /** @var KnownUserService */
+ private $knownUserService;
/** @var IEventDispatcher */
private $dispatcher;
@@ -116,6 +119,7 @@ class UsersController extends Controller {
Manager $keyManager,
IJobList $jobList,
IManager $encryptionManager,
+ KnownUserService $knownUserService,
IEventDispatcher $dispatcher
) {
parent::__construct($appName, $request);
@@ -132,6 +136,7 @@ class UsersController extends Controller {
$this->keyManager = $keyManager;
$this->jobList = $jobList;
$this->encryptionManager = $encryptionManager;
+ $this->knownUserService = $knownUserService;
$this->dispatcher = $dispatcher;
}
@@ -363,6 +368,19 @@ class UsersController extends Controller {
?string $twitter = null,
?string $twitterScope = null
) {
+ $user = $this->userSession->getUser();
+ if (!$user instanceof IUser) {
+ return new DataResponse(
+ [
+ 'status' => 'error',
+ 'data' => [
+ 'message' => $this->l10n->t('Invalid user')
+ ]
+ ],
+ Http::STATUS_UNAUTHORIZED
+ );
+ }
+
$email = strtolower($email);
if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
return new DataResponse(
@@ -375,8 +393,9 @@ class UsersController extends Controller {
Http::STATUS_UNPROCESSABLE_ENTITY
);
}
- $user = $this->userSession->getUser();
+
$data = $this->accountManager->getUser($user);
+ $beforeData = $data;
$data[IAccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
$data[IAccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
@@ -393,6 +412,9 @@ class UsersController extends Controller {
}
try {
$data = $this->saveUserSettings($user, $data);
+ if ($beforeData[IAccountManager::PROPERTY_PHONE]['value'] !== $data[IAccountManager::PROPERTY_PHONE]['value']) {
+ $this->knownUserService->deleteByContactUserId($user->getUID());
+ }
return new DataResponse(
[
'status' => 'success',
diff --git a/apps/settings/lib/Settings/Admin/Sharing.php b/apps/settings/lib/Settings/Admin/Sharing.php
index 313a182501d..6285ef399a8 100644
--- a/apps/settings/lib/Settings/Admin/Sharing.php
+++ b/apps/settings/lib/Settings/Admin/Sharing.php
@@ -73,6 +73,8 @@ class Sharing implements ISettings {
'allowResharing' => $this->config->getAppValue('core', 'shareapi_allow_resharing', 'yes'),
'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'),
diff --git a/apps/settings/templates/settings/admin/sharing.php b/apps/settings/templates/settings/admin/sharing.php
index 9f651ce6d6c..65e84d29120 100644
--- a/apps/settings/templates/settings/admin/sharing.php
+++ b/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') {
@@ -173,7 +173,31 @@
<?php if ($_['restrictUserEnumerationToGroup'] === 'yes') {
print_unescaped('checked="checked"');
} ?> />
- <label for="shareapi_restrict_user_enumeration_to_group"><?php p($l->t('Restrict username autocompletion to users within the same groups'));?></label><br />
+ <label for="shareapi_restrict_user_enumeration_to_group"><?php p($l->t('Allow username autocompletion to users within the same groups'));?></label><br />
+ </p>
+
+ <p id="shareapi_restrict_user_enumeration_to_phone_setting" class="indent <?php if ($_['shareAPIEnabled'] === 'no' || $_['allowShareDialogUserEnumeration'] === 'no') {
+ p('hidden');
+}?>">
+ <input type="checkbox" name="shareapi_restrict_user_enumeration_to_phone" value="1" id="shareapi_restrict_user_enumeration_to_phone" class="checkbox"
+ <?php if ($_['restrictUserEnumerationToPhone'] === 'yes') {
+ print_unescaped('checked="checked"');
+} ?> />
+ <label for="shareapi_restrict_user_enumeration_to_phone"><?php p($l->t('Allow username autocompletion to users based on phonebook matches'));?></label><br />
+ </p>
+ <p id="shareapi_restrict_user_enumeration_combinewarning_setting" class="indent <?php if ($_['shareAPIEnabled'] === 'no' || $_['allowShareDialogUserEnumeration'] === 'no') {
+ p('hidden');
+}?>">
+ <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>
diff --git a/apps/settings/tests/Controller/UsersControllerTest.php b/apps/settings/tests/Controller/UsersControllerTest.php
index 1a9af2ea8c9..b14e8d00d60 100644
--- a/apps/settings/tests/Controller/UsersControllerTest.php
+++ b/apps/settings/tests/Controller/UsersControllerTest.php
@@ -32,6 +32,7 @@ namespace OCA\Settings\Tests\Controller;
use OC\Accounts\AccountManager;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\Group\Manager;
+use OC\KnownUser\KnownUserService;
use OCA\Settings\Controller\UsersController;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
@@ -91,6 +92,8 @@ class UsersControllerTest extends \Test\TestCase {
private $securityManager;
/** @var IManager | \PHPUnit\Framework\MockObject\MockObject */
private $encryptionManager;
+ /** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */
+ private $knownUserService;
/** @var IEncryptionModule | \PHPUnit\Framework\MockObject\MockObject */
private $encryptionModule;
/** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
@@ -111,6 +114,7 @@ class UsersControllerTest extends \Test\TestCase {
$this->securityManager = $this->getMockBuilder(\OC\Security\IdentityProof\Manager::class)->disableOriginalConstructor()->getMock();
$this->jobList = $this->createMock(IJobList::class);
$this->encryptionManager = $this->createMock(IManager::class);
+ $this->knownUserService = $this->createMock(KnownUserService::class);
$this->dispatcher = $this->createMock(IEventDispatcher::class);
$this->l->method('t')
@@ -147,6 +151,7 @@ class UsersControllerTest extends \Test\TestCase {
$this->securityManager,
$this->jobList,
$this->encryptionManager,
+ $this->knownUserService,
$this->dispatcher
);
} else {
@@ -168,6 +173,7 @@ class UsersControllerTest extends \Test\TestCase {
$this->securityManager,
$this->jobList,
$this->encryptionManager,
+ $this->knownUserService,
$this->dispatcher
]
)->setMethods($mockedMethods)->getMock();
diff --git a/apps/settings/tests/Settings/Admin/SharingTest.php b/apps/settings/tests/Settings/Admin/SharingTest.php
index 52e83f8ba7f..1f24ef13d4b 100644
--- a/apps/settings/tests/Settings/Admin/SharingTest.php
+++ b/apps/settings/tests/Settings/Admin/SharingTest.php
@@ -64,95 +64,29 @@ class SharingTest extends TestCase {
public function testGetFormWithoutExcludedGroups() {
$this->config
- ->expects($this->at(0))
->method('getAppValue')
- ->with('core', 'shareapi_exclude_groups_list', '')
- ->willReturn('');
- $this->config
- ->expects($this->at(1))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_group_sharing', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(2))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_links', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(3))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_public_upload', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(4))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_resharing', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(5))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(6))
- ->method('getAppValue')
- ->with('core', 'shareapi_restrict_user_enumeration_to_group', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(7))
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(8))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(9))
- ->method('getAppValue')
- ->with('core', 'shareapi_expire_after_n_days', '7')
- ->willReturn('7');
- $this->config
- ->expects($this->at(10))
- ->method('getAppValue')
- ->with('core', 'shareapi_enforce_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(11))
- ->method('getAppValue')
- ->with('core', 'shareapi_exclude_groups', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(12))
- ->method('getAppValue')
- ->with('core', 'shareapi_public_link_disclaimertext', null)
- ->willReturn('Lorem ipsum');
- $this->config
- ->expects($this->at(13))
- ->method('getAppValue')
- ->with('core', 'shareapi_enable_link_password_by_default', 'no')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(14))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL)
- ->willReturn(Constants::PERMISSION_ALL);
- $this->config
- ->expects($this->at(15))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_internal_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(16))
- ->method('getAppValue')
- ->with('core', 'shareapi_internal_expire_after_n_days', '7')
- ->willReturn('7');
- $this->config
- ->expects($this->at(17))
- ->method('getAppValue')
- ->with('core', 'shareapi_enforce_internal_expire_date', 'no')
- ->willReturn('no');
+ ->willReturnMap([
+ ['core', 'shareapi_exclude_groups_list', '', ''],
+ ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_upload', 'yes', 'yes'],
+ ['core', 'shareapi_allow_resharing', 'yes', 'yes'],
+ ['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'],
+ ['core', 'shareapi_enforce_expire_date', 'no', 'no'],
+ ['core', 'shareapi_exclude_groups', 'no', 'no'],
+ ['core', 'shareapi_public_link_disclaimertext', null, 'Lorem ipsum'],
+ ['core', 'shareapi_enable_link_password_by_default', 'no', 'yes'],
+ ['core', 'shareapi_default_permissions', Constants::PERMISSION_ALL, Constants::PERMISSION_ALL],
+ ['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
+ ['core', 'shareapi_internal_expire_after_n_days', '7', '7'],
+ ['core', 'shareapi_enforce_internal_expire_date', 'no', 'no'],
+ ]);
$expected = new TemplateResponse(
'settings',
@@ -164,6 +98,8 @@ class SharingTest extends TestCase {
'allowResharing' => 'yes',
'allowShareDialogUserEnumeration' => 'yes',
'restrictUserEnumerationToGroup' => 'no',
+ 'restrictUserEnumerationToPhone' => 'no',
+ 'restrictUserEnumerationFullMatch' => 'yes',
'enforceLinkPassword' => false,
'onlyShareWithGroupMembers' => false,
'shareAPIEnabled' => 'yes',
@@ -188,96 +124,29 @@ class SharingTest extends TestCase {
public function testGetFormWithExcludedGroups() {
$this->config
- ->expects($this->at(0))
->method('getAppValue')
- ->with('core', 'shareapi_exclude_groups_list', '')
- ->willReturn('["NoSharers","OtherNoSharers"]');
- $this->config
- ->expects($this->at(1))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_group_sharing', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(2))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_links', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(3))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_public_upload', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(4))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_resharing', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(5))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(6))
- ->method('getAppValue')
- ->with('core', 'shareapi_restrict_user_enumeration_to_group', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(7))
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(8))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(9))
- ->method('getAppValue')
- ->with('core', 'shareapi_expire_after_n_days', '7')
- ->willReturn('7');
- $this->config
- ->expects($this->at(10))
- ->method('getAppValue')
- ->with('core', 'shareapi_enforce_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(11))
- ->method('getAppValue')
- ->with('core', 'shareapi_exclude_groups', 'no')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(12))
- ->method('getAppValue')
- ->with('core', 'shareapi_public_link_disclaimertext', null)
- ->willReturn('Lorem ipsum');
- $this->config
- ->expects($this->at(13))
- ->method('getAppValue')
- ->with('core', 'shareapi_enable_link_password_by_default', 'no')
- ->willReturn('yes');
- $this->config
- ->expects($this->at(14))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL)
- ->willReturn(Constants::PERMISSION_ALL);
- $this->config
- ->expects($this->at(15))
- ->method('getAppValue')
- ->with('core', 'shareapi_default_internal_expire_date', 'no')
- ->willReturn('no');
- $this->config
- ->expects($this->at(16))
- ->method('getAppValue')
- ->with('core', 'shareapi_internal_expire_after_n_days', '7')
- ->willReturn('7');
- $this->config
- ->expects($this->at(17))
- ->method('getAppValue')
- ->with('core', 'shareapi_enforce_internal_expire_date', 'no')
- ->willReturn('no');
-
+ ->willReturnMap([
+ ['core', 'shareapi_exclude_groups_list', '', '["NoSharers","OtherNoSharers"]'],
+ ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_upload', 'yes', 'yes'],
+ ['core', 'shareapi_allow_resharing', 'yes', 'yes'],
+ ['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'],
+ ['core', 'shareapi_enforce_expire_date', 'no', 'no'],
+ ['core', 'shareapi_exclude_groups', 'no', 'yes'],
+ ['core', 'shareapi_public_link_disclaimertext', null, 'Lorem ipsum'],
+ ['core', 'shareapi_enable_link_password_by_default', 'no', 'yes'],
+ ['core', 'shareapi_default_permissions', Constants::PERMISSION_ALL, Constants::PERMISSION_ALL],
+ ['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
+ ['core', 'shareapi_internal_expire_after_n_days', '7', '7'],
+ ['core', 'shareapi_enforce_internal_expire_date', 'no', 'no'],
+ ]);
$expected = new TemplateResponse(
'settings',
@@ -289,6 +158,8 @@ class SharingTest extends TestCase {
'allowResharing' => 'yes',
'allowShareDialogUserEnumeration' => 'yes',
'restrictUserEnumerationToGroup' => 'no',
+ 'restrictUserEnumerationToPhone' => 'no',
+ 'restrictUserEnumerationFullMatch' => 'yes',
'enforceLinkPassword' => false,
'onlyShareWithGroupMembers' => false,
'shareAPIEnabled' => 'yes',