Skip to content

Commit

Permalink
EZP-31079: Provided validation for email uniqueness and login pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
Nattfarinn committed Mar 24, 2020
1 parent 2d08b2d commit 52e9563
Show file tree
Hide file tree
Showing 6 changed files with 398 additions and 21 deletions.
8 changes: 6 additions & 2 deletions eZ/Publish/API/Repository/Tests/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ private function assertPropertiesEqual($propertyName, $expectedValue, $actualVal
/**
* Create a user in editor user group.
*/
protected function createUserVersion1(string $login = 'user', ?string $email = null): User
protected function createUserVersion1(string $login = 'user', ?string $email = null, ContentType $contentType = null): User
{
$repository = $this->getRepository();

Expand All @@ -314,7 +314,7 @@ protected function createUserVersion1(string $login = 'user', ?string $email = n
$userCreate = $userService->newUserCreateStruct(
$login,
$email,
'secret',
'VerySecret@Password.1234',
'eng-US'
);
$userCreate->enabled = true;
Expand All @@ -323,6 +323,10 @@ protected function createUserVersion1(string $login = 'user', ?string $email = n
$userCreate->setField('first_name', 'Example');
$userCreate->setField('last_name', 'User');

if (!empty($contentType)) {
$userCreate->contentType = $contentType;
}

// Load parent group for the user
$group = $userService->loadUserGroup($editorsGroupId);

Expand Down
12 changes: 12 additions & 0 deletions eZ/Publish/API/Repository/Tests/FieldType/UserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ public function getSettingsSchema()
'type' => 'int',
'default' => null,
],
'RequireUniqueEmail' => [
'type' => 'bool',
'default' => true,
],
'UsernamePattern' => [
'type' => 'string',
'default' => '^[^@]+$',
],
];
}

Expand All @@ -67,6 +75,8 @@ public function getValidFieldSettings()
return [
'PasswordTTL' => null,
'PasswordTTLWarning' => null,
'RequireUniqueEmail' => false,
'UsernamePattern' => '.*',
];
}

Expand Down Expand Up @@ -553,6 +563,8 @@ public function testUpdateFieldDefinitionWithIncompleteSettingsSchema()
$userFieldDefinitionUpdateStruct = $contentTypeService->newFieldDefinitionUpdateStruct();
$userFieldDefinitionUpdateStruct->fieldSettings = [
Type::PASSWORD_TTL_WARNING_SETTING => null,
Type::REQUIRE_UNIQUE_EMAIL => false,
Type::USERNAME_PATTERN => '.*',
];

