Skip to content

Limiting access to a property per operation using serialization groups does not work if the property can be set through a constructor parameter AND has a example value specified #2500

Open
@kalehmann

Description

@kalehmann

I faced a serious issue managing an entity with an immutable property using the api platform. By immutable I mean a property I can set once when I create the object with a POST request and not modify it again using PUT requests.

General steps to reproduce the problem

  1. Have an entity with a constructor parameter with the same name as the "immutable property"
  2. Have an "immutable property" that is not included in the serialization group used in the denormalization context of PUT requests
  3. Add the property to the resource config of the entity

Expected behavior

I cannot update the "immutable property" with a PUT request

Actual behavior

I can update the property with a PUT request

Example project

I provided an example project to reproduce this issue: https://github.com/kalehmann/api_test

My example entity has two properties:

  • a property named "immutable", that could only be set on the creating with a POST request and acts as the identifier of the entity
  • a property named "editable", that can be changed with PUT requests
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
*/
class Greeting
{
   /**
    * @var string
    *
    * @ORM\Id
    * @ORM\Column(type="string")
    *
    */
   private $immutable;

   /**
    * @var string A nice person
    *
    * @ORM\Column(type="string")
    */
   private $editable;

   public function __construct($immutable)
   {
       $this->immutable = $immutable;
   }

   /**
    * @return string
    */
   public function getImmutable()
   {
       return $this->immutable;
   }

   /**
    * @param string $immutable
    */
   public function setImmutable($immutable)
   {
       $this->immutable = $immutable;
   }

   /**
    * @return string
    */
   public function getEditable()
   {
       return $this->editable;
   }

   /**
    * @param string $editable
    */
   public function setEditable($editable)
   {
       $this->editable = $editable;
   }
}

I managed to implement this using serialization groups:

# api/config/serialization/greeting.yml
App\Entity\Greeting:
    attributes:
        immutable:
            groups: ['read', 'add']
        editable:
            groups: ['read', 'add', 'edit']

and assigned them to the corresponding operations in the config of the api platform:

# api/config/api_resources/resources.yml
App\Entity\Greeting:
    collectionOperations:
        get:
            method: 'GET'
        post:
            method: 'POST'
            denormalization_context:
                groups:
                    - 'add'
    attributes:
        normalization_context:
            groups:
                - 'read'
        denormalization_context:
            groups:
                - 'edit'

Until now everything works fine,I can create my entity, set its immutable property and can not update it with a PUT request. However when I want to provide an example value for the immutable property in the configuration of the api platform, I am able to update the immutable property with a PUT request.

# api/config/api_resources/resources.yml
App\Entity\Greeting:
    ...
    properties:
        immutable:
            attributes:
                swagger_context:
                    example: "immutable value"
        editable:
            attributes:
                swagger_context:
                    example: "editable value"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions