/** * Redirects on 403 Access Denied kernel exceptions. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The Event to process. */ public function onKernelException(GetResponseEvent $event) { $exception = $event->getException(); if (!$exception instanceof AccessDeniedHttpException) { return; } $config = $this->configFactory->get('r4032login.settings'); $options = array(); $options['query'] = $this->redirectDestination->getAsArray(); $options['absolute'] = TRUE; $code = $config->get('default_redirect_code'); if ($this->currentUser->isAnonymous()) { // Show custom access denied message if set. if ($config->get('display_denied_message')) { $message = $config->get('access_denied_message'); $message_type = $config->get('access_denied_message_type'); drupal_set_message(Xss::filterAdmin($message), $message_type); } // Handle redirection to the login form. $login_route = $config->get('user_login_route'); $url = Url::fromRoute($login_route, array(), $options)->toString(); $response = new RedirectResponse($url, $code); $event->setResponse($response); } else { // Check to see if we are to redirect the user. $redirect = $config->get('redirect_authenticated_users_to'); if ($redirect) { // Custom access denied page for logged in users. $url = Url::fromUserInput($redirect, $options)->toString(); $response = new RedirectResponse($url, $code); $event->setResponse($response); } } }
/** * {@inheritdoc} */ protected function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); $destination = $this->redirectDestination->getAsArray(); foreach ($operations as $key => $operation) { $operations[$key]['query'] = $destination; } return $operations; }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = NULL) { $this->data['version'] = Drupal::VERSION; $this->data['profile'] = drupal_get_profile(); $this->data['config_url'] = (new Drupal\Core\Url('webprofiler.settings', [], ['query' => $this->redirectDestination->getAsArray()]))->toString(); try { $process = new Process("git log -1 --pretty=format:'%H - %s (%ci)' --abbrev-commit"); $process->setTimeout(3600); $process->mustRun(); $this->data['git_commit'] = $process->getOutput(); $process = new Process("git log -1 --pretty=format:'%h' --abbrev-commit"); $process->setTimeout(3600); $process->mustRun(); $this->data['abbr_git_commit'] = $process->getOutput(); } catch (ProcessFailedException $e) { $this->data['git_commit'] = $this->data['git_commit_abbr'] = NULL; } }
/** * {@inheritdoc} */ public function getOperations(EntityInterface $entity) { $operations = parent::getOperations($entity); if (isset($operations['edit'])) { $destination = $this->redirectDestination->getAsArray(); $operations['edit']['query'] = $destination; } return $operations; }
/** * Gets operations for a rule. * * @param \Drupal\rng\RuleInterface $rule * The rule. * * @return array * An array of links suitable for an 'operations' element. */ protected function getOperations(RuleInterface $rule) { $links = []; $destination = $this->redirectDestination->getAsArray(); if ($component = $this->getDateCondition($rule)) { if ($component->access('edit')) { $links['edit-date'] = ['title' => $this->t('Edit date'), 'url' => $component->urlInfo('edit-form'), 'query' => $destination]; } } if ($rule->access('delete')) { $links['delete'] = ['title' => $this->t('Delete'), 'url' => $rule->urlInfo('delete-form'), 'query' => $destination]; } return $links; }
/** * {@inheritdoc} * * @param \Drupal\rng\RuleInterface $entity * A rule entity. */ public function buildRow(EntityInterface $entity) { $row['id'] = $entity->id(); $row['trigger'] = $entity->getTriggerID(); $row['conditions']['data'] = array('#theme' => 'links', '#links' => [], '#attributes' => ['class' => ['links', 'inline']]); foreach ($entity->getConditions() as $condition) { $row['conditions']['data']['#links'][] = array('title' => $this->t('Edit', ['@condition_id' => $condition->id(), '@condition' => $condition->getPluginId()]), 'url' => $condition->urlInfo('edit-form'), 'query' => $this->redirectDestination->getAsArray()); } $row['actions']['data'] = array('#theme' => 'links', '#links' => [], '#attributes' => ['class' => ['links', 'inline']]); foreach ($entity->getActions() as $action) { $row['actions']['data']['#links'][] = array('title' => $this->t('Edit', ['@action_id' => $action->id(), '@action' => $action->getPluginId()]), 'url' => $action->urlInfo('edit-form'), 'query' => $this->redirectDestination->getAsArray()); } $row['status'] = $entity->isActive() ? $this->t('Active') : $this->t('Inactive'); return $row + parent::buildRow($entity); }
/** * {@inheritdoc} */ protected function getDefaultOperations(EntityInterface $entity) { $operations = parent::getDefaultOperations($entity); $operations['edit']['weight'] = 0; if ($entity->access('import') && $entity->hasLinkTemplate('import-form')) { $operations['import'] = ['title' => $this->t('Import'), 'weight' => 2, 'url' => $entity->urlInfo('import-form')]; } if ($entity->access('clear') && $entity->hasLinkTemplate('clear-form')) { $operations['clear'] = ['title' => $this->t('Delete items'), 'weight' => 3, 'url' => $entity->urlInfo('clear-form')]; } $destination = $this->redirectDestination->getAsArray(); foreach ($operations as $key => $operation) { $operations[$key]['query'] = $destination; } return $operations; }
/** * Makes a subrequest to retrieve the default error page. * * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event * The event to process. * @param string $url * The path/url to which to make a subrequest for this error message. * @param int $status_code * The status code for the error being handled. */ protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) { $request = $event->getRequest(); $exception = $event->getException(); try { // Reuse the exact same request (so keep the same URL, keep the access // result, the exception, et cetera) but override the routing information. // This means that aside from routing, this is identical to the master // request. This allows us to generate a response that is executed on // behalf of the master request, i.e. for the original URL. This is what // allows us to e.g. generate a 404 response for the original URL; if we // would execute a subrequest with the 404 route's URL, then it'd be // generated for *that* URL, not the *original* URL. $sub_request = clone $request; // The routing to the 404 page should be done as GET request because it is // restricted to GET and POST requests only. Otherwise a DELETE request // would for example trigger a method not allowed exception. $request_context = clone $this->accessUnawareRouter->getContext(); $request_context->setMethod('GET'); $this->accessUnawareRouter->setContext($request_context); $sub_request->attributes->add($this->accessUnawareRouter->match($url)); // Add to query (GET) or request (POST) parameters: // - 'destination' (to ensure e.g. the login form in a 403 response // redirects to the original URL) // - '_exception_statuscode' $parameters = $sub_request->isMethod('GET') ? $sub_request->query : $sub_request->request; $parameters->add($this->redirectDestination->getAsArray() + ['_exception_statuscode' => $status_code]); $response = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST); // Only 2xx responses should have their status code overridden; any // other status code should be passed on: redirects (3xx), error (5xx)… // @see https://www.drupal.org/node/2603788#comment-10504916 if ($response->isSuccessful()) { $response->setStatusCode($status_code); } // Persist any special HTTP headers that were set on the exception. if ($exception instanceof HttpExceptionInterface) { $response->headers->add($exception->getHeaders()); } $event->setResponse($response); } catch (\Exception $e) { // If an error happened in the subrequest we can't do much else. Instead, // just log it. The DefaultExceptionSubscriber will catch the original // exception and handle it normally. $error = Error::decodeException($e); $this->logger->log($error['severity_level'], '%type: @message in %function (line %line of %file).', $error); } }
/** * Makes a subrequest to retrieve the default error page. * * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event * The event to process * @param string $url * The path/url to which to make a subrequest for this error message. * @param int $status_code * The status code for the error being handled. */ protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) { $request = $event->getRequest(); $exception = $event->getException(); if (!($url && $url[0] == '/')) { $url = $request->getBasePath() . '/' . $url; } $current_url = $request->getBasePath() . $request->getPathInfo(); if ($url != $request->getBasePath() . '/' && $url != $current_url) { if ($request->getMethod() === 'POST') { $sub_request = Request::create($url, 'POST', $this->redirectDestination->getAsArray() + ['_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all()); } else { $sub_request = Request::create($url, 'GET', $request->query->all() + $this->redirectDestination->getAsArray() + ['_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all()); } try { // Persist the 'exception' attribute to the subrequest. $sub_request->attributes->set('exception', $request->attributes->get('exception')); // Persist the access result attribute to the subrequest, so that the // error page inherits the access result of the master request. $sub_request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, $request->attributes->get(AccessAwareRouterInterface::ACCESS_RESULT)); // Carry over the session to the subrequest. if ($session = $request->getSession()) { $sub_request->setSession($session); } $response = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST); // Only 2xx responses should have their status code overridden; any // other status code should be passed on: redirects (3xx), error (5xx)… // @see https://www.drupal.org/node/2603788#comment-10504916 if ($response->isSuccessful()) { $response->setStatusCode($status_code); } // Persist any special HTTP headers that were set on the exception. if ($exception instanceof HttpExceptionInterface) { $response->headers->add($exception->getHeaders()); } $event->setResponse($response); } catch (\Exception $e) { // If an error happened in the subrequest we can't do much else. Instead, // just log it. The DefaultExceptionSubscriber will catch the original // exception and handle it normally. $error = Error::decodeException($e); $this->logger->log($error['severity_level'], '%type: @message in %function (line %line of %file).', $error); } } }
/** * {@inheritdoc} */ public function collect(Request $request, Response $response, \Exception $exception = NULL) { $this->data['version'] = Drupal::VERSION; $this->data['profile'] = drupal_get_profile(); $this->data['config_url'] = $this->urlGenerator->generateFromRoute('webprofiler.settings', [], ['query' => $this->redirectDestination->getAsArray()]); }
/** * Provides the Switch user list. */ public function switchUserList() { $list_size = $this->configuration['list_size']; $include_anon = $this->configuration['include_anon']; $anon = new AnonymousUserSession(); $links = array(); if ($this->currentUser->hasPermission('switch users')) { if ($include_anon) { --$list_size; } $dest = $this->redirectDestination->getAsArray(); // Try to find at least $list_size users that can switch. // Inactive users are omitted from all of the following db selects. $roles = user_roles(TRUE, 'switch users'); $query = db_select('users', 'u'); $query->join('users_field_data', 'ufd'); $query->addField('u', 'uid'); $query->addField('ufd', 'access'); $query->distinct(); $query->condition('u.uid', 0, '>'); $query->condition('ufd.status', 0, '>'); $query->orderBy('ufd.access', 'DESC'); $query->range(0, $list_size); if (!isset($roles[DRUPAL_AUTHENTICATED_RID])) { $query->leftJoin('users_roles', 'r', 'u.uid = r.uid'); $or_condition = db_or(); $or_condition->condition('u.uid', 1); if (!empty($roles)) { $or_condition->condition('r.rid', array_keys($roles), 'IN'); } $query->condition($or_condition); } $uids = $query->execute()->fetchCol(); $accounts = user_load_multiple($uids); foreach ($accounts as $account) { $path = 'devel/switch/' . $account->name->value; $links[$account->id()] = array('title' => user_format_name($account), 'href' => $path, 'query' => $dest + array('token' => $this->csrfTokenGenerator->get($path)), 'attributes' => array('title' => t('This user can switch back.')), 'html' => TRUE, 'last_access' => $account->access->value); } $num_links = count($links); if ($num_links < $list_size) { // If we don't have enough, add distinct uids until we hit $list_size. $uids = db_query_range('SELECT u.uid FROM {users} u INNER JOIN {users_field_data} ufd WHERE u.uid > 0 AND u.uid NOT IN (:uids) AND ufd.status > 0 ORDER BY ufd.access DESC', 0, $list_size - $num_links, array(':uids' => array_keys($links)))->fetchCol(); $accounts = user_load_multiple($uids); foreach ($accounts as $account) { $path = 'devel/switch/' . $account->name->value; $links[$account->id()] = array('title' => user_format_name($account), 'href' => $path, 'query' => $dest + array('token' => $this->csrfTokenGenerator->get($path)), 'attributes' => array('title' => t('Caution: this user will be unable to switch back.')), 'last_access' => $account->access->value); } uasort($links, '_devel_switch_user_list_cmp'); } if ($include_anon) { $path = 'devel/switch'; $link = array('title' => $anon->getUsername(), 'href' => $path, 'query' => $dest + array('token' => $this->csrfTokenGenerator->get($path)), 'attributes' => array('title' => t('Caution: the anonymous user will be unable to switch back.'))); if ($this->currentUser->hasPermission('switch users')) { $link['title'] = SafeMarkup::placeholder($link['title']); $link['attributes'] = array('title' => t('This user can switch back.')); $link['html'] = TRUE; } $links[$anon->id()] = $link; } } if (array_key_exists($uid = $this->currentUser->id(), $links)) { $links[$uid]['title'] = '<strong>' . $links[$uid]['title'] . '</strong>'; } return $links; }
/** * Displays a list of actions which are related to registration access on an * event. * * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The current route. * @param string $event * The parameter to find the event entity. * * @return array * A render array. */ public function listing_access(RouteMatchInterface $route_match, $event) { $event = $route_match->getParameter($event); $destination = $this->redirectDestination->getAsArray(); $event_meta = $this->eventManager->getMeta($event); $trigger = 'rng_event.register'; $build = []; $build['description'] = ['#prefix' => '<p>', '#markup' => $this->t('The following rules determine who is eligible to register or perform an operation on a registration.<br />Access is granted if all conditions for a rule evaluate as true.'), '#suffix' => '</p>']; $rows = []; // Header. $rows[0] = [['header' => TRUE, 'rowspan' => 2, 'data' => $this->t('Rule')], ['header' => TRUE, 'rowspan' => 2, 'data' => $this->t('Component')], ['header' => TRUE, 'rowspan' => 2, 'data' => $this->t('Scope')], ['header' => TRUE, 'rowspan' => 1, 'data' => $this->t('Operations'), 'colspan' => 4]]; if (!$event_meta->isDefaultRules($trigger)) { $rows[0][] = ['header' => TRUE, 'rowspan' => 2, 'data' => '']; } $operations = ['create' => $this->t('Create'), 'view' => $this->t('View'), 'update' => $this->t('Update'), 'delete' => $this->t('Delete')]; foreach ($operations as $operation) { $rows['operations'][] = ['header' => TRUE, 'data' => $operation]; } $i = 0; $rules = $event_meta->getRules($trigger, TRUE); foreach ($rules as $rule) { $i++; $scope_all = FALSE; $supports_create = 0; $condition_context = []; // Conditions. $k = 0; $row = []; $row['rule'] = ['header' => FALSE, 'data' => $this->t('@row.', ['@row' => $i]), 'rowspan' => count($rule->getConditions()) + 1]; foreach ($rule->getConditions() as $condition_storage) { $k++; $row[] = ['header' => TRUE, 'data' => $this->t('Condition #@condition', ['@condition' => $k])]; $condition = $condition_storage->createInstance(); $condition_context += array_keys($condition->getContextDefinitions()); $scope_all = !in_array('registration', $condition_context) || in_array('event', $condition_context); if (isset($row['rule']['rowspan']) && $scope_all) { $row['rule']['rowspan']++; } if ($condition instanceof RNGConditionInterface) { $supports_create++; } $row[] = ['colspan' => 5, 'data' => $condition->summary()]; if (!$event_meta->isDefaultRules($trigger)) { $row['condition_operations']['data'] = ['#type' => 'operations']; if ($condition_storage->access('edit')) { $row['condition_operations']['data']['#links']['edit'] = ['title' => t('Edit'), 'url' => $condition_storage->urlInfo('edit-form'), 'query' => $destination]; } } $rows[] = ['data' => $row, 'no_striping' => TRUE]; $row = []; } // Actions. foreach ($rule->getActions() as $action_storage) { $row = []; $row[] = ['header' => TRUE, 'data' => $this->t('Grants operations'), 'rowspan' => $scope_all ? 2 : 1]; // Scope: warn user actions apply to all registrations. $row[]['data'] = $scope_all ? $this->t('All registrations.') : $this->t('Single registration'); // Operations granted. $config = $action_storage->getConfiguration(); foreach ($operations as $op => $t) { $message = !empty($config['operations'][$op]) ? $t : '-'; $row['operation_' . $op] = ['data' => $op == 'create' && $supports_create != count($rule->getConditions()) ? $this->t('<em>N/A</em>') : $message]; } if (!$event_meta->isDefaultRules($trigger)) { $links = []; if ($action_storage->access('edit')) { $links['edit'] = ['title' => t('Edit'), 'url' => $action_storage->urlInfo('edit-form'), 'query' => $destination]; } $row[] = ['data' => ['#type' => 'operations', '#links' => $links], 'rowspan' => $scope_all ? 2 : 1]; } $rows[] = $row; if ($scope_all) { $rows[] = [['data' => $this->t('<strong>Warning:</strong> selecting view, update, or delete grants access to any registration on this event.'), 'colspan' => 5]]; } } } $build[] = ['#type' => 'table', '#header' => [], '#rows' => $rows, '#empty' => $this->t('No access rules.')]; return $build; }
/** * {@inheritdoc} */ public function getOperations($plugin_id) { $operations['configure'] = array('title' => $this->t('Configure'), 'query' => $this->redirectDestination->getAsArray(), 'url' => new Url('currency.exchange_rate_provider.fixed_rates.overview')); return $operations; }