Add ability to white list IP addresses to ignore iprestrictions
This commit is contained in:
parent
5a115b42f1
commit
bded162058
5 changed files with 112 additions and 7 deletions
11
auth.php
11
auth.php
|
@ -57,6 +57,7 @@ class auth_plugin_userkey extends auth_plugin_base {
|
||||||
'mappingfield' => self::DEFAULT_MAPPING_FIELD,
|
'mappingfield' => self::DEFAULT_MAPPING_FIELD,
|
||||||
'keylifetime' => 60,
|
'keylifetime' => 60,
|
||||||
'iprestriction' => 0,
|
'iprestriction' => 0,
|
||||||
|
'ipwhitelist' => '',
|
||||||
'redirecturl' => '',
|
'redirecturl' => '',
|
||||||
'ssourl' => '',
|
'ssourl' => '',
|
||||||
'createuser' => false,
|
'createuser' => false,
|
||||||
|
@ -347,7 +348,7 @@ class auth_plugin_userkey extends auth_plugin_base {
|
||||||
|
|
||||||
$requiredfieds = ['username', 'email', 'firstname', 'lastname'];
|
$requiredfieds = ['username', 'email', 'firstname', 'lastname'];
|
||||||
$missingfields = [];
|
$missingfields = [];
|
||||||
foreach ($requiredfieds as $requiredfied) {
|
foreach($requiredfieds as $requiredfied) {
|
||||||
if (empty($user[$requiredfied])) {
|
if (empty($user[$requiredfied])) {
|
||||||
$missingfields[] = $requiredfied;
|
$missingfields[] = $requiredfied;
|
||||||
}
|
}
|
||||||
|
@ -603,14 +604,14 @@ class auth_plugin_userkey extends auth_plugin_base {
|
||||||
|
|
||||||
$mappingfield = $this->get_mapping_field();
|
$mappingfield = $this->get_mapping_field();
|
||||||
if ($this->should_create_user() || $this->should_update_user()) {
|
if ($this->should_create_user() || $this->should_update_user()) {
|
||||||
$parameters['firstname'] = new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL);
|
$parameters['firstname'] = new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user', VALUE_OPTIONAL);
|
||||||
$parameters['lastname'] = new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL);
|
$parameters['lastname'] = new external_value(core_user::get_property_type('lastname'), 'The family name of the user', VALUE_OPTIONAL);
|
||||||
|
|
||||||
if ($mappingfield != 'email') {
|
if ($mappingfield != 'email') {
|
||||||
$parameters['email'] = new external_value(PARAM_RAW_TRIMMED, 'A valid and unique email address', VALUE_OPTIONAL);
|
$parameters['email'] = new external_value(core_user::get_property_type('email'), 'A valid and unique email address', VALUE_OPTIONAL);
|
||||||
}
|
}
|
||||||
if ($mappingfield != 'username') {
|
if ($mappingfield != 'username') {
|
||||||
$parameters['username'] = new external_value(PARAM_USERNAME, 'A valid and unique username', VALUE_OPTIONAL);
|
$parameters['username'] = new external_value(core_user::get_property_type('username'), 'A valid and unique username', VALUE_OPTIONAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,8 +124,22 @@ class core_userkey_manager implements userkey_manager_interface {
|
||||||
|
|
||||||
if ($key->iprestriction) {
|
if ($key->iprestriction) {
|
||||||
$remoteaddr = getremoteaddr(null);
|
$remoteaddr = getremoteaddr(null);
|
||||||
if (empty($remoteaddr) or !address_in_subnet($remoteaddr, $key->iprestriction)) {
|
$whitelist = get_config('auth_userkey', 'ipwhitelist');
|
||||||
print_error('ipmismatch');
|
if (!empty($whitelist)) {
|
||||||
|
$ips = explode(';', $whitelist);
|
||||||
|
$whitelisted = false;
|
||||||
|
foreach ($ips as $ip) {
|
||||||
|
if (address_in_subnet($remoteaddr, $ip)) {
|
||||||
|
$whitelisted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$whitelisted) {
|
||||||
|
print_error('ipmismatch', 'error', '', null, "Remote address: $remoteaddr\nKey IP: $key->iprestriction");
|
||||||
|
}
|
||||||
|
} else if (empty($remoteaddr) ) {
|
||||||
|
print_error('noip', 'auth_userkey');
|
||||||
|
} else if (!address_in_subnet($remoteaddr, $key->iprestriction)) {
|
||||||
|
print_error('ipmismatch', 'error', '', null, "Remote address: $remoteaddr\nKey IP: $key->iprestriction");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,10 @@ $string['mappingfield_desc'] = 'This user field will be used to find relevant us
|
||||||
$string['iprestriction'] = 'IP restriction';
|
$string['iprestriction'] = 'IP restriction';
|
||||||
$string['iprestriction_desc'] = 'If enabled, a web call has to contain "ip" parameter when requesting login URL.
|
$string['iprestriction_desc'] = 'If enabled, a web call has to contain "ip" parameter when requesting login URL.
|
||||||
A user has to have provided IP to be able to use a key to login to LMS.';
|
A user has to have provided IP to be able to use a key to login to LMS.';
|
||||||
|
$string['ipwhitelist'] = 'Whitelist IP ranges';
|
||||||
|
$string['ipwhitelist_desc'] = "Ignore IP restrictions if the IP address the token was issued for or the login attempt comes from falls within any of these ranges.
|
||||||
|
\nThis can happen when some users reach Moodle or the system issuing login tokens via a private network or DMZ.
|
||||||
|
\nIf the route to either the system issuing tokens or this Moodle is via a private address range then set this value to 10.0.0.0/8;172.16.0.0/12;192.168.0.0/16";
|
||||||
$string['keylifetime'] = 'User key life time';
|
$string['keylifetime'] = 'User key life time';
|
||||||
$string['keylifetime_desc'] = 'Life time in seconds of the each user login key.';
|
$string['keylifetime_desc'] = 'Life time in seconds of the each user login key.';
|
||||||
$string['incorrectkeylifetime'] = 'User key life time should be a number';
|
$string['incorrectkeylifetime'] = 'User key life time should be a number';
|
||||||
|
|
|
@ -49,6 +49,13 @@ $fields = get_auth_plugin('userkey')->get_allowed_mapping_fields();
|
||||||
<?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?>
|
<?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?>
|
||||||
<?php print_string($field.'_desc', 'auth_userkey')?></td>
|
<?php print_string($field.'_desc', 'auth_userkey')?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr valign="top">
|
||||||
|
<?php $field = 'ipwhitelist' ?>
|
||||||
|
<td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td>
|
||||||
|
<td><input type="text" size="60" name="<?php echo $field ?>" value="<?php print $config->$field ?>" placeholder=""><br>
|
||||||
|
<?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?>
|
||||||
|
<?php print_string($field.'_desc', 'auth_userkey') ?></td>
|
||||||
|
</tr>
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<?php $field = 'redirecturl' ?>
|
<?php $field = 'redirecturl' ?>
|
||||||
<td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td>
|
<td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td>
|
||||||
|
|
|
@ -756,6 +756,7 @@ class auth_plugin_userkey_testcase extends advanced_testcase {
|
||||||
$formconfig->mappingfield = 'email';
|
$formconfig->mappingfield = 'email';
|
||||||
$formconfig->keylifetime = 100;
|
$formconfig->keylifetime = 100;
|
||||||
$formconfig->iprestriction = 0;
|
$formconfig->iprestriction = 0;
|
||||||
|
$formconfig->ipwhitelist = '';
|
||||||
$formconfig->redirecturl = 'http://google.com/';
|
$formconfig->redirecturl = 'http://google.com/';
|
||||||
$formconfig->ssourl = 'http://google.com/';
|
$formconfig->ssourl = 'http://google.com/';
|
||||||
$formconfig->createuser = false;
|
$formconfig->createuser = false;
|
||||||
|
@ -842,6 +843,84 @@ class auth_plugin_userkey_testcase extends advanced_testcase {
|
||||||
$this->auth->user_login_userkey();
|
$this->auth->user_login_userkey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that IP address mismatch exception gets thrown if incorrect IP.
|
||||||
|
*
|
||||||
|
* @expectedException moodle_exception
|
||||||
|
* @expectedExceptionMessage Unsupported redirect to http://www.example.com/moodle detected, execution terminated.
|
||||||
|
*/
|
||||||
|
public function test_ipmismatch_exception_notthrown_if_ip_is_whitelisted() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
set_config('ipwhitelist', '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16', 'auth_userkey');
|
||||||
|
|
||||||
|
$key = new stdClass();
|
||||||
|
$key->value = 'IpmismatchKey';
|
||||||
|
$key->script = 'auth/userkey';
|
||||||
|
$key->userid = $this->user->id;
|
||||||
|
$key->instance = $this->user->id;
|
||||||
|
$key->iprestriction = '192.168.1.1';
|
||||||
|
$key->validuntil = time() + 300;
|
||||||
|
$key->timecreated = time();
|
||||||
|
$DB->insert_record('user_private_key', $key);
|
||||||
|
|
||||||
|
$_POST['key'] = 'IpmismatchKey';
|
||||||
|
$_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2';
|
||||||
|
@$this->auth->user_login_userkey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that IP address mismatch exception gets thrown if incorrect IP.
|
||||||
|
*
|
||||||
|
* @expectedException moodle_exception
|
||||||
|
* @expectedExceptionMessage Unsupported redirect to http://www.example.com/moodle detected, execution terminated.
|
||||||
|
*/
|
||||||
|
public function test_ipmismatch_exception_notthrown_if_ip_is_whitelisted_temp() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
set_config('ipwhitelist', '192.168.1.2', 'auth_userkey');
|
||||||
|
|
||||||
|
$key = new stdClass();
|
||||||
|
$key->value = 'IpmismatchKey';
|
||||||
|
$key->script = 'auth/userkey';
|
||||||
|
$key->userid = $this->user->id;
|
||||||
|
$key->instance = $this->user->id;
|
||||||
|
$key->iprestriction = '192.168.1.1';
|
||||||
|
$key->validuntil = time() + 300;
|
||||||
|
$key->timecreated = time();
|
||||||
|
$DB->insert_record('user_private_key', $key);
|
||||||
|
|
||||||
|
$_POST['key'] = 'IpmismatchKey';
|
||||||
|
$_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2';
|
||||||
|
@$this->auth->user_login_userkey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that IP address mismatch exception gets thrown if incorrect IP.
|
||||||
|
*
|
||||||
|
* @expectedException moodle_exception
|
||||||
|
* @expectedExceptionMessage Client IP address mismatch
|
||||||
|
*/
|
||||||
|
public function test_ipmismatch_exception_thrown_if_ip_is_outside_whitelist() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
set_config('ipwhitelist', '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16', 'auth_userkey');
|
||||||
|
|
||||||
|
$key = new stdClass();
|
||||||
|
$key->value = 'IpmismatchKey';
|
||||||
|
$key->script = 'auth/userkey';
|
||||||
|
$key->userid = $this->user->id;
|
||||||
|
$key->instance = $this->user->id;
|
||||||
|
$key->iprestriction = '192.161.1.1';
|
||||||
|
$key->validuntil = time() + 300;
|
||||||
|
$key->timecreated = time();
|
||||||
|
$DB->insert_record('user_private_key', $key);
|
||||||
|
|
||||||
|
$_POST['key'] = 'IpmismatchKey';
|
||||||
|
$_SERVER['HTTP_CLIENT_IP'] = '192.161.1.2';
|
||||||
|
$this->auth->user_login_userkey();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that IP address mismatch exception gets thrown if user id is incorrect.
|
* Test that IP address mismatch exception gets thrown if user id is incorrect.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue