View source
<?php
namespace Drupal\search_api_saved_searches\Entity;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\search_api_saved_searches\BundleFieldDefinition;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class SavedSearchAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
const ADMIN_PERMISSION = 'administer search_api_saved_searches';
protected $entityTypeManager;
protected $requestStack;
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
$handler = new static($entity_type);
$handler
->setEntityTypeManager($container
->get('entity_type.manager'));
$handler
->setRequestStack($container
->get('request_stack'));
return $handler;
}
public function getEntityTypeManager() {
return $this->entityTypeManager ?: \Drupal::service('entity_type.manager');
}
public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
return $this;
}
public function getRequestStack() {
return $this->requestStack ?: \Drupal::service('request_stack');
}
public function setRequestStack(RequestStack $request_stack) {
$this->requestStack = $request_stack;
return $this;
}
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
$access = parent::checkAccess($entity, $operation, $account);
if (!$access
->isAllowed()) {
if (!$entity
->getOwner()
->isAnonymous()) {
$is_owner = $account
->id() == $entity
->getOwnerId();
$owner_access = AccessResult::allowedIf($is_owner)
->addCacheableDependency($account);
}
else {
$token = $this
->getRequestStack()
->getCurrentRequest()->query
->get('token');
$token_match = $token === $entity
->getAccessToken($operation);
$owner_access = AccessResult::allowedIf($token_match)
->addCacheContexts([
'url.query_args:token',
]);
}
$owner_access
->andIf($this
->checkBundleAccess($account, $entity
->bundle()));
$access = $access
->orIf($owner_access);
}
return $access;
}
protected function checkCreateAccess(AccountInterface $account, array $context, $bundle = NULL) {
$access = parent::checkCreateAccess($account, $context, $bundle);
if (!$access
->isAllowed()) {
$access = $access
->orIf($this
->checkBundleAccess($account, $bundle));
}
return $access;
}
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
$field_name = $field_definition
->getName();
$administrative_fields = [
'uid',
'status',
'created',
'last_executed',
'next_execution',
];
if ($operation === 'edit' && in_array($field_name, $administrative_fields, TRUE)) {
return AccessResult::allowedIfHasPermission($account, self::ADMIN_PERMISSION);
}
$serialized_fields = [
'query',
];
if (in_array($field_name, $serialized_fields, TRUE)) {
return AccessResult::forbidden();
}
if ($field_name === 'index_id') {
if ($operation === 'edit') {
return AccessResult::forbidden();
}
return AccessResult::allowedIfHasPermission($account, self::ADMIN_PERMISSION);
}
if ($field_definition instanceof BundleFieldDefinition) {
$plugin_id = $field_definition
->getSetting('notification_plugin');
$bundle = $field_definition
->getTargetBundle();
if ($plugin_id && $bundle) {
$type = $this
->getEntityTypeManager()
->getStorage('search_api_saved_search_type')
->load($bundle);
if ($type && $type
->isValidNotificationPlugin($plugin_id)) {
return $type
->getNotificationPlugin($plugin_id)
->checkFieldAccess($operation, $field_definition, $account, $items);
}
}
return AccessResult::allowedIfHasPermission($account, self::ADMIN_PERMISSION);
}
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}
protected function checkBundleAccess(AccountInterface $account, $bundle) {
$permission = "use {$bundle} search_api_saved_searches";
return AccessResult::allowedIfHasPermission($account, $permission);
}
}