You are here

restrict_ip.module in Restrict IP 7

File

restrict_ip.module
View source
<?php

/**
 * Implementation of hook_menu()
 */
function restrict_ip_menu() {
  $menu['admin/config/people/restrict_ip'] = array(
    'title' => 'IP Address Whitelist',
    'description' => 'Set the list of IP addresses that will be allowed to access the site',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'restrict_ip_settings',
    ),
    'access arguments' => array(
      'Administer Restricted IP addresses',
    ),
  );
  $menu['restrict_ip/access_denied'] = array(
    'title' => 'Access Denied',
    'page callback' => 'denied',
  );
  return $menu;
}

/**
 * Implementation of hook_permission()
 */
function restrict_ip_permission() {
  return array(
    'Administer Restricted IP addresses' => array(
      'title' => 'Administer Restricted IP addresses',
      'description' => 'Allows the user to set admitted IP addresses',
    ),
  );
}

/**
 * Page callback function for admin/config/people/restrict_ip
 */
function restrict_ip_settings() {
  $form['restrict_ip_address_description'] = array(
    '#markup' => '<h2>' . t('Enter the list of allowed IP addresses below') . '</h2><p><strong style="color:red">' . t("Warning: If you don't enter your current IP address into the list, you will immediately be locked out of the system upon save, and will not be able to access the system until you are in a location with an allowed IP address.") . '</strong></p><p><strong>' . t('Your current IP address is: !ip_address', array(
      '!ip_address' => '<em>' . ip_address() . '</em>',
    )) . '</strong></p>',
  );
  $form['restrict_ip_address_list'] = array(
    '#title' => t('Allowed IP Address List'),
    '#description' => t('Enter the list of IP Addresses that are allowed to access the site. If this field is left empty, all IP addresses will be able to access the site. Enter one IP address per line. You may also enter a range of IP addresses in the format AAA.BBB.CCC.XXX - AAA.BBB.CCC.YYY'),
    '#type' => 'textarea',
    '#default_value' => variable_get('restrict_ip_address_list', ''),
  );
  $form['restrict_ip_mail_address'] = array(
    '#title' => t('Email Address'),
    '#type' => 'textfield',
    '#description' => t('If you would like to include a contact email address in the error message that is shown to users that do not have an allowed IP address, enter the email address here.'),
    '#default_value' => trim(variable_get('restrict_ip_mail_address', '')),
  );
  return system_settings_form($form);
}

/**
 * Validation function for restrict_ip_settings()
 *
 * This function determines whether or not the values entered
 * in whitelisted IPs list are valid IP addresses
 */
function restrict_ip_settings_validate($form, &$form_state) {
  $ip_addresses = $form_state['values']['restrict_ip_address_list'];
  if (strlen(trim($ip_addresses))) {
    $ip_addresses = explode(PHP_EOL, trim($form_state['values']['restrict_ip_address_list']));
    foreach ($ip_addresses as $ip_address) {
      if ($ip_address != '::1') {
        if (!preg_match('~^\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b$~', trim($ip_address))) {
          $pieces = explode('-', $ip_address);
          if (count($pieces) !== 2) {
            form_set_error('restrict_ip_address_list', t('!ip_address is not a valid IP address.', array(
              '!ip_address' => $ip_address,
            )));
          }
          else {
            $ip1 = trim($pieces[0]);
            $ip2 = trim($pieces[1]);
            $both_valid = TRUE;
            if (!preg_match('~^\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b$~', $ip1)) {
              form_set_error('restrict_ip_address_list', t('!ip_address is not a valid IP address.', array(
                '!ip_address' => $ip1,
              )));
              $both_valid = FALSE;
            }
            if (!preg_match('~^\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b$~', $ip2)) {
              form_set_error('restrict_ip_address_list', t('!ip_address is not a valid IP address.', array(
                '!ip_address' => $ip2,
              )));
              $both_valid = FALSE;
            }
            if ($both_valid) {
              $first_parts_equal = TRUE;
              $last_part_ok = TRUE;
              $ip1_pieces = explode('.', $ip1);
              $ip2_pieces = explode('.', $ip2);
              for ($i = 0; $i < 3; $i++) {
                if ($ip1_pieces[$i] != $ip2_pieces[$i]) {
                  $first_parts_equal = FALSE;
                  break;
                }
              }
              if ($first_parts_equal) {
                if ($ip2_pieces[3] <= $ip1_pieces[3]) {
                  $last_part_ok = FALSE;
                }
              }
              if (!$first_parts_equal || !$last_part_ok) {
                form_set_error('restrict_ip_address_list', t('@ip_address is not a valid range of IP addresses.', array(
                  '@ip_address' => $ip_address,
                )));
              }
            }
          }
        }
      }
    }
  }
}

/**
 * Function used to set or determine if the user's ip address is not whitelisted
 */
function restrict_ip_value($block = FALSE) {
  $blocked =& drupal_static(__FUNCTION__);
  if (is_null($blocked)) {
    $blocked = FALSE;
  }
  if ($block) {
    $blocked = TRUE;
  }
  return $blocked;
}

/**
 * Implementation of hook_init()
 *
 * This function determines whether or not the user should be
 * whitelisted, and if they should, it sets a flag indicating so
 */
