Skip to content

Commit fdb6298

Browse files
pringelmannbackportbot[bot]
authored andcommitted
fix(provisioning_api): read newUser.sendEmail as a boolean
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
1 parent 8077a8e commit fdb6298

6 files changed

Lines changed: 93 additions & 5 deletions

File tree

apps/provisioning_api/lib/Controller/UsersController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ public function addUser(
596596
// Send new user mail only if a mail is set
597597
if ($email !== '') {
598598
$newUser->setSystemEMailAddress($email);
599-
if ($this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
599+
if ($this->appConfig->getValueBool('core', 'newUser.sendEmail', true)) {
600600
try {
601601
$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
602602
$this->newUserMailHelper->sendMail($newUser, $emailTemplate);

apps/provisioning_api/tests/Controller/UsersControllerTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,67 @@ public function testAddUserSuccessfulGeneratePassword(): void {
730730
));
731731
}
732732

733+
/**
734+
* `newUser.sendEmail` has to be read as a boolean. It is stored as an untyped
735+
* 'yes'/'no' string on instances created before Nextcloud 33 and as a typed
736+
* boolean once the account settings toggle has been used, so comparing it to
737+
* the string 'yes' silently skipped the mail on upgraded instances.
738+
*/
739+
#[\PHPUnit\Framework\Attributes\DataProvider('dataAddUserWelcomeMail')]
740+
public function testAddUserSendsWelcomeMailWhenEnabled(bool $enabled): void {
741+
$this->appConfig
742+
->expects($this->atLeastOnce())
743+
->method('getValueBool')
744+
->with('core', 'newUser.sendEmail', true)
745+
->willReturn($enabled);
746+
747+
$newUser = $this->createMock(IUser::class);
748+
$newUser->expects($this->once())
749+
->method('setSystemEMailAddress')
750+
->with('foo@bar.com');
751+
$this->userManager
752+
->expects($this->once())
753+
->method('userExists')
754+
->with('NewUser')
755+
->willReturn(false);
756+
$this->userManager
757+
->expects($this->once())
758+
->method('createUser')
759+
->willReturn($newUser);
760+
$loggedInUser = $this->createMock(IUser::class);
761+
$loggedInUser
762+
->method('getUID')
763+
->willReturn('adminUser');
764+
$this->userSession
765+
->expects($this->once())
766+
->method('getUser')
767+
->willReturn($loggedInUser);
768+
$this->groupManager
769+
->expects($this->once())
770+
->method('isAdmin')
771+
->with('adminUser')
772+
->willReturn(true);
773+
774+
$emailTemplate = $this->createMock(IEMailTemplate::class);
775+
$this->newUserMailHelper
776+
->expects($enabled ? $this->once() : $this->never())
777+
->method('generateTemplate')
778+
->willReturn($emailTemplate);
779+
$this->newUserMailHelper
780+
->expects($enabled ? $this->once() : $this->never())
781+
->method('sendMail')
782+
->with($newUser, $emailTemplate);
783+
784+
$this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', 'foo@bar.com');
785+
}
786+
787+
public static function dataAddUserWelcomeMail(): array {
788+
return [
789+
'enabled' => [true],
790+
'disabled' => [false],
791+
];
792+
}
793+
733794
public function testAddUserSuccessfulLowercaseEmail(): void {
734795
$this->userManager
735796
->expects($this->once())

build/psalm-baseline.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,6 @@
22042204
<code><![CDATA[getAppValue]]></code>
22052205
<code><![CDATA[getAppValue]]></code>
22062206
<code><![CDATA[getAppValue]]></code>
2207-
<code><![CDATA[getAppValue]]></code>
22082207
<code><![CDATA[getUserValue]]></code>
22092208
<code><![CDATA[implementsActions]]></code>
22102209
<code><![CDATA[implementsActions]]></code>

core/Command/User/Add.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
180180

181181
$user->setSystemEMailAddress($email);
182182

183-
if ($this->appConfig->getValueString('core', 'newUser.sendEmail', 'yes') === 'yes') {
183+
if ($this->appConfig->getValueBool('core', 'newUser.sendEmail', true)) {
184184
try {
185185
$this->mailHelper->sendMail($user, $this->mailHelper->generateTemplate($user, true));
186186
$output->writeln('Welcome email sent to ' . $email);

tests/Core/Command/User/AddTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public function testAddEmail(
9999
$this->userManager->method('createUser')
100100
->willReturn($this->user);
101101

102-
$this->appConfig->method('getValueString')
103-
->willReturn($shouldSendEmail ? 'yes' : 'no');
102+
$this->appConfig->method('getValueBool')
103+
->willReturn($shouldSendEmail);
104104

105105
$this->mailHelper->method('generateTemplate')
106106
->willReturn(static::createMock(IEMailTemplate::class));

tests/lib/AppConfigIntegrationTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,34 @@ public function testGetValueBool(): void {
519519
$this->assertSame(true, $config->getValueBool('typed', 'bool'));
520520
}
521521

522+
/**
523+
* Untyped values predate the typed config API and are still in the database of
524+
* every upgraded instance, so they have to keep resolving to a boolean. The
525+
* deprecated setter is used on purpose, as it is the only way to write a value
526+
* without a type.
527+
*/
528+
#[\PHPUnit\Framework\Attributes\DataProvider('dataUntypedBool')]
529+
public function testGetValueBoolOnUntypedValue(string $stored, bool $expected): void {
530+
/** @var AppConfig $config */
531+
$config = $this->generateAppConfig();
532+
$config->setValue('feed', 'untyped-bool', $stored);
533+
534+
$this->assertSame($expected, $config->getValueBool('feed', 'untyped-bool'));
535+
}
536+
537+
public static function dataUntypedBool(): array {
538+
return [
539+
'yes' => ['yes', true],
540+
'no' => ['no', false],
541+
'true' => ['true', true],
542+
'false' => ['false', false],
543+
'on' => ['on', true],
544+
'1' => ['1', true],
545+
'0' => ['0', false],
546+
'empty' => ['', false],
547+
];
548+
}
549+
522550
public function testGetValueBoolOnUnknownAppReturnsDefault(): void {
523551
$config = $this->generateAppConfig();
524552
$this->assertSame(false, $config->getValueBool('typed-1', 'bool', false));

0 commit comments

Comments
 (0)