Skip to content

Commit

Permalink
Merge pull request #179 from oat-sa/backport/AUT-778/moving-resources…
Browse files Browse the repository at this point in the history
…-inherit-acl

Backport/aut 778/moving resources inherit acl
  • Loading branch information
bartlomiejmarszal committed Jul 21, 2021
2 parents f60b3a6 + 2f93ccc commit 15b70ad
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 9 deletions.
4 changes: 3 additions & 1 deletion manifest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use oat\taoDacSimple\scripts\install\AttachEventHandler;
use oat\taoDacSimple\scripts\update\Updater;

/**
Expand Down Expand Up @@ -40,7 +41,8 @@
'install' => [
'php' => [
SetupDataAccess::class,
RegisterAction::class
RegisterAction::class,
AttachEventHandler::class
],
'rdf' => [
__DIR__ . '/model/ontology/dac.rdf',
Expand Down
50 changes: 50 additions & 0 deletions migrations/Version202107121456123210_taoDacSimple.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace oat\taoDacSimple\migrations;

use Doctrine\DBAL\Schema\Schema;
use oat\oatbox\event\EventManager;
use oat\tao\model\event\ResourceMovedEvent;
use oat\tao\scripts\tools\migrations\AbstractMigration;
use oat\taoDacSimple\model\eventHandler\ResourceUpdateHandler;

final class Version202107121456123210_taoDacSimple extends AbstractMigration
{

public function getDescription(): string
{
return 'Attach ResourceMovedEvent handler';
}

public function up(Schema $schema): void
{
/** @var EventManager $eventManager */
$eventManager = $this->getServiceLocator()->get(EventManager::SERVICE_ID);
$eventManager->attach(
ResourceMovedEvent::class,
[
ResourceUpdateHandler::class,
'catchResourceUpdated'
]

);
$this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);
}

public function down(Schema $schema): void
{
/** @var EventManager $eventManager */
$eventManager = $this->getServiceLocator()->get(EventManager::SERVICE_ID);
$eventManager->detach(
ResourceMovedEvent::class,
[
ResourceUpdateHandler::class,
'catchResourceUpdated'
]

);
$this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);
}
}
32 changes: 24 additions & 8 deletions model/PermissionsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,42 @@ public function __construct(
$this->eventManager = $eventManager;
}

