/** * Determines if redirect may be performed. * * @param Request $request * The current request object. * @param string $route_name * The current route name. * * @return bool * TRUE if redirect may be performed. */ public function canRedirect(Request $request, $route_name = NULL) { $can_redirect = TRUE; if (isset($route_name)) { $route = $this->routeProvider->getRouteByName($route_name); if ($this->config->get('access_check')) { // Do not redirect if is a protected page. $can_redirect &= $this->accessManager->check($route, $request, $this->account); } } else { $route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT); } if (strpos($request->getScriptName(), 'index.php') === FALSE) { // Do not redirect if the root script is not /index.php. $can_redirect = FALSE; } elseif (!($request->isMethod('GET') || $request->isMethod('HEAD'))) { // Do not redirect if this is other than GET request. $can_redirect = FALSE; } elseif ($this->state->get('system.maintenance_mode') || defined('MAINTENANCE_MODE')) { // Do not redirect in offline or maintenance mode. $can_redirect = FALSE; } elseif ($this->config->get('ignore_admin_path') && isset($route)) { // Do not redirect on admin paths. $can_redirect &= !(bool) $route->getOption('_admin_route'); } return $can_redirect; }
/** * {@inheritdoc} */ public function getRouteParameters(RouteMatchInterface $route_match) { $parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array(); $route = $this->routeProvider->getRouteByName($this->getRouteName()); $variables = $route->compile()->getVariables(); // Normally the \Drupal\Core\ParamConverter\ParamConverterManager has // processed the Request attributes, and in that case the _raw_variables // attribute holds the original path strings keyed to the corresponding // slugs in the path patterns. For example, if the route's path pattern is // /filter/tips/{filter_format} and the path is /filter/tips/plain_text then // $raw_variables->get('filter_format') == 'plain_text'. $raw_variables = $route_match->getRawParameters(); foreach ($variables as $name) { if (isset($parameters[$name])) { continue; } if ($raw_variables && $raw_variables->has($name)) { $parameters[$name] = $raw_variables->get($name); } elseif ($value = $route_match->getRawParameter($name)) { $parameters[$name] = $value; } } // The UrlGenerator will throw an exception if expected parameters are // missing. This method should be overridden if that is possible. return $parameters; }
/** * Checks access to the route. * * @param string $route_name * The current route name. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. * * @return bool * TRUE if access is granted. */ public function canRedirect($route_name, Request $request) { $do_redirect = TRUE; /** @var \Symfony\Component\Routing\Route $route */ $route = $this->routeProvider->getRouteByName($route_name); if ($this->config->get('access_check')) { $do_redirect &= $this->accessManager->check($route, $request, $this->account); } if ($this->config->get('ignore_admin_path')) { $do_redirect &= !(bool) $route->getOption('_admin_route'); } return $do_redirect; }
/** * {@inheritdoc} */ public function getBaseRoute() { if ($this->routeCollection) { return $this->routeCollection->get($this->getBaseRouteName()); } else { return $this->routeProvider->getRouteByName($this->getBaseRouteName()); } }
/** * {@inheritdoc} */ public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account = NULL, $return_as_object = FALSE) { try { $route = $this->routeProvider->getRouteByName($route_name, $parameters); // ParamConverterManager relies on the route object being available // from the parameters array. $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route; $upcasted_parameters = $this->paramConverterManager->convert($parameters + $route->getDefaults()); $route_match = new RouteMatch($route_name, $route, $upcasted_parameters, $parameters); return $this->check($route_match, $account, NULL, $return_as_object); } catch (RouteNotFoundException $e) { // Cacheable until extensions change. $result = AccessResult::forbidden()->addCacheTags(array('extension')); return $return_as_object ? $result : $result->isAllowed(); } catch (ParamNotConvertedException $e) { // Uncacheable because conversion of the parameter may not have been // possible due to dynamic circumstances. $result = AccessResult::forbidden()->setCacheable(FALSE); return $return_as_object ? $result : $result->isAllowed(); } }
/** * Logs in a user. * * @param \Symfony\Component\HttpFoundation\Request $request * The request. * * @return \Symfony\Component\HttpFoundation\Response * A response which contains the ID and CSRF token. */ public function login(Request $request) { $format = $this->getRequestFormat($request); $content = $request->getContent(); $credentials = $this->serializer->decode($content, $format); if (!isset($credentials['name']) && !isset($credentials['pass'])) { throw new BadRequestHttpException('Missing credentials.'); } if (!isset($credentials['name'])) { throw new BadRequestHttpException('Missing credentials.name.'); } if (!isset($credentials['pass'])) { throw new BadRequestHttpException('Missing credentials.pass.'); } $this->floodControl($request, $credentials['name']); if ($this->userIsBlocked($credentials['name'])) { throw new BadRequestHttpException('The user has not been activated or is blocked.'); } if ($uid = $this->userAuth->authenticate($credentials['name'], $credentials['pass'])) { $this->flood->clear('user.http_login', $this->getLoginFloodIdentifier($request, $credentials['name'])); /** @var \Drupal\user\UserInterface $user */ $user = $this->userStorage->load($uid); $this->userLoginFinalize($user); // Send basic metadata about the logged in user. $response_data = []; if ($user->get('uid')->access('view', $user)) { $response_data['current_user']['uid'] = $user->id(); } if ($user->get('roles')->access('view', $user)) { $response_data['current_user']['roles'] = $user->getRoles(); } if ($user->get('name')->access('view', $user)) { $response_data['current_user']['name'] = $user->getAccountName(); } $response_data['csrf_token'] = $this->csrfToken->get('rest'); $logout_route = $this->routeProvider->getRouteByName('user.logout.http'); // Trim '/' off path to match \Drupal\Core\Access\CsrfAccessCheck. $logout_path = ltrim($logout_route->getPath(), '/'); $response_data['logout_token'] = $this->csrfToken->get($logout_path); $encoded_response_data = $this->serializer->encode($response_data, $format); return new Response($encoded_response_data); } $flood_config = $this->config('user.flood'); if ($identifier = $this->getLoginFloodIdentifier($request, $credentials['name'])) { $this->flood->register('user.http_login', $flood_config->get('user_window'), $identifier); } // Always register an IP-based failed login event. $this->flood->register('user.failed_login_ip', $flood_config->get('ip_window')); throw new BadRequestHttpException('Sorry, unrecognized username or password.'); }
/** * Checks a named route with parameters against applicable access check services. * * Determines whether the route is accessible or not. * * @param string $route_name * The route to check access to. * @param array $parameters * Optional array of values to substitute into the route path patern. * @param \Drupal\Core\Session\AccountInterface $account * The current user. * @param \Symfony\Component\HttpFoundation\Request $route_request * Optional incoming request object. If not provided, one will be built * using the route information and the current request from the container. * * @return bool * Returns TRUE if the user has access to the route, otherwise FALSE. */ public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL) { try { $route = $this->routeProvider->getRouteByName($route_name, $parameters); if (empty($route_request)) { // Create a request and copy the account from the current request. $defaults = $parameters + $route->getDefaults(); $route_request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), $this->urlGenerator->generate($route_name, $defaults)); $defaults[RouteObjectInterface::ROUTE_OBJECT] = $route; $route_request->attributes->add($this->paramConverterManager->convert($defaults, $route_request)); } return $this->check($route, $route_request, $account); } catch (RouteNotFoundException $e) { return FALSE; } catch (ParamNotConvertedException $e) { return FALSE; } }
/** * {@inheritdoc} */ public function checkNamedRoute($route_name, array $parameters = array(), AccountInterface $account, Request $route_request = NULL) { try { $route = $this->routeProvider->getRouteByName($route_name, $parameters); if (empty($route_request)) { // Create a cloned request with fresh attributes. $route_request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), $this->urlGenerator->generate($route_name, $parameters)); $route_request->attributes->replace(array()); // Populate $route_request->attributes with both raw and converted // parameters. $parameters += $route->getDefaults(); $route_request->attributes->set('_raw_variables', new ParameterBag($parameters)); $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route; $route_request->attributes->add($this->paramConverterManager->convert($parameters, $route_request)); } return $this->check($route, $route_request, $account); } catch (RouteNotFoundException $e) { return FALSE; } catch (ParamNotConvertedException $e) { return FALSE; } }
/** * Implements DerivativeInterface::getDerivativeDefinitions(). */ public function getDerivativeDefinitions($base_plugin_definition) { if (!isset($this->derivatives)) { // Add in the default plugin configuration and the resource type. foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { $this->derivatives[$entity_type_id] = array('id' => 'entity:' . $entity_type_id, 'entity_type' => $entity_type_id, 'serialization_class' => $entity_type->getClass(), 'label' => $entity_type->getLabel()); $default_uris = array('canonical' => "/entity/{$entity_type_id}/" . '{' . $entity_type_id . '}', 'http://drupal.org/link-relations/create' => "/entity/{$entity_type_id}"); foreach ($default_uris as $link_relation => $default_uri) { // Check if there are link templates defined for the entity type and // use the path from the route instead of the default. if ($route_name = $entity_type->getLinkTemplate($link_relation)) { // @todo remove the try/catch as part of // http://drupal.org/node/2158571 try { $route = $this->routeProvider->getRouteByName($route_name); $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath(); } catch (RouteNotFoundException $e) { if (($collection = $this->routeBuilder->getCollectionDuringRebuild()) && ($route = $collection->get($route_name))) { $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath(); } else { // If the route does not exist it means we are in a brittle state // of module enabling/disabling, so we simply exclude this entity // type. unset($this->derivatives[$entity_type_id]); // Continue with the next entity type; continue 2; } } } else { $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $default_uri; } } $this->derivatives[$entity_type_id] += $base_plugin_definition; } } return $this->derivatives; }
/** * Tests dynamic routes. */ public function testDynamicRoutes() { $this->installConfig(['entity_browser_test']); $this->container->get('router.builder')->rebuild(); /** @var $entity \Drupal\entity_browser\EntityBrowserInterface */ $entity = $this->controller->load('test'); $route = $entity->route(); $this->assertEquals($route->getPath(), '/entity-browser/test', 'Dynamic path matches.'); $this->assertEquals($route->getDefault('entity_browser_id'), $entity->id(), 'Entity browser ID matches.'); $this->assertEquals($route->getDefault('_controller'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::page', 'Controller matches.'); $this->assertEquals($route->getDefault('_title_callback'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::title', 'Title callback matches.'); $this->assertEquals($route->getRequirement('_permission'), 'access ' . $entity->id() . ' entity browser pages', 'Permission matches.'); try { $registered_route = $this->routeProvider->getRouteByName('entity_browser.' . $entity->id()); } catch (\Exception $e) { $this->fail(t('Expected route not found: @message', array('@message' => $e->getMessage()))); return; } $this->assertEquals($registered_route->getPath(), '/entity-browser/test', 'Dynamic path matches.'); $this->assertEquals($registered_route->getDefault('entity_browser_id'), $entity->id(), 'Entity browser ID matches.'); $this->assertEquals($registered_route->getDefault('_controller'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::page', 'Controller matches.'); $this->assertEquals($registered_route->getDefault('_title_callback'), 'Drupal\\entity_browser\\Controllers\\StandalonePage::title', 'Title callback matches.'); $this->assertEquals($registered_route->getRequirement('_permission'), 'access ' . $entity->id() . ' entity browser pages', 'Permission matches.'); }
/** * Get the URL for the current view. * * This URL will be adjusted for arguments. * * @param array $args * (optional) Passed in arguments. * @param string $display_id * (optional) Specify the display ID to link to, fallback to the current ID. * * @return \Drupal\Core\Url */ public function getUrl($args = NULL, $display_id = NULL) { if (!empty($this->override_url)) { return $this->override_url; } if (!isset($path)) { $path = $this->getPath(); } $display_handler = $this->displayHandlers->get($display_id ?: $this->current_display)->getRoutedDisplay(); if (!$display_handler instanceof DisplayRouterInterface) { throw new \InvalidArgumentException('You cannot create a URL to a display without routes.'); } if (!isset($args)) { $args = $this->args; // Exclude arguments that were computed, not passed on the URL. $position = 0; if (!empty($this->argument)) { foreach ($this->argument as $argument) { if (!empty($argument->is_default) && !empty($argument->options['default_argument_skip_url'])) { unset($args[$position]); } $position++; } } } // Don't bother working if there's nothing to do: if (empty($path) || empty($args) && strpos($path, '%') === FALSE) { return $display_handler->getUrlInfo(); } $argument_keys = isset($this->argument) ? array_keys($this->argument) : array(); $id = current($argument_keys); /** @var \Drupal\Core\Url $url */ $url = $display_handler->getUrlInfo(); $route = $this->routeProvider->getRouteByName($url->getRouteName()); $variables = $route->compile()->getVariables(); $parameters = $url->getRouteParameters(); foreach ($variables as $variable_name) { if (empty($args)) { // Try to never put % in a URL; use the wildcard instead. if ($id && !empty($this->argument[$id]->options['exception']['value'])) { $parameters[$variable_name] = $this->argument[$id]->options['exception']['value']; } else { // Provide some fallback in case no exception value could be found. $parameters[$variable_name] = '*'; } } else { $parameters[$variable_name] = array_shift($args); } if ($id) { $id = next($argument_keys); } } $url->setRouteParameters($parameters); return $url; }
/** * Builds a table row for the system modules page. * * @param array $modules * The list existing modules. * @param \Drupal\Core\Extension\Extension $module * The module for which to build the form row. * @param $distribution * * @return array * The form row for the given module. */ protected function buildRow(array $modules, Extension $module, $distribution) { // Set the basic properties. $row['#required'] = array(); $row['#requires'] = array(); $row['#required_by'] = array(); $row['name']['#markup'] = $module->info['name']; $row['description']['#markup'] = $this->t($module->info['description']); $row['version']['#markup'] = $module->info['version']; // Generate link for module's help page, if there is one. $row['links']['help'] = array(); if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) { if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) { $row['links']['help'] = array('#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help')))); } } // Generate link for module's permission, if the user has access to it. $row['links']['permissions'] = array(); if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) { $row['links']['permissions'] = array('#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions')))); } // Generate link for module's configuration page, if it has one. $row['links']['configure'] = array(); if ($module->status && isset($module->info['configure'])) { $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array(); if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) { $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']); /** @var \Drupal\Core\Menu\MenuLinkInterface $link */ $link = reset($links); // Most configure links have a corresponding menu link, though some just // have a route. if ($link) { $description = $link->getDescription(); } else { $request = new Request(); $request->attributes->set('_route_name', $module->info['configure']); $route_object = $this->routeProvider->getRouteByName($module->info['configure']); $request->attributes->set('_route', $route_object); $request->attributes->add($route_parameters); $description = $this->titleResolver->getTitle($request, $route_object); } $row['links']['configure'] = array('#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $description))); } } // Present a checkbox for installing and indicating the status of a module. $row['enable'] = array('#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status); // Disable the checkbox for required modules. if (!empty($module->info['required'])) { // Used when displaying modules that are required by the installation profile $row['enable']['#disabled'] = TRUE; $row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : ''); } // Check the compatibilities. $compatible = TRUE; // Initialize an empty array of reasons why the module is incompatible. Add // each reason as a separate element of the array. $reasons = array(); // Check the core compatibility. if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) { $compatible = FALSE; $reasons[] = $this->t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY)); } // Ensure this module is compatible with the currently installed version of PHP. if (version_compare(phpversion(), $module->info['php']) < 0) { $compatible = FALSE; $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : ''); $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $required, '!php_version' => phpversion())); } // If this module is not compatible, disable the checkbox. if (!$compatible) { $status = implode(' ', $reasons); $row['enable']['#disabled'] = TRUE; $row['description']['#markup'] = $status; $row['#attributes']['class'][] = 'incompatible'; } // If this module requires other modules, add them to the array. foreach ($module->requires as $dependency => $version) { if (!isset($modules[$dependency])) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency))); $row['enable']['#disabled'] = TRUE; } elseif (empty($modules[$dependency]->hidden)) { $name = $modules[$dependency]->info['name']; // Disable the module's checkbox if it is incompatible with the // dependency's version. if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> version @version)', array('@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version'])); $row['enable']['#disabled'] = TRUE; } elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array('@module' => $name)); $row['enable']['#disabled'] = TRUE; } elseif ($modules[$dependency]->status) { $row['#requires'][$dependency] = $this->t('@module', array('@module' => $name)); } else { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name)); } } } // If this module is required by other modules, list those, and then make it // impossible to disable this one. foreach ($module->required_by as $dependent => $version) { if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) { if ($modules[$dependent]->status == 1 && $module->status == 1) { $row['#required_by'][$dependent] = $this->t('@module', array('@module' => $modules[$dependent]->info['name'])); $row['enable']['#disabled'] = TRUE; } else { $row['#required_by'][$dependent] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name'])); } } } return $row; }