Search code examples
symfonyfosrestbundlejmsserializerbundlesymfony-2.8

how to deserialize a POST body content into an Entity with @ExclusionPolicy("all") set


I'm using JMSSerializerBundle and FOSRestBundle and I'm trying to deserialize my body request by means of the @ParamConverter annotation:

/**
 * @View()
 *
 * @Route("/users/{username}/globaltoken", defaults={"_format" = "json"}, requirements={"user"="\w+"})
 * @ParamConverter(
 *     "userBody", class="Belka\AuthBundle\Entity\User",
 *     converter="fos_rest.request_body"
 * )
 */
public function postAction($username, User $userBody)
{
...

The User entity has @ExclusionPolicy("all") set and some attributes are @exposed. That's perfect when I serialize; unfortunatly, when it comes to deserializing my body into a User object the unexposed attribtues are not set. Is there a clean way to handle this?


Solution

  • Answering myself: @ExclusionPolicy(“all”) is not what you want for security purposes. That tag was born for handling data that should not be serialized, whether or not sometimes it should not appear for security reasons. It's a static thing and it's OK like that.

    What I really wanted is managing what to show or not (or consider for deserialization) by using groups. Hence:

    1. Declare some groups and assign on the attributes
    2. Use the desired groups in the controller: the deserialization and serialization will consider only the attributes belonging to at least one group declared.

    An example:

    * Entity *

    class User implements EncoderAwareInterface
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="string")
         * @Assert\NotBlank(message = "user.username.not_blank")
         * @ORM\GeneratedValue(strategy="NONE")
         * @Serializer\Groups({"default"})
         */
        private $username;
    
        /**
         * @ORM\Column(type="string", nullable=true)
         * @Serializer\Groups("personal")
         */
        private $password;
    
        ...
    

    * Controller *

    /**
     * @ParamConverter(
     *     "userBody",
     *     class="Belka\AuthBundle\Entity\User",
     *     converter="fos_rest.request_body",
     *     options={"deserializationContext"={"groups"={"personal"}}}
     * )
     */
    public function postAction($username, User $userBody, $_format)
    {
    

    that way, only password will be deserialized.