Commit a5312b9a authored by pfrenssen's avatar pfrenssen Committed by drunken monkey

Issue #3058300 by pfrenssen, drunken monkey, borisson_: Changed access methods...

Issue #3058300 by pfrenssen, drunken monkey, borisson_: Changed access methods to work with AccessResult objects instead of booleans.
parent eae43106
Search API 1.x, dev (xxxx-xx-xx):
---------------------------------
- #3058300 by pfrenssen, drunken monkey, borisson_: Changed access methods to
work with AccessResult objects instead of booleans.
- #3059070 by fconnolly, borisson_, drunken monkey: Fixed Item::__toString() to
not extract fields.
- #3055775 by legolasbo, drunken monkey: Fixed documentation of
......
......@@ -137,9 +137,28 @@ interface DatasourceInterface extends IndexPluginInterface {
*
* @return bool
* TRUE if access is granted, FALSE otherwise.
*
* @deprecated in search_api:8.x-1.14 and is removed from search_api:9.x-1.0.
* Use getItemAccessResult() instead.
*
* @see https://www.drupal.org/node/3051902
*/
public function checkItemAccess(ComplexDataInterface $item, AccountInterface $account = NULL);
/**
* Checks whether a user has permission to view the given item.
*
* @param \Drupal\Core\TypedData\ComplexDataInterface $item
* An item of this datasource's type.
* @param \Drupal\Core\Session\AccountInterface|null $account
* (optional) The user session for which to check access, or NULL to check
* access for the current user.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function getItemAccessResult(ComplexDataInterface $item, AccountInterface $account = NULL);
/**
* Returns the available view modes for this datasource.
*
......
......@@ -2,6 +2,7 @@
namespace Drupal\search_api\Datasource;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Language\Language;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
......@@ -97,7 +98,15 @@ abstract class DatasourcePluginBase extends IndexPluginBase implements Datasourc
* {@inheritdoc}
*/
public function checkItemAccess(ComplexDataInterface $item, AccountInterface $account = NULL) {
return TRUE;
@trigger_error('\Drupal\search_api\Datasource\DatasourceInterface::checkItemAccess() is deprecated in search_api:8.x-1.14 and is removed from search_api:9.x-1.0. Use getItemAccessResult() instead. See https://www.drupal.org/node/3051902', E_USER_DEPRECATED);
return $this->getItemAccessResult($item, $account)->isAllowed();
}
/**
* {@inheritdoc}
*/
public function getItemAccessResult(ComplexDataInterface $item, AccountInterface $account = NULL) {
return AccessResult::allowed();
}
/**
......
......@@ -2,14 +2,15 @@
namespace Drupal\search_api\Item;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\LoggerTrait;
use Drupal\search_api\Processor\ProcessorInterface;
use Drupal\search_api\Processor\ProcessorPropertyInterface;
use Drupal\search_api\SearchApiException;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Utility\Utility;
/**
......@@ -103,6 +104,15 @@ class Item implements \IteratorAggregate, ItemInterface {
*/
protected $extraData = [];
/**
* Cached access results for the item, keyed by user ID.
*
* @var \Drupal\Core\Access\AccessResultInterface[]
*
* @see getAccessResult()
*/
protected $accessResults = [];
/**
* Constructs an Item object.
*
......@@ -406,13 +416,30 @@ class Item implements \IteratorAggregate, ItemInterface {
* {@inheritdoc}
*/
public function checkAccess(AccountInterface $account = NULL) {
try {
return $this->getDatasource()
->checkItemAccess($this->getOriginalObject(), $account);
@trigger_error('\Drupal\search_api\Item\ItemInterface::checkAccess() is deprecated in search_api:8.x-1.14 and is removed from search_api:9.x-1.0. Use getAccessResult() instead. See https://www.drupal.org/node/3051902', E_USER_DEPRECATED);
return $this->getAccessResult($account)->isAllowed();
}
/**
* {@inheritdoc}
*/
public function getAccessResult(AccountInterface $account = NULL) {
if (!$account) {
$account = \Drupal::currentUser();
}
catch (SearchApiException $e) {
return FALSE;
$uid = $account->id();
if (empty($this->accessResults[$uid])) {
try {
$this->accessResults[$uid] = $this->getDatasource()
->getItemAccessResult($this->getOriginalObject(), $account);
}
catch (SearchApiException $e) {
$this->accessResults[$uid] = AccessResult::neutral('Item could not be loaded, so cannot check access');
}
}
return $this->accessResults[$uid];
}
/**
......
......@@ -295,7 +295,24 @@ interface ItemInterface extends \Traversable {
*
* @return bool
* TRUE if access is granted, FALSE otherwise.
*
* @deprecated in search_api:8.x-1.14 and is removed from search_api:9.x-1.0.
* Use getAccessResult() instead.
*
* @see https://www.drupal.org/node/3051902
*/
public function checkAccess(AccountInterface $account = NULL);
/**
* Checks whether a user has permission to view this item.
*
* @param \Drupal\Core\Session\AccountInterface|null $account
* (optional) The user for which to check access, or NULL to check access
* for the current user.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function getAccessResult(AccountInterface $account = NULL);
}
......@@ -3,6 +3,7 @@
namespace Drupal\search_api\Plugin\search_api\datasource;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
......@@ -684,13 +685,14 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
/**
* {@inheritdoc}
*/
public function checkItemAccess(ComplexDataInterface $item, AccountInterface $account = NULL) {
if ($entity = $this->getEntity($item)) {
public function getItemAccessResult(ComplexDataInterface $item, AccountInterface $account = NULL) {
$entity = $this->getEntity($item);
if ($entity) {
return $this->getEntityTypeManager()
->getAccessControlHandler($this->getEntityTypeId())
->access($entity, 'view', $account);
->access($entity, 'view', $account, TRUE);
}
return FALSE;
return AccessResult::neutral('Item is not an entity, so cannot check access');
}
/**
......
......@@ -638,7 +638,7 @@ class SearchApiQuery extends QueryPluginBase {
// avoid them being individually loaded inside checkAccess().
$result_set->preLoadResultItems();
foreach ($results as $item_id => $result) {
if (!$result->checkAccess($account)) {
if (!$result->getAccessResult($account)->isAllowed()) {
unset($results[$item_id]);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment