diff --git a/admin/auth.php b/admin/auth.php index fa6d5c00667..4c34e95c81f 100644 --- a/admin/auth.php +++ b/admin/auth.php @@ -1,337 +1,284 @@ -libdir.'/adminlib.php'); +require_once dirname(dirname(__FILE__)) . '/config.php'; +require_once $CFG->libdir . '/tablelib.php'; +require_once($CFG->libdir.'/adminlib.php'); - $adminroot = admin_get_root(); - admin_externalpage_setup('userauthentication', $adminroot); +$adminroot = admin_get_root(); +admin_externalpage_setup('userauthentication', $adminroot); - $auth = optional_param('auth', '', PARAM_SAFEDIR); +// get currently installed and enabled auth plugins +$authsavailable = get_list_of_plugins('auth'); +if (empty($CFG->auth_plugins_enabled)) { + set_config('auth_plugins_enabled', $CFG->auth); + $CFG->auth_plugins_enabled = $CFG->auth; +} +$authsenabled = explode(',', $CFG->auth_plugins_enabled); +// save form +if ($form = data_submitted()) { - $focus = ''; - -/// If data submitted, then process and store. - - if ($config = data_submitted()) { - - if (!confirm_sesskey()) { - error(get_string('confirmsesskeybad', 'error')); - } - - $config = (array)$config; - - // extract and sanitize the auth key explicitly - $modules = get_list_of_plugins("auth"); - if (in_array($config['auth'], $modules)) { - $auth = $config['auth']; - } else { - notify("Error defining the authentication method"); - } - - // load the auth plugin library - require_once("{$CFG->dirroot}/auth/$auth/lib.php"); - - $err = array(); - if (function_exists('auth_validate_form')) { - auth_validate_form($config, $err); - } - - if (count($err) == 0) { - foreach ($config as $name => $value) { - if (preg_match('/^pluginconfig_(.+?)$/', $name, $matches)) { - $plugin = "auth/$auth"; - $name = $matches[1]; - if (! set_config($name, $value, $plugin)) { - notify("Problem saving config $name as $value for plugin $plugin"); - } - } else { // normal handling for - if (! set_config($name, $value)) { - notify("Problem saving config $name as $value"); - } - } - } - redirect("auth.php?sesskey=$USER->sesskey", get_string("changessaved"), 1); - exit; - - } else { - foreach ($err as $key => $value) { - $focus = "form.$key"; - } - } + if (!confirm_sesskey()) { + error(get_string('confirmsesskeybad', 'error')); } -/// Otherwise fill and print the form. - - if (empty($config)) { - $config = $CFG; + if (! isset($form->guestloginbutton)) { + $form->guestloginbutton = 1; } - - $modules = get_list_of_plugins("auth"); - $options = array(); - foreach ($modules as $module) { - $options[$module] = get_string("auth_$module"."title", "auth"); + if (empty($form->alternateloginurl)) { + $form->alternateloginurl = ''; } - asort($options); - if (!empty($auth) && in_array($auth, $modules)) { - } else { - $auth = $config->auth; + if (empty($form->register)) { + $form->register = 'manual'; } + set_config('guestloginbutton', $form->guestloginbutton); + set_config('alternateloginurl', $form->alternateloginurl); + set_config('auth', $form->register); - // changepassword link replaced by individual auth setting - if (!empty($config->changepassword)) { - if (empty($config->{'auth_'.$auth.'_changepasswordurl'})) { - $config->{'auth_'.$auth.'_changepasswordurl'} = $config->changepassword; - } - set_config('changepassword',''); - } - - $auth = clean_param($auth,PARAM_SAFEDIR); - require_once("$CFG->dirroot/auth/$auth/lib.php"); //just to make sure that current authentication functions are loaded - if (! isset($config->guestloginbutton)) { - $config->guestloginbutton = 1; - } - if (! isset($config->alternateloginurl)) { - $config->alternateloginurl = ''; - } - if (! isset($config->auth_instructions)) { - $config->auth_instructions = ""; - } - if (! isset($config->changepassword)) { - $config->changepassword = ""; - } - if (! isset($config->{'auth_'.$auth.'_changepasswordurl'})) { - $config->{'auth_'.$auth.'_changepasswordurl'} = ''; - } - if (! isset($config->{'auth_'.$auth.'_changepasswordhelp'})) { - $config->{'auth_'.$auth.'_changepasswordhelp'} = ''; - } - $user_fields = array("firstname", "lastname", "email", "phone1", "phone2", "department", "address", "city", "country", "description", "idnumber", "lang"); - - $guestoptions[0] = get_string("hide"); - $guestoptions[1] = get_string("show"); - - $createoptions[0] = get_string("no"); - $createoptions[1] = get_string("yes"); - - $strauthentication = get_string("authentication"); - $strauthenticationoptions = get_string("authenticationoptions","auth"); - $strsettings = get_string("settings"); - $strusers = get_string("users"); - - admin_externalpage_print_header($adminroot); - - if (empty($CFG->framename) or $CFG->framename=='_top') { - $target = ''; - } else { - $target = ' target="'.$CFG->framename.'"'; - } - - echo ""; - echo "sesskey."\" />"; - echo "
"; - print_string("chooseauthmethod","auth"); - echo "
"; - echo '  '; - - choose_from_menu ($options, "auth", $auth, "","document.location='auth.php?sesskey=$USER->sesskey&auth='+document.authmenu.auth.options[document.authmenu.auth.selectedIndex].value", ""); - - //echo "
"; - echo "
"; - print_simple_box_start("center", "100%"); - print_heading($options[$auth]); - - print_simple_box_start("center", "60%", '', 5, 'informationbox'); - print_string("auth_$auth"."description", "auth"); - print_simple_box_end(); - - echo "
"; - - print_heading($strsettings); - - echo ""; - - require_once("$CFG->dirroot/auth/$auth/config.html"); - $CFG->pagepath = 'auth/' . $auth; - - echo ''; - - if ($auth != "email" and $auth != "none" and $auth != "manual") { - // display box for URL to change password. NB now on a per-method basis (multiple auth) - echo ""; - echo ""; - echo ""; - echo ""; - - // display textbox for lost password help. NB now on a per-method basis (multiple auth) - echo ""; - echo ""; - echo ""; - echo ""; - - } - - echo ""; - echo ""; - echo ""; - echo ""; - - if (function_exists('auth_user_create')){ - echo ""; - echo ""; - echo ""; - echo ""; - } - - -/// An alternate url for the login form. It means we can use login forms that are integrated -/// into non-moodle pages - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - - echo '
'; - print_heading(get_string('auth_common_settings', 'auth')); - echo '
"; - print_string("changepassword", "auth"); - echo ":"; - $passurl = $config->{'auth_'.$auth.'_changepasswordurl'}; - echo ""; - echo ""; - print_string("auth_changepasswordurl_expl","auth",$auth); - echo "
"; - print_string("auth_changepasswordhelp", "auth"); - echo ":"; - $passhelp = $config->{'auth_'.$auth.'_changepasswordhelp'}; - echo "\n"; - echo ""; - print_string("auth_changepasswordhelp_expl","auth",$auth); - echo "
"; - print_string("guestloginbutton", "auth"); - echo ":"; - choose_from_menu($guestoptions, "guestloginbutton", $config->guestloginbutton, ""); - echo ""; - print_string("showguestlogin","auth"); - echo "
"; - print_string("auth_user_create", "auth"); - echo ":"; - choose_from_menu($createoptions, "auth_user_create", $config->auth_user_create, ""); - echo ""; - print_string("auth_user_creation","auth"); - echo "
'; - print_string('alternateloginurl', 'auth'); - echo ''; - echo ''; - echo ''; - print_string('alternatelogin', 'auth', htmlspecialchars($CFG->wwwroot.'/login/index.php')); - echo '
'; - echo '

