diff --git a/core/includes/entity.inc b/core/includes/entity.inc index 2d21e8222c7b18e98c63b3c242b4cb42c5131795..08ed917530460d764286f77c8c64c488a152d05b 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -734,3 +734,18 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) { function entity_query($entity_type, $conjunction = 'AND') { return drupal_container()->get('entity.query')->get($entity_type, $conjunction); } + +/** + * Generic access callback for entity pages. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity for which access is being checked. + * @param string $operation + * (optional) The operation being performed on the entity. Defaults to 'view'. + * + * @return bool + * TRUE if the access is granted. FALSE if access is denied. + */ +function entity_page_access(EntityInterface $entity, $operation = 'view') { + return $entity->access($operation); +} diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index ca3d96853fca1781e8c506191ffa2053a9998567..6d31124b2bb15b828cf529d6bbf2e71adf213621 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -27,8 +27,8 @@ function openid_menu() { 'title' => 'OpenID identities', 'page callback' => 'openid_user_identities', 'page arguments' => array(1), - 'access callback' => 'user_edit_access', - 'access arguments' => array(1), + 'access callback' => 'entity_page_access', + 'access arguments' => array(1, 'update'), 'type' => MENU_LOCAL_TASK, 'file' => 'openid.pages.inc', ); @@ -36,8 +36,8 @@ function openid_menu() { 'title' => 'Delete OpenID', 'page callback' => 'drupal_get_form', 'page arguments' => array('openid_user_delete_form', 1), - 'access callback' => 'user_edit_access', - 'access arguments' => array(1), + 'access callback' => 'entity_page_access', + 'access arguments' => array(1, 'update'), 'file' => 'openid.pages.inc', ); return $items; diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module index d33a878b2c2fa0c39dfbae3a34cba6e4ef5f3c47..451702157af4f6a054fd59bcee9292a749b078af 100644 --- a/core/modules/tracker/tracker.module +++ b/core/modules/tracker/tracker.module @@ -185,7 +185,7 @@ function _tracker_myrecent_access($account) { * @see tracker_menu() */ function _tracker_user_access($account) { - return user_view_access($account) && user_access('access content'); + return $account->access('view') && user_access('access content'); } /** diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php index c4f2c92417ecb624816c37296d9c5b0df8cdce2f..21e914debf842e73173bb09fc6d71f14cc13b137 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/User.php @@ -19,6 +19,7 @@ * label = @Translation("User"), * module = "user", * controller_class = "Drupal\user\UserStorageController", + * access_controller_class = "Drupal\user\UserAccessController", * form_controller_class = { * "profile" = "Drupal\user\ProfileFormController", * "register" = "Drupal\user\RegisterFormController" diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php index 51fb108c04f27ff596f126b4ba7f211901ecf1da..4d6cd274e3a7a893b7b642cd9e8eaa81d0cabff9 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkCancel.php @@ -26,7 +26,7 @@ class LinkCancel extends Link { * Overrides \Drupal\user\Plugin\views\field\Link::render_link(). */ public function render_link(EntityInterface $entity, \stdClass $values) { - if ($entity && user_cancel_access($entity)) { + if ($entity && $entity->access('delete')) { $this->options['alter']['make_link'] = TRUE; $text = !empty($this->options['text']) ? $this->options['text'] : t('cancel'); diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php index 27909e49b5208ca0a39b21f4deccf580b2223d54..82931c9ec27e98e5cb8fd553cefa038c8caf84f8 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/LinkEdit.php @@ -26,7 +26,7 @@ class LinkEdit extends Link { * Overrides \Drupal\user\Plugin\views\field\Link::render_link(). */ public function render_link(EntityInterface $entity, \stdClass $values) { - if ($entity && user_edit_access($entity)) { + if ($entity && $entity->access('edit')) { $this->options['alter']['make_link'] = TRUE; $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); diff --git a/core/modules/user/lib/Drupal/user/UserAccessController.php b/core/modules/user/lib/Drupal/user/UserAccessController.php new file mode 100644 index 0000000000000000000000000000000000000000..f0202d0d9c8b0677c4c02b7f9ea39792775d34b4 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/UserAccessController.php @@ -0,0 +1,74 @@ +<?php + +/** + * @file + * Contains \Drupal\user\UserAccessController. + */ + +namespace Drupal\user; + +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityAccessControllerInterface; +use Drupal\user\Plugin\Core\Entity\User; + +/** + * Defines the access controller for the user entity type. + */ +class UserAccessController implements EntityAccessControllerInterface { + + /** + * Implements EntityAccessControllerInterface::viewAccess(). + */ + public function viewAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) { + $uid = $entity->uid; + if (!$account) { + $account = $GLOBALS['user']; + } + + // Never allow access to view the anonymous user account. + if ($uid) { + // Admins can view all, users can view own profiles at all times. + if ($account->uid == $uid || user_access('administer users', $account)) { + return TRUE; + } + elseif (user_access('access user profiles', $account)) { + // Only allow view access if the account is active. + return $entity->status; + } + } + return FALSE; + } + + /** + * Implements EntityAccessControllerInterface::createAccess(). + */ + public function createAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) { + return user_access('administer users', $account); + } + + /** + * Implements EntityAccessControllerInterface::updateAccess(). + */ + public function updateAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) { + if (!$account) { + $account = $GLOBALS['user']; + } + // Users can always edit their own account. Users with the 'administer + // users' permission can edit any account except the anonymous account. + return (($account->uid == $entity->uid) || user_access('administer users', $account)) && $entity->uid > 0; + } + + /** + * Implements EntityAccessControllerInterface::deleteAccess(). + */ + public function deleteAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) { + if (!$account) { + $account = $GLOBALS['user']; + } + // Users with 'cancel account' permission can cancel their own account, + // users with 'administer users' permission can cancel any account except + // the anonymous account. + return ((($account->uid == $entity->uid) && user_access('cancel account', $account)) || user_access('administer users', $account)) && $entity->uid > 0; + } + +} diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 55314bbee1445e891bab723cea6550da85f98777..4500c9beecfa57ad2ddce23469496aa38ee11933 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -861,49 +861,6 @@ function user_register_access() { return user_is_anonymous() && (config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY); } -/** - * User view access callback. - * - * @param $account - * Can either be a full user object or a $uid. - */ -function user_view_access($account) { - $uid = is_object($account) ? $account->uid : (int) $account; - - // Never allow access to view the anonymous user account. - if ($uid) { - // Admins can view all, users can view own profiles at all times. - if ($GLOBALS['user']->uid == $uid || user_access('administer users')) { - return TRUE; - } - elseif (user_access('access user profiles')) { - // At this point, load the complete account object. - if (!is_object($account)) { - $account = user_load($uid); - } - return (is_object($account) && $account->status); - } - } - return FALSE; -} - -/** - * Access callback for user account editing. - */ -function user_edit_access($account) { - return (($GLOBALS['user']->uid == $account->uid) || user_access('administer users')) && $account->uid > 0; -} - -/** - * Menu access callback; limit access to account cancellation pages. - * - * Limit access to users with the 'cancel account' permission or administrative - * users, and prevent the anonymous user from cancelling the account. - */ -function user_cancel_access($account) { - return ((($GLOBALS['user']->uid == $account->uid) && user_access('cancel account')) || user_access('administer users')) && $account->uid > 0; -} - /** * Implements hook_menu(). */ @@ -1079,7 +1036,7 @@ function user_menu() { 'title arguments' => array(1), 'page callback' => 'user_view_page', 'page arguments' => array(1), - 'access callback' => 'user_view_access', + 'access callback' => 'entity_page_access', 'access arguments' => array(1), ); @@ -1093,8 +1050,8 @@ function user_menu() { 'title' => 'Cancel account', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_cancel_confirm_form', 1), - 'access callback' => 'user_cancel_access', - 'access arguments' => array(1), + 'access callback' => 'entity_page_access', + 'access arguments' => array(1, 'delete'), 'file' => 'user.pages.inc', ); @@ -1102,8 +1059,8 @@ function user_menu() { 'title' => 'Confirm account cancellation', 'page callback' => 'user_cancel_confirm', 'page arguments' => array(1, 4, 5), - 'access callback' => 'user_cancel_access', - 'access arguments' => array(1), + 'access callback' => 'entity_page_access', + 'access arguments' => array(1, 'delete'), 'file' => 'user.pages.inc', ); @@ -1111,8 +1068,8 @@ function user_menu() { 'title' => 'Edit', 'page callback' => 'entity_get_form', 'page arguments' => array(1, 'profile'), - 'access callback' => 'user_edit_access', - 'access arguments' => array(1), + 'access callback' => 'entity_page_access', + 'access arguments' => array(1, 'update'), 'type' => MENU_LOCAL_TASK, 'file' => 'user.pages.inc', ); @@ -2715,7 +2672,7 @@ function user_rdf_mapping() { */ function user_file_download_access($field, EntityInterface $entity, File $file) { if ($entity->entityType() == 'user') { - return user_view_access($entity); + return $entity->access('view'); } }