Skip to content

Commit

Permalink
BAP-14473: New system calendar doesn't appear on grid (#16930)
Browse files Browse the repository at this point in the history
  • Loading branch information
yurio authored and vsoroka committed Feb 26, 2018
1 parent 0773a95 commit 3269591
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 22 deletions.
25 changes: 25 additions & 0 deletions Controller/SystemCalendarController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
use Oro\Bundle\CalendarBundle\Entity\SystemCalendar;
use Oro\Bundle\CalendarBundle\Provider\SystemCalendarConfig;

/**
* System calendar controller.
*/
class SystemCalendarController extends Controller
{
/**
Expand Down Expand Up @@ -43,6 +46,14 @@ public function indexAction()
public function viewAction(SystemCalendar $entity)
{
$this->checkPermissionByConfig($entity);
$this->checkSystemCalendarEntityAccess($entity);

$isGranted = $entity->isPublic()
? $this->isGranted('oro_public_calendar_management')
: $this->isGranted('oro_system_calendar_management');
if (!$isGranted) {
throw new AccessDeniedException();
}

return [
'entity' => $entity,
Expand All @@ -60,6 +71,7 @@ public function viewAction(SystemCalendar $entity)
&& $this->getCalendarConfig()->isSystemCalendarEnabled()
];
}

/**
* @Route("/create", name="oro_system_calendar_create")
* @Template("OroCalendarBundle:SystemCalendar:update.html.twig")
Expand Down Expand Up @@ -90,6 +102,7 @@ public function createAction()
public function updateAction(SystemCalendar $entity)
{
$this->checkPermissionByConfig($entity);
$this->checkSystemCalendarEntityAccess($entity);

$isGranted = $entity->isPublic()
? $this->isGranted('oro_public_calendar_management')
Expand All @@ -111,6 +124,7 @@ public function updateAction(SystemCalendar $entity)
public function eventsAction(SystemCalendar $entity)
{
$this->checkPermissionByConfig($entity);
$this->checkSystemCalendarEntityAccess($entity);

if (!$entity->isPublic() && !$this->isGranted('oro_system_calendar_management')) {
// an user must have permissions to view system calendar
Expand Down Expand Up @@ -177,4 +191,15 @@ protected function getCalendarConfig()
{
return $this->get('oro_calendar.system_calendar_config');
}

/**
* @param SystemCalendar $entity
*/
private function checkSystemCalendarEntityAccess(SystemCalendar $entity)
{
if (!$entity->isPublic()
&& $entity->getOrganization()->getId() !== $this->get('oro_security.token_accessor')->getOrganizationId()) {
throw new AccessDeniedException();
}
}
}
50 changes: 29 additions & 21 deletions EventListener/EntityListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
use Oro\Bundle\SecurityBundle\Authentication\TokenAccessorInterface;
use Oro\Bundle\UserBundle\Entity\User;

/**
* Calendar entities listener. Checks organization column for SystemCalendar entities, creates new calendar
* on user creation, updates 'calculatedEndTime' field value for Recurrence calendar events.
*/
class EntityListener
{
/** @var TokenAccessorInterface */
Expand Down Expand Up @@ -50,34 +54,15 @@ public function __construct(TokenAccessorInterface $tokenAccessor, Recurrence $r
*/
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof SystemCalendar) {
if ($entity->isPublic()) {
// make sure that public calendar doesn't belong to any organization
$entity->setOrganization(null);
} elseif (!$entity->getOrganization()) {
// make sure an organization is set for system calendar
$organization = $this->tokenAccessor->getOrganization();
if ($organization) {
$entity->setOrganization($organization);
}
}
}

if ($entity instanceof RecurrenceEntity) {
$entity->setCalculatedEndTime($this->recurrenceModel->getCalculatedEndTime($entity));
}
$this->processEntity($args->getEntity());
}

/**
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof RecurrenceEntity) {
$entity->setCalculatedEndTime($this->recurrenceModel->getCalculatedEndTime($entity));
}
$this->processEntity($args->getEntity());
}

/**
Expand Down Expand Up @@ -194,4 +179,27 @@ protected function getClassMetadata($entity, EntityManager $em)

return $this->metadataLocalCache[$className];
}

/**
* @param object $entity
*/
protected function processEntity($entity)
{
if ($entity instanceof SystemCalendar) {
if ($entity->isPublic()) {
// make sure that public calendar doesn't belong to any organization
$entity->setOrganization(null);
} elseif (!$entity->getOrganization()) {
// make sure an organization is set for system calendar
$organization = $this->tokenAccessor->getOrganization();
if ($organization) {
$entity->setOrganization($organization);
}
}
}

if ($entity instanceof RecurrenceEntity) {
$entity->setCalculatedEndTime($this->recurrenceModel->getCalculatedEndTime($entity));
}
}
}
19 changes: 18 additions & 1 deletion Handler/SystemCalendarDeleteHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@

use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

use Oro\Bundle\SecurityBundle\Authentication\TokenAccessorInterface;
use Oro\Bundle\SecurityBundle\Exception\ForbiddenException;
use Oro\Bundle\SoapBundle\Handler\DeleteHandler;
use Oro\Bundle\CalendarBundle\Provider\SystemCalendarConfig;

