Skip to content

Commit 47bae0c

Browse files
committed
Allow admin to create users withoutpassword by sending mail automatically
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
1 parent fa886ef commit 47bae0c

File tree

2 files changed

+53
-10
lines changed

2 files changed

+53
-10
lines changed

apps/provisioning_api/lib/Controller/UsersController.php

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use OCP\IUserManager;
5151
use OCP\IUserSession;
5252
use OCP\L10N\IFactory;
53+
use OCP\Security\ISecureRandom;
5354

5455
class UsersController extends OCSController {
5556

@@ -73,6 +74,8 @@ class UsersController extends OCSController {
7374
private $newUserMailHelper;
7475
/** @var FederatedFileSharingFactory */
7576
private $federatedFileSharingFactory;
77+
/** @var ISecureRandom */
78+
private $secureRandom;
7679

7780
/**
7881
* @param string $appName
@@ -87,6 +90,7 @@ class UsersController extends OCSController {
8790
* @param IFactory $l10nFactory
8891
* @param NewUserMailHelper $newUserMailHelper
8992
* @param FederatedFileSharingFactory $federatedFileSharingFactory
93+
* @param ISecureRandom $secureRandom
9094
*/
9195
public function __construct(string $appName,
9296
IRequest $request,
@@ -99,7 +103,8 @@ public function __construct(string $appName,
99103
ILogger $logger,
100104
IFactory $l10nFactory,
101105
NewUserMailHelper $newUserMailHelper,
102-
FederatedFileSharingFactory $federatedFileSharingFactory) {
106+
FederatedFileSharingFactory $federatedFileSharingFactory,
107+
ISecureRandom $secureRandom) {
103108
parent::__construct($appName, $request);
104109

105110
$this->userManager = $userManager;
@@ -112,6 +117,7 @@ public function __construct(string $appName,
112117
$this->l10nFactory = $l10nFactory;
113118
$this->newUserMailHelper = $newUserMailHelper;
114119
$this->federatedFileSharingFactory = $federatedFileSharingFactory;
120+
$this->secureRandom = $secureRandom;
115121
}
116122

117123
/**
@@ -164,11 +170,12 @@ public function getUsers(string $search = '', $limit = null, $offset = null): Da
164170
*
165171
* @param string $userid
166172
* @param string $password
173+
* @param string $email
167174
* @param array $groups
168175
* @return DataResponse
169176
* @throws OCSException
170177
*/
171-
public function addUser(string $userid, string $password, array $groups = []): DataResponse {
178+
public function addUser(string $userid, string $password = '', $email='', array $groups = []): DataResponse {
172179
$user = $this->userSession->getUser();
173180
$isAdmin = $this->groupManager->isAdmin($user->getUID());
174181
$subAdminManager = $this->groupManager->getSubAdmin();
@@ -193,6 +200,18 @@ public function addUser(string $userid, string $password, array $groups = []): D
193200
}
194201
}
195202

203+
$generatePasswordResetToken = false;
204+
if ($password === '') {
205+
if ($email === '') {
206+
throw new OCSException('To send a password link to the user an email address is required.', 108);
207+
}
208+
209+
$password = $this->secureRandom->generate(30);
210+
// Make sure we pass the password_policy
211+
$password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
212+
$generatePasswordResetToken = true;
213+
}
214+
196215
try {
197216
$newUser = $this->userManager->createUser($userid, $password);
198217
$this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
@@ -202,7 +221,24 @@ public function addUser(string $userid, string $password, array $groups = []): D
202221
$this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
203222
}
204223

224+
// Send new user mail only if a mail is set
225+
if ($email !== '') {
226+
$newUser->setEMailAddress($email);
227+
try {
228+
$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
229+
$this->newUserMailHelper->sendMail($newUser, $emailTemplate);
230+
} catch (\Exception $e) {
231+
$this->logger->logException($e, [
232+
'message' => "Can't send new user mail to $email",
233+
'level' => \OCP\Util::ERROR,
234+
'app' => 'ocs_api',
235+
]);
236+
throw new OCSException('Unable to send the invitation mail', 109);
237+
}
238+
}
239+
205240
return new DataResponse();
241+
206242
} catch (HintException $e ) {
207243
$this->logger->logException($e, [
208244
'message' => 'Failed addUser attempt with hint exception.',

apps/provisioning_api/tests/Controller/UsersControllerTest.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
use OCP\IUserSession;
5757
use OCP\L10N\IFactory;
5858
use OCP\Mail\IMailer;
59+
use OCP\Security\ISecureRandom;
5960
use PHPUnit_Framework_MockObject_MockObject;
6061
use Test\TestCase;
6162

@@ -85,6 +86,8 @@ class UsersControllerTest extends TestCase {
8586
private $newUserMailHelper;
8687
/** @var FederatedFileSharingFactory|\PHPUnit_Framework_MockObject_MockObject */
8788
private $federatedFileSharingFactory;
89+
/** @var ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */
90+
private $secureRandom;
8891

8992
protected function setUp() {
9093
parent::setUp();
@@ -100,6 +103,7 @@ protected function setUp() {
100103
$this->l10nFactory = $this->createMock(IFactory::class);
101104
$this->newUserMailHelper = $this->createMock(NewUserMailHelper::class);
102105
$this->federatedFileSharingFactory = $this->createMock(FederatedFileSharingFactory::class);
106+
$this->secureRandom = $this->createMock(ISecureRandom::class);
103107

104108
$this->api = $this->getMockBuilder(UsersController::class)
105109
->setConstructorArgs([
@@ -114,7 +118,8 @@ protected function setUp() {
114118
$this->logger,
115119
$this->l10nFactory,
116120
$this->newUserMailHelper,
117-
$this->federatedFileSharingFactory
121+
$this->federatedFileSharingFactory,
122+
$this->secureRandom
118123
])
119124
->setMethods(['fillStorageInfo'])
120125
->getMock();
@@ -278,7 +283,7 @@ public function testAddUserNonExistingGroup() {
278283
->with('NonExistingGroup')
279284
->willReturn(false);
280285

281-
$this->api->addUser('NewUser', 'pass', ['NonExistingGroup']);
286+
$this->api->addUser('NewUser', 'pass', '', ['NonExistingGroup']);
282287
}
283288

284289
/**
@@ -320,7 +325,7 @@ public function testAddUserExistingGroupNonExistingGroup() {
320325
['NonExistingGroup', false]
321326
]));
322327

323-
$this->api->addUser('NewUser', 'pass', ['ExistingGroup', 'NonExistingGroup']);
328+
$this->api->addUser('NewUser', 'pass', '', ['ExistingGroup', 'NonExistingGroup']);
324329
}
325330

326331
public function testAddUserSuccessful() {
@@ -412,7 +417,7 @@ public function testAddUserExistingGroup() {
412417
['Added userid NewUser to group ExistingGroup', ['app' => 'ocs_api']]
413418
);
414419

415-
$this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup'])->getData());
420+
$this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup'])->getData());
416421
}
417422

418423
/**
@@ -539,7 +544,7 @@ public function testAddUserAsSubAdminValidGroupNotSubAdmin() {
539544
->with('ExistingGroup')
540545
->willReturn(true);
541546

542-
$this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup'])->getData();
547+
$this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup'])->getData();
543548
}
544549

545550
public function testAddUserAsSubAdminExistingGroups() {
@@ -630,7 +635,7 @@ public function testAddUserAsSubAdminExistingGroups() {
630635
)
631636
->willReturn(true);
632637

633-
$this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup1', 'ExistingGroup2'])->getData());
638+
$this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup1', 'ExistingGroup2'])->getData());
634639
}
635640

636641
/**
@@ -2885,7 +2890,8 @@ public function testGetCurrentUserLoggedIn() {
28852890
$this->logger,
28862891
$this->l10nFactory,
28872892
$this->newUserMailHelper,
2888-
$this->federatedFileSharingFactory
2893+
$this->federatedFileSharingFactory,
2894+
$this->secureRandom
28892895
])
28902896
->setMethods(['getUserData'])
28912897
->getMock();
@@ -2947,7 +2953,8 @@ public function testGetUser() {
29472953
$this->logger,
29482954
$this->l10nFactory,
29492955
$this->newUserMailHelper,
2950-
$this->federatedFileSharingFactory
2956+
$this->federatedFileSharingFactory,
2957+
$this->secureRandom
29512958
])
29522959
->setMethods(['getUserData'])
29532960
->getMock();

0 commit comments

Comments
 (0)