function restrict_ip_init() {
  global $restricted_ip;
  $restricted_ip = FALSE;
  $ip_addresses = trim(variable_get('restrict_ip_address_list', ''));
  if (strlen($ip_addresses)) {
    $ip_addresses = explode(PHP_EOL, $ip_addresses);
    $users_ip = ip_address();
    $access_denied = TRUE;
    foreach ($ip_addresses as $ip_address) {
      if (!preg_match('~^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$~', trim($ip_address)) && $ip_address != '::1') {
        $pieces = explode('-', trim($ip_address));
        $ip1_pieces = explode('.', trim($pieces[0]));
        $users_ip_pieces = explode('.', $users_ip);
        $first_parts_equal = TRUE;
        for ($i = 0; $i < 3; $i++) {
          if ($users_ip_pieces[$i] != $ip1_pieces[$i]) {
            $first_parts_equal = FALSE;
          }
          if ($first_parts_equal) {
            $ip1_end = $ip1_pieces[3];
            $ip2_pieces = explode('.', trim($pieces[1]));
            $ip2_end = $ip2_pieces[3];
            $user_end = $users_ip_pieces[3];
            if ($user_end >= $ip1_end && $user_end <= $ip2_end) {
              $access_denied = FALSE;
              break;
            }
          }
        }
      }
      elseif (trim($ip_address) == $users_ip) {
        $access_denied = FALSE;
        break;
      }
    }
    if ($access_denied) {
      if (current_path() != 'restrict_ip/access_denied') {
        drupal_goto('restrict_ip/access_denied');
      }
      $contact_mail = trim(variable_get('restrict_ip_mail_address', ''));
      if (strlen($contact_mail)) {
        $contact_mail = str_replace('@', '[at]', $contact_mail);
      }
      $contact_text = strlen($contact_mail) ? ' ' . t('If you feel this is in error, please contact an administrator at !email.', array(
        '!email' => '<span id="restrict_ip_contact_mail">' . $contact_mail . '</span>',
      )) : FALSE;
      drupal_set_message(t('This site cannot be accessed from your IP address.') . $contact_text, 'error', FALSE);
      restrict_ip_value(TRUE);
      drupal_add_js(drupal_get_path('module', 'restrict_ip') . '/js/restrict_ip.js');
    }
    elseif (current_path() == drupal_get_normal_path('restrict_ip/access_denied')) {
      drupal_goto('<front>');
    }
  }
}

/**
 * Override of template_preprocess_block()
 *
 * This function removes all data from blocks
 * for users whose accounts have been blocked,
 * preventing the blocks from being rendered
 */
function restrict_ip_preprocess_block(&$items) {
  if (restrict_ip_value()) {
    unset($items['elements']);
    unset($items['title_prefix']);
    unset($items['title_suffix']);
  }
}

/**
 * Override of template_preprocess_page()
 *
 * This function removes the data from various areas of the page
 * for users whose accounts have been blocked,
 * preventing the areas from being rendered
 */
function restrict_ip_preprocess_page(&$items) {
  if (restrict_ip_value()) {
    global $theme;
    $regions = system_region_list($theme, REGIONS_ALL);
    foreach (array_keys($regions) as $region) {
      if (isset($items['page'][$region])) {
        $items['page'][$region] = '';
      }
    }
    if (isset($items['tabs'])) {
      if (isset($items['tabs']['#primary'])) {
        $items['tabs']['#primary'] = array();
      }
      if (isset($items['tabs']['#secondary'])) {
        $items['tabs']['#primary'] = array();
      }
    }
    $items['title_prefix'] = array();
    $items['title_suffix'] = array();
    $items['main_menu'] = array();
    $items['secondary_menu'] = array();
    $items['action_links'] = array();
  }
}

/**
 * Override of template_preprocess_html()
 *
 * This function unsets $page_top and $page_bottom
 * so that they are not passed to html.tpl.php,
 * preventing these regions from being rendered
 */
function restrict_ip_preprocess_html(&$items) {
  if (restrict_ip_value()) {
    if (isset($items['page']['page_top'])) {
      unset($items['page']['page_top']);
    }
    if (isset($items['page']['page_top'])) {
      unset($items['page']['page_bottom']);
    }
  }
}

/**
 * Implementation of hook_js_alter()
 *
 * This function removes all javascript from the page
 * with the exception of jquery.js and the javascript
 * file provided with the module
 */
function restrict_ip_js_alter(&$javascript) {
  if (restrict_ip_value()) {
    $restrict_ip_js_path = drupal_get_path('module', 'restrict_ip') . '/js/restrict_ip.js';
    foreach (array_keys($javascript) as $key) {
      if ($key != $restrict_ip_js_path && $key != 'misc/jquery.js') {
        unset($javascript[$key]);
      }
    }
  }
}

Functions

Namesort descending Description
restrict_ip_init Implementation of hook_init()
restrict_ip_js_alter Implementation of hook_js_alter()
restrict_ip_menu Implementation of hook_menu()
restrict_ip_permission Implementation of hook_permission()
restrict_ip_preprocess_block Override of template_preprocess_block()
restrict_ip_preprocess_html Override of template_preprocess_html()
restrict_ip_preprocess_page Override of template_preprocess_page()
restrict_ip_settings Page callback function for admin/config/people/restrict_ip
restrict_ip_settings_validate Validation function for restrict_ip_settings()
restrict_ip_value Function used to set or determine if the user's ip address is not whitelisted