Simplified UserService
This commit is contained in:
parent
f81fe6bb65
commit
29b173de65
3 changed files with 202 additions and 55 deletions
|
@ -5,9 +5,10 @@ class UserEditFormData implements \Szurubooru\IValidatable
|
||||||
{
|
{
|
||||||
public $userName;
|
public $userName;
|
||||||
public $email;
|
public $email;
|
||||||
public $accessRank;
|
|
||||||
public $password;
|
public $password;
|
||||||
|
public $accessRank;
|
||||||
public $avatarStyle;
|
public $avatarStyle;
|
||||||
|
public $avatarContent;
|
||||||
public $browsingSettings;
|
public $browsingSettings;
|
||||||
|
|
||||||
public function __construct($inputReader = null)
|
public function __construct($inputReader = null)
|
||||||
|
|
|
@ -78,25 +78,17 @@ class UserService
|
||||||
{
|
{
|
||||||
$formData->validate($this->validator);
|
$formData->validate($this->validator);
|
||||||
|
|
||||||
if ($formData->email and $this->userDao->getByEmail($formData->email))
|
|
||||||
throw new \DomainException('User with this e-mail already exists.');
|
|
||||||
|
|
||||||
if ($this->userDao->getByName($formData->userName))
|
|
||||||
throw new \DomainException('User with this name already exists.');
|
|
||||||
|
|
||||||
$user = new \Szurubooru\Entities\User();
|
$user = new \Szurubooru\Entities\User();
|
||||||
$user->name = $formData->userName;
|
$user->registrationTime = $this->timeService->getCurrentTime();
|
||||||
$user->emailUnconfirmed = $formData->email;
|
$user->lastLoginTime = null;
|
||||||
$user->passwordHash = $this->passwordService->getHash($formData->password);
|
|
||||||
$user->accessRank = $this->userDao->hasAnyUsers()
|
$user->accessRank = $this->userDao->hasAnyUsers()
|
||||||
? \Szurubooru\Entities\User::ACCESS_RANK_REGULAR_USER
|
? \Szurubooru\Entities\User::ACCESS_RANK_REGULAR_USER
|
||||||
: \Szurubooru\Entities\User::ACCESS_RANK_ADMINISTRATOR;
|
: \Szurubooru\Entities\User::ACCESS_RANK_ADMINISTRATOR;
|
||||||
$user->registrationTime = $this->timeService->getCurrentTime();
|
|
||||||
$user->lastLoginTime = null;
|
|
||||||
$user->avatarStyle = \Szurubooru\Entities\User::AVATAR_STYLE_GRAVATAR;
|
|
||||||
|
|
||||||
$user = $this->sendActivationEmailIfNeeded($user);
|
|
||||||
|
|
||||||
|
$this->updateUserName($user, $formData->userName);
|
||||||
|
$this->updateUserPassword($user, $formData->password);
|
||||||
|
$this->updateUserAvatarStyle($user, \Szurubooru\Entities\User::AVATAR_STYLE_GRAVATAR);
|
||||||
|
$this->updateUserEmail($user, $formData->email);
|
||||||
return $this->userDao->save($user);
|
return $this->userDao->save($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,51 +98,79 @@ class UserService
|
||||||
|
|
||||||
if ($formData->avatarStyle !== null)
|
if ($formData->avatarStyle !== null)
|
||||||
{
|
{
|
||||||
$user->avatarStyle = \Szurubooru\Helpers\EnumHelper::avatarStyleFromString($formData->avatarStyle);
|
$this->updateUserAvatarStyle(
|
||||||
if ($formData->avatarContent)
|
$user,
|
||||||
{
|
\Szurubooru\Helpers\EnumHelper::avatarStyleFromString($formData->avatarStyle));
|
||||||
$target = $this->getCustomAvatarSourcePath($user);
|
|
||||||
$this->fileService->saveFromBase64($formData->avatarContent, $target);
|
|
||||||
$this->thumbnailService->deleteUsedThumbnails($target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($formData->userName !== null and $formData->userName !== $user->name)
|
if ($formData->avatarContent !== null)
|
||||||
{
|
$this->updateUserAvatarContent($user, $formData->avatarContent);
|
||||||
$userWithThisEmail = $this->userDao->getByName($formData->userName);
|
|
||||||
if ($userWithThisEmail and $userWithThisEmail->id !== $user->id)
|
|
||||||
throw new \DomainException('User with this name already exists.');
|
|
||||||
|
|
||||||
$user->name = $formData->userName;
|
if ($formData->userName !== null)
|
||||||
}
|
$this->updateUserName($user, $formData->userName);
|
||||||
|
|
||||||
if ($formData->password !== null)
|
if ($formData->password !== null)
|
||||||
{
|
$this->updateUserPassword($user, $formData->password);
|
||||||
$user->passwordHash = $this->passwordService->getHash($formData->password);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($formData->email !== null and $formData->email !== $user->email)
|
if ($formData->email !== null)
|
||||||
{
|
$this->updateUserEmail($user, $formData->email);
|
||||||
if ($this->userDao->getByEmail($formData->email))
|
|
||||||
throw new \DomainException('User with this e-mail already exists.');
|
|
||||||
|
|
||||||
$user->emailUnconfirmed = $formData->email;
|
|
||||||
$user = $this->sendActivationEmailIfNeeded($user);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($formData->accessRank !== null)
|
if ($formData->accessRank !== null)
|
||||||
{
|
$this->updateUserAccessRank($user, \Szurubooru\Helpers\EnumHelper::accessRankFromString($formData->accessRank));
|
||||||
$user->accessRank = \Szurubooru\Helpers\EnumHelper::accessRankFromString($formData->accessRank);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($formData->browsingSettings !== null)
|
if ($formData->browsingSettings !== null)
|
||||||
{
|
$this->updateUserBrowsingSettings($user, $formData->browsingSettings);
|
||||||
$user->browsingSettings = $formData->browsingSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->userDao->save($user);
|
return $this->userDao->save($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateUserAvatarStyle(\Szurubooru\Entities\User $user, $newAvatarStyle)
|
||||||
|
{
|
||||||
|
$user->avatarStyle = $newAvatarStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserAvatarContent(\Szurubooru\Entities\User $user, $newAvatarContentInBase64)
|
||||||
|
{
|
||||||
|
$target = $this->getCustomAvatarSourcePath($user);
|
||||||
|
$this->fileService->saveFromBase64($newAvatarContentInBase64, $target);
|
||||||
|
$this->thumbnailService->deleteUsedThumbnails($target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserName(\Szurubooru\Entities\User $user, $newName)
|
||||||
|
{
|
||||||
|
$this->assertNoUserWithThisName($user, $newName);
|
||||||
|
$user->name = $newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserPassword(\Szurubooru\Entities\User $user, $newPassword)
|
||||||
|
{
|
||||||
|
$user->passwordHash = $this->passwordService->getHash($newPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserEmail(\Szurubooru\Entities\User $user, $newEmail)
|
||||||
|
{
|
||||||
|
if ($user->email === $newEmail)
|
||||||
|
{
|
||||||
|
$user->emailUnconfirmed = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->assertNoUserWithThisEmail($user, $newEmail);
|
||||||
|
$user->emailUnconfirmed = $newEmail;
|
||||||
|
$user = $this->sendActivationEmailIfNeeded($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserAccessRank(\Szurubooru\Entities\User $user, $newAccessRank)
|
||||||
|
{
|
||||||
|
$user->accessRank = $newAccessRank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateUserBrowsingSettings(\Szurubooru\Entities\User $user, $newBrowsingSettings)
|
||||||
|
{
|
||||||
|
$user->browsingSettings = $newBrowsingSettings;
|
||||||
|
}
|
||||||
|
|
||||||
public function updateUserLastLoginTime(\Szurubooru\Entities\User $user)
|
public function updateUserLastLoginTime(\Szurubooru\Entities\User $user)
|
||||||
{
|
{
|
||||||
$user->lastLoginTime = $this->timeService->getCurrentTime();
|
$user->lastLoginTime = $this->timeService->getCurrentTime();
|
||||||
|
@ -235,11 +255,27 @@ class UserService
|
||||||
//5. two users share the same mail --> problem.
|
//5. two users share the same mail --> problem.
|
||||||
//by checking here again for users with such mail, this problem is solved with first-come first-serve approach:
|
//by checking here again for users with such mail, this problem is solved with first-come first-serve approach:
|
||||||
//whoever confirms e-mail first, wins.
|
//whoever confirms e-mail first, wins.
|
||||||
if ($this->userDao->getByEmail($user->emailUnconfirmed))
|
$this->assertNoUserWithThisEmail($user, $user->emailUnconfirmed);
|
||||||
throw new \DomainException('This e-mail was already confirmed by someone else in the meantime.');
|
|
||||||
|
|
||||||
|
if ($user->emailUnconfirmed)
|
||||||
|
{
|
||||||
$user->email = $user->emailUnconfirmed;
|
$user->email = $user->emailUnconfirmed;
|
||||||
$user->emailUnconfirmed = null;
|
$user->emailUnconfirmed = null;
|
||||||
|
}
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function assertNoUserWithThisName(\Szurubooru\Entities\User $owner, $nameToCheck)
|
||||||
|
{
|
||||||
|
$userWithThisName = $this->userDao->getByName($nameToCheck);
|
||||||
|
if ($userWithThisName and $userWithThisName->id !== $owner->id)
|
||||||
|
throw new \DomainException('User with this name already exists.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assertNoUserWithThisEmail(\Szurubooru\Entities\User $owner, $emailToCheck)
|
||||||
|
{
|
||||||
|
$userWithThisEmail = $this->userDao->getByEmail($emailToCheck);
|
||||||
|
if ($userWithThisEmail and $userWithThisEmail->id !== $owner->id)
|
||||||
|
throw new \DomainException('User with this e-mail already exists.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
|
|
||||||
public function testGettingByName()
|
public function testGettingByName()
|
||||||
{
|
{
|
||||||
$testUser = new \Szurubooru\Entities\User();
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
$testUser->name = 'godzilla';
|
$testUser->name = 'godzilla';
|
||||||
$this->userDaoMock->expects($this->once())->method('getByName')->willReturn($testUser);
|
$this->userDaoMock->expects($this->once())->method('getByName')->willReturn($testUser);
|
||||||
$userService = $this->getUserService();
|
$userService = $this->getUserService();
|
||||||
|
@ -49,7 +49,7 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
|
|
||||||
public function testGettingById()
|
public function testGettingById()
|
||||||
{
|
{
|
||||||
$testUser = new \Szurubooru\Entities\User();
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
$testUser->name = 'godzilla';
|
$testUser->name = 'godzilla';
|
||||||
$this->userDaoMock->expects($this->once())->method('getById')->willReturn($testUser);
|
$this->userDaoMock->expects($this->once())->method('getById')->willReturn($testUser);
|
||||||
$userService = $this->getUserService();
|
$userService = $this->getUserService();
|
||||||
|
@ -67,7 +67,7 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
|
|
||||||
public function testGettingFilteredUsers()
|
public function testGettingFilteredUsers()
|
||||||
{
|
{
|
||||||
$mockUser = new \Szurubooru\Entities\User();
|
$mockUser = new \Szurubooru\Entities\User;
|
||||||
$mockUser->name = 'user';
|
$mockUser->name = 'user';
|
||||||
$expected = [$mockUser];
|
$expected = [$mockUser];
|
||||||
$this->userSearchService->method('getFiltered')->willReturn($expected);
|
$this->userSearchService->method('getFiltered')->willReturn($expected);
|
||||||
|
@ -121,7 +121,7 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
$this->userDaoMock->method('hasAnyUsers')->willReturn(true);
|
$this->userDaoMock->method('hasAnyUsers')->willReturn(true);
|
||||||
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
$testToken = new \Szurubooru\Entities\Token();
|
$testToken = new \Szurubooru\Entities\Token;
|
||||||
$this->tokenServiceMock->expects($this->once())->method('createAndSaveToken')->willReturn($testToken);
|
$this->tokenServiceMock->expects($this->once())->method('createAndSaveToken')->willReturn($testToken);
|
||||||
$this->emailServiceMock->expects($this->once())->method('sendActivationEmail')->with(
|
$this->emailServiceMock->expects($this->once())->method('sendActivationEmail')->with(
|
||||||
$this->anything(),
|
$this->anything(),
|
||||||
|
@ -162,8 +162,11 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
$formData->password = 'password';
|
$formData->password = 'password';
|
||||||
$formData->email = 'email';
|
$formData->email = 'email';
|
||||||
|
|
||||||
|
$otherUser = new \Szurubooru\Entities\User;
|
||||||
|
$otherUser->id = 'yes, i exist in database';
|
||||||
|
|
||||||
$this->userDaoMock->method('hasAnyUsers')->willReturn(true);
|
$this->userDaoMock->method('hasAnyUsers')->willReturn(true);
|
||||||
$this->userDaoMock->method('getByName')->willReturn(new \Szurubooru\Entities\User());
|
$this->userDaoMock->method('getByName')->willReturn($otherUser);
|
||||||
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
$userService = $this->getUserService();
|
$userService = $this->getUserService();
|
||||||
|
@ -172,6 +175,113 @@ final class UserServiceTest extends \Szurubooru\Tests\AbstractTestCase
|
||||||
$savedUser = $userService->createUser($formData);
|
$savedUser = $userService->createUser($formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUpdatingName()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$testUser->name = 'wojtek';
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->userName = 'sebastian';
|
||||||
|
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$savedUser = $userService->updateUser($testUser, $formData);
|
||||||
|
$this->assertEquals('sebastian', $savedUser->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdatingNameToExisting()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$testUser->name = 'wojtek';
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->userName = 'sebastian';
|
||||||
|
|
||||||
|
$otherUser = new \Szurubooru\Entities\User;
|
||||||
|
$otherUser->id = 'yes, i exist in database';
|
||||||
|
$this->userDaoMock->method('getByName')->willReturn($otherUser);
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$this->setExpectedException(\Exception::class, 'User with this name already exists');
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$savedUser = $userService->updateUser($testUser, $formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdatingEmailWithoutConfirmation()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$this->configMock->set('security/needEmailActivationToRegister', false);
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->email = 'hikari@geofront.gov';
|
||||||
|
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$savedUser = $userService->updateUser($testUser, $formData);
|
||||||
|
$this->assertEquals('hikari@geofront.gov', $savedUser->email);
|
||||||
|
$this->assertNull($savedUser->emailUnconfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdatingEmailWithConfirmation()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$this->configMock->set('security/needEmailActivationToRegister', true);
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->email = 'hikari@geofront.gov';
|
||||||
|
|
||||||
|
$this->tokenServiceMock->method('createAndSaveToken')->willReturn(new \Szurubooru\Entities\Token());
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$savedUser = $userService->updateUser($testUser, $formData);
|
||||||
|
$this->assertNull($savedUser->email);
|
||||||
|
$this->assertEquals('hikari@geofront.gov', $savedUser->emailUnconfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdatingEmailWithConfirmationToExisting()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$this->configMock->set('security/needEmailActivationToRegister', true);
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->email = 'hikari@geofront.gov';
|
||||||
|
|
||||||
|
$otherUser = new \Szurubooru\Entities\User;
|
||||||
|
$otherUser->id = 'yes, i exist in database';
|
||||||
|
$this->tokenServiceMock->method('createAndSaveToken')->willReturn(new \Szurubooru\Entities\Token());
|
||||||
|
$this->userDaoMock->method('getByEmail')->willReturn($otherUser);
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$this->setExpectedException(\Exception::class, 'User with this e-mail already exists');
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$userService->updateUser($testUser, $formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdatingEmailToAlreadyConfirmed()
|
||||||
|
{
|
||||||
|
$testUser = new \Szurubooru\Entities\User;
|
||||||
|
$testUser->email = 'hikari@geofront.gov';
|
||||||
|
$testUser->emailUnconfirmed = 'coolcat32@sakura.ne.jp';
|
||||||
|
$testUser->id = 5;
|
||||||
|
|
||||||
|
$formData = new \Szurubooru\FormData\UserEditFormData;
|
||||||
|
$formData->email = 'hikari@geofront.gov';
|
||||||
|
|
||||||
|
$otherUser = new \Szurubooru\Entities\User;
|
||||||
|
$otherUser->id = 5;
|
||||||
|
$this->tokenServiceMock->method('createAndSaveToken')->willReturn(new \Szurubooru\Entities\Token());
|
||||||
|
$this->userDaoMock->method('getByEmail')->willReturn($otherUser);
|
||||||
|
$this->userDaoMock->method('save')->will($this->returnArgument(0));
|
||||||
|
|
||||||
|
$userService = $this->getUserService();
|
||||||
|
$savedUser = $userService->updateUser($testUser, $formData);
|
||||||
|
$this->assertEquals('hikari@geofront.gov', $savedUser->email);
|
||||||
|
$this->assertNull($savedUser->emailUnconfirmed);
|
||||||
|
}
|
||||||
|
|
||||||
private function getUserService()
|
private function getUserService()
|
||||||
{
|
{
|
||||||
return new \Szurubooru\Services\UserService(
|
return new \Szurubooru\Services\UserService(
|
||||||
|
|
Loading…
Reference in a new issue