AclSecurityHandler.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. /*
  3. * This file is part of the Sonata project.
  4. *
  5. * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sonata\AdminBundle\Security\Handler;
  11. use Symfony\Component\Security\Core\SecurityContextInterface;
  12. use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
  13. use Symfony\Component\Security\Acl\Model\AclProviderInterface;
  14. use Symfony\Component\Security\Acl\Model\AclInterface;
  15. use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
  16. use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
  17. use Symfony\Component\Security\Acl\Permission\MaskBuilder;
  18. use Sonata\AdminBundle\Admin\AdminInterface;
  19. class AclSecurityHandler implements SecurityHandlerInterface
  20. {
  21. protected $securityContext;
  22. protected $aclProvider;
  23. protected $superAdminRoles;
  24. protected $adminPermissions;
  25. /**
  26. * @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext
  27. * @param array $superAdminRoles
  28. */
  29. public function __construct(SecurityContextInterface $securityContext, AclProviderInterface $aclProvider, array $superAdminRoles)
  30. {
  31. $this->securityContext = $securityContext;
  32. $this->aclProvider = $aclProvider;
  33. $this->superAdminRoles = $superAdminRoles;
  34. }
  35. /**
  36. * Set the permissions not related to an object instance and also to be available when objects do not exist
  37. *
  38. * @param array $permissions
  39. */
  40. public function setAdminPermissions(array $permissions)
  41. {
  42. $this->adminPermissions = $permissions;
  43. }
  44. /**
  45. * Return the permissions not related to an object instance and also to be available when objects do not exist
  46. *
  47. * @return array
  48. */
  49. public function getAdminPermissions()
  50. {
  51. return $this->adminPermissions;
  52. }
  53. /**
  54. * {@inheritDoc}
  55. */
  56. public function isGranted(AdminInterface $admin, $attributes, $object = null)
  57. {
  58. if (!is_array($attributes)) {
  59. $attributes = array($attributes);
  60. }
  61. try {
  62. return $this->securityContext->isGranted($this->superAdminRoles) || $this->securityContext->isGranted($attributes, $object);
  63. } catch (AuthenticationCredentialsNotFoundException $e) {
  64. return false;
  65. } catch (\Exception $e) {
  66. throw $e;
  67. }
  68. }
  69. /**
  70. * {@inheritDoc}
  71. */
  72. public function getBaseRole(AdminInterface $admin)
  73. {
  74. return 'ROLE_'.str_replace('.', '_', strtoupper($admin->getCode())).'_%s';
  75. }
  76. /**
  77. * {@inheritDoc}
  78. */
  79. public function buildSecurityInformation(AdminInterface $admin)
  80. {
  81. $baseRole = $this->getBaseRole($admin);
  82. $results = array();
  83. foreach ($admin->getSecurityInformation() as $role => $permissions) {
  84. $results[sprintf($baseRole, $role)] = $permissions;
  85. }
  86. return $results;
  87. }
  88. /**
  89. * {@inheritDoc}
  90. */
  91. public function createObjectOwner(AdminInterface $admin, $object)
  92. {
  93. $acl = $this->getNewObjectOwnerAcl($admin, $object);
  94. $this->updateAcl($acl);
  95. }
  96. /**
  97. * Get a new ACL with an object ACE where the currently logged in user is set as owner
  98. *
  99. * @param AdminInterface $admin
  100. * @param object $object
  101. * @return Symfony\Component\Security\Acl\Model\AclInterface
  102. */
  103. public function getNewObjectOwnerAcl(AdminInterface $admin, $object)
  104. {
  105. // creating the ACL, fe.
  106. // Comment 1 ACL
  107. $objectIdentity = ObjectIdentity::fromDomainObject($object);
  108. $acl = $this->aclProvider->createAcl($objectIdentity);
  109. // inherit class ACE's from the admin ACL, fe.
  110. // Comment admin ACL
  111. // - Comment 1 ACL
  112. $parentOid = ObjectIdentity::fromDomainObject($admin);
  113. $parentAcl = $this->aclProvider->findAcl($parentOid);
  114. $acl->setParentAcl($parentAcl);
  115. // retrieving the security identity of the currently logged-in user
  116. $user = $this->securityContext->getToken()->getUser();
  117. $securityIdentity = UserSecurityIdentity::fromAccount($user);
  118. // grant owner access
  119. $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
  120. return $acl;
  121. }
  122. /**
  123. * Update the ACL
  124. */
  125. public function updateAcl(AclInterface $acl)
  126. {
  127. $this->aclProvider->updateAcl($acl);
  128. }
  129. }