Symfony4 根据与用户关联的实体中的权限访问站点

Symfony4 Access to the site based on permissions in the entity associated with the User

我对 Symfony Voters 有疑问。 我有实体 UserPermissionList,它看起来像这样:

class UserPermissionList {

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 */
private $name;

/**
 * @ORM\Column(type="string", length=50)
 */
private $path;

/**
 * @ORM\Column(type="smallint")
 */
private $view;

public function getId(): ?int {
    return $this->id;
}

public function getName(): ?string {
    return $this->name;
}

public function setName(string $name): self {
    $this->name = $name;

    return $this;
}

/**
 * @return mixed
 */
public function getPath() {
    return $this->path;
}

/**
 * @param mixed $path
 */
public function setPath($path): void {
    $this->path = $path;
}

/**
 * @return mixed
 */
public function getView() {
    return $this->view;
}

/**
 * @param mixed $view
 */
public function setView($view): void {
    $this->view = $view;
}
}

路径 属性 是特定路线的实际路径,例如:/desktop 或 /mobile

我的用户实体看起来像这样:

class User implements UserInterface
{
public const ROLE_USER = 'ROLE_USER';

/**
 * @ORM\Id()
 * @ORM\GeneratedValue()
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\UserPermissionList")
 * @ORM\JoinTable(name="user_permisions")
 */
private $permissions;

public function __construct()
{
    $this->permissions = new ArrayCollection();
}

public function getId(): ?int
{
    return $this->id;
}

/**
 * @return Collection|UserPermissionList[]
 */
public function getPermissions(): Collection
{
    return $this->permissions;
}

public function addPermission(UserPermissionList $permission): self
{
    if (!$this->permissions->contains($permission)) {
        $this->permissions[] = $permission;
    }

    return $this;
}

public function removePermission(UserPermissionList $permission): self
{
    if ($this->permissions->contains($permission)) {
        $this->permissions->removeElement($permission);
    }

    return $this;
}}

现在,当用户与 UserPermissionList 中的特定权限相关时,我需要制定允许他访问此实体中指定的路由的逻辑。

例如。我有权限名称:桌面,路径:/dekstop 和视图:2(意味着权限只能在桌面设备上显示)。

只有在UserPermissionList中与此权限相关的用户才能访问页面/桌面。

我的选民应该是什么样子?

编辑。好吧,我做了这样的选民:

class ViewVoter extends Voter
{
/**
 * @var UserPermissionListRepository
 */
private $permissionListRepository;

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

protected function supports($attribute, $subject)
{
    $permissions = $this->permissionListRepository->findAll();
    $permissionList = [];

    foreach ($permissions as $permission) {
        $permissionList[] = $permission->getPath();
    }

    return in_array($attribute, $permissionList)
        && $subject instanceof User;
}

protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
    $permissions = $subject->getPermissions();
    $permissionList = [];

    foreach ($permissions as $permission) {
        $permissionList[] = $permission->getPath();
    }

    return in_array($attribute, $permissionList);
}
}

而且比在我的控制器中,例如在 DesktopController 我添加注释:

@Security("is_granted('/desktop', user)")