Skip to content

Commit e45d734

Browse files
committed
new user password email option, improved on #29368
Signed-off-by: Anupam Kumar <[email protected]>
1 parent 9083cd5 commit e45d734

File tree

3 files changed

+76
-135
lines changed

3 files changed

+76
-135
lines changed

core/Command/User/Add.php

Lines changed: 43 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/**
33
* @copyright Copyright (c) 2016, ownCloud, Inc.
44
*
5+
* @author Anupam Kumar <[email protected]>
56
* @author Arthur Schiwon <[email protected]>
67
* @author Christoph Wurst <[email protected]>
78
* @author Joas Schilling <[email protected]>
@@ -25,8 +26,6 @@
2526
*/
2627
namespace OC\Core\Command\User;
2728

28-
use Egulias\EmailValidator\EmailValidator;
29-
use Egulias\EmailValidator\Validation\RFCValidation;
3029
use OC\Files\Filesystem;
3130
use OCA\Settings\Mailer\NewUserMailHelper;
3231
use OCP\EventDispatcher\IEventDispatcher;
@@ -35,6 +34,7 @@
3534
use OCP\IGroupManager;
3635
use OCP\IUser;
3736
use OCP\IUserManager;
37+
use OCP\Mail\IMailer;
3838
use OCP\Security\Events\GenerateSecurePasswordEvent;
3939
use OCP\Security\ISecureRandom;
4040
use Symfony\Component\Console\Command\Command;
@@ -46,63 +46,16 @@
4646
use Symfony\Component\Console\Question\Question;
4747