'; - - print_simple_box_end(); - - echo ''; - - admin_externalpage_print_footer($adminroot); - exit; - -/// Functions ///////////////////////////////////////////////////////////////// - -// -// Good enough for most auth plugins -// but some may want a custom one if they are offering -// other options -// Note: pluginconfig_ fields have special handling. -function print_auth_lock_options ($auth, $user_fields, $helptext, $retrieveopts, $updateopts) { - - echo ''; - if ($retrieveopts) { - print_heading(get_string('auth_data_mapping', 'auth')); - } else { - print_heading(get_string('auth_fieldlocks', 'auth')); - } - echo ''; - - $lockoptions = array ('unlocked' => get_string('unlocked', 'auth'), - 'unlockedifempty' => get_string('unlockedifempty', 'auth'), - 'locked' => get_string('locked', 'auth')); - $updatelocaloptions = array('oncreate' => get_string('update_oncreate', 'auth'), - 'onlogin' => get_string('update_onlogin', 'auth')); - $updateextoptions = array('0' => get_string('update_never', 'auth'), - '1' => get_string('update_onupdate', 'auth')); - - $pluginconfig = get_config("auth/$auth"); - - // helptext is on a field with rowspan - if (empty($helptext)) { - $helptext = ' '; - } - - foreach ($user_fields as $field) { - - // Define some vars we'll work with - if(empty($pluginconfig->{"field_map_$field"})) { - $pluginconfig->{"field_map_$field"} = ''; - } - if(empty($pluginconfig->{"field_updatelocal_$field"})) { - $pluginconfig->{"field_updatelocal_$field"} = ''; - } - if (empty($pluginconfig->{"field_updateremote_$field"})) { - $pluginconfig->{"field_updateremote_$field"} = ''; - } - if (empty($pluginconfig->{"field_lock_$field"})) { - $pluginconfig->{"field_lock_$field"} = ''; - } - - // define the fieldname we display to the user - $fieldname = $field; - if ($fieldname === 'lang') { - $fieldname = get_string('language'); - } elseif (preg_match('/^(.+?)(\d+)$/', $fieldname, $matches)) { - $fieldname = get_string($matches[1]) . ' ' . $matches[2]; - } else { - $fieldname = get_string($fieldname); - } - - echo ''; - echo $fieldname; - echo ''; - - if ($retrieveopts) { - $varname = 'field_map_' . $field; - - echo "$varname}\">"; - echo '
'; - echo get_string('auth_updatelocal', 'auth') . '  '; - choose_from_menu($updatelocaloptions, "pluginconfig_field_updatelocal_{$field}", $pluginconfig->{"field_updatelocal_$field"}, ""); - echo '
'; - if ($updateopts) { - echo get_string('auth_updateremote', 'auth') . '  '; - '  '; - choose_from_menu($updateextoptions, "pluginconfig_field_updateremote_{$field}", $pluginconfig->{"field_updateremote_$field"}, ""); - echo '
'; - - - } - echo get_string('auth_fieldlock', 'auth') . '  '; - choose_from_menu($lockoptions, "pluginconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, ""); - echo '
'; - } else { - choose_from_menu($lockoptions, "pluginconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, ""); - } - echo ''; - if (!empty($helptext)) { - echo '' . $helptext . ''; - $helptext = ''; - } - echo ''; + // add $CFG->auth to auth_plugins_enabled list + if (!array_search($form->register, $authsenabled)) { + $authsenabled[] = $form->register; + $authsenabled = array_unique($authsenabled); + set_config('auth_plugins_enabled', implode(',', $authsenabled)); } } +// grab GET/POST parameters +$params = new object(); +$params->action = optional_param('action', '', PARAM_ACTION); +$params->auth = optional_param('auth', $CFG->auth, PARAM_ALPHANUM); + +//////////////////////////////////////////////////////////////////////////////// +// process actions + +switch ($params->action) { + + case 'disable': + // remove from enabled list + $key = array_search($params->auth, $authsenabled); + if ($key !== false and $params->auth != $CFG->auth) { + unset($authsenabled[$key]); + set_config('auth_plugins_enabled', implode(',', $authsenabled)); + } + break; + + case 'enable': + // check auth plugin is valid first + if (!exists_auth_plugin($params->auth)) { + error("Authentication plugin '{$params->auth}' is not installed.", $url); + } + // add to enabled list + if (!array_search($params->auth, $authsenabled)) { + $authsenabled[] = $params->auth; + $authsenabled = array_unique($authsenabled); + set_config('auth_plugins_enabled', implode(',', $authsenabled)); + } + break; + + case 'down': + $key = array_search($params->auth, $authsenabled); + // check auth plugin is valid + if ($key === false) { + error("Authentication plugin '{$params->auth}' is not enabled.", $url); + } + // move down the list + if ($key < (count($authsenabled) - 1)) { + $fsave = $authsenabled[$key]; + $authsenabled[$key] = $authsenabled[$key + 1]; + $authsenabled[$key + 1] = $fsave; + set_config('auth_plugins_enabled', implode(',', $authsenabled)); + } + break; + + case 'up': + $key = array_search($params->auth, $authsenabled); + // check auth is valid + if ($key === false) { + error("Authentication plugin '{$params->auth}' is not enabled.", $url); + } + // move up the list + if ($key >= 1) { + $fsave = $authsenabled[$key]; + $authsenabled[$key] = $authsenabled[$key - 1]; + $authsenabled[$key - 1] = $fsave; + set_config('auth_plugins_enabled', implode(',', $authsenabled)); + } + break; + + case 'save': + // save settings + set_config('auth_plugins_enabled', implode(',', $authsenabled)); + set_config('auth', $authsenabled[0]); + redirect("auth.php?sesskey=$USER->sesskey", get_string('changessaved'), 1); + break; + + default: + break; +} + +// display strings +$txt = get_strings(array('authenticationplugins', 'users', 'administration', + 'settings', 'edit', 'name', 'enable', 'disable', + 'up', 'down', 'none')); +$txt->updown = "$txt->up/$txt->down"; + +// construct the display array, with enabled auth plugins at the top, in order +$displayauths = array(); +$registrationauths = array(); +$registrationauths['manual'] = $txt->disable; +foreach ($authsenabled as $auth) { + $displayauths[$auth] = get_string("auth_{$auth}title", 'auth'); + $authplugin = get_auth_plugin($auth); + if (method_exists($authplugin, 'user_signup')) { + $registrationauths[$auth] = get_string("auth_{$auth}title", 'auth'); + } +} +foreach ($authsavailable as $auth) { + if (!array_key_exists($auth, $displayauths)) { + $displayauths[$auth] = get_string("auth_{$auth}title", 'auth'); + } + $authplugin = get_auth_plugin($auth); + if (method_exists($authplugin, 'user_signup')) { + $registrationauths[$auth] = get_string("auth_{$auth}title", 'auth'); + } +} + +// build the display table +$table = new flexible_table('auth_admin_table'); +$table->define_columns(array('name', 'enable', 'order', 'settings')); +$table->column_style('enable', 'text-align', 'center'); +$table->column_style('order', 'text-align', 'center'); +$table->column_style('settings', 'text-align', 'center'); +$table->define_headers(array($txt->name, $txt->enable, $txt->updown, $txt->settings)); +$table->define_baseurl("{$CFG->wwwroot}/{$CFG->admin}/auth.php"); +$table->set_attribute('id', 'blocks'); +$table->set_attribute('class', 'flexible generaltable generalbox'); +$table->set_attribute('style', 'margin:auto;'); +$table->set_attribute('cellpadding', '5'); +$table->setup(); + +// iterate through auth plugins and add to the display table +$updowncount = 1; +$authcount = count($authsenabled); +$url = "auth.php?sesskey=" . sesskey(); +foreach ($displayauths as $auth => $name) { + // hide/show link + if (in_array($auth, $authsenabled)) { + $hideshow = ""; + $hideshow .= "pixpath}/i/hide.gif\" height=\"16\" width=\"16\" alt=\"disable\" />"; + // $hideshow = ""; + $enabled = true; + $displayname = "$name"; + } + else { + $hideshow = ""; + $hideshow .= "pixpath}/i/show.gif\" height=\"16\" width=\"16\" alt=\"enable\" />"; + // $hideshow = ""; + $enabled = false; + $displayname = "$name"; + } + + // up/down link (only if auth is enabled) + $updown = ''; + if ($enabled) { + if ($updowncount > 1) { + $updown .= ""; + $updown .= "pixpath}/t/up.gif\" alt=\"up\" /> "; + } + else { + $updown .= "pixpath}/spacer.gif\" height=\"16\" width=\"16\" alt=\"\" /> "; + } + if ($updowncount < $authcount) { + $updown .= ""; + $updown .= "pixpath}/t/down.gif\" alt=\"down\" />"; + } + else { + $updown .= "pixpath}/spacer.gif\" height=\"16\" width=\"16\" alt=\"\" />"; + } + ++ $updowncount; + } + + // settings link + $settings = "sesskey}&auth=$auth\">{$txt->settings}"; + + // add a row to the table + $table->add_data(array($displayname, $hideshow, $updown, $settings)); +} + +// output form +admin_externalpage_print_header($adminroot); +print_simple_box(get_string('configauthenticationplugins', 'admin'), 'center', '700'); + +if (empty($CFG->framename) or $CFG->framename=='_top') { + $target = ''; +} else { + $target = ' target="'.$CFG->framename.'"'; +} +echo ""; +echo "sesskey."\">"; +print_table($table); + +//////////////////////////////////////////////////////////////////////////////// + +$guestoptions[0] = get_string("hide"); +$guestoptions[1] = get_string("show"); + +echo '
'; +print_heading(get_string('auth_common_settings', 'auth')); +echo ''; + +// User self registration +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +// Login as guest button enabled +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +/// An alternate url for the login form. It means we can use login forms that are integrated +/// into non-moodle pages +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +echo "
\n"; +print_string("selfregistration", "auth"); +echo ":\n"; +choose_from_menu($registrationauths, "register", $CFG->auth, ""); +echo "\n"; +print_string("selfregistration_help", "auth"); +echo "
\n"; +print_string("guestloginbutton", "auth"); +echo ":\n"; +choose_from_menu($guestoptions, "guestloginbutton", $CFG->guestloginbutton, ""); +echo "\n"; +print_string("showguestlogin","auth"); +echo "
\n"; +print_string('alternateloginurl', 'auth'); +echo "\n"; +echo '\n"; +echo "\n"; +print_string('alternatelogin', 'auth', htmlspecialchars($CFG->wwwroot.'/login/index.php')); +echo "
\n"; + +//////////////////////////////////////////////////////////////////////////////// + + +echo '
'; +echo ''; +admin_externalpage_print_footer($adminroot); + ?> diff --git a/admin/auth_config.php b/admin/auth_config.php new file mode 100644 index 00000000000..f7ce6833925 --- /dev/null +++ b/admin/auth_config.php @@ -0,0 +1,176 @@ +libdir.'/adminlib.php'; + +$adminroot = admin_get_root(); +admin_externalpage_setup('userauthentication', $adminroot); +$auth = optional_param('auth', '', PARAM_SAFEDIR); +$authplugin = get_auth_plugin($auth); +$err = array(); + +// save configuration changes +if ($frm = data_submitted()) { + + if (!confirm_sesskey()) { + error(get_string('confirmsesskeybad', 'error')); + } + + if (method_exists($authplugin, 'validate_form')) { + $authplugin->validate_form($frm, $err); + } + + if (count($err) == 0) { + + // save plugin config + if ($authplugin->process_config($frm)) { + + // save field lock configuration + foreach ($frm as $name => $value) { + if (preg_match('/^lockconfig_(.+?)$/', $name, $matches)) { + $plugin = "auth/$auth"; + $name = $matches[1]; + if (!set_config($name, $value, $plugin)) { + notify("Problem saving config $name as $value for plugin $plugin"); + } + } + } + redirect("auth.php?sesskey=$USER->sesskey", get_string("changessaved"), 1); + exit; + } + } else { + foreach ($err as $key => $value) { + $focus = "form.$key"; + } + } +} else { + $frm = get_config("auth/$auth"); +} + +$user_fields = array("firstname", "lastname", "email", "phone1", "phone2", "department", "address", "city", "country", "description", "idnumber", "lang"); + +$modules = get_list_of_plugins('auth'); +foreach ($modules as $module) { + $options[$module] = get_string("auth_{$module}title", 'auth'); +} +asort($options); + +// output configuration form +admin_externalpage_print_header($adminroot); + +if (empty($CFG->framename) or $CFG->framename=='_top') { + $target = ''; +} else { + $target = ' target="'.$CFG->framename.'"'; +} +// choose an authentication method +echo "\n"; +echo "sesskey."\">\n"; +echo "

