restrict_by_ip.module in Restrict Login or Role Access by IP Address 6.2
Same filename and directory in other branches
Allows the admin to select which ip addresses role or a user can login from for this site Some of the code below is taken from the cck_ipaddress_module
File
restrict_by_ip.moduleView source
<?php
/**
* @file
* Allows the admin to select which ip addresses role or a user can login from for this site
* Some of the code below is taken from the cck_ipaddress_module
*/
/**
* This just checks the database for any roles associated with that user
* that are in the restrict_by_ip table. From there it does a ip check
* on each one of them to see if they are within the range of ip's allowed for that
* role.
*/
function restrict_by_ip_role_check(&$user) {
//now do the resrict by ip check, remove roles from above array that should not be there
//get all possible roles for the given user (other than annonmyous role and )
$result = db_query('select rip.rid, rip.restrict_by_ip_address from {restrict_by_ip} rip left join {users_roles} ur ON ur.rid = rip.rid where ur.uid = %d', intval($user->uid));
$ip2check = $_SERVER['REMOTE_ADDR'];
while ($role = db_fetch_object($result)) {
$ipaddresses = explode(";", $role->restrict_by_ip_address);
foreach ($ipaddresses as $ipaddress) {
if (!_restrict_by_ip_cidrcheck($ip2check, $ipaddress)) {
//unset a role if its not within the allowed ip range for this role
unset($user->roles[$role->rid]);
}
}
}
}
/**
* Hook to the admin_permissions submit function
*/
function restrict_by_ip_user_admin_perm_submit($form, &$form_state) {
$rid = $form_state['values']['rid'];
$role_restrict_by_ip_type = $form_state['values']['restrict_by_ip_type'];
$restrict_by_ip_address = $form_state['values']['restrict_by_ip_address'];
if ($role_restrict_by_ip_type == "1") {
if (db_result(db_query('SELECT rid FROM {restrict_by_ip} WHERE rid = %d', $rid))) {
db_query("UPDATE {restrict_by_ip} SET restrict_by_ip_type = %d, restrict_by_ip_address = '%s' WHERE rid = %d", intval($role_restrict_by_ip_type), t($restrict_by_ip_address), intval($rid));
}
else {
db_query("INSERT INTO {restrict_by_ip} (rid, restrict_by_ip_type, restrict_by_ip_address) VALUES ( %d ,%d, '%s' )", intval($rid), intval($role_restrict_by_ip_type), t($restrict_by_ip_address));
}
}
else {
db_query("DELETE FROM {restrict_by_ip} WHERE rid=%d", intval($rid));
}
}
/**
* Hook for the permissions validate function. Checks to make sure the ip-address is valid.
*/
function restrict_by_ip_user_admin_perm_validate($form, &$form_state) {
// Seperate the ip address by semi-colon delimiter
$ret = TRUE;
$sms = "Retrict by IP Address setting not updated to role";
if ($form_state['values']['rip']['restrict_by_ip_type']) {
$ret = _restrict_by_ip_validate_ip($form_state['values']['restrict_by_ip_address'], $sms);
}
return $ret;
}
/**
* Hook to the admin_permissions form
*/
function restrict_by_ip_form_user_admin_perm_alter(&$form, $form_state) {
$rid = arg(3);
//check to make sure its a single role we are editing
//and that it is not a annonymous user or simply an "authenticated user"
//we could change this later?
if (isset($rid) && intval($rid) > 2) {
$roledata_restrict_by_ip_type = "0";
// Grab the current restrict by ip data if it exists
$found = db_result(db_query('SELECT count(*) FROM {restrict_by_ip} WHERE rid = %d', intval($rid)));
if ($found) {
$roledata = db_fetch_object(db_query('SELECT * FROM {restrict_by_ip} WHERE rid = %d', intval($rid)));
$roledata_restrict_by_ip_type = "1";
$roledata_restrict_by_ip_address = $roledata->restrict_by_ip_address;
}
$form['rip'] = array(
'#type' => 'fieldset',
'#attributes' => array(
'class' => 'restrict-by-ip',
),
'#title' => t('Restrict by IP settings'),
'#collapsible' => FALSE,
);
$form['rip']['rid'] = array(
'#type' => 'value',
'#value' => $rid,
);
$form['rip']['restrict_by_ip_type'] = array(
'#type' => 'radios',
'#title' => t('Restrict By IP'),
'#default_value' => $roledata_restrict_by_ip_type,
'#options' => array(
t('No'),
t('Yes'),
),
);
$form['rip']['restrict_by_ip_address'] = array(
'#type' => 'textfield',
'#default_value' => $roledata_restrict_by_ip_address,
'#size' => 128,
'#maxlength' => 128,
'#description' => t('Enter IP Address Ranges in CIDR Notation seperated with semi-colons, with no trailing semi-colon. E.G. 10.20.30.0/24;192.168.199.1/32;1.0.0.0/8<br />For more information on CIDR notation <a href="http://www.brassy.net/2007/mar/cidr_basic_subnetting" target="_blank">click here</a>.'),
);
$form['#submit'] = array(
'restrict_by_ip_user_admin_perm_submit',
'user_admin_perm_submit',
);
$form['#validate'] = array(
'restrict_by_ip_user_admin_perm_validate',
);
//unset the submit just so we can add the button again
//this way restrict ip does not show up at bottom of page
//I do not know any other way to do this?
unset($form['submit']);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save Permissions',
);
}
}
/**
* Implementation of hook_help()
*/
function restrict_by_ip_help($section) {
switch ($section) {
case 'admin/help#restrict_by_ip':
$output = '<p>The site administrator can limit a user to only be able to login from certain IP Addresses or ranges of IP Addresses using CIDR notation.</p>';
break;
}
return $output;
}
/**
* Implementation of hook_menu()
* Add a menu item to the ddminister >> site building menu for displaying the restrict_by_ip
*/
function restrict_by_ip_menu() {
$items = array();
$items['admin/settings/restrict_by_ip'] = array(
'title' => t('Restrict by IP settings'),
'description' => t('Limit the IP address a user is allowed to login from.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'restrict_by_ip_settings',
),
'access arguments' => array(
'administer restrict by ip',
),
);
return $items;
}
/**
* Implementation of hook_perm()
*/
function restrict_by_ip_perm() {
return array(
'administer restrict by ip',
);
}
/**
* Menu callback to configure module settings
*/
function restrict_by_ip_settings() {
//from here is default
$form = array();
$form['restrict_by_ip_error_page'] = array(
'#type' => 'textfield',
'#title' => t('Login denied page'),
'#description' => t("This the address of the page to which the user will be redirected if they are not allowed to login. If you don't set this the user will not know why they couldn't login"),
'#weight' => -5,
'#default_value' => variable_get('restrict_by_ip_error_page', ''),
'#required' => TRUE,
);
return system_settings_form($form);
}
/**
* Implementation of hook_user()
*/
function restrict_by_ip_user($type, &$edit, &$account, $category = NULL) {
global $user;
switch ($type) {
case 'login':
return _restrict_by_ip_login($user);
break;
case 'form':
case 'register':
return _restrict_by_ip_form($account->uid);
break;
case 'insert':
case 'update':
return _restrict_by_ip_update($account->uid, $edit);
break;
case 'submit':
//Drupal Bug: http://drupal.org/node/321787 - using for edit user will still update user data if error
return _restrict_by_ip_validate($edit, 1);
break;
case 'validate':
//Drupal Bug: http://drupal.org/node/321787 - not fired when editing user only on new user
return _restrict_by_ip_validate($edit, 2);
break;
case 'delete':
return _restrict_by_ip_delete($account->uid);
break;
}
}
/**
* Login function
* Checks the user's ip address on login
* If they are not restricted, or logging in from the appropriate address
* allow logon to continue. If not redirect to a designated page
*/
function _restrict_by_ip_login(&$user) {
if ($user->uid > 1) {
$usrdata = db_fetch_object(db_query('SELECT * FROM {restrict_by_ip} WHERE uid = %d', $user->uid));
$logonvalid = FALSE;
$ip2check = $_SERVER['REMOTE_ADDR'];
// If the user has restrict by ip address set
if ($usrdata->restrict_by_ip_type) {
$ipaddresses = explode(";", $usrdata->restrict_by_ip_address);
// Check each valid ip address in database against users ip address
// If one matches allow logon
foreach ($ipaddresses as $ipaddress) {
if (_restrict_by_ip_cidrcheck($ip2check, $ipaddress)) {
$logonvalid = TRUE;
}
//else if(_restrict_by_role($user->$roles){}
}
// Restrict by ip address is set and no addresses match users ip address
if (!$logonvalid) {
// Log the error with the ip address
watchdog('user', t('Session closed for %name - Invalid IP. ' . $ip2check, array(
'%name' => $user->name,
)));
// Destroy the current session
session_destroy();
module_invoke_all('user', 'logout', NULL, $user);
// Load the anonymous user
$user = drupal_anonymous_user();
// unset destination required to force them to the ip page during drupal_goto()
if (isset($_REQUEST['destination'])) {
unset($_REQUEST['destination']);
}
// Goto the page detailed in the site configuration - restrict by ip - settings page
drupal_goto(variable_get('restrict_by_ip_error_page', '0'));
}
}
return $logonvalid;
}
else {
return TRUE;
}
}
/**
* Form and register function
* Insert the restrict by ip form into the user settings and new user forms for authorised users
*/
function _restrict_by_ip_form($uid) {
global $user;
//new code here
if (user_access('administer site configuration') || user_access('administer restrict by ip')) {
$form = array();
drupal_add_css(drupal_get_path('module', 'restrict_by_ip') . '/restrict_by_ip.css', 'module', 'screen', FALSE);
$usrdata_restrict_by_ip_type = "0";
$usrdata_restrict_by_ip_address = "";
// Grab the current restrict by ip data if it exists
$found = db_result(db_query('SELECT count(*) FROM {restrict_by_ip} WHERE uid = %d', $uid));
if ($found) {
$usrdata = db_fetch_object(db_query('SELECT * FROM {restrict_by_ip} WHERE uid = %d', $uid));
$usrdata_restrict_by_ip_type = "1";
$usrdata_restrict_by_ip_address = $usrdata->restrict_by_ip_address;
}
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
$form['rip'] = array(
'#type' => 'fieldset',
'#attributes' => array(
'class' => 'restrict-by-ip',
),
'#title' => t('Restrict by IP settings'),
'#weight' => 5,
'#collapsible' => FALSE,
);
$form['rip']['restrict_by_ip_type'] = array(
'#type' => 'radios',
'#title' => t('Restrict By IP'),
'#default_value' => t($usrdata_restrict_by_ip_type),
'#options' => array(
t('No'),
t('Yes'),
),
);
$form['rip']['restrict_by_ip_address'] = array(
'#type' => 'textfield',
'#default_value' => t($usrdata_restrict_by_ip_address),
'#size' => 128,
'#maxlength' => 128,
'#description' => t('Enter IP Address Ranges in CIDR Notation seperated with semi-colons, with no trailing semi-colon. E.G. 10.20.30.0/24;192.168.199.1/32;1.0.0.0/8<br />For more information on CIDR notation <a href="http://www.brassy.net/2007/mar/cidr_basic_subnetting" target="_blank">click here</a>.'),
);
return $form;
}
else {
return FALSE;
}
}
/**
* Update and insert function
* Update or create new restrict by ip database entry from the form data
*/
function _restrict_by_ip_update($uid, &$edit) {
if (user_access('administer site configuration') || user_access('administer restrict by ip')) {
$form = array();
if ($edit['restrict_by_ip_type']) {
if (db_result(db_query('SELECT uid FROM {restrict_by_ip} WHERE uid = %d', $uid))) {
db_query("UPDATE {restrict_by_ip} SET restrict_by_ip_type = %d, restrict_by_ip_address = '%s' WHERE uid = %d", intval($edit['restrict_by_ip_type']), $edit['restrict_by_ip_address'], $uid);
}
else {
db_query("INSERT INTO {restrict_by_ip} (uid, restrict_by_ip_type, restrict_by_ip_address) VALUES ( %d ,%d ,'%s')", $uid, intval($edit['restrict_by_ip_type']), $edit['restrict_by_ip_address']);
}
}
else {
db_query("DELETE FROM {restrict_by_ip} WHERE uid=%d", $uid);
// Attempting here to get the form to delete the ip address data if 'no' to restrict by ip address is selected
// Not working needs more investigation
if (isset($form['rip'])) {
$form['newform'] = array(
'#type' => 'textfield',
'#default_value' => t(''),
'#size' => 128,
'#maxlength' => 128,
'#description' => t('Enter IP Address Ranges in CIDR Notation seperated with semi-colons, with no trailing semi-colon. E.G. 10.20.30.0/24;192.168.199.1/32;1.0.0.0/8<br />For more information on CIDR notation <a href="http://www.brassy.net/2007/mar/cidr_basic_subnetting" target="_blank">click here</a>.'),
);
$form['rip']['restrict_by_ip_address'] = $form['newform'];
unset($form['newform']);
}
}
unset($edit['restrict_by_ip_type']);
unset($edit['restrict_by_ip_address']);
return TRUE;
}
else {
return FALSE;
}
}
/**
* Validate function
* Validate the restrict by ip form data
*/
function _restrict_by_ip_validate(&$edit, $call) {
$ret = TRUE;
// Set up error messages for new user and edit user
$sms = "Retrict by IP Address setting not updated to user";
if ($call == 2) {
$sms = "User not added";
}
// Only validate is 'yes' is selected for restrict by ip
if ($edit['restrict_by_ip_type']) {
// Seperate the ip address by semi-colon delimiter
$ret = _restrict_by_ip_validate_ip($edit['restrict_by_ip_address'], $sms);
}
if (!$ret) {
unset($edit['restrict_by_ip_type']);
unset($edit['restrict_by_ip_address']);
}
return $ret;
}
/**
* User deleted function
* Remove the restrict by ip data from the database table
*/
function _restrict_by_ip_delete($uid) {
if ($uid > 1) {
return db_query("DELETE FROM {restrict_by_ip} WHERE uid=%d", $uid);
}
else {
return FALSE;
}
}
/**
* This function just makes sure the user input for the ip address
* section is valid. $sms is the error message if the ip validation fails
*/
function _restrict_by_ip_validate_ip($ip_address, $sms) {
$ret = TRUE;
$ipaddresses = explode(";", $ip_address);
$j = 1;
// Check each ip address individually
foreach ($ipaddresses as $ipaddress) {
// Seperate in to address and cidr mask
$cidr = explode("/", $ipaddress);
// Check address and cidr mask entered
if (count($cidr) == 2) {
$ipaddr = explode(".", $cidr[0]);
// Check four quads entered
if (count($ipaddr) == 4) {
// Check each quad is valid - numeric and 0 < value < 255
for ($i = 0; $i < 4; $i++) {
if (!is_numeric($ipaddr[$i]) || $ipaddr[$i] < 0 || $ipaddr[$i] > 255) {
form_set_error('restrict_by_ip_address', t($sms . '. Illegal value for the an IP Address. Each IP Address must be valid. Check IP Address No. ' . $j));
$ret = FALSE;
}
}
// Check cidr mask value - numeric and 0 < value < 33
if (!is_numeric($cidr[1]) || $cidr[1] < 1 || $cidr[1] > 32) {
form_set_error('restrict_by_ip_address', t($sms . '. Illegal value for the CIDR value. Check CIDR No. ' . $j));
$ret = FALSE;
}
}
else {
form_set_error('restrict_by_ip_address', t($sms . '. IP Address Incorrect Number of Quads. Check IP Address No. ' . $j));
$ret = FALSE;
}
}
else {
form_set_error('restrict_by_ip_address', t($sms . '. IP Address in Incorrect Format. Check IP Address No. ' . $j));
$ret = FALSE;
}
$j++;
}
return $ret;
}
/**
* Check ip address against a network in cidr notation. E.g:
* _restrict_by_ip_cidrcheck('192.168.10.100','192.168.10.0/24'); returns 1
* _restrict_by_ip_cidrcheck('192.168.10.100','192.168.12.0/24'); returns 0
*/
function _restrict_by_ip_cidrcheck($iptocheck, $ipslashcidr) {
// Seperate ip address and cidr mask
$netmask = explode("/", $ipslashcidr);
// Get valid network as long
$ip_net = ip2long($netmask[0]);
// Get valid network mask as long
$ip_mask = ~((1 << 32 - $netmask[1]) - 1);
// Get ip address to check as long
$ip_ip = ip2long($iptocheck);
// Mask ip address to check to get subnet
$ip_ip_net = $ip_ip & $ip_mask;
// Only returns 1 if the valid network
//and the subnet of the ip address
//to check are the same
return $ip_ip_net == $ip_net;
}
Functions
Name![]() |
Description |
---|---|
restrict_by_ip_form_user_admin_perm_alter | Hook to the admin_permissions form |
restrict_by_ip_help | Implementation of hook_help() |
restrict_by_ip_menu | Implementation of hook_menu() Add a menu item to the ddminister >> site building menu for displaying the restrict_by_ip |
restrict_by_ip_perm | Implementation of hook_perm() |
restrict_by_ip_role_check | This just checks the database for any roles associated with that user that are in the restrict_by_ip table. From there it does a ip check on each one of them to see if they are within the range of ip's allowed for that role. |
restrict_by_ip_settings | Menu callback to configure module settings |
restrict_by_ip_user | Implementation of hook_user() |
restrict_by_ip_user_admin_perm_submit | Hook to the admin_permissions submit function |
restrict_by_ip_user_admin_perm_validate | Hook for the permissions validate function. Checks to make sure the ip-address is valid. |
_restrict_by_ip_cidrcheck | Check ip address against a network in cidr notation. E.g: _restrict_by_ip_cidrcheck('192.168.10.100','192.168.10.0/24'); returns 1 _restrict_by_ip_cidrcheck('192.168.10.100','192.168.12.0/24'); returns 0 |
_restrict_by_ip_delete | User deleted function Remove the restrict by ip data from the database table |
_restrict_by_ip_form | Form and register function Insert the restrict by ip form into the user settings and new user forms for authorised users |
_restrict_by_ip_login | Login function Checks the user's ip address on login If they are not restricted, or logging in from the appropriate address allow logon to continue. If not redirect to a designated page |
_restrict_by_ip_update | Update and insert function Update or create new restrict by ip database entry from the form data |
_restrict_by_ip_validate | Validate function Validate the restrict by ip form data |
_restrict_by_ip_validate_ip | This function just makes sure the user input for the ip address section is valid. $sms is the error message if the ip validation fails |