You are here

securepages.test in Secure Pages 6

Same filename and directory in other branches
  1. 8 securepages.test
  2. 6.2 securepages.test
  3. 7 securepages.test

Provides SimpleTests for Secure Pages module.

File

securepages.test
View source
<?php

/**
 * @file
 * Provides SimpleTests for Secure Pages module.
 */
class SecurePagesTestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Secure Pages',
      'description' => 'Test Secure Pages redirects.',
      'group' => 'Secure Pages',
    );
  }
  function setUp() {
    parent::setUp('securepages', 'comment', 'path');
    variable_set('https', TRUE);
    variable_set('securepages_enable', TRUE);
    variable_set('comment_form_location_story', COMMENT_FORM_BELOW);
    variable_set('comment_preview_story', COMMENT_PREVIEW_OPTIONAL);
  }

  /**
   * Runs all the test functions.  These are run from a single outer function to avoid
   * multiple re-installs by simpletest.
   */
  function testSecurePages() {
    $this
      ->_testSettingsForm();
    $this
      ->_testMatch();
    $this
      ->_testAnonymous();
    $this
      ->_testFormAlter();
    $this
      ->_testCachedResponse();
    $this
      ->_testPathAlias();
    $this
      ->_testOpenRedirect();
    $this
      ->_testXHR();
    $this
      ->_testRoles();
    $this
      ->_testPathNorms();
  }

  /**
   * Test submitting the settings form
   */
  function _testSettingsForm() {

    // Undo the setUp() function.
    variable_del('securepages_enable');

    // Enable securepages.
    $this->web_user = $this
      ->drupalCreateUser(array(
      'administer site configuration',
      'access administration pages',
    ));
    $this
      ->loginHTTPS($this->web_user);
    $edit = array(
      'securepages_enable' => 1,
    );
    $this
      ->drupalPost($this
      ->_toHTTPS(url('admin/build/securepages', array(
      'absolute' => TRUE,
    ))), $edit, t('Save configuration'));
    $this
      ->assertRaw(t('The configuration options have been saved.'));
    $this
      ->drupalLogout();
  }

  /**
   * Tests the securepages_match() function.
   */
  function _testMatch() {
    variable_set('securepages_ignore', '*/autocomplete/*');
    $this
      ->assertTrue(securepages_match('user'), 'path user matches.');
    $this
      ->assertTrue(securepages_match('user/login'), 'path user/login matches.');
    $this
      ->assertTrue(securepages_match('admin/modules'), 'path admin/modules matches.');
    $this
      ->assertFalse(securepages_match('node'), 'path node does not match.');
    $this
      ->assertTrue(securepages_match('user/autocomplete/alice') == securepages_is_secure() ? 1 : 0, 'autocomplete path is ignored.');
  }

  /**
   * Tests for anonymous browsing with securepages.
   */
  function _testAnonymous() {

    // Visit the home page and /node with plain HTTP.
    $this
      ->drupalGet('');
    $this
      ->assertResponse(200);
    $this
      ->assertUrl(url('', array(
      'absolute' => TRUE,
    )));
    $this
      ->drupalGet('node');
    $this
      ->assertResponse(200);
    $this
      ->assertUrl(url('node', array(
      'absolute' => TRUE,
    )));

    // Visit the login page and confirm that browser is redirected to HTTPS.
    $this
      ->drupalGet('user');
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('user', array(
      'absolute' => TRUE,
    ))));

    // Visit the home page and /node with HTTPS and confirm that no redirection happens.
    $this
      ->drupalGet($this
      ->_toHTTPS(url('', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('', array(
      'absolute' => TRUE,
    ))));
    $this
      ->drupalGet($this
      ->_toHTTPS(url('node', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('node', array(
      'absolute' => TRUE,
    ))));

    // Enable "Switch back to http pages when there are no matches".
    variable_set('securepages_switch', TRUE);

    // Visit the home page and /node with HTTPS and confirm that switch-back happens.
    $this
      ->drupalGet($this
      ->_toHTTPS(url('', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl(url('', array(
      'absolute' => TRUE,
    )));
    $this
      ->drupalGet($this
      ->_toHTTPS(url('node', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTP(url('node', array(
      'absolute' => TRUE,
    ))));

    // Clean up
    variable_del('securepages_pages');
  }

  /**
   * Tests the ability to alter form actions.
   *
   * Uses the comment form, since it has an #action set.
   */
  function _testFormAlter() {
    variable_set('securepages_switch', TRUE);

    // Enable anonymous user comments.
    db_query("UPDATE {permission} SET perm = '%s' WHERE rid = %d", 'access comments, access content, post comments, post comments without approval', DRUPAL_ANONYMOUS_RID);
    $this->web_user = $this
      ->drupalCreateUser(array(
      'access comments',
      'post comments',
      'post comments without approval',
    ));
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'story',
      'promote' => 1,
    ));
    foreach (array(
      'anonymous',
      'authenticated',
    ) as $mode) {
      if ($mode == 'authenticated') {
        $this
          ->drupalLogin($this->web_user);
      }

      // Test plain HTTP posting to HTTPS.
      variable_set('securepages_pages', "comment/reply/*\nuser*");
      $this
        ->drupalGet('node/' . $node->nid);
      $this
        ->assertFieldByXPath('//form[@id="comment-form" and starts-with(@action, "https:")]', NULL, "The {$mode} comment form action is https.");
      $comment_body = $this
        ->randomName(8);
      $this
        ->drupalPost(NULL, array(
        'comment' => $comment_body,
      ), t('Save'));
      $this
        ->assertRaw($comment_body);

      // Test HTTPS posting to plain HTTP.
      variable_set('securepages_pages', "node/*\nuser*");
      $this
        ->drupalGet($this
        ->_toHTTPS(url('node/' . $node->nid), array(
        'absolute' => TRUE,
      )));
      $this
        ->assertUrl($this
        ->_toHTTPS(url('node/' . $node->nid, array(
        'absolute' => TRUE,
      ))));
      $this
        ->assertFieldByXPath('//form[@id="comment-form" and starts-with(@action, "http:")]', NULL, "The {$mode} comment form action is http.");
      $comment_body = $this
        ->randomName(8);
      $this
        ->drupalPost(NULL, array(
        'comment' => $comment_body,
      ), t('Save'));
      $this
        ->assertRaw($comment_body);
    }
    $this
      ->drupalLogout();

    // Test the user login block.
    $this
      ->drupalGet('');
    $edit = array(
      'name' => $this->web_user->name,
      'pass' => $this->web_user->pass_raw,
    );
    $this
      ->drupalPost(NULL, $edit, t('Log in'));
    $this
      ->drupalGet('user/' . $this->web_user->uid . '/edit');
    $this
      ->assertResponse(200);

    // Clean up
    $this
      ->drupalLogout();
    variable_del('securepages_pages');
    variable_del('securepages_switch');
  }
  function _testCachedResponse() {

    // Enable the page cache and fetch the login page.
    variable_set('cache', TRUE);
    $url = url('user/login', array(
      'absolute' => TRUE,
    ));
    $this
      ->drupalGet($url);

    // Short-circuit redirects within the simpletest browser.
    variable_set('simpletest_maximum_redirects', 0);
    $this
      ->drupalGet($url);
    $this
      ->assertResponse(302);
    $this
      ->assertEqual($this
      ->drupalGetHeader('Location'), $this
      ->_toHTTPS(url('user/login', array(
      'absolute' => TRUE,
    ))));

    // $this->assertEqual($this->drupalGetHeader('X-Securepages-Cache'), 'HIT', 'Page was cached.'); @FIXME
    // Clean up
    variable_del('cache');
    variable_del('simpletest_maximum_redirects');
  }

  /**
   * Test redirection on aliased paths.
   */
  function _testPathAlias() {
    variable_set('securepages_pages', "node/*\nuser*");

    // Create test user and login.
    $web_user = $this
      ->drupalCreateUser(array(
      'create page content',
      'edit own page content',
      'administer url aliases',
      'create url aliases',
    ));
    $this
      ->drupalLogin($web_user);

    // Create test node.
    $node = $this
      ->drupalCreateNode();

    // Create alias.
    $edit = array();
    $edit['src'] = 'node/' . $node->nid;
    $edit['dst'] = $this
      ->randomName(8);
    $this
      ->drupalPost('admin/build/path/add', $edit, t('Create new alias'));

    // Short-circuit redirects within the simpletest browser.
    variable_set('simpletest_maximum_redirects', 0);
    $this
      ->drupalGet($edit['dst'], array(
      'absolute' => TRUE,
    ));
    $this
      ->assertResponse(302);
    $this
      ->assertEqual($this
      ->drupalGetHeader('Location'), $this
      ->_toHTTPS(url($edit['dst'], array(
      'absolute' => TRUE,
    ))));

    // Clean up
    variable_del('simpletest_maximum_redirects');
    $this
      ->drupalLogout();
    variable_del('securepages_pages');
  }

  /**
   * Verifies that securepages is not an open redirect.
   */
  function _testOpenRedirect() {

    // Short-circuit redirects within the simpletest browser.
    variable_set('simpletest_maximum_redirects', 0);
    variable_set('securepages_switch', TRUE);
    global $base_url, $base_path;
    $secure_base_url = str_replace('http', 'https', $base_url);
    $this
      ->drupalGet($secure_base_url . $base_path . '?q=http://example.com/', array(
      'external' => TRUE,
    ));
    $this
      ->assertResponse(302);
    $this
      ->assertTrue(strstr($this
      ->drupalGetHeader('Location'), $base_url), t('Open redirect test passed.'));
    $this
      ->drupalGet($secure_base_url . $base_path . '?q=' . urlencode('http://example.com/'), array(
      'external' => TRUE,
    ));
    $this
      ->assertResponse(404);

    // Clean up
    variable_del('simpletest_maximum_redirects');
  }

  /**
   * Test detection of XHR requests.
   */
  function _testXHR() {
    $admin_user = $this
      ->drupalCreateUser(array(
      'access user profiles',
      'administer users',
      'access administration pages',
    ));
    $this
      ->drupalLogin($admin_user);

    // Without XHR header
    $this
      ->drupalGet($this
      ->_toHTTP(url('user/autocomplete/a', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('user/autocomplete/a', array(
      'absolute' => TRUE,
    ))));

    // With XHR header
    $this
      ->drupalGet($this
      ->_toHTTP(url('user/autocomplete/a', array(
      'absolute' => TRUE,
    ))), array(), array(
      'X-Requested-With: XMLHttpRequest',
    ));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTP(url('user/autocomplete/a', array(
      'absolute' => TRUE,
    ))));

    // Clean up
    $this
      ->drupalLogout();
  }

  /**
   * Test role-based switching.
   */
  function _testRoles() {

    // Enable securepages.
    $this->web_user = $this
      ->drupalCreateUser(array(
      'administer site configuration',
      'access administration pages',
      'access comments',
      'post comments',
    ));

    // Extract the role that was just generated.
    $role = $this->web_user->roles;
    unset($role[DRUPAL_AUTHENTICATED_RID]);
    $role = current(array_keys($role));
    $this
      ->loginHTTPS($this->web_user);
    $edit = array(
      'securepages_enable' => 1,
      'securepages_switch' => 1,
      "securepages_roles[{$role}]" => 1,
    );
    $this
      ->drupalPost('admin/build/securepages', $edit, t('Save configuration'), array(
      'https' => TRUE,
    ));
    $this
      ->assertRaw(t('The configuration options have been saved.'));

    // Visit the home page and /node with HTTPS and confirm that redirection happens.
    $this
      ->drupalGet('', array(
      'https' => FALSE,
    ));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('', array(
      'absolute' => TRUE,
    ))));
    $this
      ->drupalGet($this
      ->_toHTTP(url('node')));
    $this
      ->assertResponse(200);
    $this
      ->assertUrl($this
      ->_toHTTPS(url('', array(
      'absolute' => TRUE,
    ))));

    // Test that forms actions aren't switched back to http.
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'story',
      'promote' => 1,
    ));
    $this
      ->drupalGet($this
      ->_toHTTPS(url('node/' . $node->nid, array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertFieldByXPath('//form[@id="comment-form" and starts-with(@action, "/")]', NULL, "The comment form action is https.");

    // Clean up
    variable_del('securepages_switch');
    variable_del('securepages_roles');
    $this
      ->drupalLogout();
  }

  /**
   * Test path normalization checks.
   */
  function _testPathNorms() {
    variable_set('securepages_switch', TRUE);
    variable_set('securepages_pages', 'user');

    // Test mixed-case path.
    $this
      ->drupalGet('UsEr');
    $this
      ->assertUrl($this
      ->_toHTTPS(url('UsEr', array(
      'absolute' => TRUE,
    ))));
    $this
      ->assertFieldByXPath('//form[@id="user-login" and starts-with(@action, "/")]', NULL, 'The user login form action is https.');

    // Test that a trailing slash will not force a protected form's action to
    // http.
    $https_path = $this
      ->_toHTTPS(url('user/', array(
      'absolute' => TRUE,
    )));

    // A http based 'user/' path will become 'user' when doing the redirect, so
    // best to ensure that the test gets the right conditions the path should be
    // https based.
    $this
      ->drupalGet($https_path);
    $this
      ->assertUrl($https_path);
    $this
      ->assertFieldByXPath('//form[@id="user-login" and starts-with(@action, "/")]', NULL, 'The user login form action is https.');

    // Clean up.
    variable_del('securepages_switch');
    variable_del('securepages_pages');
  }

  /**
   * Logs in a user using HTTPS.
   */
  function loginHTTPS($user) {
    $edit = array(
      'name' => $user->name,
      'pass' => $user->pass_raw,
    );
    $this
      ->drupalPost($this
      ->_toHTTPS(url('user', array(
      'absolute' => TRUE,
    ))), $edit, t('Log in'));
  }

  /**
   * Helper function, because url() in D6 lacks 'https' => TRUE
   */
  function _toHTTPS($url) {
    return str_replace('http://', 'https://', $url);
  }

  /**
   * Helper function, because url() in D6 lacks 'https' => FALSE
   */
  function _toHTTP($url) {
    return str_replace('https://', 'http://', $url);
  }

}

Classes

Namesort descending Description
SecurePagesTestCase @file Provides SimpleTests for Secure Pages module.