Skip to content

Commit

Permalink
updated user deleted status
Browse files Browse the repository at this point in the history
Signed-off-by: bidi <[email protected]>
  • Loading branch information
bidi47 committed Dec 10, 2024
1 parent 265058a commit 02f5877
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 50 deletions.
2 changes: 1 addition & 1 deletion data/doctrine/migrations/Version20241120160406.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE contact_message (uuid BINARY(16) NOT NULL, email VARCHAR(150) NOT NULL, name VARCHAR(150) NOT NULL, subject LONGTEXT NOT NULL, message LONGTEXT NOT NULL, platform LONGTEXT NOT NULL, created DATETIME NOT NULL, updated DATETIME DEFAULT NULL, PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('CREATE TABLE user (uuid BINARY(16) NOT NULL, identity VARCHAR(191) NOT NULL, password VARCHAR(191) NOT NULL, status ENUM(\'active\', \'pending\') DEFAULT \'pending\' NOT NULL, isDeleted TINYINT(1) NOT NULL, hash VARCHAR(64) NOT NULL, created DATETIME NOT NULL, updated DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_8D93D6496A95E9C4 (identity), UNIQUE INDEX UNIQ_8D93D649D1B862B8 (hash), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('CREATE TABLE user (uuid BINARY(16) NOT NULL, identity VARCHAR(191) NOT NULL, password VARCHAR(191) NOT NULL, status ENUM(\'active\', \'pending\', \'deleted\') DEFAULT \'pending\' NOT NULL, hash VARCHAR(64) NOT NULL, created DATETIME NOT NULL, updated DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_8D93D6496A95E9C4 (identity), UNIQUE INDEX UNIQ_8D93D649D1B862B8 (hash), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('CREATE TABLE user_roles (userUuid BINARY(16) NOT NULL, roleUuid BINARY(16) NOT NULL, INDEX IDX_54FCD59FD73087E9 (userUuid), INDEX IDX_54FCD59F88446210 (roleUuid), PRIMARY KEY(userUuid, roleUuid)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('CREATE TABLE user_avatar (uuid BINARY(16) NOT NULL, name VARCHAR(191) NOT NULL, created DATETIME NOT NULL, updated DATETIME DEFAULT NULL, userUuid BINARY(16) NOT NULL, UNIQUE INDEX UNIQ_73256912D73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('CREATE TABLE user_detail (uuid BINARY(16) NOT NULL, firstName VARCHAR(191) DEFAULT NULL, lastName VARCHAR(191) DEFAULT NULL, created DATETIME NOT NULL, updated DATETIME DEFAULT NULL, userUuid BINARY(16) NOT NULL, UNIQUE INDEX UNIQ_4B5464AED73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4');
Expand Down
2 changes: 1 addition & 1 deletion src/App/src/Middleware/RememberMeMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
$hash === $rememberUser->getRememberMeToken() &&
$rememberUser->getUserAgent() === $deviceType &&
$rememberUser->getExpireDate() > new DateTimeImmutable('now') &&
$user->getIsDeleted() === false
$user->isDeleted() === false
) {
$userIdentity = UserIdentity::fromEntity($user);
$this->authenticationService->getStorage()->write($userIdentity);
Expand Down
13 changes: 8 additions & 5 deletions src/User/src/Controller/AccountController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public function activateAction(): ResponseInterface
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
}

if ($user->isDeleted()) {
$this->messenger->addError(Message::ACCOUNT_NOT_FOUND, 'user-login');
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
}

if ($user->isActive()) {
$this->messenger->addError(Message::USER_ALREADY_ACTIVATED, 'user-login');
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
Expand Down Expand Up @@ -96,7 +101,7 @@ public function unregisterAction(): ResponseInterface
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
}

if ($user->getIsDeleted() === User::IS_DELETED_YES) {
if ($user->isDeleted()) {
$this->messenger->addError(Message::USER_ALREADY_DEACTIVATED, 'user-login');
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
}
Expand All @@ -107,7 +112,7 @@ public function unregisterAction(): ResponseInterface
}

try {
$this->userService->updateUser($user, ['isDeleted' => User::IS_DELETED_YES]);
$this->userService->deleteUser($user);
} catch (Exception $exception) {
$this->messenger->addError($exception->getMessage(), 'user-login');
return new RedirectResponse($this->router->generateUri('user', ['action' => 'login']));
Expand Down Expand Up @@ -423,10 +428,8 @@ public function deleteAccountAction(): ResponseInterface
if (RequestMethodInterface::METHOD_POST === $this->request->getMethod()) {
$form->setData($this->request->getParsedBody());
if ($form->isValid()) {
/** @var array $userData */
$userData = $form->getData();
try {
$this->userService->updateUser($user, $userData);
$this->userService->deleteUser($user);
$this->userService->deleteAvatar($user);
} catch (Exception $e) {
$this->messenger->addData('shouldRebind', true);
Expand Down
21 changes: 2 additions & 19 deletions src/User/src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ class User extends AbstractEntity implements UserInterface
#[ORM\Column(type: 'user_status_enum', options: ['default' => UserStatusEnum::Pending])]
protected UserStatusEnum $status = UserStatusEnum::Pending;

#[ORM\Column(name: 'isDeleted', type: 'boolean')]
protected bool $isDeleted = self::IS_DELETED_NO;

#[ORM\Column(name: 'hash', type: 'string', length: 64, unique: true, nullable: false)]
protected string $hash;

Expand Down Expand Up @@ -138,18 +135,6 @@ public function setStatus(UserStatusEnum $status): self
return $this;
}

public function getIsDeleted(): bool
{
return $this->isDeleted;
}

public function setIsDeleted(bool $isDeleted): self
{
$this->isDeleted = $isDeleted;

return $this;
}

public function getHash(): string
{
return $this->hash;
Expand Down Expand Up @@ -213,11 +198,9 @@ public function isPending(): bool
return $this->status === UserStatusEnum::Pending;
}

public function markAsDeleted(): self
public function isDeleted(): bool
{
$this->isDeleted = self::IS_DELETED_YES;

return $this;
return $this->status === UserStatusEnum::Deleted;
}

public function getName(): string
Expand Down
2 changes: 0 additions & 2 deletions src/User/src/Entity/UserInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ public function addRole(UserRole $role): UserInterface;

public function removeRole(UserRole $role): UserInterface;

public function getIsDeleted(): bool;

public function getArrayCopy(): array;

public function activate(): UserInterface;
Expand Down
1 change: 1 addition & 0 deletions src/User/src/Enum/UserStatusEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ enum UserStatusEnum: string
{
case Active = 'active';
case Pending = 'pending';
case Deleted = 'deleted';
}
2 changes: 1 addition & 1 deletion src/User/src/Form/ProfileDeleteForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function init(): void
'title' => 'Delete account',
],
'options' => [
'label' => 'I want to delete account',
'label' => 'I want to delete my account',
'use_hidden_element' => false,
'checked_value' => (string) User::IS_DELETED_YES,
'unchecked_value' => (string) User::IS_DELETED_NO,
Expand Down
17 changes: 14 additions & 3 deletions src/User/src/Repository/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Exception;
use Frontend\User\Entity\User;
use Frontend\User\Entity\UserRememberMe;
use Frontend\User\Enum\UserStatusEnum;
use Ramsey\Uuid\Uuid;

use function is_string;
Expand All @@ -36,6 +37,9 @@ public function findByUuid(string $uuid): ?User
->where("user.uuid = :uuid")
->setParameter('uuid', $uuid)
->setMaxResults(1);

//ignore deleted users
$qb->andWhere('user.status != :status')->setParameter('status', UserStatusEnum::Deleted);
return $qb->getQuery()->useQueryCache(true)->getOneOrNullResult();
}

Expand Down Expand Up @@ -72,7 +76,10 @@ public function findByResetPasswordHash(string $hash): ?User
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select(['user', 'resetPasswords'])->from(User::class, 'user')
->leftJoin('user.resetPasswords', 'resetPasswords')
->andWhere('resetPasswords.hash = :hash')->setParameter('hash', $hash);
->andWhere('resetPasswords.hash = :hash')
->setParameter('hash', $hash)
->andWhere('user.status != :deleted')
->setParameter('deleted', UserStatusEnum::Deleted);

return $qb->getQuery()->useQueryCache(true)->getSingleResult();
} catch (Exception) {
Expand All @@ -95,7 +102,9 @@ public function getRememberUser(string $token): ?UserRememberMe
$qb->select('user_remember_me')
->from(UserRememberMe::class, 'user_remember_me')
->where('user_remember_me.rememberMeToken = :token')
->setParameter('token', $token);
->setParameter('token', $token)
->andWhere('user.status != :deleted')
->setParameter('deleted', UserStatusEnum::Deleted);

return $qb->getQuery()->useQueryCache(true)->getOneOrNullResult();
}
Expand All @@ -111,7 +120,9 @@ public function findRememberMeUser(User $user, string $userAgent): ?UserRemember
->where('user_remember_me.user = :uuid')
->setParameter('uuid', $user->getUuid()->getBytes())
->andWhere('user_remember_me.userAgent = :userAgent')
->setParameter('userAgent', $userAgent);
->setParameter('userAgent', $userAgent)
->andWhere('user.status != :deleted')
->setParameter('deleted', UserStatusEnum::Deleted);

return $qb->getQuery()->useQueryCache(true)->getOneOrNullResult();
}
Expand Down
38 changes: 22 additions & 16 deletions src/User/src/Service/UserService.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,6 @@ public function updateUser(User $user, array $data = []): User
$user->setStatus($data['status']);
}

if (isset($data['isDeleted'])) {
$user->setIsDeleted((bool) $data['isDeleted']);

if ((bool) $data['isDeleted'] === true) {
// make user anonymous
$user->setIdentity(
sprintf('anonymous%s@%s', date('dmYHis'), $this->config['userAnonymizeAppend'])
);
$userDetails = $user->getDetail();
$userDetails->setFirstName('anonymous' . date('dmYHis'));
$userDetails->setLastName('anonymous' . date('dmYHis'));

$user->setDetail($userDetails);
}
}

if (isset($data['hash'])) {
$user->setHash($data['hash']);
}
Expand Down Expand Up @@ -189,6 +173,28 @@ public function updateUser(User $user, array $data = []): User
return $this->userRepository->saveUser($user);
}

public function deleteUser(User $user): User
{
$user->setStatus(UserStatusEnum::Deleted);

if ($user->isDeleted()) {
$placeholder = $this->getAnonymousPlaceholder();

// make user anonymous
$user
->setIdentity($placeholder . $this->config['userAnonymizeAppend'])
->getDetail()
->setFirstName($placeholder)
->setLastName($placeholder);
}
return $this->userRepository->saveUser($user);
}

private function getAnonymousPlaceholder(): string
{
return 'anonymous' . date('dmYHis');
}

protected function createAvatar(User $user, UploadedFile $uploadedFile): UserAvatar
{
$path = sprintf('%s/%s/', $this->config['uploads']['user']['path'], $user->getUuid()->toString());
Expand Down
2 changes: 2 additions & 0 deletions src/User/src/Service/UserServiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public function deleteExpiredRememberMeTokens(): void;

public function updateUser(User $user, array $data = []): UserInterface;

public function deleteUser(User $user): UserInterface;

public function deleteAvatar(User $user): void;

public function deleteAvatarFile(string $path): bool;
Expand Down
2 changes: 0 additions & 2 deletions test/Unit/App/Middleware/RememberMeMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public function testAutologin(): void

$user = (new User())
->setIdentity('[email protected]')
->setIsDeleted(false)
->activate();

$detail = (new UserDetail())
Expand Down Expand Up @@ -126,7 +125,6 @@ public function testAutologinExpired(): void

$user = (new User())
->setIdentity('[email protected]')
->setIsDeleted(false)
->activate();

$detail = (new UserDetail())
Expand Down

0 comments on commit 02f5877

Please sign in to comment.