View source
<?php
namespace Drupal\Tests\search_api\Kernel\Processor;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\node\NodeInterface;
use Drupal\Tests\search_api\Kernel\ResultsTrait;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
class RoleAccessTest extends ProcessorTestBase {
use ResultsTrait;
protected $nodes;
protected $testUsers;
public function setUp($processor = NULL) {
parent::setUp('role_access');
$this
->installSchema('system', [
'sequences',
]);
NodeType::create([
'type' => 'page',
'name' => 'page',
])
->save();
\Drupal::state()
->set('search_api_test_add_role_access_control', TRUE);
foreach ([
'foo',
'bar',
'baz',
'anonymous',
'authenticated',
] as $role_id) {
Role::create([
'id' => $role_id,
'name' => $role_id,
])
->grantPermission('access content')
->save();
}
foreach ([
'foo',
'bar',
'baz',
] as $role_id) {
$test_user = User::create([
'name' => $role_id,
]);
$test_user
->addRole($role_id);
$test_user
->save();
$this->testUsers[$role_id] = $test_user;
}
$anonymous_user = User::create([
'uid' => 0,
'name' => '',
]);
$anonymous_user
->save();
$this->testUsers['anonymous'] = $anonymous_user;
$authenticated_user = User::create([
'name' => 'Authenticated',
]);
$authenticated_user
->save();
$this->testUsers['authenticated'] = $authenticated_user;
}
public function testRoleBasedAccess() {
$allowed_foo = $this
->createTestNode('allow for foo role');
$allowed_bar = $this
->createTestNode('allow for bar role');
$allowed_anonymous = $this
->createTestNode('allow for anonymous role');
$allowed_authenticated = $this
->createTestNode('allow for authenticated role');
$allowed_all = $this
->createTestNode('allow for foo, bar, baz, anonymous, authenticated role');
$this->index
->reindex();
$this
->indexItems();
$query = \Drupal::getContainer()
->get('search_api.query_helper')
->createQuery($this->index);
$expected = [
'foo' => [
'node' => [
$allowed_all,
$allowed_foo,
$allowed_authenticated,
],
],
'bar' => [
'node' => [
$allowed_all,
$allowed_bar,
$allowed_authenticated,
],
],
'baz' => [
'node' => [
$allowed_all,
$allowed_authenticated,
],
],
'anonymous' => [
'node' => [
$allowed_anonymous,
$allowed_all,
],
],
'authenticated' => [
'node' => [
$allowed_authenticated,
$allowed_all,
],
],
];
foreach ($expected as $role_id => $expected_role_results) {
$cloned_query = clone $query;
$cloned_query
->setOption('search_api_access_account', $this->testUsers[$role_id]);
$result = $cloned_query
->execute();
$this
->assertResults($result, $expected_role_results);
}
}
public function testComputedFieldValues() {
$allowed_foo = $this
->createTestNode('allow for foo role');
$allowed_bar = $this
->createTestNode('allow for bar role');
$allowed_anonymous = $this
->createTestNode('allow for anonymous role');
$allowed_authenticated = $this
->createTestNode('allow for authenticated role');
$allowed_all = $this
->createTestNode('allow for foo, bar, baz, anonymous, authenticated role');
$expected_roles = [
$allowed_foo => [
'foo',
],
$allowed_bar => [
'bar',
],
$allowed_anonymous => [
'anonymous',
],
$allowed_authenticated => [
'authenticated',
],
$allowed_all => [
'foo',
'bar',
'baz',
'anonymous',
'authenticated',
],
];
$fields_helper = \Drupal::getContainer()
->get('search_api.fields_helper');
$datasource = $this->index
->getDatasource('entity:node');
foreach ($expected_roles as $i => $roles) {
$node = $this->nodes[$i];
$item = $fields_helper
->createItemFromObject($this->index, $node
->getTypedData(), NULL, $datasource);
$this->processor
->addFieldValues($item);
$this
->assertEquals($roles, $item
->getField('role_access')
->getValues(), "Wrong roles computed for node \"{$node->label()}\".");
}
}
public function testDefaultingToLoggedInUser() {
$allowed_foo = $this
->createTestNode('allow for foo role');
\Drupal::currentUser()
->setAccount($this->testUsers['foo']);
$index_storage = \Drupal::entityTypeManager()
->getStorage('search_api_index');
$index_storage
->resetCache([
$this->index
->id(),
]);
$this->index = $index_storage
->load($this->index
->id());
$this->index
->reindex();
$this
->indexItems();
$query = \Drupal::getContainer()
->get('search_api.query_helper')
->createQuery($this->index);
$result = $query
->execute();
$this
->assertResults($result, [
'node' => [
$allowed_foo,
],
]);
}
public function testIdBasedCurrentUser() {
$allowed_foo = $this
->createTestNode('allow for foo role');
$this
->createTestNode('allow for bar role');
$this->index
->reindex();
$this
->indexItems();
$query = \Drupal::getContainer()
->get('search_api.query_helper')
->createQuery($this->index);
$query
->setOption('search_api_access_account', $this->testUsers['foo']
->id());
$result = $query
->execute();
$this
->assertResults($result, [
'node' => [
$allowed_foo,
],
]);
}
public function testQueryAccessBypass() {
$disallowed = $this
->createTestNode('disallowed');
$this->index
->reindex();
$this
->indexItems();
$this
->assertEquals(1, $this->index
->getTrackerInstance()
->getIndexedItemsCount());
$query = \Drupal::getContainer()
->get('search_api.query_helper')
->createQuery($this->index, [
'search_api_bypass_access' => TRUE,
]);
$result = $query
->execute();
$expected = [
'node' => [
$disallowed,
],
];
$this
->assertResults($result, $expected);
}
public function testAlterPropertyDefinitions() {
$properties = $this->processor
->getPropertyDefinitions(NULL);
$this
->assertArrayHasKey('search_api_role_access', $properties);
$property = $properties['search_api_role_access'];
$this
->assertInstanceOf(DataDefinitionInterface::class, $property);
$this
->assertEquals('string', $property
->getDataType());
$datasource = $this->index
->getDatasource('entity:node');
$properties = $this->processor
->getPropertyDefinitions($datasource);
$this
->assertEquals([], $properties);
}
protected function createTestNode(string $title) : int {
$node = Node::create([
'status' => NodeInterface::PUBLISHED,
'type' => 'page',
'title' => $title,
]);
$node
->save();
$this->nodes[] = $node;
end($this->nodes);
return key($this->nodes);
}
}