user delete (should work)

This commit is contained in:
overflowerror 2021-01-17 23:33:04 +01:00
parent 0471d4fd95
commit 106acf7aea
6 changed files with 131 additions and 3 deletions

View file

@ -47,4 +47,12 @@
.no-wrap { .no-wrap {
white-space: nowrap; white-space: nowrap;
}
.deleteToggle {
color: red;
}
.deleteToggle:disabled {
color: dimgrey;
} }

View file

@ -4,11 +4,15 @@
namespace App\Controller; namespace App\Controller;
use App\Mapper\CustomUuidMapper;
use App\Service\UserService; use App\Service\UserService;
use Doctrine\DBAL\Types\ConversionException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
@ -17,11 +21,18 @@ class UserController extends AbstractController
private const USER_RELATIVE = "../"; private const USER_RELATIVE = "../";
private const USER_DIRECTORY = "content/users/"; private const USER_DIRECTORY = "content/users/";
private $userService; public const DELETE_USER_CSRF_TOKEN_ID = "delete-user";
public function __construct(UserService $userService) private $userService;
private $uuidMapper;
public function __construct(
UserService $userService,
CustomUuidMapper $uuidMapper
)
{ {
$this->userService = $userService; $this->userService = $userService;
$this->uuidMapper = $uuidMapper;
} }
/** /**
@ -53,10 +64,55 @@ class UserController extends AbstractController
throw new AccessDeniedHttpException(); throw new AccessDeniedHttpException();
} }
$users = $this->userService->getUsers(); $users = array_map(function ($user) {
$user->setCustomId($this->uuidMapper->toString($user->getId()));
return $user;
}, $this->userService->getUsers());
return $this->render("user/users.html.twig", [ return $this->render("user/users.html.twig", [
"current" => $this->userService->getLoggedInUser(),
"users" => $users "users" => $users
]); ]);
} }
/**
* @Route("/admin/users/delete", name="app_user_delete")
*/
public function userDelete(Request $request): Response
{
if (!$this->isGranted("ROLE_ADMIN")) {
// not logged in
throw new AccessDeniedHttpException();
}
$token = $request->request->get("csrfToken");
$userId = $request->request->get("userId");
if (!$this->isCsrfTokenValid(self::DELETE_USER_CSRF_TOKEN_ID, $token)) {
throw new AccessDeniedHttpException();
}
if (!$userId) {
throw new BadRequestHttpException();
}
try {
$userId = $this->uuidMapper->fromString($userId);
} catch (ConversionException $e) {
throw new BadRequestHttpException();
}
$user = $this->userService->get($userId);
if ($user == null) {
throw new NotFoundHttpException();
}
if ($user == $this->userService->getLoggedInUser()) {
throw new BadRequestHttpException();
}
$this->userService->delete($user);
return $this->redirectToRoute("app_user_list");
}
} }

View file

@ -22,6 +22,7 @@ class User implements UserInterface
* @ORM\CustomIdGenerator(class=UuidGenerator::class) * @ORM\CustomIdGenerator(class=UuidGenerator::class)
*/ */
private $id; private $id;
private $customId;
/** /**
* @ORM\Column(type="string", length=180, unique=true) * @ORM\Column(type="string", length=180, unique=true)
@ -184,4 +185,15 @@ class User implements UserInterface
$this->email = $email; $this->email = $email;
return $this; return $this;
} }
public function getCustomId(): string
{
return $this->customId;
}
public function setCustomId(string $customId): self
{
$this->customId = $customId;
return $this;
}
} }

View file

@ -62,4 +62,9 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
->getQuery() ->getQuery()
->getOneOrNullResult(); ->getOneOrNullResult();
}*/ }*/
public function delete(User $user)
{
$this->_em->remove($user);
$this->_em->flush();
}
} }

View file

@ -6,6 +6,7 @@ namespace App\Service;
use App\Entity\User; use App\Entity\User;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
class UserService class UserService
@ -39,4 +40,14 @@ class UserService
{ {
return $this->userRepository->findOneByEmail($email); return $this->userRepository->findOneByEmail($email);
} }
public function delete($user)
{
$this->userRepository->delete($user);
}
public function get(UUIDInterface $userId)
{
return $this->userRepository->findOneById($userId);
}
} }

View file

@ -6,6 +6,7 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
{% set deleteCsrfToken = csrf_token(constant("App\\Controller\\UserController::DELETE_USER_CSRF_TOKEN_ID")) %}
<div class="users bg-light shadow-5"> <div class="users bg-light shadow-5">
<table class="table"> <table class="table">
<tr> <tr>
@ -23,6 +24,8 @@
<th> <th>
Roles Roles
</th> </th>
<th>
</th>
</tr> </tr>
{% for user in users %} {% for user in users %}
<tr> <tr>
@ -47,6 +50,39 @@
<div class="customChip">{{ role }}</div> <div class="customChip">{{ role }}</div>
{% endfor %} {% endfor %}
</td> </td>
<td>
<div class="btn-group" role="group">
<a class="btn btn-link" href="">
<i class="fas fa-cog"></i>
</a>
<form action="{{ path("app_user_delete") }}" method="POST">
<input type="hidden" name="userId" value="{{ user.customId }}">
<input type="hidden" name="csrfToken" value="{{ deleteCsrfToken }}">
<button class="btn btn-link dropdown-toggle deleteToggle"
id="-deleteDropDown"
data-mdb-toggle="dropdown"
aria-expanded="false"
onclick=""
{% if user.id == current.id %}
disabled
{% endif %}
>
<i class="fas fa-trash-alt"></i>
</button>
<div class="dropdown-menu dropdown-menu-end deleteConfirm"
id="-deleteDropDownMenu"
aria-labelledby="-deleteDropDown">
Do you really want to delete this user?<br/>
<button class="btn btn-link deleteButton">YES</button>
<button class="btn btn-primary" onclick="removeClass('show', [
'#-deleteDropDown',
'#-deleteDropDownMenu'
]); return false;">NO
</button>
</div>
</form>
</div>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>