BasicAuthTest.php 5.53 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\basic_auth\Tests\Authentication\BasicAuthTest.
6 7
 */

8
namespace Drupal\basic_auth\Tests\Authentication;
9

10
use Drupal\language\Entity\ConfigurableLanguage;
11 12 13
use Drupal\simpletest\WebTestBase;

/**
14 15 16
 * Tests for BasicAuth authentication provider.
 *
 * @group basic_auth
17
 */
18
class BasicAuthTest extends WebTestBase {
19 20 21 22 23 24

  /**
   * Modules enabled for all tests.
   *
   * @var array
   */
25
  public static $modules = array('basic_auth', 'router_test', 'locale');
26 27 28 29

  /**
   * Test http basic authentication.
   */
30
  public function testBasicAuth() {
31 32
    $account = $this->drupalCreateUser();

33 34
    $this->basicAuthGet('router_test/test11', $account->getUsername(), $account->pass_raw);
    $this->assertText($account->getUsername(), 'Account name is displayed.');
35 36 37
    $this->assertResponse('200', 'HTTP response is OK');
    $this->curlClose();

38
    $this->basicAuthGet('router_test/test11', $account->getUsername(), $this->randomMachineName());
39
    $this->assertNoText($account->getUsername(), 'Bad basic auth credentials do not authenticate the user.');
40 41 42 43
    $this->assertResponse('403', 'Access is not granted.');
    $this->curlClose();

    $this->drupalGet('router_test/test11');
44
    $this->assertResponse('401', 'Not authenticated on the route that allows only basic_auth. Prompt to authenticate received.');
45 46 47 48 49 50

    $this->drupalGet('admin');
    $this->assertResponse('403', 'No authentication prompt for routes not explicitly defining authentication providers.');

    $account = $this->drupalCreateUser(array('access administration pages'));

51
    $this->basicAuthGet('admin', $account->getUsername(), $account->pass_raw);
52 53 54 55 56
    $this->assertNoLink('Log out', 0, 'User is not logged in');
    $this->assertResponse('403', 'No basic authentication for routes not explicitly defining authentication providers.');
    $this->curlClose();
  }

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
  /**
   * Test the global login flood control.
   */
  function testGlobalLoginFloodControl() {
    \Drupal::config('user.flood')
      ->set('ip_limit', 2)
      // Set a high per-user limit out so that it is not relevant in the test.
      ->set('user_limit', 4000)
      ->save();

    $user = $this->drupalCreateUser(array());
    $incorrect_user = clone $user;
    $incorrect_user->pass_raw .= 'incorrect';

    // Try 2 failed logins.
    for ($i = 0; $i < 2; $i++) {
      $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
    }

    // IP limit has reached to its limit. Even valid user credentials will fail.
    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
    $this->assertResponse('403', 'Access is blocked because of IP based flood prevention.');
  }

  /**
   * Test the per-user login flood control.
   */
  function testPerUserLoginFloodControl() {
    \Drupal::config('user.flood')
      // Set a high global limit out so that it is not relevant in the test.
      ->set('ip_limit', 4000)
      ->set('user_limit', 2)
      ->save();

    $user = $this->drupalCreateUser(array());
    $incorrect_user = clone $user;
    $incorrect_user->pass_raw .= 'incorrect';
    $user2 = $this->drupalCreateUser(array());

    // Try a failed login.
    $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);

    // A successful login will reset the per-user flood control count.
    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
    $this->assertResponse('200', 'Per user flood prevention gets reset on a successful login.');

    // Try 2 failed logins for a user. They will trigger flood control.
    for ($i = 0; $i < 2; $i++) {
      $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
    }

    // Now the user account is blocked.
    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
    $this->assertResponse('403', 'The user account is blocked due to per user flood prevention.');

    // Try one successful attempt for a different user, it should not trigger
    // any flood control.
    $this->basicAuthGet('router_test/test11', $user2->getUsername(), $user2->pass_raw);
    $this->assertResponse('200', 'Per user flood prevention does not block access for other users.');
  }

118 119 120 121
  /**
   * Tests compatibility with locale/UI translation.
   */
  function testLocale() {
122
    ConfigurableLanguage::create(array('id' => 'de', 'label' => 'German', 'default' => TRUE))->save();
123 124 125 126 127 128 129 130 131

    $account = $this->drupalCreateUser();

    $this->basicAuthGet('router_test/test11', $account->getUsername(), $account->pass_raw);
    $this->assertText($account->getUsername(), 'Account name is displayed.');
    $this->assertResponse('200', 'HTTP response is OK');
    $this->curlClose();
  }

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  /**
   * Does HTTP basic auth request.
   *
   * We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to
   * set curl settings for basic authentication.
   *
   * @param string $path
   *   The request path.
   * @param string $username
   *   The user name to authenticate with.
   * @param string $password
   *   The password.
   *
   * @return string
   *   Curl output.
   */
  protected function basicAuthGet($path, $username, $password) {
    $out = $this->curlExec(
      array(
        CURLOPT_HTTPGET => TRUE,
        CURLOPT_URL => url($path, array('absolute' => TRUE)),
        CURLOPT_NOBODY => FALSE,
        CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
        CURLOPT_USERPWD => $username . ':' . $password,
      )
    );

    $this->verbose('GET request to: ' . $path .
      '<hr />' . $out);

    return $out;
  }
164

165
}