fix(technique) : cloisonner par site les sous-ressources prestataire + RG-3.04 fonction (ERP-134, ERP-135)
Les operations Get/Patch/Delete des sous-ressources Contact/Adresse/RIB passaient par le provider Doctrine par defaut (non cloisonne), et le POST resolvait le parent sans controle de scope : un user cloisonne pouvait lire/editer/supprimer une sous-ressource d'un prestataire hors de son site (IBAN/BIC du RIB inclus). SiteScopedQueryExtension ne filtre que les SiteAwareInterface, que ces entites ne sont pas. - ProviderSiteScopeChecker : decision de cloisonnement centralisee (source unique), consommee par ProviderProvider (refactore), le provider decore et les processors. - ProviderSubResourceItemProvider : decore le provider par defaut sur Get/Patch/Delete des 3 sous-ressources -> 404 si parent hors perimetre. - Garde assertInScope au POST dans les 3 processors -> 404 si parent hors perimetre. ProviderOwnedInterface sur les 3 entites. RG-3.04 : alignement code <-> spec (ligne 926). La Fonction (jobTitle) rend desormais un contact valide a elle seule : ajout au validateName, au CHECK chk_provider_contact_name et normalisation (normalizeText, vide -> null). Tests : ProviderSubResourceSiteScopeTest (fuite cross-site, 7 cas) ; RG-3.04 jobTitle reecrit. Spec § 2.13 corrigee (l'heritage n'etait pas automatique). Suite back complete verte (685 tests).
This commit is contained in:
@@ -11,6 +11,7 @@ use ApiPlatform\Metadata\Link;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use App\Module\Technique\Infrastructure\ApiPlatform\State\Processor\ProviderRibProcessor;
|
||||
use App\Module\Technique\Infrastructure\ApiPlatform\State\Provider\ProviderSubResourceItemProvider;
|
||||
use App\Shared\Domain\Attribute\Auditable;
|
||||
use App\Shared\Domain\Contract\BlamableInterface;
|
||||
use App\Shared\Domain\Contract\TimestampableInterface;
|
||||
@@ -49,6 +50,8 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
new Get(
|
||||
security: "is_granted('technique.providers.accounting.view')",
|
||||
normalizationContext: ['groups' => ['provider:read:accounting']],
|
||||
// Cloisonnement par site du prestataire parent (§ 2.13) : 404 hors perimetre.
|
||||
provider: ProviderSubResourceItemProvider::class,
|
||||
),
|
||||
new Post(
|
||||
uriTemplate: '/providers/{providerId}/ribs',
|
||||
@@ -69,10 +72,12 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
security: "is_granted('technique.providers.accounting.manage')",
|
||||
normalizationContext: ['groups' => ['provider:read:accounting']],
|
||||
denormalizationContext: ['groups' => ['provider:write:accounting']],
|
||||
provider: ProviderSubResourceItemProvider::class,
|
||||
processor: ProviderRibProcessor::class,
|
||||
),
|
||||
new Delete(
|
||||
security: "is_granted('technique.providers.accounting.manage')",
|
||||
provider: ProviderSubResourceItemProvider::class,
|
||||
processor: ProviderRibProcessor::class,
|
||||
),
|
||||
],
|
||||
@@ -81,7 +86,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
#[ORM\Table(name: 'provider_rib')]
|
||||
#[ORM\Index(name: 'idx_provider_rib_provider', columns: ['provider_id'])]
|
||||
#[Auditable]
|
||||
class ProviderRib implements TimestampableInterface, BlamableInterface
|
||||
class ProviderRib implements TimestampableInterface, BlamableInterface, ProviderOwnedInterface
|
||||
{
|
||||
use TimestampableBlamableTrait;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user