[#321] Gestion des rôles dans l'application (#2)
All checks were successful
Auto Tag Develop / tag (push) Successful in 6s

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|        #321          |        Gestion des rôles dans l'application         |

## Description de la PR
[#321] Gestion des rôles dans l'application

## Modification du .env

## Check list

- [x] Pas de régression
- [ ] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [ ] CHANGELOG modifié

Reviewed-on: #2
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #2.
This commit is contained in:
2026-02-16 07:19:05 +00:00
committed by Autin
parent 4845230429
commit 76f1363457
19 changed files with 965 additions and 40 deletions

View File

@@ -20,7 +20,9 @@ use Symfony\Component\Serializer\Attribute\Groups;
],
denormalizationContext: [
'datetime_format' => 'Y-m-d',
]
],
paginationEnabled: false,
security: "is_granted('ROLE_ADMIN')",
)]
#[ApiFilter(DateFilter::class, properties: ['startDate', 'endDate'])]
#[ApiFilter(SearchFilter::class, properties: ['employee.site' => 'exact'])]

View File

@@ -8,7 +8,11 @@ use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(normalizationContext: ['groups' => ['absence_type:read']])]
#[ApiResource(
normalizationContext: ['groups' => ['absence_type:read']],
paginationEnabled: false,
security: "is_granted('ROLE_ADMIN')"
)]
#[ORM\Entity]
#[ORM\Table(name: 'absence_types')]
class AbsenceType

View File

@@ -11,7 +11,9 @@ use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
normalizationContext: ['groups' => ['employee:read', 'site:read']],
denormalizationContext: ['groups' => ['employee:write']]
denormalizationContext: ['groups' => ['employee:write']],
paginationEnabled: false,
security: "is_granted('ROLE_ADMIN')"
)]
#[ORM\Entity]
#[ORM\Table(name: 'employees')]

View File

@@ -8,7 +8,11 @@ use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(normalizationContext: ['groups' => ['site:read']])]
#[ApiResource(
normalizationContext: ['groups' => ['site:read']],
paginationEnabled: false,
security: "is_granted('ROLE_ADMIN')"
)]
#[ORM\Entity]
#[ORM\Table(name: 'sites')]
class Site

View File

@@ -4,12 +4,20 @@ declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\State\CurrentUserProvider;
use App\State\UserPasswordHasherProcessor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
@@ -19,6 +27,29 @@ use Symfony\Component\Security\Core\User\UserInterface;
security: "is_granted('ROLE_USER')",
provider: CurrentUserProvider::class
),
new GetCollection(
normalizationContext: ['groups' => ['user:read', 'employee:read', 'site:read']],
security: "is_granted('ROLE_ADMIN')"
),
new Get(
uriTemplate: '/users/{id}',
normalizationContext: ['groups' => ['user:read', 'employee:read', 'site:read']],
security: "is_granted('ROLE_ADMIN')"
),
new Post(
denormalizationContext: ['groups' => ['user:write']],
normalizationContext: ['groups' => ['user:read']],
security: "is_granted('ROLE_ADMIN')",
processor: UserPasswordHasherProcessor::class
),
new Patch(
uriTemplate: '/users/{id}',
paginationEnabled: false,
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']],
security: "is_granted('ROLE_ADMIN')",
processor: UserPasswordHasherProcessor::class
),
]
)]
#[ORM\Entity]
@@ -29,17 +60,40 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['user:read'])]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 180)]
#[Groups(['user:read', 'user:write'])]
private string $username = '';
#[ORM\Column(type: 'json')]
#[Groups(['user:write'])]
private array $roles = [];
#[ORM\Column(type: 'string')]
private string $password = '';
#[Groups(['user:write'])]
private string $plainPassword = '';
#[ApiProperty(readableLink: true)]
#[ORM\OneToOne(targetEntity: Employee::class)]
#[ORM\JoinColumn(nullable: true, unique: true)]
#[Groups(['user:read', 'user:write'])]
private ?Employee $employee = null;
/**
* @var Collection<int, UserSiteRole>
*/
#[ORM\OneToMany(mappedBy: 'user', targetEntity: UserSiteRole::class, orphanRemoval: true)]
private Collection $siteRoles;
public function __construct()
{
$this->siteRoles = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
@@ -65,6 +119,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
/**
* @return list<string>
*/
#[Groups(['user:read'])]
public function getRoles(): array
{
$roles = $this->roles;
@@ -95,5 +150,58 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
public function getPlainPassword(): string
{
return $this->plainPassword;
}
public function setPlainPassword(string $plainPassword): self
{
$this->plainPassword = $plainPassword;
return $this;
}
public function getEmployee(): ?Employee
{
return $this->employee;
}
public function setEmployee(?Employee $employee): self
{
$this->employee = $employee;
return $this;
}
/**
* @return Collection<int, UserSiteRole>
*/
public function getSiteRoles(): Collection
{
return $this->siteRoles;
}
public function addSiteRole(UserSiteRole $siteRole): self
{
if (!$this->siteRoles->contains($siteRole)) {
$this->siteRoles->add($siteRole);
$siteRole->setUser($this);
}
return $this;
}
public function removeSiteRole(UserSiteRole $siteRole): self
{
if ($this->siteRoles->removeElement($siteRole)) {
if ($siteRole->getUser() === $this) {
$siteRole->setUser(null);
}
}
return $this;
}
public function eraseCredentials(): void {}
}

101
src/Entity/UserSiteRole.php Normal file
View File

@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(
uriTemplate: '/user_site_roles',
normalizationContext: ['groups' => ['user_site_role:read', 'site:read', 'user:read']],
security: "is_granted('ROLE_ADMIN')"
),
new Post(
uriTemplate: '/user_site_roles',
denormalizationContext: ['groups' => ['user_site_role:write']],
security: "is_granted('ROLE_ADMIN')"
),
new Delete(
uriTemplate: '/user_site_roles/{id}',
security: "is_granted('ROLE_ADMIN')"
),
],
paginationEnabled: false,
)]
#[ORM\Entity()]
#[ORM\Table(name: 'user_site_roles')]
#[ORM\UniqueConstraint(name: 'uniq_user_site_role', fields: ['user', 'site', 'role'])]
class UserSiteRole
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['user_site_role:read'])]
private ?int $id = null;
#[ApiProperty(readableLink: true)]
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'siteRoles')]
#[ORM\JoinColumn(nullable: false)]
#[Groups(['user_site_role:read', 'user_site_role:write'])]
private ?User $user = null;
#[ApiProperty(readableLink: true)]
#[ORM\ManyToOne(targetEntity: Site::class)]
#[ORM\JoinColumn(nullable: false)]
#[Groups(['user_site_role:read', 'user_site_role:write'])]
private ?Site $site = null;
#[ORM\Column(type: 'string', length: 50)]
#[Groups(['user_site_role:read', 'user_site_role:write'])]
private string $role = '';
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getSite(): ?Site
{
return $this->site;
}
public function setSite(?Site $site): self
{
$this->site = $site;
return $this;
}
public function getRole(): string
{
return $this->role;
}
public function setRole(string $role): self
{
$this->role = $role;
return $this;
}
}