diff options
author | Joas Schilling <coding@schilljs.com> | 2023-03-24 12:32:12 +0100 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2023-04-26 08:41:37 +0200 |
commit | 1c0aae9c54a01c33cb32373b8a455b932ec25829 (patch) | |
tree | 5dc116a4f3d90d347403d6b048d4b3ee42d5294c | |
parent | 278f6413c9ee6d5c011c59a81d2f8e24a86dfbac (diff) | |
download | nextcloud-server-1c0aae9c54a01c33cb32373b8a455b932ec25829.tar.gz nextcloud-server-1c0aae9c54a01c33cb32373b8a455b932ec25829.zip |
fix(provisioning_api): Don't allow to configure the same additional email multiple times
Signed-off-by: Joas Schilling <coding@schilljs.com>
3 files changed, 183 insertions, 4 deletions
diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index bc97e32faa4..b005acc4d7f 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -942,11 +942,11 @@ class UsersController extends AUserData { if (filter_var($value, FILTER_VALIDATE_EMAIL) && $value !== $targetUser->getSystemEMailAddress()) { $userAccount = $this->accountManager->getAccount($targetUser); $mailCollection = $userAccount->getPropertyCollection(IAccountManager::COLLECTION_EMAIL); - foreach ($mailCollection->getProperties() as $property) { - if ($property->getValue() === $value) { - break; - } + + if ($mailCollection->getPropertyByValue($value)) { + throw new OCSException('', 102); } + $mailCollection->addPropertyWithDefaults($value); $this->accountManager->updateAccount($userAccount); } else { diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php index b8b8fa8715c..419f9eceb79 100644 --- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php +++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php @@ -52,7 +52,9 @@ use OCA\Settings\Mailer\NewUserMailHelper; use OCP\Accounts\IAccount; use OCP\Accounts\IAccountManager; use OCP\Accounts\IAccountProperty; +use OCP\Accounts\IAccountPropertyCollection; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCS\OCSException; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IGroup; @@ -1544,7 +1546,162 @@ class UsersControllerTest extends TestCase { $this->assertEquals([], $this->api->editUser('UserToEdit', 'email', 'demo@nextcloud.com')->getData()); } + public function testEditUserRegularUserSelfEditAddAdditionalEmailValid(): void { + $loggedInUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $loggedInUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + $targetUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->willReturn($loggedInUser); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('UserToEdit') + ->willReturn($targetUser); + $targetUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + + $backend = $this->createMock(UserInterface::class); + $targetUser + ->expects($this->any()) + ->method('getBackend') + ->willReturn($backend); + + $userAccount = $this->createMock(IAccount::class); + + $this->accountManager + ->expects($this->once()) + ->method('getAccount') + ->with($targetUser) + ->willReturn($userAccount); + $this->accountManager + ->expects($this->once()) + ->method('updateAccount') + ->with($userAccount); + + $this->assertEquals([], $this->api->editUser('UserToEdit', 'additional_mail', 'demo1@nextcloud.com')->getData()); + } + + public function testEditUserRegularUserSelfEditAddAdditionalEmailMainAddress(): void { + $loggedInUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $loggedInUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + $targetUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->willReturn($loggedInUser); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('UserToEdit') + ->willReturn($targetUser); + $targetUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + + $backend = $this->createMock(UserInterface::class); + $targetUser + ->expects($this->any()) + ->method('getBackend') + ->willReturn($backend); + $targetUser + ->expects($this->any()) + ->method('getSystemEMailAddress') + ->willReturn('demo@nextcloud.com'); + + $userAccount = $this->createMock(IAccount::class); + $this->accountManager + ->expects($this->never()) + ->method('getAccount') + ->with($targetUser) + ->willReturn($userAccount); + $this->accountManager + ->expects($this->never()) + ->method('updateAccount') + ->with($userAccount); + + $this->expectException(OCSException::class); + $this->expectExceptionCode(102); + $this->api->editUser('UserToEdit', 'additional_mail', 'demo@nextcloud.com')->getData(); + } + + public function testEditUserRegularUserSelfEditAddAdditionalEmailDuplicate(): void { + $loggedInUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $loggedInUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + $targetUser = $this->getMockBuilder(IUser::class) + ->disableOriginalConstructor() + ->getMock(); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->willReturn($loggedInUser); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('UserToEdit') + ->willReturn($targetUser); + $targetUser + ->expects($this->any()) + ->method('getUID') + ->willReturn('UID'); + + $backend = $this->createMock(UserInterface::class); + $targetUser + ->expects($this->any()) + ->method('getBackend') + ->willReturn($backend); + + $property = $this->createMock(IAccountProperty::class); + $property->method('getValue') + ->willReturn('demo1@nextcloud.com'); + $collection = $this->createMock(IAccountPropertyCollection::class); + $collection->method('getPropertyByValue') + ->with('demo1@nextcloud.com') + ->willReturn($property); + + $userAccount = $this->createMock(IAccount::class); + $userAccount->method('getPropertyCollection') + ->with(IAccountManager::COLLECTION_EMAIL) + ->willReturn($collection); + + $this->accountManager + ->expects($this->once()) + ->method('getAccount') + ->with($targetUser) + ->willReturn($userAccount); + $this->accountManager + ->expects($this->never()) + ->method('updateAccount') + ->with($userAccount); + + $this->expectException(OCSException::class); + $this->expectExceptionCode(102); + $this->api->editUser('UserToEdit', 'additional_mail', 'demo1@nextcloud.com')->getData(); + } public function testEditUserRegularUserSelfEditChangeEmailInvalid() { $this->expectException(\OCP\AppFramework\OCS\OCSException::class); diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature index d34e1bceb6a..e6a570694b4 100644 --- a/build/integration/features/provisioning-v1.feature +++ b/build/integration/features/provisioning-v1.feature @@ -199,6 +199,28 @@ Feature: provisioning | value | private | Then the OCS status code should be "100" And the HTTP status code should be "200" + And sending "PUT" to "/cloud/users/brand-new-user" with + | key | email | + | value | no-reply@nextcloud.com | + And the OCS status code should be "100" + And the HTTP status code should be "200" + # Duplicating primary address + And sending "PUT" to "/cloud/users/brand-new-user" with + | key | additional_mail | + | value | no-reply@nextcloud.com | + And the OCS status code should be "102" + And the HTTP status code should be "200" + And sending "PUT" to "/cloud/users/brand-new-user" with + | key | additional_mail | + | value | no.reply@nextcloud.com | + And the OCS status code should be "100" + And the HTTP status code should be "200" + # Duplicating another additional address + And sending "PUT" to "/cloud/users/brand-new-user" with + | key | additional_mail | + | value | no.reply@nextcloud.com | + And the OCS status code should be "102" + And the HTTP status code should be "200" Then user "brand-new-user" has | id | brand-new-user | | phoneScope | v2-private | |