$contentTypeService->updateFieldDefinition($contentTypeDraft, $userFieldDefinition, $userFieldDefinitionUpdateStruct);
Expand Down
130 changes: 114 additions & 16 deletions eZ/Publish/API/Repository/Tests/UserServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use eZ\Publish\API\Repository\Values\User\UserTokenUpdateStruct;
use eZ\Publish\API\Repository\Values\User\UserUpdateStruct;
use eZ\Publish\API\Repository\Values\User\User;
use eZ\Publish\Core\FieldType\User\Type;
use eZ\Publish\Core\FieldType\ValidationError;
use eZ\Publish\Core\Repository\Values\Content\Content;
use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
Expand Down Expand Up @@ -190,7 +191,6 @@ public function testLoadSubUserGroupsThrowsNotFoundException()
* @return \eZ\Publish\API\Repository\Values\User\UserGroupCreateStruct
*
* @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct()
* @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
*/
public function testNewUserGroupCreateStruct()
{
Expand Down Expand Up @@ -244,7 +244,6 @@ public function testNewUserGroupCreateStructSetsContentType($groupCreate)
*
* @see \eZ\Publish\API\Repository\UserService::newUserGroupCreateStruct($mainLanguageCode, $contentType)
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
*/
public function testNewUserGroupCreateStructWithSecondParameter()
{
Expand Down Expand Up @@ -279,7 +278,6 @@ public function testNewUserGroupCreateStructWithSecondParameter()
* @see \eZ\Publish\API\Repository\UserService::createUserGroup()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
*/
public function testCreateUserGroup()
{
Expand Down Expand Up @@ -427,7 +425,6 @@ public function testCreateUserGroupWhenMissingField()
* @see \eZ\Publish\API\Repository\UserService::createUserGroup()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserGroupCreateStruct
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
*/
public function testCreateUserGroupInTransactionWithRollback()
{
Expand Down Expand Up @@ -864,7 +861,6 @@ public function testNewUserCreateStructSetsExpectedProperties($userCreate)
*
* @see \eZ\Publish\API\Repository\UserService::newUserCreateStruct($login, $email, $password, $mainLanguageCode, $contentType)
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentTypeServiceTest::testLoadContentTypeByIdentifier
*/
public function testNewUserCreateStructWithFifthParameter()
{
Expand Down Expand Up @@ -916,7 +912,6 @@ public function testNewUserWithDomainName()
* @see \eZ\Publish\API\Repository\UserService::createUser()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
*/
public function testCreateUser()
{
Expand Down Expand Up @@ -1084,6 +1079,114 @@ public function testCreateUserThrowsInvalidArgumentException()
$this->fail('Expected ValidationError messages did not occur.');
}

/**
* Test for the createUser() method.
*
* @covers \eZ\Publish\API\Repository\UserService::createUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
*/
public function testCreateUserWithEmailAlreadyTaken(): void
{
$repository = $this->getRepository();

$userContentType = $this->createUserContentTypeWithAccountSettings('user_email_unique', [
Type::REQUIRE_UNIQUE_EMAIL => true,
]);

$existingUser = $this->createUserVersion1(
'existing_user',
'unique@email.com',
$userContentType,
);

$editorsGroupId = $this->generateId('group', 13);
/* BEGIN: Use Case */
// $editorsGroupId is the ID of the "Editors" user group in an eZ
// Publish demo installation

$userService = $repository->getUserService();

// Instantiate a create struct with mandatory properties
$userCreate = $userService->newUserCreateStruct(
'another_user',
// email is already taken
'unique@email.com',
'VerySecure@Password.1234',
'eng-US',
$userContentType
);

$userCreate->setField('first_name', 'Example');
$userCreate->setField('last_name', 'User');

// Load parent group for the user
$group = $userService->loadUserGroup($editorsGroupId);

try {
// This call will fail with a "ContentFieldValidationException", because the
// user with "unique@email.com" email already exists in database.
$userService->createUser($userCreate, [$group]);
} catch (ContentFieldValidationException $e) {
// Exception is caught, as there is no other way to check exception properties.
$this->assertValidationErrorOccurs($e, 'Email \'%email%\' is used by another user. You must enter a unique email.');

return;
}

$this->fail('Expected ValidationError messages did not occur.');
}

/**
* Test for the createUser() method.
*
* @covers \eZ\Publish\API\Repository\UserService::createUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
*/
public function testCreateInvalidFormatUsername(): void
{
$repository = $this->getRepository();

$userContentType = $this->createUserContentTypeWithAccountSettings('username_format', [
Type::USERNAME_PATTERN => '^[^@]$',
]);

$editorsGroupId = $this->generateId('group', 13);
/* BEGIN: Use Case */
// $editorsGroupId is the ID of the "Editors" user group in an eZ
// Publish demo installation

$userService = $repository->getUserService();

// Instantiate a create struct with mandatory properties
$userCreate = $userService->newUserCreateStruct(
// login contains @
'invalid@user',
'unique@email.com',
'VerySecure@Password.1234',
'eng-US',
$userContentType
);

$userCreate->setField('first_name', 'Example');
$userCreate->setField('last_name', 'User');

// Load parent group for the user
$group = $userService->loadUserGroup($editorsGroupId);

try {
// This call will fail with a "ContentFieldValidationException", because the
// user with "invalid@user" login does not match "^[^@]$" pattern.
$userService->createUser($userCreate, [$group]);
} catch (ContentFieldValidationException $e) {
// Exception is caught, as there is no other way to check exception properties.
$this->assertValidationErrorOccurs($e, 'Invalid login format');

return;
}

$this->fail('Expected ValidationError messages did not occur.');
}

/**
* Test for the createUser() method.
*
Expand All @@ -1092,7 +1195,6 @@ public function testCreateUserThrowsInvalidArgumentException()
* @see \eZ\Publish\API\Repository\UserService::createUser()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testLoadUserGroup
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserCreateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testCreateContent
*/
public function testCreateUserInTransactionWithRollback()
{
Expand Down Expand Up @@ -1253,7 +1355,7 @@ public function testLoadUserThrowsNotFoundException()

/**
* @see \eZ\Publish\API\Repository\UserService::checkUserCredentials()
* @depends \eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
*/
public function testCheckUserCredentialsValid(): void
{
Expand All @@ -1265,15 +1367,15 @@ public function testCheckUserCredentialsValid(): void
$user = $this->createUserVersion1();

// Load the newly created user credentials
$credentialsValid = $userService->loadUserByCredentials($user, 'secret');
$credentialsValid = $userService->checkUserCredentials($user, 'VerySecret@Password.1234');
/* END: Use Case */

$this->assertTrue($credentialsValid);
}

/**
* @see \eZ\Publish\API\Repository\UserService::checkUserCredentials()
* @depends \eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
*/
public function testCheckUserCredentialsInvalid(): void
{
Expand All @@ -1285,7 +1387,7 @@ public function testCheckUserCredentialsInvalid(): void
$user = $this->createUserVersion1();

// Load the newly created user credentials
$credentialsValid = $userService->loadUserByCredentials($user, '1234');
$credentialsValid = $userService->checkUserCredentials($user, 'NotSoSecretPassword');
/* END: Use Case */

$this->assertFalse($credentialsValid);
Expand Down Expand Up @@ -1559,8 +1661,6 @@ public function testNewUserUpdateStruct()
* @see \eZ\Publish\API\Repository\UserService::updateUser()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
*/
public function testUpdateUser()
{
Expand Down Expand Up @@ -1623,8 +1723,6 @@ public function testUpdateUserEmail(): void
* @see \eZ\Publish\API\Repository\UserService::updateUser()
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testCreateUser
* @depends eZ\Publish\API\Repository\Tests\UserServiceTest::testNewUserUpdateStruct
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContent
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testUpdateContentMetadata
*/
public function testUpdateUserNoPassword()
{
Expand Down Expand Up @@ -3031,7 +3129,7 @@ private function createUserContentTypeWithAccountSettings(

$typeCreate->addFieldDefinition($lastNameFieldCreate);

$accountFieldCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('account', 'ezuser');
$accountFieldCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('user_account', 'ezuser');
$accountFieldCreateStruct->names = [
'eng-GB' => 'User account',
];
Expand Down
Loading

0 comments on commit 52e9563

Please sign in to comment.