From a9b0121e0fdd6568ead6fd7c4f625dbf7388dba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20=C5=A0pa=C4=8Dek?= Date: Wed, 15 May 2024 02:30:10 +0200 Subject: [PATCH] Authentication --- config/packages/security.yaml | 5 +- public/scripts/charts/donut_chart.js | 2 +- public/scripts/charts/stacked_chart.js | 2 +- src/Controller/UserController.php | 44 +++++++++++----- src/Document/Chart.php | 24 +++++++++ src/Document/User.php | 73 ++++++++++++++++++++++++-- templates/login.html.twig | 6 ++- 7 files changed, 135 insertions(+), 21 deletions(-) diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 367af25..bb1363d 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -22,8 +22,9 @@ security: # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: - # - { path: ^/admin, roles: ROLE_ADMIN } - # - { path: ^/profile, roles: ROLE_USER } + - { path: ^/admin, roles: ROLE_ADMIN } + role_hierarchy: + ROLE_ADMIN: ROLE_USER when@test: security: diff --git a/public/scripts/charts/donut_chart.js b/public/scripts/charts/donut_chart.js index 3b98148..99c12aa 100644 --- a/public/scripts/charts/donut_chart.js +++ b/public/scripts/charts/donut_chart.js @@ -1,7 +1,7 @@ /** * Donut Chart */ -class DonutChart extends Chart { +class DonutChart extends PieChart { /** * Creates a new instance of the DonutChart class * diff --git a/public/scripts/charts/stacked_chart.js b/public/scripts/charts/stacked_chart.js index d13d3c6..b500916 100644 --- a/public/scripts/charts/stacked_chart.js +++ b/public/scripts/charts/stacked_chart.js @@ -1,7 +1,7 @@ /** * Stacked Chart */ -class StackedChart extends Chart { +class StackedChart extends BarChart { /** * Creates a new instance of the StackedChart class * diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 192fb7c..038bc24 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -6,27 +6,24 @@ use App\Document\User; use App\Form\Type\UserType; use Doctrine\ODM\MongoDB\DocumentManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Redirect; use Symfony\Component\Routing\Annotation\Route; +#[Route(path: '/users', name: 'users_')] class UserController extends AbstractController { - #[Route('/register', name: 'register')] - public function registerAction(): Response - { - $form = $this->createForm(UserType::class, new User()); - return $this->render('register.html.twig', [ - 'form' => $form->createView() - ]); - } - - #[Route('/create', name: 'create')] - public function createAction(DocumentManager $dm, Request $request) + #[Route('/create', name: 'create', defaults: ['id' => null])] + #[Route('/{id}/edit', name: 'edit', requirements: ['id' => '\d+'])] + public function editAction(DocumentManager $dm, Request $request, User $user) { - $form = $this->createForm(UserType::class, new User()); + if ($user == null) + $user = new User(); + + $form = $this->createForm(UserType::class, $user); $form->handleRequest($request); @@ -43,4 +40,27 @@ class UserController extends AbstractController 'form' => $form->createView() ]); } + + #[Route('/login', name: 'login')] + public function login(AuthenticationUtils $authenticationUtils): Response + { + return $this->render('auth/login.html.twig', [ + 'last_username' => $authenticationUtils->getLastUsername(), + 'error' => $authenticationUtils->getLastAuthenticationError(), + ]); + } + + + /*#[Route('/{id}', name: 'detail', requirements: ['id' => '\d+'])] + public function detail(DocumentManager $dm, Request $request, User $user): Response + { + if ($user === null) + throw $this->createNotFoundException('Uživatel nenalezen!'); + + //$this->denyAccessUnlessGranted(UserVoter::VIEW, $user); + + return $this->render('users/detail.html.twig', [ + 'user' => $user, + ]); + }*/ } diff --git a/src/Document/Chart.php b/src/Document/Chart.php index 86eea11..faa9eb8 100644 --- a/src/Document/Chart.php +++ b/src/Document/Chart.php @@ -2,6 +2,7 @@ namespace App\Document; +use App\Document\User; use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; use Symfony\Component\Validator\Constraints as Assert; @@ -16,6 +17,9 @@ class Chart #[MongoDB\Id] protected string $id; + #[MongoDB\ReferenceOne(targetDocument: User::class, inversedBy: "charts")] + protected $user; + #[MongoDB\Field(type: 'string')] #[Assert\NotBlank] protected ?string $name = null; @@ -37,6 +41,26 @@ class Chart return $this->id; } + /** + * Get the user associated with the chart. + * + * @return User + */ + public function getUser(): ?User + { + return $this->user; + } + + /** + * Set the user associated with the chart. + * + * @param User $user The user to set + */ + public function setUser(?User $user): void + { + $this->user = $user; + } + public function getName(): ?string { return $this->name; diff --git a/src/Document/User.php b/src/Document/User.php index f1bd1cf..b138b47 100644 --- a/src/Document/User.php +++ b/src/Document/User.php @@ -2,13 +2,17 @@ namespace App\Document; +use App\Document\Chart; +use Doctrine\Common\Collections\Collection; use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique; +use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; use Symfony\Component\Validator\Constraints as Assert; #[MongoDB\Document(collection: 'users')] #[MongoDB\Unique(fields: 'email')] -class User +class User implements UserInterface, PasswordAuthenticatedUserInterface { /** * @MongoDB\Id @@ -25,6 +29,12 @@ class User #[Assert\NotBlank] protected ?string $password = null; + #[MongoDB\Field(type: 'collection')] + private array $roles = ['ROLE_USER']; + + #[MongoDB\ReferenceMany(targetDocument: Chart::class, mappedBy: "user")] + protected $charts; + public function getId(): string { return $this->id; @@ -45,9 +55,64 @@ class User return $this->password; } - // stupid simple encryption (please don't copy it!) - public function setPassword(?string $password): void + public function setPassword(string $password): static + { + $this->password = $password; + + return $this; + } + + /** + * @return Collection + */ + public function getCharts(): Collection + { + return $this->charts; + } + + /** + * Adds a chart to the user. + * + * @param Chart $chart The chart to add + */ + public function addChart(Chart $chart): void + { + // Check if the chart already exists in the collection + if (!$this->charts->contains($chart)) { + // Add the chart to the collection + $this->charts->add($chart); + // Set the user reference in the chart entity + $chart->setUser($this); + } + } + + public function getRoles(): array { - $this->password = sha1($password); + $roles = $this->roles; + // guarantee every user at least has ROLE_USER + $roles[] = 'ROLE_USER'; + + return array_unique($roles); + } + + public function setRoles(array $roles): self + { + $this->roles = $roles; + + return $this; + } + + + public function eraseCredentials(): void + { + // $this->password = null; + } + + + public function getUserIdentifier(): string + { + return $this->email; } + + } \ No newline at end of file diff --git a/templates/login.html.twig b/templates/login.html.twig index 216c33d..06af37a 100644 --- a/templates/login.html.twig +++ b/templates/login.html.twig @@ -8,7 +8,11 @@ {{ parent() }}
- + {{ form_start(form, {'action': path('create'), 'method': 'POST'}) }} + {{ form_widget(form) }} + + + {{ form_end(form) }}
{% endblock %} \ No newline at end of file