Skip to content

Commit 9f2e984

Browse files
committed
Create account returns colliding users if ignoreNameCollision flag is not set.
1 parent 992ea18 commit 9f2e984

File tree

2 files changed

+116
-4
lines changed

2 files changed

+116
-4
lines changed

app/V1Module/presenters/RegistrationPresenter.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\V1Module\Presenters;
44

55
use App\Helpers\MetaFormats\Attributes\Post;
6+
use App\Helpers\MetaFormats\Validators\VBool;
67
use App\Helpers\MetaFormats\Validators\VEmail;
78
use App\Helpers\MetaFormats\Validators\VMixed;
89
use App\Helpers\MetaFormats\Validators\VString;
@@ -162,6 +163,12 @@ public function checkCreateAccount()
162163
#[Post("instanceId", new VString(1), "Identifier of the instance to register in")]
163164
#[Post("titlesBeforeName", new VString(1), "Titles which is placed before user name", required: false)]
164165
#[Post("titlesAfterName", new VString(1), "Titles which is placed after user name", required: false)]
166+
#[Post(
167+
"ignoreNameCollision",
168+
new VBool(),
169+
"If a use with the same name exists, this needs to be set to true.",
170+
required: false
171+
)]
165172
public function actionCreateAccount()
166173
{
167174
$req = $this->getRequest();
@@ -179,8 +186,13 @@ public function actionCreateAccount()
179186
$instanceId = $req->getPost("instanceId");
180187
$instance = $this->getInstance($instanceId);
181188

182-
$titlesBeforeName = $req->getPost("titlesBeforeName") === null ? "" : $req->getPost("titlesBeforeName");
183-
$titlesAfterName = $req->getPost("titlesAfterName") === null ? "" : $req->getPost("titlesAfterName");
189+
$titlesBeforeName = trim($req->getPost("titlesBeforeName") ?? "");
190+
$titlesAfterName = trim($req->getPost("titlesAfterName") ?? "");
191+
$firstName = trim($req->getPost("firstName") ?? "");
192+
$lastName = trim($req->getPost("lastName") ?? "");
193+
if (!$firstName || !$lastName) {
194+
throw new BadRequestException("The user's full name must be filled in.");
195+
}
184196

185197
// check given passwords
186198
$password = $req->getPost("password");
@@ -192,10 +204,23 @@ public function actionCreateAccount()
192204
);
193205
}
194206

207+
// Check for name collisions, unless the request explicitly says to ignore them.
208+
if (!$req->getPost("ignoreNameCollision")) {
209+
$sameName = $this->users->findByName($instance, $firstName, $lastName);
210+
if ($sameName) {
211+
// let's report the colliding users
212+
$this->sendSuccessResponse([
213+
"user" => null,
214+
"usersWithSameName" => $this->userViewFactory->getUsers($sameName),
215+
]);
216+
return;
217+
}
218+
}
219+
195220
$user = new User(
196221
$email,
197-
$req->getPost("firstName"),
198-
$req->getPost("lastName"),
222+
$firstName,
223+
$lastName,
199224
$titlesBeforeName,
200225
$titlesAfterName,
201226
Roles::STUDENT_ROLE,

tests/Presenters/RegistrationPresenter.phpt

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,93 @@ class TestRegistrationPresenter extends Tester\TestCase
356356
);
357357
}
358358

359+
public function testCreateAccountSameName()
360+
{
361+
$student = $this->presenter->users->getByEmail(PresenterTestHelper::STUDENT_GROUP_MEMBER_LOGIN);
362+
Assert::notNull($student);
363+
364+
$email = "email@email.email";
365+
$firstName = $student->getFirstName();
366+
$lastName = $student->getLastName();
367+
$password = "password";
368+
$instances = $this->instances->findAll();
369+
$instanceId = array_pop($instances)->getId();
370+
$titlesBeforeName = "titlesBeforeName";
371+
$titlesAfterName = "titlesAfterName";
372+
373+
$payload = PresenterTestHelper::performPresenterRequest(
374+
$this->presenter,
375+
$this->presenterPath,
376+
'POST',
377+
['action' => 'createAccount'],
378+
[
379+
'email' => $email,
380+
'firstName' => $firstName,
381+
'lastName' => $lastName,
382+
'password' => $password,
383+
'passwordConfirm' => $password,
384+
'instanceId' => $instanceId,
385+
'titlesBeforeName' => $titlesBeforeName,
386+
'titlesAfterName' => $titlesAfterName
387+
]
388+
);
389+
390+
Assert::equal(null, $payload["user"]);
391+
Assert::count(1, $payload["usersWithSameName"]);
392+
$user = current($payload["usersWithSameName"]);
393+
Assert::equal($student->getId(), $user["id"]);
394+
}
395+
396+
public function testCreateAccountSameNameEnabled()
397+
{
398+
$student = $this->presenter->users->getByEmail(PresenterTestHelper::STUDENT_GROUP_MEMBER_LOGIN);
399+
Assert::notNull($student);
400+
401+
$email = "email@email.email";
402+
$firstName = $student->getFirstName();
403+
$lastName = $student->getLastName();
404+
$password = "password";
405+
$instances = $this->instances->findAll();
406+
$instanceId = array_pop($instances)->getId();
407+
$titlesBeforeName = "titlesBeforeName";
408+
$titlesAfterName = "titlesAfterName";
409+
410+
$request = new Nette\Application\Request(
411+
$this->presenterPath,
412+
'POST',
413+
['action' => 'createAccount'],
414+
[
415+
'email' => $email,
416+
'firstName' => $firstName,
417+
'lastName' => $lastName,
418+
'password' => $password,
419+
'passwordConfirm' => $password,
420+
'instanceId' => $instanceId,
421+
'titlesBeforeName' => $titlesBeforeName,
422+
'titlesAfterName' => $titlesAfterName,
423+
'ignoreNameCollision' => true,
424+
]
425+
);
426+
$response = $this->presenter->run($request);
427+
Assert::type(Nette\Application\Responses\JsonResponse::class, $response);
428+
429+
$result = $response->getPayload();
430+
Assert::equal(201, $result['code']);
431+
Assert::equal(2, count($result['payload']));
432+
Assert::true(array_key_exists("accessToken", $result["payload"]));
433+
Assert::true(array_key_exists("user", $result["payload"]));
434+
435+
// check created user
436+
$user = $result["payload"]["user"];
437+
Assert::equal("$titlesBeforeName $firstName $lastName $titlesAfterName", $user["fullName"]);
438+
Assert::equal($email, $user["privateData"]["email"]);
439+
440+
// check created login
441+
$login = $this->logins->findByUserId($user["id"]);
442+
Assert::equal($user["id"], $login->getUser()->getId());
443+
Assert::true($login->passwordsMatchOrEmpty($password, $this->presenter->passwordsService));
444+
}
445+
359446
public function testValidateRegistrationData()
360447
{
361448
$request = new Nette\Application\Request(

0 commit comments

Comments
 (0)