Commit cccc57ba authored by Primoz Hmeljak's avatar Primoz Hmeljak Committed by Sascha Grossenbacher
Browse files

Issue #3344064 by Primsi: Allow non admin users to ignore 404 pages

parent b7c56834
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
ignore 404 requests:
  title: 'Ignore 404 requests'
  description: 'This allows users without the Administer redirect settings to ignore specific 404 requests, without the ability to customize the 404 exclude patterns.'
+1 −1
Original line number Diff line number Diff line
@@ -11,5 +11,5 @@ redirect_404.ignore_404:
  defaults:
    _controller: '\Drupal\redirect_404\Controller\Fix404IgnoreController::ignorePath'
  requirements:
    _permission: 'administer redirect settings'
    _permission: 'administer redirect settings+ignore 404 requests'
    _csrf_token: 'TRUE'
+28 −13
Original line number Diff line number Diff line
@@ -60,26 +60,41 @@ class Fix404IgnoreController extends ControllerBase {
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   */
  public function ignorePath(Request $request) {
    $ignored_paths = $this->config('redirect_404.settings')->get('pages');
    $editable = $this->configuration->getEditable('redirect_404.settings');
    $existing_config_raw = $editable->get('pages');
    $path = $request->query->get('path');
    $langcode = $request->query->get('langcode');

    if (empty($ignored_paths) || !strpos($path, $ignored_paths)) {
    if (empty($existing_config_raw) || !empty($path) || !strpos($path, $existing_config_raw)) {
      $this->redirectStorage->resolveLogRequest($path, $langcode);

      $this->messenger()->addMessage($this->t('Resolved the path %path in the database. Please check the ignored list and save the settings.', [
      // Users without 'administer redirect settings' and 'ignore 4040 request'
      // permission can also ignore pages.
      if (!$this->currentUser()->hasPermission('administer redirect settings') && $this->currentUser()->hasPermission('ignore 404 requests')) {
        $existing_config_raw .= $path . "\n";
        $editable->set('pages', $existing_config_raw);
        $editable->save();

        $response = $this->redirect('redirect_404.fix_404');
        $this->messenger()->addMessage($this->t('Resolved the path %path in the database.', [
          '%path' => $path,
        ]));
      }

      else {
        $options = [
          'query' => [
            'ignore' => $path,
            'destination' => Url::fromRoute('redirect_404.fix_404')->getInternalPath(),
          ],
        ];
        $response = $this->redirect('redirect.settings', [], $options);
        $this->messenger()->addMessage($this->t('Resolved the path %path in the database. Please check the ignored list and save the settings.', [
          '%path' => $path,
        ]));
      }

    return $this->redirect('redirect.settings', [], $options);
      return $response;
    }
  }

}
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ class Redirect404Operations extends FieldPluginBase {
      'url' => Url::fromRoute('redirect.add', [], $query),
    ];

    if ($this->currentUser->hasPermission('administer redirect settings')) {
    if ($this->currentUser->hasPermission('administer redirect settings') || $this->currentUser->hasPermission('ignore 404 requests')) {
      $links['ignore'] = [
        'title' => $this->t('Ignore'),
        'url' => Url::fromRoute('redirect_404.ignore_404', [
+44 −0
Original line number Diff line number Diff line
@@ -193,6 +193,50 @@ class Fix404RedirectUITest extends Redirect404TestBase {
    $this->assertSession()->fieldValueEquals('ignore_pages', "/node/*\n/term/*\n/llama_page");
  }

  /**
   * Tests the redirect ignore pages for users without the 'administer redirect
   * settings' permission.
   */
  public function testIgnorePagesNonAdmin() {
    // Create a node.
    $node = $this->drupalCreateNode(['type' => 'page']);
    $this->container->get('config.factory')
      ->getEditable('redirect_404.settings')
      ->set('pages', "/brian\n/flying/circus\n/meaning/of/*\n")
      ->save();

    // Create a non admin user.
    $user = $this->drupalCreateUser([
      'administer redirects',
      'ignore 404 requests',
      'access content',
      'bypass node access',
      'create url aliases',
      'administer url aliases',
    ]);
    $this->drupalLogin($user);

    // Visit non existing pages.
    $this->drupalGet('node/' . $node->id() . '/foobar');
    // Go to the "fix 404" page and check there is a 404 entry.
    $this->drupalGet('admin/config/search/redirect/404');
    $this->assertSession()->pageTextContains('node/' . $node->id() . '/foobar');

    // Add this 404 entry to the 'ignore path' list, assert it works properly.
    $this->clickLink('Ignore');
    $this->assertSession()->addressEquals('admin/config/search/redirect/404');
    // Check the message.
    $this->assertSession()->pageTextContains('Resolved the path /node/' . $node->id() . '/foobar in the database.');
    // This removes the message.
    $this->drupalGet('admin/config/search/redirect/404');
    $this->assertSession()->pageTextNotContains('node/' . $node->id() . '/foobar');

    $config = $this->container->get('config.factory')
      ->get('redirect_404.settings')
      ->get('pages');
    $this->assertStringContainsString('node/' . $node->id() . '/foobar', $config);
  }

  /**
   * Tests the test_404_reset_submit button to remove all 404 entries.
   */