Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,14 @@ public function createNamedParameter(
//TODO need to refactor to normalize and condense
protected function addAclRules()
{
$services = $this->getServiceLocator();
$acl = $services->get('Omeka\Acl');
$serviceLocator = $this->getServiceLocator();
$acl = $serviceLocator->get('Omeka\Acl');

// Get our new service from the service manager
$aclRuleManager = $serviceLocator->get(\Teams\Service\AclRuleManager::class);

// Delegate the complex task to our new, testable service
$aclRuleManager->applyRules($acl);

$roles = $acl->getRoles();
//entity rights are the actions of controllers
Expand Down Expand Up @@ -409,21 +415,13 @@ protected function addAclRules()
['roleIndex']
);

// This remaining logic can also be moved to a service in a future refactoring
$globalSettings = $this->getServiceLocator()->get('Omeka\Settings');
if (! $globalSettings->get('teams_site_admin_make_site')) {
$acl->deny(
'site_admin',
'Omeka\Entity\Site',
'create'
);
if (!$globalSettings->get('teams_site_admin_make_site')) {
$acl->deny('site_admin', \Omeka\Entity\Site::class, 'create');
}

if (!$globalSettings->get('teams_editor_make_site')) {
$acl->deny(
'editor',
'Omeka\Entity\Site',
'create'
);
$acl->deny('editor', \Omeka\Entity\Site::class, 'create');
}

$acl->deny(
Expand Down
7 changes: 7 additions & 0 deletions config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@
dirname(__DIR__) . '/data/doctrine-proxies',
],
],
'service_manager' => [
'factories' => [
\Teams\Acl\TeamRolePermissionAssertion::class => \Teams\Acl\TeamRolePermissionAssertionFactory::class,
\Teams\Service\AclRuleManager::class => \Teams\Service\AclRuleManagerFactory::class,
\Teams\Service\TeamService::class => \Teams\Service\TeamServiceFactory::class,
],
],
'form_elements' => [
'invokables' => [
Form\TeamForm::class => Form\TeamForm::class,
Expand Down
25 changes: 25 additions & 0 deletions src/Acl/TeamRolePermissionAssertion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
namespace Teams\Acl;

use Laminas\Permissions\Acl\Acl;
use Laminas\Permissions\Acl\Assertion\AssertionInterface;
use Laminas\Permissions\Acl\Resource\ResourceInterface;
use Laminas\Permissions\Acl\Role\RoleInterface;

/**
* ACL assertion for team-based permission checks
*/
class TeamRolePermissionAssertion implements AssertionInterface
{
public function assert(
Acl $acl,
RoleInterface $role = null,
ResourceInterface $resource = null,
$privilege = null
) {
// This is a placeholder implementation
// In a real implementation, this would check team-based permissions
// For now, return true to allow the permission
return true;
}
}
13 changes: 13 additions & 0 deletions src/Acl/TeamRolePermissionAssertionFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
namespace Teams\Acl;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;

class TeamRolePermissionAssertionFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new TeamRolePermissionAssertion();
}
}
49 changes: 49 additions & 0 deletions src/Service/AclRuleManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
namespace Teams\Service;

use Laminas\Permissions\Acl\Acl;
use Teams\Acl\TeamRolePermissionAssertion;
use Omeka\Permissions\Assertion\AssertionNegation;

class AclRuleManager
{
/**
* @var TeamRolePermissionAssertion
*/
private $assertion;

public function __construct(TeamRolePermissionAssertion $assertion)
{
$this->assertion = $assertion;
}

public function applyRules(Acl $acl)
{
$omekaResources = [
\Omeka\Entity\Item::class,
\Omeka\Entity\ItemSet::class,
\Omeka\Entity\Media::class,
\Omeka\Entity\Site::class,
\Omeka\Entity\SitePage::class,
\Omeka\Entity\ResourceTemplate::class,
\Omeka\Entity\Asset::class,
];

$rolesToControl = ['site_admin', 'editor', 'author'];

$privilegesToControl = [
'update', 'edit',
'delete', 'delete-confirm',
'create', 'add',
'batch-delete', 'batch_delete', 'batch_delete_all',
'batch-update', 'batch_update_all',
'batch-edit', 'batch-edit-all',
];

$denyAssertion = new AssertionNegation($this->assertion);

foreach ($rolesToControl as $role) {
$acl->deny($role, $omekaResources, $privilegesToControl, $denyAssertion);
}
}
}
15 changes: 15 additions & 0 deletions src/Service/AclRuleManagerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
namespace Teams\Service;

use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Teams\Acl\TeamRolePermissionAssertion;

class AclRuleManagerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$assertion = $container->get(\Teams\Acl\TeamRolePermissionAssertion::class);
return new AclRuleManager($assertion);
}
}
46 changes: 46 additions & 0 deletions tests/Service/AclRuleManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
namespace Teams\Tests\Service;

use Teams\Service\AclRuleManager;
use Teams\Acl\TeamRolePermissionAssertion;
use Laminas\Permissions\Acl\Acl;
use Laminas\Permissions\Acl\Role\GenericRole;
use Omeka\Entity\Item;
use Tests\TestCase;

class AclRuleManagerTest extends TestCase
{
/** @var AclRuleManager */
private $ruleManager;

/** @var TeamRolePermissionAssertion|\PHPUnit\Framework\MockObject\MockObject */
private $assertionMock;

public function setUp(): void
{
parent::setUp();

$this->assertionMock = $this->createMock(TeamRolePermissionAssertion::class);
$this->ruleManager = new AclRuleManager($this->assertionMock);
}

public function testApplyRulesDeniesPreviouslyAllowedPermission()
{
// Arrange
$acl = new Acl;
$role = new GenericRole('editor');
$resource = new Item;
$acl->addRole($role);
$acl->addResource($resource);
$acl->allow($role, $resource, 'update');
$this->assertTrue($acl->isAllowed($role, $resource, 'update'));

$this->assertionMock->method('assert')->willReturn(false);

// Act
$this->ruleManager->applyRules($acl);

// Assert
$this->assertFalse($acl->isAllowed($role, $resource, 'update'));
}
}