/**
* Delete handler for SystemCalendar entities.
*/
class SystemCalendarDeleteHandler extends DeleteHandler
{
/** @var SystemCalendarConfig */
Expand All @@ -18,6 +22,9 @@ class SystemCalendarDeleteHandler extends DeleteHandler
/** @var AuthorizationCheckerInterface */
protected $authorizationChecker;

/** @var TokenAccessorInterface */
private $tokenAccessor;

/**
* @param SystemCalendarConfig $calendarConfig
*/
Expand All @@ -34,6 +41,14 @@ public function setAuthorizationChecker(AuthorizationCheckerInterface $authoriza
$this->authorizationChecker = $authorizationChecker;
}

/**
* @param TokenAccessorInterface $tokenAccessor
*/
public function setTokenAccessor(TokenAccessorInterface $tokenAccessor)
{
$this->tokenAccessor = $tokenAccessor;
}

/**
* {@inheritdoc}
*/
Expand All @@ -48,7 +63,9 @@ protected function checkPermissions($entity, ObjectManager $em)
} else {
if (!$this->calendarConfig->isSystemCalendarEnabled()) {
throw new ForbiddenException('System calendars are disabled.');
} elseif (!$this->authorizationChecker->isGranted('oro_system_calendar_management')) {
} elseif (!$this->authorizationChecker->isGranted('oro_system_calendar_management')
|| $entity->getOrganization()->getId() !== $this->tokenAccessor->getOrganizationId()
) {
throw new ForbiddenException('Access denied.');
}
}
Expand Down
1 change: 1 addition & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ services:
calls:
- [setCalendarConfig, ['@oro_calendar.system_calendar_config']]
- [setAuthorizationChecker, ['@security.authorization_checker']]
- [setTokenAccessor, ['@oro_security.token_accessor']]

oro_calendar.calendar_event.handler.delete:
class: %oro_calendar.calendar_event.handler.delete.class%
Expand Down
30 changes: 30 additions & 0 deletions Tests/Unit/EventListener/EntityListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,34 @@ protected function getPersistentCollection($owner, array $mapping, array $items

return $coll;
}

public function testPrePersistPublicCalendar()
{
$entity = new SystemCalendar();
$entity->setOrganization(new Organization());
$this->assertNotNull($entity->getOrganization());

$args = new LifecycleEventArgs($entity, $this->em);

$entity->setPublic(true);
$this->listener->prePersist($args);
$this->assertNull($entity->getOrganization());
}

public function testPrePersistSystemCalendar()
{
$organization = new Organization();

$entity = new SystemCalendar();
$this->assertNull($entity->getOrganization());

$args = new LifecycleEventArgs($entity, $this->em);

$this->tokenAccessor->expects($this->once())
->method('getOrganization')
->will($this->returnValue($organization));

$this->listener->prePersist($args);
$this->assertSame($organization, $entity->getOrganization());
}
}
36 changes: 36 additions & 0 deletions Tests/Unit/Handler/SystemCalendarDeleteHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use Oro\Bundle\CalendarBundle\Entity\SystemCalendar;
use Oro\Bundle\CalendarBundle\Handler\SystemCalendarDeleteHandler;
use Oro\Bundle\OrganizationBundle\Entity\Organization;
use Oro\Bundle\SecurityBundle\Authentication\TokenAccessorInterface;

class SystemCalendarDeleteHandlerTest extends \PHPUnit_Framework_TestCase
{
Expand All @@ -18,6 +20,9 @@ class SystemCalendarDeleteHandlerTest extends \PHPUnit_Framework_TestCase
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $manager;

/** @var \PHPUnit_Framework_MockObject_MockObject */
private $tokenAccessor;

/** @var SystemCalendarDeleteHandler */
protected $handler;

Expand All @@ -39,11 +44,13 @@ protected function setUp()
$ownerDeletionManager = $this->getMockBuilder('Oro\Bundle\OrganizationBundle\Ownership\OwnerDeletionManager')
->disableOriginalConstructor()
->getMock();
$this->tokenAccessor = $this->createMock(TokenAccessorInterface::class);

$this->handler = new SystemCalendarDeleteHandler();
$this->handler->setCalendarConfig($this->calendarConfig);
$this->handler->setAuthorizationChecker($this->authorizationChecker);
$this->handler->setOwnerDeletionManager($ownerDeletionManager);
$this->handler->setTokenAccessor($this->tokenAccessor);
}

/**
Expand Down Expand Up @@ -127,4 +134,33 @@ public function testHandleDeleteWhenSystemCalendarDeleteNotGranted()

$this->handler->handleDelete(1, $this->manager);
}

/**
* @expectedException \Oro\Bundle\SecurityBundle\Exception\ForbiddenException
* @expectedExceptionMessage Access denied.
*/
public function testHandleDeleteWhenSystemCalendarWasCreatedInAnotherOrganization()
{
$calendarOrganization = new Organization();
$calendarOrganization->setId(1);
$calendar = new SystemCalendar();
$calendar->setOrganization($calendarOrganization);

$this->tokenAccessor->expects($this->once())
->method('getOrganizationId')
->willReturn(2);

$this->manager->expects($this->once())
->method('find')
->will($this->returnValue($calendar));
$this->calendarConfig->expects($this->once())
->method('isSystemCalendarEnabled')
->will($this->returnValue(true));
$this->authorizationChecker->expects($this->once())
->method('isGranted')
->with('oro_system_calendar_management')
->will($this->returnValue(true));

$this->handler->handleDelete(1, $this->manager);
}
}

0 comments on commit 3269591

Please sign in to comment.