Here is my scenario:
I have an Article
entity. Each Article has an owner (a User
). A user can own many articles. The user can post an article over the API.
I want to have the user_id
column for the article set automatically based on the Bearer token (I am using JWT auth).
I cannot find any documentation anywhere on how to do this. Can someone please help with how to achieve this?
Note: I am looking for solutions that would avoid having to use additional extensions (or controllers) in Symfony, if possible. I believe Api Platform should be able to achieve this using built-in technology, but I could be wrong.
Here are my entities:
User:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ApiResource()
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity(fields="email", message="Email already taken")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $password
*
* @ORM\Column(type="string", length=64)
* @Assert\NotBlank()
*/
private $password;
/**
* @var string $plainPassword
*
* @Assert\NotBlank()
* @Assert\Length(max=4096)
*/
private $plainPassword;
/**
* @var string $email
*
* @ORM\Column(type="string", length=254, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
*/
private $email;
/**
* @var bool $isActive
*
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* @ORM\OneToMany(targetEntity="Article", mappedBy="user")
*/
private $articles;
/**
* @ORM\Column(type="array")
*/
private $roles;
public function __construct($email)
{
$this->isActive = true;
$this->email = $email;
$this->articles = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getUsername()
{
return $this->email;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
*
* @return $this
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* @return null|string
*/
public function getSalt()
{
return null;
}
/**
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* @param string $password
*
* @return $this
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* @return array
*/
public function getRoles()
{
return ['ROLE_USER'];
}
public function eraseCredentials()
{
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
));
}
/** @see \Serializable::unserialize()
* @param $serialized
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
) = unserialize($serialized, array('allowed_classes' => false));
}
}
Article
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* A User's article
*
* @ORM\Table(name="articles")
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* collectionOperations={
* "get",
* "post"={"access_control"="is_granted('ROLE_USER')"}
* },
* itemOperations={
* "get"={"access_control"="is_granted('ROLE_USER') and object.owner == user"}
* }
* )
* @ORM\Entity
* @ORM\HasLifecycleCallbacks()
*/
class Article
{
/**
* @var int $id
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var string $user
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="articles")
*/
private $user;
/**
* @var string $name
*
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $name;
/**
* @var string $location
*
* @ORM\Column(type="text")
*/
private $location;
/**
* @var \DateTimeInterface $createdAt
*
* @ORM\Column(type="datetime_immutable")
*/
private $createdAt;
/**
* @var \DateTimeInterface $updatedAt
*
* @ORM\Column(type="date_immutable", nullable=true)
*/
private $updatedAt;
/**
* @ORM\PrePersist()
*/
public function setCreatedAt()
{
$this->createdAt = new \DateTime();
}
/**
* @ORM\PreUpdate()
*/
public function setUpdatedAt()
{
$this->updatedAt = new \DateTime();
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* @return string
*/
public function getUser(): string
{
return $this->user;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* @return string
*/
public function getLocation(): string
{
return $this->location;
}
/**
* @param string $location
*/
public function setLocation(string $location): void
{
$this->location = $location;
}
}