annotate core/modules/node/src/NodeAccessControlHandler.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
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 * {@inheritdoc}
Chris@0 55 */
Chris@0 56 public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
Chris@0 57 $account = $this->prepareUser($account);
Chris@0 58
Chris@0 59 if ($account->hasPermission('bypass node access')) {
Chris@0 60 $result = AccessResult::allowed()->cachePerPermissions();
Chris@0 61 return $return_as_object ? $result : $result->isAllowed();
Chris@0 62 }
Chris@0 63 if (!$account->hasPermission('access content')) {
Chris@0 64 $result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions();
Chris@0 65 return $return_as_object ? $result : $result->isAllowed();
Chris@0 66 }
Chris@0 67 $result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
Chris@0 68
Chris@0 69 return $return_as_object ? $result : $result->isAllowed();
Chris@0 70 }
Chris@0 71
Chris@0 72 /**
Chris@0 73 * {@inheritdoc}
Chris@0 74 */
Chris@0 75 public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
Chris@0 76 $account = $this->prepareUser($account);
Chris@0 77
Chris@0 78 if ($account->hasPermission('bypass node access')) {
Chris@0 79 $result = AccessResult::allowed()->cachePerPermissions();
Chris@0 80 return $return_as_object ? $result : $result->isAllowed();
Chris@0 81 }
Chris@0 82 if (!$account->hasPermission('access content')) {
Chris@17 83 $result = AccessResult::forbidden("The 'access content' permission is required.")->cachePerPermissions();
Chris@0 84 return $return_as_object ? $result : $result->isAllowed();
Chris@0 85 }
Chris@0 86
Chris@0 87 $result = parent::createAccess($entity_bundle, $account, $context, TRUE)->cachePerPermissions();
Chris@0 88 return $return_as_object ? $result : $result->isAllowed();
Chris@0 89 }
Chris@0 90
Chris@0 91 /**
Chris@0 92 * {@inheritdoc}
Chris@0 93 */
Chris@0 94 protected function checkAccess(EntityInterface $node, $operation, AccountInterface $account) {
Chris@0 95 /** @var \Drupal\node\NodeInterface $node */
Chris@0 96
Chris@0 97 // Fetch information from the node object if possible.
Chris@0 98 $status = $node->isPublished();
Chris@0 99 $uid = $node->getOwnerId();
Chris@0 100
Chris@0 101 // Check if authors can view their own unpublished nodes.
Chris@0 102 if ($operation === 'view' && !$status && $account->hasPermission('view own unpublished content') && $account->isAuthenticated() && $account->id() == $uid) {
Chris@0 103 return AccessResult::allowed()->cachePerPermissions()->cachePerUser()->addCacheableDependency($node);
Chris@0 104 }
Chris@0 105
Chris@0 106 // Evaluate node grants.
Chris@0 107 return $this->grantStorage->access($node, $operation, $account);
Chris@0 108 }
Chris@0 109
Chris@0 110 /**
Chris@0 111 * {@inheritdoc}
Chris@0 112 */
Chris@0 113 protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
Chris@0 114 return AccessResult::allowedIf($account->hasPermission('create ' . $entity_bundle . ' content'))->cachePerPermissions();
Chris@0 115 }
Chris@0 116
Chris@0 117 /**
Chris@0 118 * {@inheritdoc}
Chris@0 119 */
Chris@0 120 protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
Chris@0 121 // Only users with the administer nodes permission can edit administrative
Chris@0 122 // fields.
Chris@0 123 $administrative_fields = ['uid', 'status', 'created', 'promote', 'sticky'];
Chris@0 124 if ($operation == 'edit' && in_array($field_definition->getName(), $administrative_fields, TRUE)) {
Chris@0 125 return AccessResult::allowedIfHasPermission($account, 'administer nodes');
Chris@0 126 }
Chris@0 127
Chris@0 128 // No user can change read only fields.
Chris@0 129 $read_only_fields = ['revision_timestamp', 'revision_uid'];
Chris@0 130 if ($operation == 'edit' && in_array($field_definition->getName(), $read_only_fields, TRUE)) {
Chris@0 131 return AccessResult::forbidden();
Chris@0 132 }
Chris@0 133
Chris@0 134 // Users have access to the revision_log field either if they have
Chris@0 135 // administrative permissions or if the new revision option is enabled.
Chris@0 136 if ($operation == 'edit' && $field_definition->getName() == 'revision_log') {
Chris@0 137 if ($account->hasPermission('administer nodes')) {
Chris@0 138 return AccessResult::allowed()->cachePerPermissions();
Chris@0 139 }
Chris@0 140 return AccessResult::allowedIf($items->getEntity()->type->entity->isNewRevision())->cachePerPermissions();
Chris@0 141 }
Chris@0 142 return parent::checkFieldAccess($operation, $field_definition, $account, $items);
Chris@0 143 }
Chris@0 144
Chris@0 145 /**
Chris@0 146 * {@inheritdoc}
Chris@0 147 */
Chris@0 148 public function acquireGrants(NodeInterface $node) {
Chris@0 149 $grants = $this->moduleHandler->invokeAll('node_access_records', [$node]);
Chris@0 150 // Let modules alter the grants.
Chris@0 151 $this->moduleHandler->alter('node_access_records', $grants, $node);
Chris@0 152 // If no grants are set and the node is published, then use the default grant.
Chris@0 153 if (empty($grants) && $node->isPublished()) {
Chris@0 154 $grants[] = ['realm' => 'all', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0];
Chris@0 155 }
Chris@0 156 return $grants;
Chris@0 157 }
Chris@0 158
Chris@0 159 /**
Chris@0 160 * {@inheritdoc}
Chris@0 161 */
Chris@0 162 public function writeGrants(NodeInterface $node, $delete = TRUE) {
Chris@0 163 $grants = $this->acquireGrants($node);
Chris@0 164 $this->grantStorage->write($node, $grants, NULL, $delete);
Chris@0 165 }
Chris@0 166
Chris@0 167 /**
Chris@0 168 * {@inheritdoc}
Chris@0 169 */
Chris@0 170 public function writeDefaultGrant() {
Chris@0 171 $this->grantStorage->writeDefault();
Chris@0 172 }
Chris@0 173
Chris@0 174 /**
Chris@0 175 * {@inheritdoc}
Chris@0 176 */
Chris@0 177 public function deleteGrants() {
Chris@0 178 $this->grantStorage->delete();
Chris@0 179 }
Chris@0 180
Chris@0 181 /**
Chris@0 182 * {@inheritdoc}
Chris@0 183 */
Chris@0 184 public function countGrants() {
Chris@0 185 return $this->grantStorage->count();
Chris@0 186 }
Chris@0 187
Chris@0 188 /**
Chris@0 189 * {@inheritdoc}
Chris@0 190 */
Chris@0 191 public function checkAllGrants(AccountInterface $account) {
Chris@0 192 return $this->grantStorage->checkAll($account);
Chris@0 193 }
Chris@0 194
Chris@0 195 }