\n"; +echo get_string('chooseauthmethod').': '; +choose_from_menu ($options, "auth", $auth, '', "document.location='auth_config.php?sesskey=$USER->sesskey&auth='+document.authmenu.auth.options[document.authmenu.auth.selectedIndex].value", ''); +echo "

\n\n"; + +// auth plugin description +print_simple_box_start('center', '80%'); +print_heading($options[$auth]); +print_simple_box_start('center', '60%', '', 5, 'informationbox'); +print_string("auth_{$auth}description", 'auth'); +print_simple_box_end(); +echo "
\n"; +$authplugin->config_form($frm, $err); +print_simple_box_end(); +echo '

\n"; +echo "\n"; + +admin_externalpage_print_footer($adminroot); +exit; + +/// Functions ///////////////////////////////////////////////////////////////// + +// Good enough for most auth plugins +// but some may want a custom one if they are offering +// other options +// Note: lockconfig_ fields have special handling. +function print_auth_lock_options ($auth, $user_fields, $helptext, $retrieveopts, $updateopts) { + + echo ''; + if ($retrieveopts) { + print_heading(get_string('auth_data_mapping', 'auth')); + } else { + print_heading(get_string('auth_fieldlocks', 'auth')); + } + echo ''; + + $lockoptions = array ('unlocked' => get_string('unlocked', 'auth'), + 'unlockedifempty' => get_string('unlockedifempty', 'auth'), + 'locked' => get_string('locked', 'auth')); + $updatelocaloptions = array('oncreate' => get_string('update_oncreate', 'auth'), + 'onlogin' => get_string('update_onlogin', 'auth')); + $updateextoptions = array('0' => get_string('update_never', 'auth'), + '1' => get_string('update_onupdate', 'auth')); + + $pluginconfig = get_config("auth/$auth"); + + // helptext is on a field with rowspan + if (empty($helptext)) { + $helptext = ' '; + } + + foreach ($user_fields as $field) { + + // Define some vars we'll work with + optional_variable($pluginconfig->{"field_map_$field"}, ''); + optional_variable($pluginconfig->{"field_updatelocal_$field"}, ''); + optional_variable($pluginconfig->{"field_updateremote_$field"}, ''); + optional_variable($pluginconfig->{"field_lock_$field"}, ''); + + // define the fieldname we display to the user + $fieldname = $field; + if ($fieldname === 'lang') { + $fieldname = get_string('language'); + } elseif (preg_match('/^(.+?)(\d+)$/', $fieldname, $matches)) { + $fieldname = get_string($matches[1]) . ' ' . $matches[2]; + } else { + $fieldname = get_string($fieldname); + } + + echo ''; + echo $fieldname; + echo ''; + + if ($retrieveopts) { + $varname = 'field_map_' . $field; + + echo "$varname}\">"; + echo '
'; + echo get_string('auth_updatelocal', 'auth') . '  '; + choose_from_menu($updatelocaloptions, "lockconfig_field_updatelocal_{$field}", $pluginconfig->{"field_updatelocal_$field"}, ""); + echo '
'; + if ($updateopts) { + echo get_string('auth_updateremote', 'auth') . '  '; + '  '; + choose_from_menu($updateextoptions, "lockconfig_field_updateremote_{$field}", $pluginconfig->{"field_updateremote_$field"}, ""); + echo '
'; + + + } + echo get_string('auth_fieldlock', 'auth') . '  '; + choose_from_menu($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, ""); + echo '
'; + } else { + choose_from_menu($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, ""); + } + echo ''; + if (!empty($helptext)) { + echo '' . $helptext . ''; + $helptext = ''; + } + echo ''; + } +} + +?> diff --git a/admin/cron.php b/admin/cron.php index 94b1b6af576..a00dca629b9 100644 --- a/admin/cron.php +++ b/admin/cron.php @@ -304,6 +304,23 @@ unset($enrol); } +/// Run the auth cron, if any + if (!($auths = explode(',', $CFG->auth_plugins_enabled))) { + $auths = array($user->auth); + } + mtrace("Running auth crons if required..."); + foreach ($auths as $auth) { + $authplugin = get_auth_plugin($auth); + if (method_exists($authplugin, 'cron')) { + mtrace("Running cron for auth/$auth..."); + $authplugin->cron(); + if (!empty($authplugin->log)) { + mtrace($authplugin->log); + } + } + unset($authplugin); + } + if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) { // check we're not before our runtime diff --git a/admin/environment.xml b/admin/environment.xml index 24ce1e66780..fa5231937b8 100644 --- a/admin/environment.xml +++ b/admin/environment.xml @@ -102,6 +102,11 @@ + + + + + diff --git a/admin/index.php b/admin/index.php index 9c75be92f1d..fe54b03557f 100644 --- a/admin/index.php +++ b/admin/index.php @@ -187,6 +187,7 @@ 'filter_multilang_converted' => 1)); notify($strdatabasesuccess, "green"); + require_once $CFG->dirroot.'/mnet/lib.php'; } else { error("Error: Main databases NOT set up successfully"); } @@ -360,6 +361,11 @@ require_once("$CFG->dirroot/group/db/upgrade.php"); upgrade_group_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards +/// Check for changes to RPC functions + require_once($CFG->dirroot.'/admin/mnet/adminlib.php'); + upgrade_RPC_functions("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + + /// just make sure upgrade logging is properly terminated upgrade_log_finish(); @@ -433,6 +439,7 @@ $guest->lastname = " "; $guest->email = "root@localhost"; $guest->description = addslashes(get_string("guestuserinfo")); + $guest->mnethostid = $CFG->mnet_localhost_id; $guest->confirmed = 1; $guest->lang = $CFG->lang; $guest->timemodified= time(); diff --git a/admin/report/log/index.php b/admin/report/log/index.php index b83c976fe19..94761326417 100644 --- a/admin/report/log/index.php +++ b/admin/report/log/index.php @@ -16,7 +16,7 @@ print_heading(get_string('chooselogs') .':'); - print_log_selector_form($course); + print_mnet_log_selector_form($CFG->mnet_localhost_id, $course); echo '
'; print_heading(get_string('chooselivelogs') .':'); diff --git a/admin/settings/mnet.php b/admin/settings/mnet.php new file mode 100644 index 00000000000..380cfdfc955 --- /dev/null +++ b/admin/settings/mnet.php @@ -0,0 +1,10 @@ +add('mnet', new admin_externalpage('net', get_string('settings', 'mnet'), $CFG->wwwroot . '/admin/mnet/index.php', 'moodle/site:config')); +$ADMIN->add('mnet', new admin_externalpage('ssoaccesscontrol', get_string('ssoaccesscontrol', 'mnet'), $CFG->wwwroot . '/admin/mnet/access_control.php', 'moodle/site:config')); + +$ADMIN->add('mnet', new admin_externalpage('mnetpeers', get_string('mnetpeers', 'mnet'), $CFG->wwwroot . '/admin/mnet/peers.php', 'moodle/site:config')); +$ADMIN->add('mnet', new admin_externalpage('trustedhosts', get_string('trustedhosts', 'mnet'), $CFG->wwwroot . '/admin/mnet/trustedhosts.php', 'moodle/site:config')); +?> diff --git a/admin/settings/top.php b/admin/settings/top.php index 963db2141d7..58fb07b8262 100644 --- a/admin/settings/top.php +++ b/admin/settings/top.php @@ -26,6 +26,7 @@ $ADMIN->add('modules', new admin_externalpage('managefilters', get_string('manag $ADMIN->add('root', new admin_category('security', get_string('security','admin'))); $ADMIN->add('root', new admin_category('appearance', get_string('appearance','admin'))); $ADMIN->add('root', new admin_category('server', get_string('server','admin'))); +$ADMIN->add('root', new admin_category('mnet', get_string('net','mnet'))); $ADMIN->add('root', new admin_category('reports', get_string('reports'))); foreach (get_list_of_plugins('admin/report') as $plugin) { diff --git a/admin/uploaduser.php b/admin/uploaduser.php index 413f09616ae..a896e37f0b5 100755 --- a/admin/uploaduser.php +++ b/admin/uploaduser.php @@ -236,7 +236,7 @@ if ($um->preprocess_files() && confirm_sesskey()) { // an old record instead if ($allowrenames && !empty($user->oldusername) ) { $user->oldusername = moodle_strtolower($user->oldusername); - if ($olduser = get_record('user','username',$user->oldusername)) { + if ($olduser = get_record('user', 'username', $user->oldusername, 'mnethostid', $CFG->mnet_localhost_id)) { if (set_field('user', 'username', $user->username, 'username', $user->oldusername)) { notify(get_string('userrenamed', 'admin') . " : $user->oldusername $user->username"); $renames++; @@ -252,7 +252,7 @@ if ($um->preprocess_files() && confirm_sesskey()) { } } - if ($olduser = get_record("user","username",$username)) { + if ($olduser = get_record("user", "username", $username, "mnethostid", $CFG->mnet_localhost_id)) { if ($updateaccounts) { // Record is being updated $user->id = $olduser->id; diff --git a/admin/user.php b/admin/user.php index 46234674b91..f2d0369ea8a 100644 --- a/admin/user.php +++ b/admin/user.php @@ -14,6 +14,29 @@ $search = trim(optional_param('search', '', PARAM_RAW)); $lastinitial = optional_param('lastinitial', '', PARAM_CLEAN); // only show students with this last initial $firstinitial = optional_param('firstinitial', '', PARAM_CLEAN); // only show students with this first initial + $ru = optional_param('ru', '2', PARAM_INT); // show remote users + $lu = optional_param('lu', '2', PARAM_INT); // show local users + $acl = optional_param('acl', '0', PARAM_INT); // id of user to tweak mnet ACL (requires $access) + + // Determine which users we are looking at (local, remote, or both). Start with both. + if (!isset($_SESSION['admin-user-remoteusers'])) { + $_SESSION['admin-user-remoteusers'] = 1; + $_SESSION['admin-user-localusers'] = 1; + } + if ($ru == 0 or $ru == 1) { + $_SESSION['admin-user-remoteusers'] = $ru; + } + if ($lu == 0 or $lu == 1) { + $_SESSION['admin-user-localusers'] = $lu; + } + $remoteusers = $_SESSION['admin-user-remoteusers']; + $localusers = $_SESSION['admin-user-localusers']; + + // if neither remote nor local, set to sensible local only + if (!$remoteusers and !$localusers) { + $_SESSION['admin-user-localusers'] = 1; + $localusers = 1; + } if (!$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID)) { // Should never happen redirect('index.php'); @@ -28,6 +51,7 @@ $user->password = hash_internal_user_password('admin'); $user->email = 'root@localhost'; $user->confirmed = 1; + $user->mnethostid = $CFG->mnet_localhost_id; $user->lang = $CFG->lang; $user->maildisplay = 1; $user->timemodified = time(); @@ -105,6 +129,7 @@ $user->lang = $CFG->lang; $user->confirmed = 1; $user->timemodified = time(); + $user->mnethostid = $CFG->mnet_localhost_id; if (! $user->id = insert_record('user', $user)) { error('Could not start a new user!'); @@ -182,6 +207,40 @@ notify(get_string('deletednot', '', fullname($user, true))); } } + } else if ($acl and confirm_sesskey()) { + if (!has_capability('moodle/user:delete', $sitecontext)) { + // TODO: this should be under a separate capability + error('You are not permitted to modify the MNET access control list.'); + } + if (!$user = get_record('user', 'id', $acl)) { + error("No such user."); + } + if (!is_mnet_remote_user($user)) { + error('Users in the MNET access control list must be remote MNET users.'); + } + $access = strtolower(required_param('access', PARAM_ALPHA)); + if ($access != 'allow' and $access != 'deny') { + error('Invalid access parameter.'); + } + $aclrecord = get_record('mnet_sso_access_control', 'username', $user->username, 'mnet_host_id', $user->mnethostid); + if (empty($aclrecord)) { + $aclrecord = new object(); + $aclrecord->mnet_host_id = $user->mnethostid; + $aclrecord->username = $user->username; + $aclrecord->access = $access; + if (!insert_record('mnet_sso_access_control', $aclrecord)) { + error("Database error - Couldn't modify the MNET access control list."); + } + } else { + $aclrecord->access = $access; + if (!update_record('mnet_sso_access_control', $aclrecord)) { + error("Database error - Couldn't modify the MNET access control list."); + } + } + $mnethosts = get_records('mnet_host', '', '', 'id', 'id,wwwroot,name'); + notify("MNET access control list updated: username '$user->username' from host '" + . $mnethosts[$user->mnethostid]->name + . "' access now set to '$access'."); } // Carry on with the user listing @@ -213,8 +272,21 @@ if ($sort == "name") { $sort = "firstname"; } - - $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, $search, $firstinitial, $lastinitial); + + // tell the query which users we are looking at (local, remote, or both) + $remotewhere = ''; + if ($localusers) { + $remotewhere .= " and mnethostid = {$CFG->mnet_localhost_id} "; + } + if ($remoteusers) { + if ($localusers) { + $remotewhere = ''; // more efficient SQL + } else { + $remotewhere .= " and mnethostid <> {$CFG->mnet_localhost_id} "; + } + } + + $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, $search, $firstinitial, $lastinitial, $remotewhere); $usercount = get_users(false); $usersearchcount = get_users(false, $search, true, "", "", $firstinitial, $lastinitial); @@ -294,6 +366,9 @@ } else { $countries = get_list_of_countries(); + if (empty($mnethosts)) { + $mnethosts = get_records('mnet_host', '', '', 'id', 'id,wwwroot,name'); + } foreach ($users as $key => $user) { if (!empty($user->country)) { @@ -329,7 +404,7 @@ } } - if (has_capability('moodle/user:update', $sitecontext)) { + if (has_capability('moodle/user:update', $sitecontext) and ! is_mnet_remote_user($user)) { $editbutton = "id&course=$site->id\">$stredit"; if ($user->confirmed == 0) { $confirmbutton = "id&sesskey=$USER->sesskey\">" . get_string('confirm') . ""; @@ -345,6 +420,27 @@ } } + // for remote users, shuffle columns around and display MNET stuff + if (is_mnet_remote_user($user)) { + $access = 'allow'; + if ($acl = get_record('mnet_sso_access_control', 'username', $user->username, 'mnet_host_id', $user->mnethostid)) { + $access = $acl->access; + } + $changeaccessto = ($access == 'deny' ? 'allow' : 'deny'); + // delete button in confirm column - remote users should already be confirmed + // TODO: no delete for remote users, for now. new userid, delete flag, unique on username/host... + $confirmbutton = ""; + // ACL in delete column + $deletebutton = ucfirst($access); + if (has_capability('moodle/user:delete', $sitecontext)) { + // TODO: this should be under a separate capability + $deletebutton .= " (id}&access=$changeaccessto&sesskey={$USER->sesskey}\">" + . ucfirst($changeaccessto) . " access)"; + } + // mnet info in edit column + $editbutton = $mnethosts[$user->mnethostid]->name; + } + if ($user->lastaccess) { $strlastaccess = format_time(time() - $user->lastaccess); } else { @@ -363,6 +459,19 @@ } } + echo "

"; + if ($remoteusers == 1) { + echo "Hide remote users | "; + } else { + echo "Show remote users | "; + } + if ($localusers == 1) { + echo "Hide local users"; + } else { + echo "Show local users"; + } + echo "

"; + echo "
"; echo "
"; echo ""; diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php index 206e00fe686..973a19cdfe3 100644 --- a/lang/en_utf8/admin.php +++ b/lang/en_utf8/admin.php @@ -53,6 +53,7 @@ $string['configallowusermailcharset'] = 'Enabling this, every user in the site w $string['configallowuserthemes'] = 'If you enable this, then users will be allowed to set their own themes. User themes override site themes (but not course themes)'; $string['configallusersaresitestudents'] = 'For activities on the front page of the site, should ALL users be considered as students? If you answer \"Yes\", then any confirmed user account will be allowed to participate as a student in those activities. If you answer \"No\", then only users who are already a participant in at least one course will be able to take part in those front page activities. Only admins and specially assigned teachers can act as teachers for these front page activities.'; $string['configvisiblecourses'] = 'Display courses in hidden categories normally'; +$string['configauthenticationplugins'] = 'Please choose the authentication plugins you wish to use and arrange them in order of failthrough. Self registration will be handled by the plugin selected in the \'Registration\' column (usually \'email\').'; $string['configautologinguests'] = 'Should visitors be logged in as guests automatically when entering courses with guest access?'; $string['configbloglevel'] = 'This setting allows you to restrict the level to which user blogs can be viewed on this site. Note that they specify the maximum context of the VIEWER not the poster or the types of blog posts. Blogs can also be disabled completely if you don\'t want them at all.'; $string['configcachetext'] = 'For larger sites or sites that use text filters, this setting can really speed things up. Copies of texts will be retained in their processed form for the time specified here. Setting this too small may actually slow things down slightly, but setting it too large may mean texts take too long to refresh (with new links, for example).'; @@ -195,6 +196,7 @@ $string['cronerrorclionly'] = 'Sorry, internet access to this page has been disa $string['cronerrorpassword'] = 'Sorry, you have not provided a valid password to access this page'; $string['cronremotepassword'] = 'Cron password for remote access'; $string['cronwarning'] = 'The cron.php maintenance script has not been run for at least 24 hours.'; +$string['curlrecommended'] = 'Installing the optional Curl library is highly recommended in order to enable Moodle Networking functionality.'; $string['datarootsecuritywarning'] = 'Your site configuration might not be secure. Please make sure that your dataroot directory ($a) is not directly accessible via web.'; $string['dbmigrate'] = 'Moodle Database Migration'; $string['dbmigrateconnecerror'] = 'Could not connect to the database specified.';