annotate core/lib/Drupal/Core/Access/AccessManager.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Access;
Chris@0 4
Chris@0 5 use Drupal\Core\ParamConverter\ParamConverterManagerInterface;
Chris@0 6 use Drupal\Core\ParamConverter\ParamNotConvertedException;
Chris@0 7 use Drupal\Core\Routing\RouteMatch;
Chris@0 8 use Drupal\Core\Routing\RouteMatchInterface;
Chris@0 9 use Drupal\Core\Routing\RouteProviderInterface;
Chris@0 10 use Drupal\Core\Session\AccountInterface;
Chris@0 11 use Drupal\Component\Utility\ArgumentsResolverInterface;
Chris@0 12 use Symfony\Component\HttpFoundation\Request;
Chris@0 13 use Symfony\Component\Routing\Exception\RouteNotFoundException;
Chris@0 14 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Attaches access check services to routes and runs them on request.
Chris@0 18 *
Chris@0 19 * @see \Drupal\Tests\Core\Access\AccessManagerTest
Chris@0 20 */
Chris@0 21 class AccessManager implements AccessManagerInterface {
Chris@0 22 /**
Chris@0 23 * The route provider.
Chris@0 24 *
Chris@0 25 * @var \Drupal\Core\Routing\RouteProviderInterface
Chris@0 26 */
Chris@0 27 protected $routeProvider;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * The paramconverter manager.
Chris@0 31 *
Chris@0 32 * @var \Drupal\Core\ParamConverter\ParamConverterManagerInterface
Chris@0 33 */
Chris@0 34 protected $paramConverterManager;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * The access arguments resolver.
Chris@0 38 *
Chris@0 39 * @var \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface
Chris@0 40 */
Chris@0 41 protected $argumentsResolverFactory;
Chris@0 42
Chris@0 43 /**
Chris@0 44 * The current user.
Chris@0 45 *
Chris@0 46 * @var \Drupal\Core\Session\AccountInterface
Chris@0 47 */
Chris@0 48 protected $currentUser;
Chris@0 49
Chris@0 50 /**
Chris@0 51 * The check provider.
Chris@0 52 *
Chris@0 53 * @var \Drupal\Core\Access\CheckProviderInterface
Chris@0 54 */
Chris@0 55 protected $checkProvider;
Chris@0 56
Chris@0 57 /**
Chris@0 58 * Constructs a AccessManager instance.
Chris@0 59 *
Chris@0 60 * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
Chris@0 61 * The route provider.
Chris@0 62 * @param \Drupal\Core\ParamConverter\ParamConverterManagerInterface $paramconverter_manager
Chris@0 63 * The param converter manager.
Chris@0 64 * @param \Drupal\Core\Access\AccessArgumentsResolverFactoryInterface $arguments_resolver_factory
Chris@0 65 * The access arguments resolver.
Chris@0 66 * @param \Drupal\Core\Session\AccountInterface $current_user
Chris@0 67 * The current user.
Chris@0 68 * @param CheckProviderInterface $check_provider
Chris@0 69 */
Chris@0 70 public function __construct(RouteProviderInterface $route_provider, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverFactoryInterface $arguments_resolver_factory, AccountInterface $current_user, CheckProviderInterface $check_provider) {
Chris@0 71 $this->routeProvider = $route_provider;
Chris@0 72 $this->paramConverterManager = $paramconverter_manager;
Chris@0 73 $this->argumentsResolverFactory = $arguments_resolver_factory;
Chris@0 74 $this->currentUser = $current_user;
Chris@0 75 $this->checkProvider = $check_provider;
Chris@0 76 }
Chris@0 77
Chris@0 78 /**
Chris@0 79 * {@inheritdoc}
Chris@0 80 */
Chris@0 81 public function checkNamedRoute($route_name, array $parameters = [], AccountInterface $account = NULL, $return_as_object = FALSE) {
Chris@0 82 try {
Chris@0 83 $route = $this->routeProvider->getRouteByName($route_name, $parameters);
Chris@0 84
Chris@0 85 // ParamConverterManager relies on the route name and object being
Chris@0 86 // available from the parameters array.
Chris@0 87 $parameters[RouteObjectInterface::ROUTE_NAME] = $route_name;
Chris@0 88 $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route;
Chris@0 89 $upcasted_parameters = $this->paramConverterManager->convert($parameters + $route->getDefaults());
Chris@0 90
Chris@0 91 $route_match = new RouteMatch($route_name, $route, $upcasted_parameters, $parameters);
Chris@0 92 return $this->check($route_match, $account, NULL, $return_as_object);
Chris@0 93 }
Chris@0 94 catch (RouteNotFoundException $e) {
Chris@0 95 // Cacheable until extensions change.
Chris@0 96 $result = AccessResult::forbidden()->addCacheTags(['config:core.extension']);
Chris@0 97 return $return_as_object ? $result : $result->isAllowed();
Chris@0 98 }
Chris@0 99 catch (ParamNotConvertedException $e) {
Chris@0 100 // Uncacheable because conversion of the parameter may not have been
Chris@0 101 // possible due to dynamic circumstances.
Chris@0 102 $result = AccessResult::forbidden()->setCacheMaxAge(0);
Chris@0 103 return $return_as_object ? $result : $result->isAllowed();
Chris@0 104 }
Chris@0 105 }
Chris@0 106
Chris@0 107 /**
Chris@0 108 * {@inheritdoc}
Chris@0 109 */
Chris@0 110 public function checkRequest(Request $request, AccountInterface $account = NULL, $return_as_object = FALSE) {
Chris@0 111 $route_match = RouteMatch::createFromRequest($request);
Chris@0 112 return $this->check($route_match, $account, $request, $return_as_object);
Chris@0 113 }
Chris@0 114
Chris@0 115 /**
Chris@0 116 * {@inheritdoc}
Chris@0 117 */
Chris@0 118 public function check(RouteMatchInterface $route_match, AccountInterface $account = NULL, Request $request = NULL, $return_as_object = FALSE) {
Chris@0 119 if (!isset($account)) {
Chris@0 120 $account = $this->currentUser;
Chris@0 121 }
Chris@0 122 $route = $route_match->getRouteObject();
Chris@0 123 $checks = $route->getOption('_access_checks') ?: [];
Chris@0 124
Chris@0 125 // Filter out checks which require the incoming request.
Chris@0 126 if (!isset($request)) {
Chris@0 127 $checks = array_diff($checks, $this->checkProvider->getChecksNeedRequest());
Chris@0 128 }
Chris@0 129
Chris@0 130 $result = AccessResult::neutral();
Chris@0 131 if (!empty($checks)) {
Chris@0 132 $arguments_resolver = $this->argumentsResolverFactory->getArgumentsResolver($route_match, $account, $request);
Chris@0 133 $result = AccessResult::allowed();
Chris@0 134 foreach ($checks as $service_id) {
Chris@0 135 $result = $result->andIf($this->performCheck($service_id, $arguments_resolver));
Chris@0 136 }
Chris@0 137 }
Chris@0 138 return $return_as_object ? $result : $result->isAllowed();
Chris@0 139 }
Chris@0 140
Chris@0 141 /**
Chris@0 142 * Performs the specified access check.
Chris@0 143 *
Chris@0 144 * @param string $service_id
Chris@0 145 * The access check service ID to use.
Chris@0 146 * @param \Drupal\Component\Utility\ArgumentsResolverInterface $arguments_resolver
Chris@0 147 * The parametrized arguments resolver instance.
Chris@0 148 *
Chris@0 149 * @return \Drupal\Core\Access\AccessResultInterface
Chris@0 150 * The access result.
Chris@0 151 *
Chris@0 152 * @throws \Drupal\Core\Access\AccessException
Chris@0 153 * Thrown when the access check returns an invalid value.
Chris@0 154 */
Chris@0 155 protected function performCheck($service_id, ArgumentsResolverInterface $arguments_resolver) {
Chris@0 156 $callable = $this->checkProvider->loadCheck($service_id);
Chris@0 157 $arguments = $arguments_resolver->getArguments($callable);
Chris@0 158 /** @var \Drupal\Core\Access\AccessResultInterface $service_access **/
Chris@0 159 $service_access = call_user_func_array($callable, $arguments);
Chris@0 160
Chris@0 161 if (!$service_access instanceof AccessResultInterface) {
Chris@0 162 throw new AccessException("Access error in $service_id. Access services must return an object that implements AccessResultInterface.");
Chris@0 163 }
Chris@0 164
Chris@0 165 return $service_access;
Chris@0 166 }
Chris@0 167
Chris@0 168 }