4848
class Add extends Command {
49-
/**
50-
* @var IUserManager
51-
*/
52-
protected $userManager;
53-
54-
/**
55-
* @var IGroupManager
56-
*/
57-
protected $groupManager;
58-
59-
/**
60-
* @var EmailValidator
61-
*/
62-
protected $emailValidator;
63-
64-
/**
65-
* @var IConfig
66-
*/
67-
private $config;
68-
69-
/**
70-
* @var NewUserMailHelper
71-
*/
72-
private $mailHelper;
73-
74-
/**
75-
* @var IEventDispatcher
76-
*/
77-
private $eventDispatcher;
78-
79-
/**
80-
* @var ISecureRandom
81-
*/
82-
private $secureRandom;
83-
84-
/**
85-
* @param IUserManager $userManager
86-
* @param IGroupManager $groupManager
87-
* @param EmailValidator $emailValidator
88-
*/
8949
public function __construct(
90-
IUserManager $userManager,
91-
IGroupManager $groupManager,
92-
EmailValidator $emailValidator,
93-
IConfig $config,
94-
NewUserMailHelper $mailHelper,
95-
IEventDispatcher $eventDispatcher,
96-
ISecureRandom $secureRandom
50+
protected IUserManager $userManager,
51+
protected IGroupManager $groupManager,
52+
protected IMailer $mailer,
53+
private IConfig $config,
54+
private NewUserMailHelper $mailHelper,
55+
private IEventDispatcher $eventDispatcher,
56+
private ISecureRandom $secureRandom
9757
) {
9858
parent::__construct();
99-
$this->userManager = $userManager;
100-
$this->groupManager = $groupManager;
101-
$this->emailValidator = $emailValidator;
102-
$this->config = $config;
103-
$this->mailHelper = $mailHelper;
104-
$this->eventDispatcher = $eventDispatcher;
105-
$this->secureRandom = $secureRandom;
10659
}
10760

10861
protected function configure() {
@@ -142,23 +95,38 @@ protected function configure() {
14295

14396
protected function execute(InputInterface $input, OutputInterface $output): int {
14497
$uid = $input->getArgument('uid');
145-
$emailIsSet = \is_string($input->getOption('email')) && \mb_strlen($input->getOption('email')) > 0;
146-
$emailIsValid = $this->emailValidator->isValid($input->getOption('email') ?? '', new RFCValidation());
147-
$password = '';
148-
$temporaryPassword = '';
149-
15098
if ($this->userManager->userExists($uid)) {
15199
$output->writeln('<error>The user "' . $uid . '" already exists.</error>');
152100
return 1;
153101
}
154102

103+
$password = '';
104+
$sendPasswordEmail = false;
105+
155106
if ($input->getOption('password-from-env')) {
156107
$password = getenv('OC_PASS');
157108

158109
if (!$password) {
159110
$output->writeln('<error>--password-from-env given, but OC_PASS is empty!</error>');
160111
return 1;
161112
}
113+
} elseif (\mb_strlen($input->getOption('email')) > 0) {
114+
if (!$this->mailer->validateMailAddress($input->getOption(('email')))) {
115+
$output->writeln(\sprintf(
116+
'<error>The given E-Mail address "%s" is invalid</error>',
117+
$input->getOption('email'),
118+
));
119+
120+
return 1;
121+
}
122+
123+
$output->writeln('Setting a temporary password.');
124+
125+
$passwordEvent = new GenerateSecurePasswordEvent();
126+
$this->eventDispatcher->dispatchTyped($passwordEvent);
127+
$password = $passwordEvent->getPassword() ?? $this->secureRandom->generate(20);
128+
129+
$sendPasswordEmail = true;
162130
} elseif ($input->isInteractive()) {
163131
/** @var QuestionHelper $helper */
164132
$helper = $this->getHelper('question');
@@ -180,26 +148,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
180148
return 1;
181149
}
182150

183-
if (trim($password) === '' && $emailIsSet) {
184-
if ($emailIsValid) {
185-
$output->writeln('Setting a temporary password.');
186-
187-
$temporaryPassword = $this->getTemporaryPassword();
188-
} else {
189-
$output->writeln(\sprintf(
190-
'<error>The given E-Mail address "%s" is invalid: %s</error>',
191-
$input->getOption('email'),
192-
$this->emailValidator->getError()->description()
193-
));
194-
195-
return 1;
196-
}
197-
}
198-
199151
try {
200152
$user = $this->userManager->createUser(
201153
$input->getArgument('uid'),
202-
$password ?: $temporaryPassword
154+
$password,
203155
);
204156
} catch (\Exception $e) {
205157
$output->writeln('<error>' . $e->getMessage() . '</error>');
@@ -215,24 +167,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
215167

216168
if ($input->getOption('display-name')) {
217169
$user->setDisplayName($input->getOption('display-name'));
218-
$output->writeln(sprintf('Display name set to "%s"', $user->getDisplayName()));
219-
}
220-
221-
if ($emailIsSet && $emailIsValid) {
222-
$user->setSystemEMailAddress($input->getOption('email'));
223-
$output->writeln(sprintf('E-Mail set to "%s"', (string) $user->getSystemEMailAddress()));
224-
225-
if (trim($password) === '' && $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
226-
try {
227-
$this->mailHelper->sendMail(
228-
$user,
229-
$this->mailHelper->generateTemplate($user, true)
230-
);
231-
$output->writeln('Invitation E-Mail sent.');
232-
} catch (\Exception $e) {
233-
$output->writeln(\sprintf('Unable to send the invitation mail to %s', $user->getEMailAddress()));
234-
}
235-
}
170+
$output->writeln(\sprintf('Display name set to "%s"', $user->getDisplayName()));
236171
}
237172

238173
$groups = $input->getOption('group');
@@ -257,18 +192,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
257192
$output->writeln('User "' . $user->getUID() . '" added to group "' . $group->getGID() . '"');
258193
}
259194
}
260-
return 0;
261-
}
262195

263-
/**
264-
* @return string
265-
*/
266-
protected function getTemporaryPassword(): string
267-
{
268-
$passwordEvent = new GenerateSecurePasswordEvent();
196+
// Send email to user if we set a temporary password
197+
if ($sendPasswordEmail && $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
198+
$email = $input->getOption('email');
199+
$user->setSystemEMailAddress($email);
269200

270-
$this->eventDispatcher->dispatchTyped($passwordEvent);
201+
try {
202+
$this->mailHelper->sendMail($user, $this->mailHelper->generateTemplate($user, true));
203+
$output->writeln(\sprintf('Invitation E-Mail sent to %s', $email));
204+
} catch (\Exception $e) {
205+
$output->writeln(\sprintf('Unable to send the invitation mail to %s', $email));
206+
}
207+
}
271208

272-
return $passwordEvent->getPassword() ?? $this->secureRandom->generate(20);
209+
return 0;
273210
}
274211
}

core/register_command.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/**
66
* @copyright Copyright (c) 2016, ownCloud, Inc.
77
*
8+
* @author Anupam Kumar <[email protected]>
89
* @author Bart Visscher <[email protected]>
910
* @author Björn Schießle <[email protected]>
1011
* @author Christian Kampka <[email protected]>
@@ -183,7 +184,8 @@
183184
$application->add(\OC::$server->query(\OC\Core\Command\Preview\Repair::class));
184185
$application->add(\OC::$server->query(\OC\Core\Command\Preview\ResetRenderedTexts::class));
185186

186-
$application->add(new OC\Core\Command\User\Add(\OC::$server->getUserManager(), \OC::$server->getGroupManager(), \OC::$server->get(Egulias\EmailValidator\EmailValidator::class), \OC::$server->get(\OC\AllConfig::class), \OC::$server->get(\OCA\Settings\Mailer\NewUserMailHelper::class), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->get(\OCP\Security\ISecureRandom::class)));
187+
$application->add(new OC\Core\Command\User\Add(\OC::$server->get(\OCP\IUserManager::class), \OC::$server->get(\OCP\IGroupManager::class
188+
), \OC::$server->get(\OCP\Mail\IMailer::class), \OC::$server->get(\OC\AllConfig::class), \OC::$server->get(\OCA\Settings\Mailer\NewUserMailHelper::class), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->get(\OCP\Security\ISecureRandom::class)));
187189
$application->add(new OC\Core\Command\User\Delete(\OC::$server->getUserManager()));
188190
$application->add(new OC\Core\Command\User\Disable(\OC::$server->getUserManager()));
189191
$application->add(new OC\Core\Command\User\Enable(\OC::$server->getUserManager()));

tests/Core/Command/User/AddTest.php

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
namespace Core\Command\User;
2727

28-
use Egulias\EmailValidator\EmailValidator;
2928
use OC\Core\Command\User\Add;
3029
use OCA\Settings\Mailer\NewUserMailHelper;
3130
use OCP\EventDispatcher\IEventDispatcher;
@@ -34,19 +33,20 @@
3433
use OCP\IUser;
3534
use OCP\IUserManager;
3635
use OCP\Mail\IEMailTemplate;
36+
use OCP\mail\IMailer;
3737
use OCP\Security\ISecureRandom;
3838
use Symfony\Component\Console\Input\InputInterface;
3939
use Symfony\Component\Console\Output\OutputInterface;
4040
use Test\TestCase;
4141

4242
class AddTest extends TestCase {
43-
4443
/**
4544
* @dataProvider addEmailDataProvider
4645
*/
4746
public function testAddEmail(?string $email, bool $isValid, bool $shouldSendMail): void {
4847
$userManager = static::createMock(IUserManager::class);
4948
$groupManager = static::createStub(IGroupManager::class);
49+
$mailer = static::createMock(IMailer::class);
5050
$user = static::createMock(IUser::class);
5151
$config = static::createMock(IConfig::class);
5252
$mailHelper = static::createMock(NewUserMailHelper::class);
@@ -56,7 +56,7 @@ public function testAddEmail(?string $email, bool $isValid, bool $shouldSendMail
5656
$consoleInput = static::createMock(InputInterface::class);
5757
$consoleOutput = static::createMock(OutputInterface::class);
5858

59-
$user->expects($isValid ? static::once() : static::never())
59+
$user->expects($isValid && $shouldSendMail ? static::once() : static::never())
6060
->method('setSystemEMailAddress')
6161
->with(static::equalTo($email));
6262

@@ -66,6 +66,9 @@ public function testAddEmail(?string $email, bool $isValid, bool $shouldSendMail
6666
$config->method('getAppValue')
6767
->willReturn($shouldSendMail ? 'yes' : 'no');
6868

69+
$mailer->method('validateMailAddress')
70+
->willReturn($isValid);
71+
6972
$mailHelper->method('generateTemplate')
7073
->willReturn(static::createMock(IEMailTemplate::class));
7174

@@ -82,7 +85,7 @@ public function testAddEmail(?string $email, bool $isValid, bool $shouldSendMail
8285
$addCommand = new Add(
8386
$userManager,
8487
$groupManager,
85-
new EmailValidator(),
88+
$mailer,
8689
$config,
8790
$mailHelper,
8891
$eventDispatcher,
@@ -96,31 +99,30 @@ public function testAddEmail(?string $email, bool $isValid, bool $shouldSendMail
9699
}
97100

98101
/**
99-
* @return \Generator<string, array>
102+
* @return array
100103
*/
101-
public function addEmailDataProvider(): \Generator {
102-
yield 'Valid E-Mail' => [
103-
104-
true,
105-
true,
106-
];
107-
108-
yield 'Invalid E-Mail' => [
109-
'info@@example.com',
110-
false,
111-
true,
112-
];
113-
114-
yield 'No E-Mail' => [
115-
'',
116-
false,
117-
true,
118-
];
119-
120-
yield 'Valid E-Mail, but no mail should be sent' => [
121-
122-
true,
123-
false,
104+
public function addEmailDataProvider(): array {
105+
return [
106+
'Valid E-Mail' => [
107+
108+
true,
109+
true,
110+
],
111+
'Invalid E-Mail' => [
112+
'info@@example.com',
113+
false,
114+
true,
115+
],
116+
'No E-Mail' => [
117+
'',
118+
false,
119+
true,
120+
],
121+
'Valid E-Mail, but no mail should be sent' => [
122+
123+
true,
124+
false,
125+
],
124126
];
125127
}
126128
}

0 commit comments

Comments
 (0)