annotate core/modules/node/src/NodeAccessControlHandler.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\node;
Chris@0 4
Chris@0 5 use Drupal\Core\Access\AccessResult;
Chris@0 6 use Drupal\Core\Entity\EntityHandlerInterface;
Chris@0 7 use Drupal\Core\Entity\EntityTypeInterface;
Chris@0 8 use Drupal\Core\Field\FieldDefinitionInterface;
Chris@0 9 use Drupal\Core\Field\FieldItemListInterface;
Chris@0 10 use Drupal\Core\Entity\EntityAccessControlHandler;
Chris@0 11 use Drupal\Core\Entity\EntityInterface;
Chris@0 12 use Drupal\Core\Session\AccountInterface;
Chris@0 13 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Defines the access control handler for the node entity type.
Chris@0 17 *
Chris@0 18 * @see \Drupal\node\Entity\Node
Chris@0 19 * @ingroup node_access
Chris@0 20 */
Chris@0 21 class NodeAccessControlHandler extends EntityAccessControlHandler implements NodeAccessControlHandlerInterface, EntityHandlerInterface {
Chris@0 22
Chris@0 23 /**
Chris@0 24 * The node grant storage.
Chris@0 25 *
Chris@0 26 * @var \Drupal\node\NodeGrantDatabaseStorageInterface
Chris@0 27 */
Chris@0 28 protected $grantStorage;
Chris@0 29
Chris@0 30 /**
Chris@0 31 * Constructs a NodeAccessControlHandler object.
Chris@0 32 *
Chris@0 33 * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
Chris@0 34 * The entity type definition.
Chris@0 35 * @param \Drupal\node\NodeGrantDatabaseStorageInterface $grant_storage
Chris@0 36 * The node grant storage.
Chris@0 37 */
Chris@0 38 public function __construct(EntityTypeInterface $entity_type, NodeGrantDatabaseStorageInterface $grant_storage) {
Chris@0 39 parent::__construct($entity_type);
Chris@0 40 $this->grantStorage = $grant_storage;
Chris@0 41 }
Chris@0 42
Chris@0 43 /**
Chris@0 44 * {@inheritdoc}
Chris@0 45 */
Chris@0 46 public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
Chris@0 47 return new static(
Chris@0 48 $entity_type,
Chris@0 49 $container->get('node.grant_storage')
Chris@0 50 );
Chris@0 51 }
Chris@0 52
Chris@0 53
Chris@0 54 /**
Chris@0 55 * {@inheritdoc}
Chris@0 56 */
Chris@0 57 public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
Chris@0 58 $account = $this->prepareUser($account);
Chris@0 59
Chris@0 60 if ($account->hasPermission('bypass node access')) {
Chris@0 61 $result = AccessResult::allowed()->cachePerPermissions();
Chris@0 62 return $return_as_object ? $result : $result->isAllowed();
Chris@0 63 }
Chris@0 64 if (!$account->hasPermission('access content')) {
Chris@0 65 $result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions();
Chris@0 66 return $return_as_object ? $result : $result->isAllowed();
Chris@0 67 }
Chris@0 68 $result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
Chris@0 69
Chris@0 70 return $return_as_object ? $result : $result->isAllowed();
Chris@0 71 }
Chris@0 72
Chris@0 73 /**
Chris@0 74 * {@inheritdoc}
Chris@0 75 */
Chris@0 76 public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
Chris@0 77 $account = $this->prepareUser($account);
Chris@0 78
Chris@0 79 if ($account->hasPermission('bypass node access')) {
Chris@0 80 $result = AccessResult::allowed()->cachePerPermissions();
Chris@0 81 return $return_as_object ? $result : $result->isAllowed();
Chris@0 82 }
Chris@0 83 if (!$account->hasPermission('access content')) {
Chris@0 84 $result = AccessResult::forbidden()->cachePerPermissions();
Chris@0 85 return $return_as_object ? $result : $result->isAllowed();
Chris@0 86 }
Chris@0 87
Chris@0 88 $result = parent::createAccess($entity_bundle, $account, $context, TRUE)->cachePerPermissions();
Chris@0 89 return $return_as_object ? $result : $result->isAllowed();
Chris@0 90 }
Chris@0 91
Chris@0 92 /**
Chris@0 93 * {@inheritdoc}
Chris@0 94 */
Chris@0 95 protected function checkAccess(EntityInterface $node, $operation, AccountInterface $account) {
Chris@0 96 /** @var \Drupal\node\NodeInterface $node */
Chris@0 97
Chris@0 98 // Fetch information from the node object if possible.
Chris@0 99 $status = $node->isPublished();
Chris@0 100 $uid = $node->getOwnerId();
Chris@0 101
Chris@0 102 // Check if authors can view their own unpublished nodes.
Chris@0 103 if ($operation === 'view' && !$status && $account->hasPermission('view own unpublished content') && $account->isAuthenticated() && $account->id() == $uid) {
Chris@0 104 return AccessResult::allowed()->cachePerPermissions()->cachePerUser()->addCacheableDependency($node);
Chris@0 105 }
Chris@0 106
Chris@0 107 // Evaluate node grants.
Chris@0 108 return $this->grantStorage->access($node, $operation, $account);
Chris@0 109 }
Chris@0 110
Chris@0 111 /**
Chris@0 112 * {@inheritdoc}
Chris@0 113 */
Chris@0 114 protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
Chris@0 115 return AccessResult::allowedIf($account->hasPermission('create ' . $entity_bundle . ' content'))->cachePerPermissions();
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * {@inheritdoc}
Chris@0 120 */
Chris@0 121 protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
Chris@0 122 // Only users with the administer nodes permission can edit administrative
Chris@0 123 // fields.
Chris@0 124 $administrative_fields = ['uid', 'status', 'created', 'promote', 'sticky'];
Chris@0 125 if ($operation == 'edit' && in_array($field_definition->getName(), $administrative_fields, TRUE)) {
Chris@0 126 return AccessResult::allowedIfHasPermission($account, 'administer nodes');
Chris@0 127 }
Chris@0 128
Chris@0 129 // No user can change read only fields.
Chris@0 130 $read_only_fields = ['revision_timestamp', 'revision_uid'];
Chris@0 131 if ($operation == 'edit' && in_array($field_definition->getName(), $read_only_fields, TRUE)) {
Chris@0 132 return AccessResult::forbidden();
Chris@0 133 }
Chris@0 134
Chris@0 135 // Users have access to the revision_log field either if they have
Chris@0 136 // administrative permissions or if the new revision option is enabled.
Chris@0 137 if ($operation == 'edit' && $field_definition->getName() == 'revision_log') {
Chris@0 138 if ($account->hasPermission('administer nodes')) {
Chris@0 139 return AccessResult::allowed()->cachePerPermissions();
Chris@0 140 }
Chris@0 141 return AccessResult::allowedIf($items->getEntity()->type->entity->isNewRevision())->cachePerPermissions();
Chris@0 142 }
Chris@0 143 return parent::checkFieldAccess($operation, $field_definition, $account, $items);
Chris@0 144 }
Chris@0 145
Chris@0 146 /**
Chris@0 147 * {@inheritdoc}
Chris@0 148 */
Chris@0 149 public function acquireGrants(NodeInterface $node) {
Chris@0 150 $grants = $this->moduleHandler->invokeAll('node_access_records', [$node]);
Chris@0 151 // Let modules alter the grants.
Chris@0 152 $this->moduleHandler->alter('node_access_records', $grants, $node);
Chris@0 153 // If no grants are set and the node is published, then use the default grant.
Chris@0 154 if (empty($grants) && $node->isPublished()) {
Chris@0 155 $grants[] = ['realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0];
Chris@0 156 }
Chris@0 157 return $grants;
Chris@0 158 }
Chris@0 159
Chris@0 160 /**
Chris@0 161 * {@inheritdoc}
Chris@0 162 */
Chris@0 163 public function writeGrants(NodeInterface $node, $delete = TRUE) {
Chris@0 164 $grants = $this->acquireGrants($node);
Chris@0 165 $this->grantStorage->write($node, $grants, NULL, $delete);
Chris@0 166 }
Chris@0 167
Chris@0 168 /**
Chris@0 169 * {@inheritdoc}
Chris@0 170 */
Chris@0 171 public function writeDefaultGrant() {
Chris@0 172 $this->grantStorage->writeDefault();
Chris@0 173 }
Chris@0 174
Chris@0 175 /**
Chris@0 176 * {@inheritdoc}
Chris@0 177 */
Chris@0 178 public function deleteGrants() {
Chris@0 179 $this->grantStorage->delete();
Chris@0 180 }
Chris@0 181
Chris@0 182 /**
Chris@0 183 * {@inheritdoc}
Chris@0 184 */
Chris@0 185 public function countGrants() {
Chris@0 186 return $this->grantStorage->count();
Chris@0 187 }
Chris@0 188
Chris@0 189 /**
Chris@0 190 * {@inheritdoc}
Chris@0 191 */
Chris@0 192 public function checkAllGrants(AccountInterface $account) {
Chris@0 193 return $this->grantStorage->checkAll($account);
Chris@0 194 }
Chris@0 195
Chris@0 196 }