public function savePermissions(
bool $isRecursive,
core_kernel_classes_Class $class,
public function saveResourcePermissionsRecursive(
core_kernel_classes_Resource $resource,
array $privilegesToSet
): void {
$currentPrivileges = $this->dataBaseAccess->getResourcePermissions($class->getUri());
):void {
$this->saveResourcePermissions($resource, $privilegesToSet, true);
}

private function saveResourcePermissions(
core_kernel_classes_Resource $resource,
array $privilegesToSet, bool $isRecursive
): void {
$currentPrivileges = $this->dataBaseAccess->getResourcePermissions($resource->getUri());
$addRemove = $this->strategy->normalizeRequest($currentPrivileges, $privilegesToSet);

if (empty($addRemove)) {
return;
}

$resourcesToUpdate = $this->getResourcesToUpdate($class, $isRecursive);
$resourcesToUpdate = $this->getResourcesToUpdate($resource, $isRecursive);
$permissionsList = $this->getResourcesPermissions($resourcesToUpdate);
$actions = $this->getActions($resourcesToUpdate, $permissionsList, $addRemove);

$this->dryRun($actions, $permissionsList);
$this->wetRun($actions);
$this->triggerEvents($addRemove, $class->getUri(), $isRecursive);
$this->triggerEvents($addRemove, $resource->getUri(), $isRecursive);
}

/**
* @deprecated use saveResourcePermissions
*/
public function savePermissions(
bool $isRecursive,
core_kernel_classes_Class $class,
array $privilegesToSet
): void {
$this->saveResourcePermissions($class, $privilegesToSet, $isRecursive);
}

private function getActions(array $resourcesToUpdate, array $permissionsList, array $addRemove): array
Expand Down Expand Up @@ -151,7 +167,7 @@ private function getResourcesToUpdate(core_kernel_classes_Resource $resource, bo
{
$resources = [$resource];

if ($isRecursive) {
if ($isRecursive && $resource->isClass()) {
return array_merge($resources, $resource->getSubClasses(true), $resource->getInstances(true));
}

Expand Down
61 changes: 61 additions & 0 deletions model/eventHandler/ResourceUpdateHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2021 (original work) Open Assessment Technologies SA;
*/

declare(strict_types=1);

namespace oat\taoDacSimple\model\eventHandler;

use Laminas\ServiceManager\ServiceLocatorAwareTrait;
use oat\oatbox\service\ConfigurableService;
use oat\tao\model\event\ResourceMovedEvent;
use oat\taoDacSimple\model\PermissionsService;
use oat\taoDacSimple\model\PermissionsServiceFactory;
use oat\taoDacSimple\model\RolePrivilegeRetriever;

class ResourceUpdateHandler extends ConfigurableService
{
use ServiceLocatorAwareTrait;

public function catchResourceUpdated(ResourceMovedEvent $event): void
{
$movedResource = $event->getMovedResource();

$rolePrivilegeList = $this->getRolePrivilegeRetriever()->retrieveByResourceIds([
$event->getDestinationClass()->getUri(),
$movedResource->getUri()
]);

$this->getPermissionService()->saveResourcePermissionsRecursive(
$movedResource,
$rolePrivilegeList
);
}


private function getRolePrivilegeRetriever(): RolePrivilegeRetriever
{
return $this->getServiceLocator()->get(RolePrivilegeRetriever::class);
}

private function getPermissionService(): PermissionsService
{
return $this->getServiceLocator()->get(PermissionsServiceFactory::class)->create();
}
}
46 changes: 46 additions & 0 deletions scripts/install/AttachEventHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2021 (original work) Open Assessment Technologies SA;
*/

declare(strict_types=1);

namespace oat\taoDacSimple\scripts\install;


use oat\oatbox\event\EventManager;
use oat\oatbox\extension\InstallAction;
use oat\tao\model\event\ResourceMovedEvent;
use oat\taoDacSimple\model\eventHandler\ResourceUpdateHandler;

class AttachEventHandler extends InstallAction
{
public function __invoke($params)
{
$eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID);
$eventManager->attach(
ResourceMovedEvent::class,
[
ResourceUpdateHandler::class,
'catchResourceUpdated'
]

);
$this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager);
}
}
137 changes: 137 additions & 0 deletions test/unit/model/eventHandler/ResourceUpdateHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2021 (original work) Open Assessment Technologies SA;
*/

declare(strict_types=1);

namespace oat\taoDacSimple\test\unit\model\eventHandler;

use core_kernel_classes_Class;
use core_kernel_classes_Resource;
use oat\generis\test\MockObject;
use oat\generis\test\TestCase;
use oat\tao\model\event\ResourceMovedEvent;
use oat\taoDacSimple\model\eventHandler\ResourceUpdateHandler;
use oat\taoDacSimple\model\PermissionsService;
use oat\taoDacSimple\model\PermissionsServiceFactory;
use oat\taoDacSimple\model\RolePrivilegeRetriever;

class ResourceUpdateHandlerTest extends TestCase
{
/** @var RolePrivilegeRetriever|MockObject */
private $rolePrivilegeRetriever;

/** @var PermissionsService|MockObject */
private $permissionsServiceMock;

/** @var PermissionsServiceFactory|MockObject */
private $permissionsServiceFactory;

/** @var ResourceMovedEvent|MockObject */
private $eventMock;

/** @var core_kernel_classes_Resource|MockObject */
private $resourceMock;

/** @var core_kernel_classes_Class|MockObject */
private $classMock;

/** @var ResourceUpdateHandler */
private $subject;

public function setUp(): void
{
$this->permissionsServiceMock = $this->createMock(PermissionsService::class);
$this->rolePrivilegeRetriever = $this->createMock(RolePrivilegeRetriever::class);
$this->permissionsServiceFactory = $this->createMock(PermissionsServiceFactory::class);
$this->eventMock = $this->createMock(ResourceMovedEvent::class);
$this->resourceMock = $this->createMock(core_kernel_classes_Resource::class);
$this->classMock = $this->createMock(core_kernel_classes_Class::class);

$this->permissionsServiceFactory
->method('create')
->willReturn($this->permissionsServiceMock);

$this->subject = new ResourceUpdateHandler();
$this->subject->setServiceLocator(
$this->getServiceLocatorMock(
[
RolePrivilegeRetriever::class => $this->rolePrivilegeRetriever,
PermissionsServiceFactory::class => $this->permissionsServiceFactory
]
)
);
}

public function testCatchResourceUpdated()
{
$this->eventMock
->method('getMovedResource')
->willReturn($this->resourceMock);

$this->resourceMock
->method('getUri')
->willReturn('resourceUri');

$this->eventMock
->method('getDestinationClass')
->willReturn($this->classMock);

$this->classMock
->method('getUri')
->willReturn('classUri');

$this->rolePrivilegeRetriever
->expects($this->once())
->method('retrieveByResourceIds')
->with(
[
'classUri',
'resourceUri'
]
)
->willReturn(
[
'http://www.tao.lu/Ontologies/TAO.rdf#BackOfficeRole' => [
'GRANT',
'READ',
'WRITE'
],
]
);

$this->permissionsServiceMock
->expects($this->once())
->method('saveResourcePermissions')
->with(
true,
$this->resourceMock,
[
'http://www.tao.lu/Ontologies/TAO.rdf#BackOfficeRole' => [
'GRANT',
'READ',
'WRITE'
],
]
);

$this->subject->catchResourceUpdated($this->eventMock);

}
}

0 comments on commit 15b70ad

Please sign in to comment.