View source
<?php
declare (strict_types=1);
namespace Drupal\Tests\og\Kernel\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\KernelTests\KernelTestBase;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\og\Entity\OgRole;
use Drupal\og\Og;
use Drupal\og\OgAccess;
use Drupal\og\OgRoleInterface;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
class GroupLevelAccessTest extends KernelTestBase {
public static $modules = [
'system',
'user',
'field',
'og',
'entity_test',
];
protected $ogAccess;
protected $nonMemberUser;
protected $ownerUser;
protected $adminUser;
protected $alternativeAdminUser;
protected $group;
protected $groupBundle;
protected function setUp() : void {
parent::setUp();
$this
->installConfig([
'og',
]);
$this
->installEntitySchema('og_membership');
$this
->installEntitySchema('user');
$this
->installEntitySchema('entity_test');
$this
->installSchema('system', 'sequences');
$this->ogAccess = $this->container
->get('og.access');
$this->groupBundle = mb_strtolower($this
->randomMachineName());
Og::groupTypeManager()
->addGroup('entity_test', $this->groupBundle);
User::create([
'name' => $this
->randomString(),
])
->save();
$this->ownerUser = User::create([
'name' => $this
->randomString(),
]);
$this->ownerUser
->save();
$this->group = EntityTest::create([
'type' => $this->groupBundle,
'name' => $this
->randomString(),
'user_id' => $this->ownerUser
->id(),
]);
$this->group
->save();
$this->nonMemberUser = User::create([
'name' => $this
->randomString(),
]);
$this->nonMemberUser
->save();
$admin_role = OgRole::loadByGroupAndName($this->group, OgRoleInterface::ADMINISTRATOR);
$this->adminUser = $this
->createUserWithOgRole($admin_role);
$alternative_admin_role = $this
->createOgRole([], TRUE);
$this->alternativeAdminUser = $this
->createUserWithOgRole($alternative_admin_role);
}
public function testUserAccessArbitraryPermissions() {
[
$roles,
$users,
] = $this
->setupUserAccessArbitraryPermissions();
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $users['has_permission_in_both_groups'])
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm_2', $users['has_permission_in_both_groups'])
->isNeutral());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $users['has_permission_in_both_groups'])
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $users['has_no_permission'])
->isNeutral());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->nonMemberUser)
->isNeutral());
$role = OgRole::loadByGroupAndName($this->group, OgRoleInterface::ANONYMOUS);
$role
->grantPermission('some_perm')
->save();
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->nonMemberUser)
->isAllowed());
$role
->revokePermission('some_perm')
->save();
$this
->assertFalse($this->ogAccess
->userAccess($this->group, 'some_perm', $this->nonMemberUser)
->isAllowed());
$membership = Og::createMembership($this->group, $this->nonMemberUser);
$membership
->addRole($roles['arbitrary_permission'])
->save();
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->nonMemberUser)
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->adminUser)
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, $this
->randomMachineName(), $this->adminUser)
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->alternativeAdminUser)
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, $this
->randomMachineName(), $this->alternativeAdminUser)
->isAllowed());
$admin_role = OgRole::loadByGroupAndName($this->group, OgRoleInterface::ADMINISTRATOR);
$admin_role
->setIsAdmin(FALSE)
->save();
$this
->assertFalse($this->ogAccess
->userAccess($this->group, 'some_perm', $this->adminUser)
->isAllowed());
$this
->assertFalse($this->ogAccess
->userAccess($this->group, $this
->randomMachineName(), $this->adminUser)
->isAllowed());
$this
->assertTrue($this->ogAccess
->userAccess($this->group, 'some_perm', $this->ownerUser)
->isAllowed());
$this
->config('og.settings')
->set('group_manager_full_access', FALSE)
->save();
$this
->assertFalse($this->ogAccess
->userAccess($this->group, 'some_perm', $this->ownerUser)
->isAllowed());
}
protected function setupUserAccessArbitraryPermissions() {
$roles = [];
$users = [];
$alternate_group = EntityTest::create([
'type' => $this->groupBundle,
'name' => $this
->randomString(),
'user_id' => $this->ownerUser
->id(),
]);
$alternate_group
->save();
$roles['arbitrary_permission'] = $this
->createOgRole([
'some_perm',
]);
$alternate_role = OgRole::create();
$alternate_role
->setName($this
->randomMachineName())
->setLabel($this
->randomString())
->setGroupType($alternate_group
->getEntityTypeId())
->setGroupBundle($alternate_group
->bundle())
->grantPermission('some_perm_2')
->save();
$roles['alternate'] = $alternate_role;
$user = $this
->createUserWithOgRole($roles['arbitrary_permission']);
$membership = Og::createMembership($alternate_group, $user);
$membership
->addRole($alternate_role)
->save();
$users['has_permission_in_both_groups'] = $user;
$role_without_permissions = $this
->createOgRole();
$user = $this
->createUserWithOgRole($role_without_permissions);
$users['has_no_permission'] = $user;
return [
$roles,
$users,
];
}
public function testGroupEntityOperationPermissions(string $user, array $access_matrix) : void {
$users = $this
->setupGroupEntityOperationPermissions();
$user = $users[$user];
foreach ($access_matrix as $operation => $expected_access) {
$result = $this->ogAccess
->userAccessEntityOperation($operation, $this->group, $user);
$this
->assertEquals($expected_access, $result
->isAllowed());
$arguments = [
$this->group,
$operation,
$user,
];
$hook_result = \Drupal::moduleHandler()
->invokeAll('entity_access', $arguments);
if (empty($hook_result)) {
$result = AccessResult::neutral();
}
else {
$result = array_shift($hook_result);
foreach ($hook_result as $other) {
$result = $result
->orIf($other);
}
}
$this
->assertEquals($expected_access, $result
->isAllowed());
}
}
protected function setupGroupEntityOperationPermissions() : array {
$users = [
'owner' => $this->ownerUser,
'non-member' => $this->nonMemberUser,
'admin' => $this->adminUser,
'alternative-admin' => $this->alternativeAdminUser,
];
$role_with_update_permission = $this
->createOgRole([
OgAccess::UPDATE_GROUP_PERMISSION,
]);
$user = $this
->createUserWithOgRole($role_with_update_permission);
$users['update'] = $user;
$role_with_delete_permission = $this
->createOgRole([
OgAccess::DELETE_GROUP_PERMISSION,
]);
$user = $this
->createUserWithOgRole($role_with_delete_permission);
$users['delete'] = $user;
return $users;
}
public function groupEntityOperationPermissionsTestProvider() : array {
return [
[
'owner',
[
'update' => TRUE,
'delete' => TRUE,
],
],
[
'non-member',
[
'update' => FALSE,
'delete' => FALSE,
],
],
[
'delete',
[
'update' => FALSE,
'delete' => TRUE,
],
],
[
'update',
[
'update' => TRUE,
'delete' => FALSE,
],
],
[
'admin',
[
'update' => TRUE,
'delete' => TRUE,
],
],
[
'alternative-admin',
[
'update' => TRUE,
'delete' => TRUE,
],
],
];
}
protected function createOgRole(array $permissions = [], bool $is_admin = FALSE) : OgRoleInterface {
$role = OgRole::create();
$role
->setName($this
->randomMachineName())
->setLabel($this
->randomString())
->setGroupType($this->group
->getEntityTypeId())
->setGroupBundle($this->groupBundle)
->setIsAdmin($is_admin);
foreach ($permissions as $permission) {
$role
->grantPermission($permission);
}
$role
->save();
return $role;
}
protected function createUserWithOgRole(OgRoleInterface $role) : UserInterface {
$user = User::create([
'name' => $this
->randomString(),
]);
$user
->save();
$membership = Og::createMembership($this->group, $user);
$membership
->addRole($role)
->save();
return $user;
}
}