Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v22.0.0beta1
@@ -49,8 +49,7 @@ use libphonenumber\PhoneNumberUtil; | |||
use OC\Accounts\AccountManager; | |||
use OC\Authentication\Token\RemoteWipe; | |||
use OC\HintException; | |||
use OC\KnownUser\KnownUser; | |||
use OC\KnownUser\KnownUserMapper; | |||
use OC\KnownUser\KnownUserService; | |||
use OCA\Provisioning_API\FederatedShareProviderFactory; | |||
use OCA\Settings\Mailer\NewUserMailHelper; | |||
use OCP\Accounts\IAccountManager; | |||
@@ -92,8 +91,8 @@ class UsersController extends AUserData { | |||
private $secureRandom; | |||
/** @var RemoteWipe */ | |||
private $remoteWipe; | |||
/** @var KnownUserMapper */ | |||
private $knownUserMapper; | |||
/** @var KnownUserService */ | |||
private $knownUserService; | |||
/** @var IEventDispatcher */ | |||
private $eventDispatcher; | |||
@@ -112,7 +111,7 @@ class UsersController extends AUserData { | |||
FederatedShareProviderFactory $federatedShareProviderFactory, | |||
ISecureRandom $secureRandom, | |||
RemoteWipe $remoteWipe, | |||
KnownUserMapper $knownUserMapper, | |||
KnownUserService $knownUserService, | |||
IEventDispatcher $eventDispatcher) { | |||
parent::__construct($appName, | |||
$request, | |||
@@ -131,7 +130,7 @@ class UsersController extends AUserData { | |||
$this->federatedShareProviderFactory = $federatedShareProviderFactory; | |||
$this->secureRandom = $secureRandom; | |||
$this->remoteWipe = $remoteWipe; | |||
$this->knownUserMapper = $knownUserMapper; | |||
$this->knownUserService = $knownUserService; | |||
$this->eventDispatcher = $eventDispatcher; | |||
} | |||
@@ -237,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) { | |||
@@ -271,25 +277,10 @@ class UsersController extends AUserData { | |||
} | |||
$matches = []; | |||
$knownUsers = []; | |||
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; | |||
$knownUsers[] = $userId; | |||
} | |||
/** @var IUser $user */ | |||
$user = $this->userSession->getUser(); | |||
$knownTo = $user->getUID(); | |||
// Cleanup all previous entries and only allow new matches | |||
$this->knownUserMapper->deleteKnownTo($knownTo); | |||
foreach ($knownUsers as $knownUser) { | |||
$entity = new KnownUser(); | |||
$entity->setKnownTo($knownTo); | |||
$entity->setKnownUser($knownUser); | |||
$this->knownUserMapper->insert($entity); | |||
$this->knownUserService->storeIsKnownToUser($knownTo, $userId); | |||
} | |||
return new DataResponse($matches); | |||
@@ -701,7 +692,7 @@ class UsersController extends AUserData { | |||
$this->accountManager->updateUser($targetUser, $userAccount, true); | |||
if ($key === IAccountManager::PROPERTY_PHONE) { | |||
$this->knownUserMapper->deleteKnownUser($targetUser->getUID()); | |||
$this->knownUserService->deleteKnownUser($targetUser->getUID()); | |||
} | |||
} catch (\InvalidArgumentException $e) { | |||
throw new OCSException('Invalid ' . $e->getMessage(), 102); |
@@ -23,18 +23,18 @@ declare(strict_types=1); | |||
namespace OCA\Provisioning_API\Listener; | |||
use OC\KnownUser\KnownUserMapper; | |||
use OC\KnownUser\KnownUserService; | |||
use OCP\EventDispatcher\Event; | |||
use OCP\EventDispatcher\IEventListener; | |||
use OCP\User\Events\UserDeletedEvent; | |||
class UserDeletedListener implements IEventListener { | |||
/** @var KnownUserMapper */ | |||
private $knownUserMapper; | |||
/** @var KnownUserService */ | |||
private $service; | |||
public function __construct(KnownUserMapper $knownUserMapper) { | |||
$this->knownUserMapper = $knownUserMapper; | |||
public function __construct(KnownUserService $service) { | |||
$this->service = $service; | |||
} | |||
public function handle(Event $event): void { | |||
@@ -46,9 +46,9 @@ class UserDeletedListener implements IEventListener { | |||
$user = $event->getUser(); | |||
// Delete all entries of this user | |||
$this->knownUserMapper->deleteKnownTo($user->getUID()); | |||
$this->service->deleteKnownTo($user->getUID()); | |||
// Delete all entries that other users know this user | |||
$this->knownUserMapper->deleteKnownUser($user->getUID()); | |||
$this->service->deleteKnownUser($user->getUID()); | |||
} | |||
} |
@@ -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']) |
@@ -1168,6 +1168,7 @@ return array( | |||
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => $baseDir . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php', | |||
'OC\\KnownUser\\KnownUser' => $baseDir . '/lib/private/KnownUser/KnownUser.php', | |||
'OC\\KnownUser\\KnownUserMapper' => $baseDir . '/lib/private/KnownUser/KnownUserMapper.php', | |||
'OC\\KnownUser\\KnownUserService' => $baseDir . '/lib/private/KnownUser/KnownUserService.php', | |||
'OC\\L10N\\Factory' => $baseDir . '/lib/private/L10N/Factory.php', | |||
'OC\\L10N\\L10N' => $baseDir . '/lib/private/L10N/L10N.php', | |||
'OC\\L10N\\L10NString' => $baseDir . '/lib/private/L10N/L10NString.php', |
@@ -1197,6 +1197,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php', | |||
'OC\\KnownUser\\KnownUser' => __DIR__ . '/../../..' . '/lib/private/KnownUser/KnownUser.php', | |||
'OC\\KnownUser\\KnownUserMapper' => __DIR__ . '/../../..' . '/lib/private/KnownUser/KnownUserMapper.php', | |||
'OC\\KnownUser\\KnownUserService' => __DIR__ . '/../../..' . '/lib/private/KnownUser/KnownUserService.php', | |||
'OC\\L10N\\Factory' => __DIR__ . '/../../..' . '/lib/private/L10N/Factory.php', | |||
'OC\\L10N\\L10N' => __DIR__ . '/../../..' . '/lib/private/L10N/L10N.php', | |||
'OC\\L10N\\L10NString' => __DIR__ . '/../../..' . '/lib/private/L10N/L10NString.php', |
@@ -62,6 +62,19 @@ class KnownUserMapper extends QBMapper { | |||
return (int) $query->execute(); | |||
} | |||
/** | |||
* @param string $knownTo | |||
* @return KnownUser[] | |||
*/ | |||
public function getKnownTo(string $knownTo): array { | |||
$query = $this->db->getQueryBuilder(); | |||
$query->select('*') | |||
->from($this->getTableName()) | |||
->where($query->expr()->eq('known_to', $query->createNamedParameter($knownTo))); | |||
return $this->findEntities($query); | |||
} | |||
public function createKnownUserFromRow(array $row): KnownUser { | |||
return $this->mapRowToEntity([ | |||
'id' => $row['s_id'], |
@@ -0,0 +1,62 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2021 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 OC\KnownUser; | |||
class KnownUserService { | |||
/** @var KnownUserMapper */ | |||
protected $mapper; | |||
/** @var array */ | |||
protected $knownUsers = []; | |||
public function __construct(KnownUserMapper $mapper) { | |||
$this->mapper = $mapper; | |||
} | |||
public function deleteKnownTo(string $knownTo): int { | |||
return $this->mapper->deleteKnownTo($knownTo); | |||
} | |||
public function deleteKnownUser(string $knownUser): int { | |||
return $this->mapper->deleteKnownUser($knownUser); | |||
} | |||
public function storeIsKnownToUser(string $knownTo, string $knownUser): void { | |||
$entity = new KnownUser(); | |||
$entity->setKnownTo($knownTo); | |||
$entity->setKnownUser($knownUser); | |||
$this->mapper->insert($entity); | |||
} | |||
public function isKnownToUser(string $knownTo, string $user): bool { | |||
if (!isset($this->knownUsers[$knownTo])) { | |||
$entities = $this->mapper->getKnownTo($knownTo); | |||
$this->knownUsers[$knownTo] = []; | |||
foreach ($entities as $entity) { | |||
$this->knownUsers[$knownTo][$entity->getKnownUser()] = true; | |||
} | |||
} | |||
return isset($this->knownUsers[$knownTo][$user]); | |||
} | |||
} |