/** * Define the form. */ public function definition() { global $CFG, $COURSE, $USER; $mform = $this->_form; $editoroptions = null; $filemanageroptions = null; $usernotfullysetup = user_not_fully_set_up($USER); if (!is_array($this->_customdata)) { throw new coding_exception('invalid custom data for user_edit_form'); } $editoroptions = $this->_customdata['editoroptions']; $filemanageroptions = $this->_customdata['filemanageroptions']; $user = $this->_customdata['user']; $userid = $user->id; if (empty($user->country)) { // We must unset the value here so $CFG->country can be used as default one. unset($user->country); } // Accessibility: "Required" is bad legend text. $strgeneral = get_string('general'); $strrequired = get_string('required'); // Add some extra hidden fields. $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'course', $COURSE->id); $mform->setType('course', PARAM_INT); // Print the required moodle fields first. $mform->addElement('header', 'moodle', $strgeneral); // Shared fields. useredit_shared_definition($mform, $editoroptions, $filemanageroptions, $user); // Extra settigs. if (!empty($CFG->disableuserimages) || $usernotfullysetup) { $mform->removeElement('deletepicture'); $mform->removeElement('imagefile'); $mform->removeElement('imagealt'); } // If the user isn't fully set up, let them know that they will be able to change // their profile picture once their profile is complete. if ($usernotfullysetup) { $userpicturewarning = $mform->createElement('warning', 'userpicturewarning', 'notifymessage', get_string('newpictureusernotsetup')); $enabledusernamefields = useredit_get_enabled_name_fields(); if ($mform->elementExists('moodle_additional_names')) { $mform->insertElementBefore($userpicturewarning, 'moodle_additional_names'); } else { if ($mform->elementExists('moodle_interests')) { $mform->insertElementBefore($userpicturewarning, 'moodle_interests'); } else { $mform->insertElementBefore($userpicturewarning, 'moodle_optional'); } } // This is expected to exist when the form is submitted. $imagefile = $mform->createElement('hidden', 'imagefile'); $mform->insertElementBefore($imagefile, 'userpicturewarning'); } // Next the customisable profile fields. profile_definition($mform, $userid); $this->add_action_buttons(false, get_string('updatemyprofile')); $this->set_data($user); }
/** * podcaster basic authentication * * @author Humboldt Universitaet zu Berlin * Christoph Soergel <*****@*****.**> * @version 1.0 * @package podcaster * */ function http_basic_login() { global $USER; $realm = 'restricted'; $userValid = false; if (isloggedin()) { return true; } $realm = 'restricted'; if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $user = authenticate_user_login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); do { if (!$user) { $realm = 'loginerror'; break; } $USER = $user; // check whether the user should be changing password if (get_user_preferences('auth_forcepasswordchange', false)) { if ($passwordchangeurl != '') { $realm = 'mustchangepassword'; } else { $realm = 'mustchangepassword_butnourl'; } break; } // check wether user is fully setup if (user_not_fully_set_up($USER)) { $realm = 'notfullysetup'; break; } return true; } while (false); unset($USER); } // no credentials header('WWW-Authenticate: Basic realm="' . get_string($realm, 'podcaster') . '"'); header('HTTP/1.0 401 Unauthorized'); echo get_string($realm, 'podcaster'); exit; }
/** * Renders the popup. * * @param renderer_base $renderer * @return string The HTML */ function message_popup_render_navbar_output(\renderer_base $renderer) { global $USER, $CFG; // Early bail out conditions. if (!isloggedin() || isguestuser() || user_not_fully_set_up($USER) || get_user_preferences('auth_forcepasswordchange') || $CFG->sitepolicy && !$USER->policyagreed && !is_siteadmin()) { return ''; } $output = ''; // Add the messages popover. if (!empty($CFG->messaging)) { $context = ['userid' => $USER->id, 'urls' => ['seeall' => (new moodle_url('/message/index.php'))->out(), 'writeamessage' => (new moodle_url('/message/index.php', ['contactsfirst' => 1]))->out(), 'preferences' => (new moodle_url('/message/edit.php', ['id' => $USER->id]))->out()]]; $output .= $renderer->render_from_template('message_popup/message_popover', $context); } // Add the notifications popover. $enabled = \core_message\api::is_processor_enabled("popup"); if ($enabled) { $context = ['userid' => $USER->id, 'urls' => ['seeall' => (new moodle_url('/message/output/popup/notifications.php'))->out(), 'preferences' => (new moodle_url('/message/notificationpreferences.php', ['userid' => $USER->id]))->out()]]; $output .= $renderer->render_from_template('message_popup/notification_popover', $context); } return $output; }
/** * Renders the popup. * * @param renderer_base $renderer * @return string The HTML */ function message_popup_render_navbar_output(\renderer_base $renderer) { global $USER, $DB, $CFG; // Early bail out conditions. if (!isloggedin() || isguestuser() || user_not_fully_set_up($USER) || get_user_preferences('auth_forcepasswordchange')) { return ''; } $output = ''; // Add the messages popover. if (!empty($CFG->messaging)) { $context = ['userid' => $USER->id, 'urls' => ['preferences' => (new moodle_url('/message/edit.php', ['id' => $USER->id]))->out()]]; $output .= $renderer->render_from_template('message_popup/message_popover', $context); } // Add the notifications popover. $processor = $DB->get_record('message_processors', array('name' => 'popup')); if ($processor && $processor->enabled) { $context = ['userid' => $USER->id, 'urls' => ['preferences' => (new moodle_url('/message/notificationpreferences.php', ['userid' => $USER->id]))->out()]]; $output .= $renderer->render_from_template('message_popup/notification_popover', $context); } return $output; }
/** * Post authentication hook. * This method is called from authenticate_user_login() for all enabled auth plugins. * * @param object $user user object, later used for $USER * @param string $username (with system magic quotes) * @param string $password plain text password (with system magic quotes) */ function user_authenticated_hook(&$user, $username, $password) { global $SESSION; global $CFG; global $DB; $record = $DB->get_record('block_gdata_gapps', array('userid' => $user->id)); if (empty($record) || !empty($record->remove)) { return true; } // Shouldn't need due to Gmail using OAuth // // TODO: IMPORTANT user_auth hook gets called for all plugins so // setting user to gsaml auth may override all moodle user auth plugins. // auth_gsaml still needs to run the update password code somehow. // if there was another way to test for it.... as compare if password is diff // and then set the google user to the new password. :/ // Verify that user has a google account. If not create one for them. if (!file_exists($CFG->dirroot . '/blocks/gdata/gapps.php')) { debugging('gdata block is not installed'); } else { require_once $CFG->dirroot . '/blocks/gdata/gapps.php'; try { $g = new blocks_gdata_gapps(); try { $g_user = $g->gapps_get_user($username); if (empty($g_user)) { /* * MOODLE must enforce the above minium 6 char passwords! * http://www.google.com/support/a/bin/answer.py?answer=33386 */ // Create Moodle User in the Gsync system $g->moodle_create_user($user); // Create google user $m_user = $g->moodle_get_user($user->id); $g->create_user($m_user); } } catch (blocks_gdata_exception $e) { // TODO: catch and inform of this common error //if (stripos($e->getMessage(),'Error 1100: UserDeletedRecently') ) { // notice('Error 1100: UserDeletedRecently.<br/> Google does not allow a user to be created after deletion until at least 5 days have passed.'); //} if (method_exists($e, 'getErrors')) { $errors = $e->getErrors(); foreach ($errors as $errorcode => $error) { debugging("Error({$errorcode}): {$error}", DEBUG_NORMAL, true); } } else { debugging($e, DEBUG_DEVELOPER); } } } catch (blocks_gdata_exception $e) { //'Authentication with Google Apps failed. Please check your credentials. ->getMessage() ? // if Authentication with Google Apps failed. Please check your credentials. // print $e->getMessage(); // TODO: catch and inform of this Error debugging($e, DEBUG_DEVELOPER); } } // We are Succesfully logged in and we have a SAML Request // So we want to process the rest of the log in and redirect // to the Service that the SAML Request is asking for. // // All this code essentialy makes up for the fact that // we have to exit the login page prematurely. if (isset($SESSION->samlrequest)) { $SESSION->samlrequest = false; if (!($user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id)))) { // User could not be logged in error(get_string('errusernotloggedin', 'auth_gsaml')); } if (!validate_internal_user_password($user, $password)) { // Password not valid error(get_string('pwdnotvalid', 'auth_gsaml')); } // Added to fix navigation $navlinks = array(array('name' => 'test', 'link' => null, 'type' => 'misc')); $navigation = build_navigation($navlinks); update_login_count(); if ($user) { // language setup if ($user->username == 'guest') { // no predefined language for guests - use existing session or default site lang unset($user->lang); } else { if (!empty($user->lang)) { // unset previous session language - use user preference instead unset($SESSION->lang); } } if (empty($user->confirmed)) { // This account was never confirmed print_header(get_string("mustconfirm"), get_string("mustconfirm")); print_heading(get_string("mustconfirm")); print_simple_box(get_string("emailconfirmsent", "", $user->email), "center"); print_footer(); die; } // TODO : Fix this bug frm isn't on this page here if (isset($frm)) { // if isset placed here for now if ($frm->password == 'changeme') { //force the change set_user_preference('auth_forcepasswordchange', true, $user->id); } } // end of if issuet /// Let's get them all set up. add_to_log(SITEID, 'user', 'login', "view.php?id={$USER->id}&course=" . SITEID, $user->id, 0, $user->id); $USER = complete_user_login($user); /// Prepare redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } /// Go to my-moodle page instead of homepage if mymoodleredirect enabled if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and !empty($CFG->mymoodleredirect) and !isguest()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') { $urltogo = $CFG->wwwroot . '/my/'; } } /// check if user password has expired /// Currently supported only for ldap-authentication module $userauth = get_auth_plugin($USER->auth); if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { if ($userauth->can_change_password()) { $passwordchangeurl = $userauth->change_password_url(); } else { $passwordchangeurl = $CFG->httpswwwroot . '/login/change_password.php'; } $days2expire = $userauth->password_expire($USER->username); if (intval($days2expire) > 0 && intval($days2expire) < intval($userauth->config->expiration_warning)) { print_header("{$site->fullname}: {$loginsite}", "{$site->fullname}", $navigation, '', '', true, "<div class=\"langmenu\">{$langmenu}</div>"); notice_yesno(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo); print_footer(); exit; } elseif (intval($days2expire) < 0) { print_header("{$site->fullname}: {$loginsite}", "{$site->fullname}", $navigation, '', '', true, "<div class=\"langmenu\">{$langmenu}</div>"); notice_yesno(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo); print_footer(); exit; } } reset_login_count(); // END of the regular Moodle Login Procedures // Process the SAML Request and redirect to the Service // it is asking for. // This function should never return unless there's an error. if (!gsaml_send_auth_response($SESSION->samlrequestdata)) { // SAML code failed turn debugging on error(get_string('samlcodefailed', 'auth_gsaml')); } } else { if (empty($errormsg)) { $errormsg = get_string("invalidlogin"); $errorcode = 3; } // TODO: if the user failed to authenticate, check if the username corresponds to a remote mnet user if (!empty($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode === 'strict' && is_enabled_auth('mnet')) { $errormsg .= get_string('loginlinkmnetuser', 'mnet', "mnet_email.php?u={$frm->username}"); } } } // else if NO SAML request is made we don't do anything but log in normally }
/** * Test that {@link user_not_fully_set_up()} takes required custom fields into account. */ public function test_profile_has_required_custom_fields_set() { global $CFG, $DB; require_once $CFG->dirroot . '/mnet/lib.php'; $this->resetAfterTest(); // Add a required, visible, unlocked custom field. $DB->insert_record('user_info_field', ['shortname' => 'house', 'name' => 'House', 'required' => 1, 'visible' => 1, 'locked' => 0, 'categoryid' => 1, 'datatype' => 'text']); // Add an optional, visible, unlocked custom field. $DB->insert_record('user_info_field', ['shortname' => 'pet', 'name' => 'Pet', 'required' => 0, 'visible' => 1, 'locked' => 0, 'categoryid' => 1, 'datatype' => 'text']); // Add required but invisible custom field. $DB->insert_record('user_info_field', ['shortname' => 'secretid', 'name' => 'Secret ID', 'required' => 1, 'visible' => 0, 'locked' => 0, 'categoryid' => 1, 'datatype' => 'text']); // Add required but locked custom field. $DB->insert_record('user_info_field', ['shortname' => 'muggleborn', 'name' => 'Muggle-born', 'required' => 1, 'visible' => 1, 'locked' => 1, 'categoryid' => 1, 'datatype' => 'checkbox']); // Create some student accounts. $hermione = $this->getDataGenerator()->create_user(); $harry = $this->getDataGenerator()->create_user(); $ron = $this->getDataGenerator()->create_user(); $draco = $this->getDataGenerator()->create_user(); // Hermione has all available custom fields filled (of course she has). profile_save_data((object) ['id' => $hermione->id, 'profile_field_house' => 'Gryffindor']); profile_save_data((object) ['id' => $hermione->id, 'profile_field_pet' => 'Crookshanks']); // Harry has only the optional field filled. profile_save_data((object) ['id' => $harry->id, 'profile_field_pet' => 'Hedwig']); // Draco has only the required field filled. profile_save_data((object) ['id' => $draco->id, 'profile_field_house' => 'Slytherin']); // Only students with required fields filled should be considered as fully set up in the default (strict) mode. $this->assertFalse(user_not_fully_set_up($hermione)); $this->assertFalse(user_not_fully_set_up($draco)); $this->assertTrue(user_not_fully_set_up($harry)); $this->assertTrue(user_not_fully_set_up($ron)); // In the lax mode, students do not need to have required fields filled. $this->assertFalse(user_not_fully_set_up($hermione, false)); $this->assertFalse(user_not_fully_set_up($draco, false)); $this->assertFalse(user_not_fully_set_up($harry, false)); $this->assertFalse(user_not_fully_set_up($ron, false)); // Lack of required core field is seen as a problem in either mode. unset($hermione->email); $this->assertTrue(user_not_fully_set_up($hermione, true)); $this->assertTrue(user_not_fully_set_up($hermione, false)); // When confirming remote MNet users, we do not have custom fields available. $roamingharry = mnet_strip_user($harry, ['firstname', 'lastname', 'email']); $roaminghermione = mnet_strip_user($hermione, ['firstname', 'lastname', 'email']); $this->assertTrue(user_not_fully_set_up($roamingharry, true)); $this->assertFalse(user_not_fully_set_up($roamingharry, false)); $this->assertTrue(user_not_fully_set_up($roaminghermione, true)); $this->assertTrue(user_not_fully_set_up($roaminghermione, false)); }
/// If we can find the Shibboleth attribute, save it in session and return to main login page if (!empty($_SERVER[$pluginconfig->user_attribute])) { // Shibboleth auto-login $frm = new stdClass(); $frm->username = strtolower($_SERVER[$pluginconfig->user_attribute]); // The password is never actually used, but needs to be passed to the functions 'user_login' and // 'authenticate_user_login'. Shibboleth returns true for the function 'prevent_local_password', which is // used when setting the password in 'update_internal_user_password'. When 'prevent_local_password' // returns true, the password is set to 'not cached' (AUTH_PASSWORD_NOT_CACHED) in the Moodle DB. However, // rather than setting the password to a hard-coded value, we will generate one each time, in case there are // changes to the Shibboleth plugin and it is actually used. $frm->password = generate_password(8); /// Check if the user has actually submitted login data to us if ($shibbolethauth->user_login($frm->username, $frm->password) && ($user = authenticate_user_login($frm->username, $frm->password))) { complete_user_login($user); if (user_not_fully_set_up($USER, true)) { $urltogo = $CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { $urltogo = $CFG->wwwroot . '/'; /// Go to the standard home page unset($SESSION->wantsurl); /// Just in case } } /// Go to my-moodle page instead of homepage if defaulthomepage enabled
/** * Open user account using SREG & AX data if available * If no matching user found and create flag is true, creates new user account * * @access private * @param object &$resp An OpenID consumer response object * @param boolean $create_flag - set if account creation permitted, default: true * @uses $CFG * @uses $USER * @uses $openid_tmp_login * @return object The new user */ function _open_account(&$resp, $create_flag = true) { global $CFG, $USER, $openid_tmp_login; $url = $resp->identity_url; $password = hash_internal_user_password('openid'); $server = $resp->endpoint->server_url; $user = openid_resp_to_user($resp); if ($user == false) { // multiple matches to users! Don't know which user to pick. print_error('auth_openid_multiple_matches', 'auth_openid'); return false; // won't get here. } if (isset($user->id)) { $openid_tmp_login = true; $openid_action = 'change'; if ($user->auth == 'openid') { if (empty($this->config->auth_openid_allow_muliple)) { print_error('auth_openid_no_multiple', 'auth_openid'); return false; } $openid_action = 'append'; } else { if (empty($this->config->auth_openid_confirm_switch)) { openid_if_unique_change_account($user, $url); return $USER; } } $USER = clone $user; // To clone or not to clone //$mode = optional_param('openid_mode', null); //error_log("auth/openid/auth.php::_open_account() setting openid_mode={$mode} (openid_process_url={$openid_process_url})"); redirect("{$CFG->wwwroot}/auth/openid/actions.php?openid_tmp_login=1&openid_action={$openid_action}&openid_url={$url}"); // Try to get it not to make second request to be accepted, double confirm - TBD: openid_mode=??? } if (!$create_flag) { // Error: This site is configured to disallow new users via OpenID print_error('auth_openid_require_account', 'auth_openid'); return false; // won't get here. } $usertmp = create_user_record($user->username, $password, 'openid'); $user->id = $usertmp->id; openid_append_url($user, $url); if (!isset($user->city) || $user->city == '') { //use "*" as the default city name $user->city = '*'; } if (empty($user->country) && !empty($CFG->country)) { //use the configured default country code $user->country = $CFG->country; } if (empty($user->country)) { //out of other options, to try to copy the admin's country if ($admin = get_admin()) { $user->country = $admin->country; } } update_record('user', $user); $user = get_complete_user_data('id', $user->id); events_trigger('user_created', $user); // BJB120125 - moved from below redirect for alfresco, etc... if (function_exists('on_openid_create_account')) { on_openid_create_account($resp, $user); } // Redirect the user to their profile page if not set up properly if (!empty($user) && user_not_fully_set_up($user)) { $USER = clone $user; $urltogo = $CFG->wwwroot . '/user/edit.php'; redirect($urltogo); } if (openid_server_requires_confirm($server, $this->config)) { $secret = random_string(15); set_field('user', 'secret', $secret, 'id', $user->id); $user->secret = $secret; set_field('user', 'confirmed', 0, 'id', $user->id); $user->confirmed = 0; openid_send_confirmation_email($user); } return $user; }
/** * Find the session set by ntlmsso_magic(), validate it and * call authenticate_user_login() to authenticate the user through * the auth machinery. * * It is complemented by a similar check in user_login(). * * If it succeeds, it never returns. * */ function ntlmsso_finish() { global $CFG, $USER, $SESSION; $key = sesskey(); $cf = get_cache_flags($this->pluginconfig . '/ntlmsess'); if (!isset($cf[$key]) || $cf[$key] === '') { return false; } $username = $cf[$key]; // Here we want to trigger the whole authentication machinery // to make sure no step is bypassed... $user = authenticate_user_login($username, $key); if ($user) { complete_user_login($user); // Cleanup the key to prevent reuse... // and to allow re-logins with normal credentials unset_cache_flag($this->pluginconfig . '/ntlmsess', $key); // Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } // We do not want to redirect if we are in a PHPUnit test. if (!PHPUNIT_TEST) { redirect($urltogo); } } // Should never reach here. return false; }
$toprow[] = new tabobject('roles', $CFG->wwwroot . '/' . $CFG->admin . '/roles/usersroles.php?userid=' . $user->id . '&courseid=' . $course->id, get_string('roles')); if (in_array($currenttab, array('usersroles', 'assign', 'override', 'check'))) { $inactive = array('roles'); $activetwo = array('roles'); $secondrow = array(); $secondrow[] = new tabobject('usersroles', $CFG->wwwroot . '/' . $CFG->admin . '/roles/usersroles.php?userid=' . $user->id . '&courseid=' . $course->id, get_string('thisusersroles', 'role')); if (!empty($assignableroles) || $currenttab == 'assign') { $secondrow[] = new tabobject('assign', $CFG->wwwroot . '/' . $CFG->admin . '/roles/assign.php?contextid=' . $usercontext->id . '&userid=' . $user->id . '&courseid=' . $course->id, get_string('assignrolesrelativetothisuser', 'role'), '', true); } if (!empty($overridableroles) || $currenttab == 'override') { $secondrow[] = new tabobject('override', $CFG->wwwroot . '/' . $CFG->admin . '/roles/override.php?contextid=' . $usercontext->id . '&userid=' . $user->id . '&courseid=' . $course->id, get_string('overridepermissions', 'role'), '', true); } if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:assign'), $usercontext)) { $secondrow[] = new tabobject('check', $CFG->wwwroot . '/' . $CFG->admin . '/roles/check.php?contextid=' . $usercontext->id . '&userid=' . $user->id . '&courseid=' . $course->id, get_string('checkpermissions', 'role')); } } } } /// Add second row to display if there is one if (!empty($secondrow)) { $tabs = array($toprow, $secondrow); } else { $tabs = array($toprow); } if ($currenttab == 'editprofile' && $user->id == $USER->id && user_not_fully_set_up($USER)) { /// We're being forced here to fix profile notify(get_string('moreprofileinfoneeded')); } else { /// Print out the tabs and continue! print_tabs($tabs, $currenttab, $inactive, $activetwo); }
/** Determine where a user should be redirected after they have been logged in. * @return string url the user should be redirected to. */ function core_login_get_return_url() { global $CFG, $SESSION, $USER; // Prepare redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0 or strpos($SESSION->wantsurl, str_replace('http://', 'https://', $CFG->wwwroot)) === 0)) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } // If the url to go to is the same as the site page, check for default homepage. if ($urltogo == $CFG->wwwroot . '/') { $homepage = get_home_page(); // Go to my-moodle page instead of site homepage if defaulthomepage set to homepage_my. if ($homepage == HOMEPAGE_MY && !is_siteadmin() && !isguestuser()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') { $urltogo = $CFG->wwwroot . '/my/'; } } } return $urltogo; }
function loginpage_hook() { global $CFG, $SESSION, $DB, $USER; require_once $CFG->dirroot . '/auth/vatsim/config.php'; // initiate the SSO class with consumer details and encryption details $SSO = new SSO($sso['base'], $sso['key'], $sso['secret'], $sso['method'], $sso['cert']); // return variable is needed later in this script $sso_return = $sso['return']; // remove other config variables unset($sso); // if VATSIM has redirected the member back if (isset($_GET['oauth_verifier']) && !isset($_GET['oauth_cancel'])) { // check to make sure there is a saved token for this user if (isset($_SESSION[SSO_SESSION]) && isset($_SESSION[SSO_SESSION]['key']) && isset($_SESSION[SSO_SESSION]['secret'])) { if (@$_GET['oauth_token'] != $_SESSION[SSO_SESSION]['key']) { throw new moodle_exception("An error occurred with the login process - please try again", 'auth_vatsim'); } if (@(!isset($_GET['oauth_verifier']))) { throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } // obtain the details of this user from VATSIM $vatsimUser = $SSO->checkLogin($_SESSION[SSO_SESSION]['key'], $_SESSION[SSO_SESSION]['secret'], @$_GET['oauth_verifier']); if ($vatsimUser) { // One-time use of tokens, token no longer valid unset($_SESSION[SSO_SESSION]); $vatsim = $vatsimUser->user; //print_r($user->user); $username = $vatsim->id; // plugin only designed where email address is returned, if no email specified, if (@empty($vatsim->email)) { throw new moodle_exception('noemail', "auth_vatsim"); } $useremail = $vatsim->email; // find the user in the current database, by CID, not email $user = $DB->get_record('user', array('username' => $username, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // create the user if it doesn't exist if (empty($user)) { // deny login if setting "Prevent account creation when authenticating" is on if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_vatsim"); } //retrieve more information from the provider $newuser = new stdClass(); $newuser->email = $useremail; $newuser->firstname = $vatsim->name_first; $newuser->lastname = $vatsim->name_last; $newuser->country = $vatsim->country->code; create_user_record($username, '', 'vatsim'); } else { $username = $user->username; } add_to_log(SITEID, 'auth_vatsim', '', '', $username . '/' . $useremail); $user = authenticate_user_login($username, null); if ($user) { //prefill more user information if new user if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); $user = (object) array_merge((array) $user, (array) $newuser); } complete_user_login($user); // Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { // OAuth or cURL errors have occurred //$error = $SSO->error(); throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } } // the user cancelled their login and were sent back } else { if (isset($_GET['oauth_cancel'])) { throw new moodle_exception("You cancelled your login", 'auth_vatsim'); } } // create a request token for this login. Provides return URL and suspended/inactive settings $token = $SSO->requestToken($sso_return, false, false); if ($token) { // store the token information in the session so that we can retrieve it when the user returns $_SESSION[SSO_SESSION] = array('key' => (string) $token->token->oauth_token, 'secret' => (string) $token->token->oauth_token_secret); // redirect the member to VATSIM $SSO->sendToVatsim(); } else { throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } }
/** * Find the session set by ntlmsso_magic(), validate it and * call authenticate_user_login() to authenticate the user through * the auth machinery. * * It is complemented by a similar check in user_login(). * * If it succeeds, it never returns. * */ function ntlmsso_finish() { global $CFG, $USER, $SESSION; $key = sesskey(); $cf = get_cache_flags('auth/ldap/ntlmsess'); if (!isset($cf[$key]) || $cf[$key] === '') { return false; } $username = $cf[$key]; // Here we want to trigger the whole authentication machinery // to make sure no step is bypassed... $user = authenticate_user_login($username, $key); if ($user) { add_to_log(SITEID, 'user', 'login', "view.php?id={$USER->id}&course=" . SITEID, $user->id, 0, $user->id); $USER = complete_user_login($user); // Cleanup the key to prevent reuse... // and to allow re-logins with normal credentials unset_cache_flag('auth/ldap/ntlmsess', $key); /// Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } // Should never reach here. return false; }
/** * Determines whether a user is fully set up, using cached results where possible. * * @since 3.2.0 * @param \stdClass $user the user record. * @return bool true if the user is fully set up, false otherwise. */ protected function is_user_setup($user) { if (!isset($this->userssetupcache[$user->id])) { $this->userssetupcache[$user->id] = !user_not_fully_set_up($user); } return $this->userssetupcache[$user->id]; }
/** * @link http://docs.moodle.org/dev/Authentication_plugins#loginpage_hook.28.29 * * Hook for overriding behaviour of login page. * Another auth hook. Process login if $authorizationcode is defined in OAuth url. * Makes cURL POST/GET request to social webservice and fill response data to Moodle user. * We check access tokens in cookies, if the ones exists - get it from $_COOKIE, if no - setcookie * * @uses $SESSION, $CFG, $DB core global objects/variables * @return void or @moodle_exception if OAuth request returns error or fail * * @author Igor Sazonov ( @tigusigalpa ) */ function loginpage_hook() { global $SESSION, $CFG, $DB; $access_token = false; $authorizationcode = optional_param('oauthcode', '', PARAM_TEXT); // get authorization code from url if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_TEXT); // get authorization provider (webservice name) $hack_authprovider = $authprovider == 'yahoo1' || $authprovider == 'yahoo2' ? 'yahoo' : $authprovider; $config_field_str = 'auth_lenauth_' . $hack_authprovider . '_social_id_field'; $this->_field_shortname = $this->_oauth_config->{$config_field_str}; $this->_field_id = $this->_lenauth_get_fieldid(); $params = array(); // params to generate data for token request $encode_params = true; $code = true; $redirect_uri = true; $curl_header = false; $curl_options = array(); //if we have access_token in $_COOKIE, so do not need to make request fot the one $this->_send_oauth_request = !isset($_COOKIE[$authprovider]['access_token']) ? true : false; //if service is not enabled, why should we make request? hack protect. maybe $enabled_str = 'auth_lenauth_' . $hack_authprovider . '_enabled'; if (empty($this->_oauth_config->{$enabled_str})) { throw new moodle_exception('Service not enabled in your LenAuth Settings', 'auth_lenauth'); } switch ($authprovider) { case 'facebook': /** * @link https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0#exchangecode */ $params['client_id'] = $this->_oauth_config->auth_lenauth_facebook_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_facebook_app_secret; break; case 'google': /** * @link https://developers.google.com/accounts/docs/OAuth2Login#exchangecode */ $params['client_id'] = $this->_oauth_config->auth_lenauth_google_client_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_google_client_secret; $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; break; case 'yahoo1': if (!isset($_COOKIE[$authprovider]['access_token']) && !isset($_COOKIE[$authprovider]['oauth_verifier'])) { $params = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&'), array('oauth_callback' => $this->_lenauth_redirect_uri($authprovider))); $code = false; $redirect_uri = false; $this->_send_oauth_request = isset($_REQUEST['oauth_token'], $_REQUEST['oauth_verifier']) ? false : true; $oauth_verifier = false; // yahoo =)) if (!$this->_send_oauth_request && isset($SESSION->yahoo_expires) && !empty($SESSION->yahoo_expires)) { $access_token = $SESSION->yahoo_access_token = optional_param('oauth_token', '', PARAM_TEXT); setcookie($authprovider . '[access_token]', $access_token, time() + $SESSION->yahoo_expires); $oauth_verifier = $SESSION->yahoo_oauth_verifier = optional_param('oauth_verifier', '', PARAM_TEXT); setcookie($authprovider . '[oauth_verifier]', $oauth_verifier, time() + $SESSION->yahoo_expires); } else { } } else { $this->_send_oauth_request = false; } break; case 'yahoo2': $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; $curl_options = array('USERPWD' => $this->_oauth_config->auth_lenauth_yahoo_consumer_key . ':' . $this->_oauth_config->auth_lenauth_yahoo_consumer_secret); break; case 'twitter': if (!empty($this->_oauth_config->auth_lenauth_twitter_enabled)) { if (!isset($_COOKIE[$authprovider]['access_token'])) { $params = array_merge($this->_lenauth_twitter_request_array($this->_oauth_config->auth_lenauth_twitter_consumer_secret . '&'), array('oauth_callback' => $this->_lenauth_redirect_uri($authprovider))); $code = false; $redirect_uri = false; $this->_send_oauth_request = isset($_REQUEST['oauth_token'], $_REQUEST['oauth_verifier']) ? false : true; $oauth_verifier = false; if (!$this->_send_oauth_request && isset($_COOKIE[$authprovider]['oauth_token_secret'])) { $access_token = $SESSION->twitter_access_token = optional_param('oauth_token', '', PARAM_TEXT); setcookie($authprovider . '[access_token]', $access_token, time() + $this->_settings[$authprovider]['expire'], '/'); $oauth_verifier = $SESSION->twitter_oauth_verifier = optional_param('oauth_verifier', '', PARAM_TEXT); setcookie($authprovider . '[oauth_verifier]', $oauth_verifier, time() + $this->_settings[$authprovider]['expire'], '/'); } else { $curl_header = $this->_lenauth_set_twitter_header($params); } //$curl_header = $this->_lenauth_set_twitter_header($params, $access_token/*, $oauth_token_secret = false*/); /*$curl_options = array( 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_FOLLOWLOCATION' => true ); if ( !empty( $params['oauth_callback'] ) ) { $curl_options['CURLOPT_POSTFIELDS'] = http_build_query( array() ); }*/ //TWITTER IS GOOD!! $encode_params = false; } else { $this->_send_oauth_request = false; } } break; case 'vk': /** * @link http://vk.com/dev/auth_sites */ $params['client_id'] = $this->_oauth_config->auth_lenauth_vk_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_vk_app_secret; break; case 'yandex': $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; $params['client_id'] = $this->_oauth_config->auth_lenauth_yandex_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_yandex_app_password; break; case 'mailru': $params['client_id'] = $this->_oauth_config->auth_lenauth_mailru_site_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_mailru_client_secret; $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; break; //odnoklassniki.ru was wrote by school programmers at 1st class and it not used mojority. bye-bye! /*case 'ok': $params['client_id'] = $this->_oauth_config->ok_app_id; $params['client_secret'] = $this->_oauth_config->ok_secret_key; break;*/ //odnoklassniki.ru was wrote by school programmers at 1st class and it not used mojority. bye-bye! /*case 'ok': $params['client_id'] = $this->_oauth_config->ok_app_id; $params['client_secret'] = $this->_oauth_config->ok_secret_key; break;*/ default: // if authorization provider is wrong throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } // url for catch token value // exception for Yahoo OAuth, because it like.. if ($code) { $params['code'] = $authorizationcode; } if ($redirect_uri) { $params['redirect_uri'] = $this->_lenauth_redirect_uri($authprovider); } //require cURL from Moodle core require_once $CFG->libdir . '/filelib.php'; // requires library with cURL class $curl = new curl(); //hack for twitter and Yahoo if (!empty($curl_options) && is_array($curl_options)) { $curl->setopt($curl_options); } $curl->resetHeader(); // clean cURL header from garbage //Twitter and Yahoo has an own cURL headers, so let them to be! if (!$curl_header) { $curl->setHeader('Content-Type: application/x-www-form-urlencoded'); } else { $curl->setHeader($curl_header); } // cURL REQUEST for tokens if we hasnt it in $_COOKIE if ($this->_send_oauth_request) { if ($this->_curl_type == 'post') { $curl_tokens_values = $curl->post($this->_settings[$authprovider]['request_token_url'], $encode_params ? $this->_generate_query_data($params) : $params); } else { $curl_tokens_values = $curl->get($this->_settings[$authprovider]['request_token_url'] . '?' . ($encode_params ? $this->_generate_query_data($params) : $params)); } } // check for token response if (!empty($curl_tokens_values) || !$this->_send_oauth_request) { $token_values = array(); // parse token values switch ($authprovider) { case 'facebook': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { parse_str($curl_tokens_values, $token_values); $expires = $token_values['expires']; //5183999 = 2 months $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'google': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //3600 = 1 hour $access_token = $token_values['access_token']; if (!empty($access_token) && !empty($expires)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yahoo1': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['oauth_token_secret'])) { parse_str($curl_tokens_values, $token_values); $expires = $SESSION->yahoo_expires = $token_values['oauth_expires_in']; //3600 = 1 hour $access_token = $SESSION->yahoo_access_token = $token_values['oauth_token']; setcookie($authprovider . '[oauth_token_secret]', $token_values['oauth_token_secret'], time() + $SESSION->yahoo_expires); $xoauth_request_auth_url = $token_values['xoauth_request_auth_url']; } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['oauth_verifier']) || isset($SESSION->yahoo_access_token, $SESSION->yahoo_oauth_verifier)) { $access_token = isset($_COOKIE[$authprovider]['access_token']) ? $_COOKIE[$authprovider]['access_token'] : $SESSION->yahoo_access_token; $oauth_verifier = isset($_COOKIE[$authprovider]['oauth_verifier']) ? $_COOKIE[$authprovider]['oauth_verifier'] : $SESSION->yahoo_oauth_verifier; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yahoo2': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //3600 = 1 hour $access_token = $token_values['access_token']; $refresh_token = $token_values['refresh_token']; $user_id = $token_values['xoauth_yahoo_guid']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); if (!empty($user_id)) { setcookie($authprovider . '[user_id]', $user_id, time() + $expires, '/'); } } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['user_id'])) { $access_token = $_COOKIE[$authprovider]['access_token']; $user_id = $_COOKIE[$authprovider]['user_id']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'twitter': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['oauth_token_secret'])) { parse_str($curl_tokens_values, $token_values); $access_token = $SESSION->twitter_access_token = $token_values['oauth_token']; setcookie($authprovider . '[oauth_token_secret]', $token_values['oauth_token_secret'], time() + $this->_settings[$authprovider]['expire'], '/'); } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['oauth_token_secret']) || isset($SESSION->twitter_access_token, $SESSION->twitter_oauth_verifier)) { $access_token = isset($_COOKIE[$authprovider]['access_token']) ? $_COOKIE[$authprovider]['access_token'] : $SESSION->twitter_access_token; $oauth_verifier = isset($_COOKIE[$authprovider]['oauth_verifier']) ? $_COOKIE[$authprovider]['oauth_verifier'] : $SESSION->twitter_oauth_verifier; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'vk': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); if (isset($token_values['error'])) { throw new moodle_exception('Native VK Error ' . $token_values['error'] . (isset($token_values['error_description']) ? ' with description: ' . $token_values['error_description'] : ''), 'auth_lenauth'); } $expires = $token_values['expires_in']; //86400 = 24 hours $access_token = $token_values['access_token']; if (!empty($access_token) && !empty($expires)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } $user_id = $token_values['user_id']; if (!empty($user_id)) { setcookie($authprovider . '[user_id]', $user_id, time() + $expires, '/'); } /** * VK user may do not enter email, soooo =(( */ $user_email = isset($token_values['email']) ? $token_values['email'] : false; // WOW!!! So early???))) Awesome! if (!empty($user_email)) { setcookie($authprovider . '[user_email]', $user_email, time() + $expires, '/'); } } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['user_id'])) { $access_token = $_COOKIE[$authprovider]['access_token']; $user_id = $_COOKIE[$authprovider]['user_id']; if (isset($_COOKIE[$authprovider]['user_email'])) { $user_email = $_COOKIE[$authprovider]['user_email']; } } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yandex': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //31536000 = 1 year $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'mailru': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //86400 = 24 hours $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { //check native errors if exists if (isset($token_values['error'])) { switch ($token_values['error']) { case 'invalid_client': throw new moodle_exception('Mail.RU invalid OAuth settings. Check your Private Key and Secret Key', 'auth_lenauth'); default: throw new moodle_exception('Mail.RU Unknown Error with code: ' . $token_values['error']); } } if (empty($expires) || empty($access_token)) { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; /*case 'ok': $token_values = json_decode( $curl_tokens_values, true ); $access_token = $token_values['access_token']; break;*/ /*case 'ok': $token_values = json_decode( $curl_tokens_values, true ); $access_token = $token_values['access_token']; break;*/ default: throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } } if (!empty($access_token)) { $queryparams = array(); // array to generate data for final request to get user data $request_api_url = $this->_settings[$authprovider]['request_api_url']; //some services check accounts for verifier, so we will check it too. No unverified accounts, only verified! only hardCORE! $is_verified = true; $image_url = ''; switch ($authprovider) { case 'facebook': $queryparams['access_token'] = $access_token; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['id']; $user_email = $curl_final_data['email']; $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $is_verified = $curl_final_data['verified']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = 'http://graph.facebook.com/' . $social_uid . '/picture'; } break; /** * @link https://developers.google.com/accounts/docs/OAuth2Login#obtaininguserprofileinformation */ /** * @link https://developers.google.com/accounts/docs/OAuth2Login#obtaininguserprofileinformation */ case 'google': $queryparams['access_token'] = $access_token; $queryparams['alt'] = 'json'; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); if (isset($curl_final_data['error'])) { if (!empty($curl_final_data['error']['errors']) && is_array($curl_final_data['error']['errors'])) { foreach ($curl_final_data['error']['errors'] as $error) { throw new moodle_exception('Native Google error. Message: ' . $error['message'], 'auth_lenauth'); } } else { throw new moodle_exception('Native Google error', 'auth_lenauth'); } } $social_uid = $curl_final_data['id']; $user_email = $curl_final_data['emails'][0]['value']; $first_name = $curl_final_data['name']['givenName']; $last_name = $curl_final_data['name']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['image']['url']) ? $curl_final_data['image']['url'] : ''; } break; case 'yahoo1': if (!$oauth_verifier) { header('Location: ' . $xoauth_request_auth_url); // yahoo =)) die; } $queryparams1 = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $_COOKIE[$authprovider]['oauth_token_secret']), array('oauth_token' => $access_token, 'oauth_verifier' => $oauth_verifier)); $curl_response_pre = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams1)); parse_str($curl_response_pre, $values); $queryparams2 = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $values['oauth_token_secret']), array('oauth_token' => $values['oauth_token'], 'oauth_session_handle' => $values['oauth_session_handle'])); $yet_another = $curl->post($request_api_url . '?' . $this->_generate_query_data($queryparams2)); parse_str($yet_another, $yet_another_values); $params = array('q' => 'SELECT * FROM social.profile where guid="' . $yet_another_values['xoauth_yahoo_guid'] . '"', 'format' => 'json', 'env' => 'http://datatables.org/alltables.env'); $auth_array = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $yet_another_values['oauth_token_secret']), array('realm' => 'yahooapis.com', 'oauth_token' => $yet_another_values['oauth_token'])); $header = ''; foreach ($auth_array as $key => $value) { $header .= ($header === '' ? ' ' : ',') . $this->urlEncodeRfc3986($key) . '="' . $this->urlEncodeRfc3986($value) . '"'; } $curl->setHeader(array('Expect:', 'Accept: application/json', 'Authorization: OAuth ' . $header)); $curl_response = $curl->post($this->_settings[$authprovider]['yql_url'] . '?' . $this->_generate_query_data($params)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['query']['results']['profile']['guid']; $emails = $curl_final_data['query']['results']['profile']['emails']; if (!empty($emails) && is_array($emails)) { foreach ($emails as $email_array) { $user_email = $email_array['handle']; if (isset($email_array['primary'])) { break; } } } $first_name = $curl_final_data['query']['results']['profile']['givenName']; $last_name = $curl_final_data['query']['results']['profile']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['query']['results']['profile']['image']['imageUrl']) ? $curl_final_data['query']['results']['profile']['image']['imageUrl'] : ''; } break; case 'yahoo2': $request_api_url = 'https://social.yahooapis.com/v1/user/' . $user_id . '/profile?format=json'; $queryparams['access_token'] = $access_token; $now_header = array('Authorization: Bearer ' . $access_token, 'Accept: application/json', 'Content-Type: application/json'); $curl->resetHeader(); $curl->setHeader($now_header); $curl_response = $curl->get($request_api_url, $queryparams); $curl->resetHeader(); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['profile']['guid']; $emails = $curl_final_data['profile']['emails']; if (!empty($emails) && is_array($emails)) { foreach ($emails as $email_array) { $user_email = $email_array['handle']; if (isset($email_array['primary'])) { break; } } } $first_name = $curl_final_data['profile']['givenName']; $last_name = $curl_final_data['profile']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['profile']['image']['imageUrl']) ? $curl_final_data['profile']['image']['imageUrl'] : ''; } break; case 'twitter': if (!$oauth_verifier) { header('Location: ' . $this->_settings[$authprovider]['request_api_url'] . '?' . http_build_query(array('oauth_token' => $access_token))); die; } $queryparams = array_merge($this->_lenauth_twitter_request_array(), array('oauth_verifier' => $oauth_verifier, 'oauth_token' => $access_token, 'oauth_token_secret' => $_COOKIE[$authprovider]['oauth_token_secret'])); $curl_header = $this->_lenauth_set_twitter_header($queryparams, $access_token, $_COOKIE[$authprovider]['oauth_token_secret']); $curl->setHeader($curl_header); $curl_final_data_pre = $curl->post($this->_settings[$authprovider]['token_url'], $queryparams); $json_decoded = json_decode($curl_final_data_pre, true); if (isset($json_decoded['error']) && isset($json_decoded['request'])) { throw new moodle_exception('Native Twitter Error: ' . $json_decoded['error'] . '. For request ' . $json_decoded['request'], 'auth_lenauth'); } parse_str($curl_final_data_pre, $curl_final_data); $social_uid = $curl_final_data['user_id']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url_pre = 'https://twitter.com/' . $curl_final_data['screen_name'] . '/profile_image?size=original'; $image_header = get_headers($image_url_pre, 1); $image_url = $image_header['location']; } break; case 'vk': /** * @link http://vk.com/dev/api_requests */ $queryparams['access_token'] = $access_token; $queryparams['user_id'] = !empty($user_id) ? $user_id : false; $queryparams['v'] = self::$vk_api_version; $curl_response = $curl->post($request_api_url, $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); //$social_uid = ( isset( $user_id ) ) ? $user_id : $curl_final_data['response'][0]['id']; //dont forget about this $social_uid = $queryparams['user_id']; /** * If user_email is empty, its not so scare, because its second login and */ $user_email = isset($user_email) ? $user_email : false; //hack, because VK has bugs sometimes $first_name = $curl_final_data['response'][0]['first_name']; $last_name = $curl_final_data['response'][0]['last_name']; /** * @link http://vk.com/dev/users.get */ $fields_array = array('avatar' => 'photo_200'); $additional_fields_pre = $curl->get('http://api.vk.com/method/users.get?user_ids=' . $social_uid . '&fields=' . join(',', $fields_array)); $additional_fields = json_decode($additional_fields_pre, true); if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($additional_fields['response'][0][$fields_array['avatar']]) ? $additional_fields['response'][0][$fields_array['avatar']] : ''; } break; /** * @link http://api.yandex.ru/oauth/doc/dg/reference/accessing-protected-resource.xml * @link http://api.yandex.ru/login/doc/dg/reference/request.xml */ /** * @link http://api.yandex.ru/oauth/doc/dg/reference/accessing-protected-resource.xml * @link http://api.yandex.ru/login/doc/dg/reference/request.xml */ case 'yandex': $queryparams['format'] = $this->_settings[$authprovider]['format']; $queryparams['oauth_token'] = $access_token; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['id']; /** * fix @since 24.12.2014. Thanks for Yandex Tech team guys!! * @link https://tech.yandex.ru/passport/ */ $user_email = $curl_final_data['default_email']; //was $curl_final_data['emails'][0]; - wrong! $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $nickname = $curl_final_data['display_name']; //for future if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { /** * @link https://tech.yandex.ru/passport/doc/dg/reference/response-docpage/#norights_5 */ $yandex_avatar_size = 'islands-200'; if (isset($curl_final_data['default_avatar_id'])) { $image_url = 'https://avatars.yandex.net/get-yapic/' . $curl_final_data['default_avatar_id'] . '/' . $yandex_avatar_size; } } break; case 'mailru': $queryparams['app_id'] = $params['client_id']; $secret_key = $params['client_secret']; /** * @link http://api.mail.ru/docs/reference/rest/users-getinfo/ */ $queryparams['method'] = 'users.getInfo'; $queryparams['session_key'] = $access_token; $queryparams['secure'] = 1; /** * Additional security from mail.ru * @link http://api.mail.ru/docs/guides/restapi/#sig */ ksort($queryparams); $sig = ''; foreach ($queryparams as $k => $v) { $sig .= "{$k}={$v}"; } $queryparams['sig'] = md5($sig . $secret_key); $curl_response = $curl->post($request_api_url, $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data[0]['uid']; $user_email = $curl_final_data[0]['email']; $first_name = $curl_final_data[0]['first_name']; $last_name = $curl_final_data[0]['last_name']; $is_verified = $curl_final_data[0]['is_verified']; $birthday = $curl_final_data[0]['birthday']; //dd.mm.YYYY if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data[0]['pic_big']) ? $curl_final_data[0]['pic_big'] : ''; } break; /*case 'ok': $queryparams['access_token'] = $access_token; $queryparams['method'] = 'users.getCurrentUser'; $queryparams['sig'] = md5( 'application_key=' . $this->_oauth_config->ok_public_key . 'method=' . $queryparams['method'] . md5( $queryparams['access_token'] . $this->_oauth_config->ok_secret_key ) ); $queryparams['application_key'] = $this->_oauth_config->ok_public_key; $curl_response = $curl->get( $request_api_url . '?' . $this->_generate_query_data( $queryparams ) ); $curl_final_data = json_decode( $curl_response, true ); $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $social_uid = $curl_final_data['uid']; break;*/ /*case 'ok': $queryparams['access_token'] = $access_token; $queryparams['method'] = 'users.getCurrentUser'; $queryparams['sig'] = md5( 'application_key=' . $this->_oauth_config->ok_public_key . 'method=' . $queryparams['method'] . md5( $queryparams['access_token'] . $this->_oauth_config->ok_secret_key ) ); $queryparams['application_key'] = $this->_oauth_config->ok_public_key; $curl_response = $curl->get( $request_api_url . '?' . $this->_generate_query_data( $queryparams ) ); $curl_final_data = json_decode( $curl_response, true ); $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $social_uid = $curl_final_data['uid']; break;*/ default: throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } /** * Check for email returned by webservice. If exist - check for user with this email in Moodle Database */ if (!empty($curl_final_data)) { if (!empty($social_uid)) { if ($is_verified) { if (!empty($user_email)) { if ($err = email_is_not_allowed($user_email)) { throw new moodle_exception($err, 'auth_lenauth'); } $user_lenauth = $DB->get_record('user', array('email' => $user_email, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); } else { if (empty($user_lenauth)) { $user_lenauth = $this->_lenauth_get_userdata_by_social_id($social_uid); } /*if ( empty( $user_lenauth ) ) { $user_lenauth = $DB->get_record('user', array('username' => $username, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); }*/ } } else { throw new moodle_exception('Your social account is not verified', 'auth_lenauth'); } } else { throw new moodle_exception('Empty Social UID', 'auth_lenauth'); } } else { /** * addon @since 24.12.2014 * I forgot about clear $_COOKIE, thanks again for Yandex Tech Team guys!!! */ @setcookie($authprovider, null, time() - 3600); throw new moodle_exception('Final request returns nothing', 'auth_lenauth'); } $last_user_number = intval($this->_oauth_config->auth_lenauth_last_user_number); $last_user_number = empty($last_user_number) ? 1 : $last_user_number + 1; //$username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; //@todo /** * If user with email from webservice not exists, we will create an account */ if (empty($user_lenauth)) { $username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; //check for username exists in DB $user_lenauth_check = $DB->get_record('user', array('username' => $username)); $i_check = 0; while (!empty($user_lenauth_check)) { $user_lenauth_check = $user_lenauth_check + 1; $username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; $user_lenauth_check = $DB->get_record('user', array('username' => $username)); $i_check++; if ($i_check > 20) { throw new moodle_exception('Something wrong with usernames of LenAuth users. Limit of 20 queries is out. Check last mdl_user table of Moodle', 'auth_lenauth'); } } // create user HERE $user_lenauth = create_user_record($username, '', 'lenauth'); /** * User exists... */ } else { $username = $user_lenauth->username; } set_config('auth_lenauth_last_user_number', $last_user_number, 'auth/lenauth'); if (!empty($social_uid)) { $user_social_uid_custom_field = new stdClass(); $user_social_uid_custom_field->userid = $user_lenauth->id; $user_social_uid_custom_field->fieldid = $this->_field_id; $user_social_uid_custom_field->data = $social_uid; if (!$DB->record_exists('user_info_data', array('userid' => $user_lenauth->id, 'fieldid' => $this->_field_id))) { $DB->insert_record('user_info_data', $user_social_uid_custom_field); } else { $record = $DB->get_record('user_info_data', array('userid' => $user_lenauth->id, 'fieldid' => $this->_field_id)); $user_social_uid_custom_field->id = $record->id; $DB->update_record('user_info_data', $user_social_uid_custom_field); } } //add_to_log( SITEID, 'auth_lenauth', '', '', $username . '/' . $user_email . '/' . $userid ); // complete Authenticate user authenticate_user_login($username, null); // fill $newuser object with response data from webservices $newuser = new stdClass(); if (!empty($user_email)) { $newuser->email = $user_email; } if (!empty($first_name)) { $newuser->firstname = $first_name; } if (!empty($last_name)) { $newuser->lastname = $last_name; } if (!empty($this->_oauth_config->auth_lenauth_default_country)) { $newuser->country = $this->_oauth_config->auth_lenauth_default_country; } if ($user_lenauth) { // update user record if (!empty($newuser)) { $newuser->id = $user_lenauth->id; /*require_once( $CFG->libdir . '/gdlib.php' ); $fs = get_file_storage(); $file_obj = $fs->create_file_from_url( array( 'contextid' => context_user::instance( $newuser->id, MUST_EXIST )->id, 'component' => 'user', 'filearea' => 'icon', 'itemid' => 0, 'filepath' => '/', 'source' => '', 'filename' => 'f' . $newuser->id . '.' . $ext ), $image_url ); //$newuser->picture = $file_obj->get_id();*/ $user_lenauth = (object) array_merge((array) $user_lenauth, (array) $newuser); $DB->update_record('user', $user_lenauth); if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { //processing user avatar from social webservice if (!empty($image_url) && intval($user_lenauth->picture) === 0) { $image_header = get_headers($image_url, 1); if (isset($image_header['Content-Type']) && is_string($image_header['Content-Type']) && in_array($image_header['Content-Type'], array_keys(self::$_allowed_icons_types))) { $mime = $image_header['Content-Type']; } else { if (isset($image_header['Content-Type'][0]) && is_string($image_header['Content-Type'][0]) && in_array($image_header['Content-Type'][0], array_keys(self::$_allowed_icons_types))) { $mime = $image_header['Content-Type'][0]; } } $ext = $this->_lenauth_get_image_extension_from_mime($mime); if ($ext) { //create temp file $tempfilename = substr(microtime(), 0, 10) . '.tmp'; $templfolder = $CFG->tempdir . '/filestorage'; if (!file_exists($templfolder)) { mkdir($templfolder, $CFG->directorypermissions); } @chmod($templfolder, 0777); $tempfile = $templfolder . '/' . $tempfilename; if (copy($image_url, $tempfile)) { require_once $CFG->libdir . '/gdlib.php'; $usericonid = process_new_icon(context_user::instance($newuser->id, MUST_EXIST), 'user', 'icon', 0, $tempfile); if ($usericonid) { $DB->set_field('user', 'picture', $usericonid, array('id' => $newuser->id)); } unset($tempfile); } @chmod($templfolder, $CFG->directorypermissions); } } } } complete_user_login($user_lenauth); // complete user login // Redirection $urltogo = $CFG->wwwroot; if (user_not_fully_set_up($user_lenauth)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; } else { if (isset($SESSION->wantsurl) && strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; unset($SESSION->wantsurl); } else { unset($SESSION->wantsurl); } } } redirect($urltogo); } else { throw new moodle_exception('Could not get access to access token. Check your App Settings', 'auth_lenauth'); } } }
/** * Create a new account using simple registration data if available * * @access private * @param object &$resp An OpenID consumer response object * @return object The new user */ function _create_account(&$resp) { global $CFG, $USER; $url = $resp->identity_url; $password = hash_internal_user_password('openid'); $server = $resp->endpoint->server_url; $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($resp); $sreg = $sreg_resp->contents(); // We'll attempt to use the user's nickname to set their username if (isset($sreg['nickname']) && !empty($sreg['nickname']) && !record_exists('users', 'username', $sreg['nickname'])) { $username = $sreg['nickname']; } else { $username = openid_normalize_url_as_username($url); } create_user_record($username, $password, 'openid'); $user = get_complete_user_data('username', $username); openid_append_url($user, $url); // SREG fullname if (isset($sreg['fullname']) && !empty($sreg['fullname'])) { $name = openid_parse_full_name($sreg['fullname']); $user->firstname = $name['first']; $user->lastname = $name['last']; } // SREG email if (isset($sreg['email']) && !empty($sreg['email']) && !record_exists('user', 'email', $sreg['email'])) { $user->email = $sreg['email']; } // SREG country if (isset($sreg['country']) && !empty($sreg['country'])) { $country = $sreg['country']; $country_code = strtoupper($country); $countries = get_list_of_countries(); if (strlen($country) != 2 || !isset($countries[$country_code])) { $countries_keys = array_keys($countries); $countries_vals = array_values($countries); $country_code = array_search($country, $countries_vals); if ($country_code > 0) { $country_code = $countries_keys[$country_code]; } else { $country_code = ''; } } if (!empty($country_code)) { $user->country = $country_code; } } /* We're currently not attempting to get language and timezone values // SREG language if (isset($sreg['language']) && !empty($sreg['language'])) { } // SREG timezone if (isset($sreg['timezone']) && !empty($sreg['timezone'])) { } */ if (function_exists('on_openid_create_account')) { on_openid_create_account($resp, $user); } update_record('user', $user); $user = get_complete_user_data('id', $user->id); // Redirect the user to their profile page if not set up properly if (!empty($user) && user_not_fully_set_up($user)) { $USER = clone $user; $urltogo = $CFG->wwwroot . '/user/edit.php'; redirect($urltogo); } return $user; }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ public function loginpage_hook() { global $USER, $SESSION, $CFG, $DB; // Check the Google authorization code. $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_ALPHANUMEXT); require_once $CFG->dirroot . '/auth/googleoauth2/classes/provider/' . $authprovider . '.php'; $providerclassname = 'provideroauth2' . $authprovider; $provider = new $providerclassname(); // Try to get an access token (using the authorization code grant). $token = $provider->getAccessToken('authorization_code', ['code' => $authorizationcode]); $accesstoken = $token->accessToken; $refreshtoken = $token->refreshToken; $tokenexpires = $token->expires; // With access token request by curl the email address. if (!empty($accesstoken)) { try { // We got an access token, let's now get the user's details. $userdetails = $provider->getUserDetails($token); // Use these details to create a new profile. switch ($authprovider) { case 'battlenet': // Battlenet as no email notion. // TODO: need to check the idp table for matching user and request user to add his email. // TODO: It will be similar logic for twitter. $useremail = $userdetails->id . '@fakebattle.net'; break; case 'github': $useremails = $provider->getUserEmails($token); // Going to try to find someone with a similar email using googleoauth2 auth. $fallbackuseremail = ''; foreach ($useremails as $githubuseremail) { if ($githubuseremail->verified) { if ($DB->record_exists('user', array('auth' => 'googleoauth2', 'email' => $githubuseremail->email))) { $useremail = $githubuseremail->email; } $fallbackuseremail = $githubuseremail->email; } } // If we didn't find anyone then we take a verified email address. if (empty($useremail)) { $useremail = $fallbackuseremail; } break; case 'vk': // VK doesn't return the email address? if ($userdetails->uid) { $useremail = 'id' . $userdetails->uid . '@vkmessenger.com'; } break; default: $useremail = $userdetails->email; break; } $verified = 1; } catch (Exception $e) { // Failed to get user details. throw new moodle_exception('faileduserdetails', 'auth_googleoauth2'); } // Throw an error if the email address is not verified. if (!$verified) { throw new moodle_exception('emailaddressmustbeverified', 'auth_googleoauth2'); } // Prohibit login if email belongs to the prohibited domain. if ($err = email_is_not_allowed($useremail)) { throw new moodle_exception($err, 'auth_googleoauth2'); } // If email not existing in user database then create a new username (userX). if (empty($useremail) or $useremail != clean_param($useremail, PARAM_EMAIL)) { throw new moodle_exception('couldnotgetuseremail', 'auth_googleoauth2'); // TODO: display a link for people to retry. } // Get the user. // Don't bother with auth = googleoauth2 because authenticate_user_login() will fail it if it's not 'googleoauth2'. $user = $DB->get_record('user', array('email' => $useremail, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // Create the user if it doesn't exist. if (empty($user)) { // Deny login if setting "Prevent account creation when authenticating" is on. if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_googleoauth2"); } // Get following incremented username. $googleuserprefix = core_text::strtolower(get_config('auth/googleoauth2', 'googleuserprefix')); $lastusernumber = get_config('auth/googleoauth2', 'lastusernumber'); $lastusernumber = empty($lastusernumber) ? 1 : $lastusernumber + 1; // Check the user doesn't exist. $nextuser = $DB->record_exists('user', array('username' => $googleuserprefix . $lastusernumber)); while ($nextuser) { $lastusernumber++; $nextuser = $DB->record_exists('user', array('username' => $googleuserprefix . $lastusernumber)); } set_config('lastusernumber', $lastusernumber, 'auth/googleoauth2'); $username = $googleuserprefix . $lastusernumber; // Retrieve more information from the provider. $newuser = new stdClass(); $newuser->email = $useremail; switch ($authprovider) { case 'battlenet': // Battlenet as no firstname/lastname notion. $newuser->firstname = $userdetails->display_name; $newuser->lastname = '[' . $userdetails->clan_tag . ']'; break; case 'github': case 'dropbox': // As Github/Dropbox doesn't provide firstname/lastname, we'll split the name at the first whitespace. $githubusername = explode(' ', $userdetails->name, 2); $newuser->firstname = $githubusername[0]; $newuser->lastname = $githubusername[1]; break; default: $newuser->firstname = $userdetails->firstName; $newuser->lastname = $userdetails->lastName; break; } // Some providers allow empty firstname and lastname. if (empty($newuser->firstname)) { $newuser->firstname = get_string('unknownfirstname', 'auth_googleoauth2'); } if (empty($newuser->lastname)) { $newuser->lastname = get_string('unknownlastname', 'auth_googleoauth2'); } // Retrieve country and city if the provider failed to give it. if (!isset($newuser->country) or !isset($newuser->city)) { $googleipinfodbkey = get_config('auth/googleoauth2', 'googleipinfodbkey'); if (!empty($googleipinfodbkey)) { require_once $CFG->libdir . '/filelib.php'; $curl = new curl(); $locationdata = $curl->get('http://api.ipinfodb.com/v3/ip-city/?key=' . $googleipinfodbkey . '&ip=' . getremoteaddr() . '&format=json'); $locationdata = json_decode($locationdata); } if (!empty($locationdata)) { // TODO: check that countryCode does match the Moodle country code. $newuser->country = isset($newuser->country) ? isset($newuser->country) : $locationdata->countryCode; $newuser->city = isset($newuser->city) ? isset($newuser->city) : $locationdata->cityName; } } create_user_record($username, '', 'googleoauth2'); } else { $username = $user->username; } // Authenticate the user. // TODO: delete this log later. require_once $CFG->dirroot . '/auth/googleoauth2/lib.php'; $userid = empty($user) ? 'new user' : $user->id; oauth_add_to_log(SITEID, 'auth_googleoauth2', '', '', $username . '/' . $useremail . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { // Set a cookie to remember what auth provider was selected. setcookie('MOODLEGOOGLEOAUTH2_' . $CFG->sessioncookie, $authprovider, time() + DAYSECS * 60, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly); // Prefill more user information if new user. if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); $user = (object) array_merge((array) $user, (array) $newuser); } complete_user_login($user); // Let's save/update the access token for this user. $cansaveaccesstoken = get_config('auth/googleoauth2', 'saveaccesstoken'); if (!empty($cansaveaccesstoken)) { $existingaccesstoken = $DB->get_record('auth_googleoauth2_user_idps', array('userid' => $user->id, 'provider' => $authprovider)); if (empty($existingaccesstoken)) { $accesstokenrow = new stdClass(); $accesstokenrow->userid = $user->id; switch ($authprovider) { case 'battlenet': $accesstokenrow->provideruserid = $userdetails->id; break; default: $accesstokenrow->provideruserid = $userdetails->uid; break; } $accesstokenrow->provider = $authprovider; $accesstokenrow->accesstoken = $accesstoken; $accesstokenrow->refreshtoken = $refreshtoken; $accesstokenrow->expires = $tokenexpires; $DB->insert_record('auth_googleoauth2_user_idps', $accesstokenrow); } else { $existingaccesstoken->accesstoken = $accesstoken; $DB->update_record('auth_googleoauth2_user_idps', $existingaccesstoken); } } // Check if the user picture is the default and retrieve the provider picture. if (empty($user->picture)) { switch ($authprovider) { case 'battlenet': require_once $CFG->libdir . '/filelib.php'; require_once $CFG->libdir . '/gdlib.php'; $imagefilename = $CFG->tempdir . '/googleoauth2-portrait-' . $user->id; $imagecontents = download_file_content($userdetails->portrait_url); file_put_contents($imagefilename, $imagecontents); if ($newrev = process_new_icon(context_user::instance($user->id), 'user', 'icon', 0, $imagefilename)) { $DB->set_field('user', 'picture', $newrev, array('id' => $user->id)); } unlink($imagefilename); break; default: // TODO retrieve other provider profile pictures. break; } } // Create event for authenticated user. $event = \auth_googleoauth2\event\user_loggedin::create(array('context' => context_system::instance(), 'objectid' => $user->id, 'relateduserid' => $user->id, 'other' => array('accesstoken' => $accesstoken))); $event->trigger(); // Redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } $loginrecord = array('userid' => $USER->id, 'time' => time(), 'auth' => 'googleoauth2', 'subtype' => $authprovider); $DB->insert_record('auth_googleoauth2_logins', $loginrecord); redirect($urltogo); } else { // Authenticate_user_login() failure, probably email registered by another auth plugin. // Do a check to confirm this hypothesis. $userexist = $DB->get_record('user', array('email' => $useremail)); if (!empty($userexist) and $userexist->auth != 'googleoauth2') { $a = new stdClass(); $a->loginpage = (string) new moodle_url(empty($CFG->alternateloginurl) ? '/login/index.php' : $CFG->alternateloginurl); $a->forgotpass = (string) new moodle_url('/login/forgot_password.php'); throw new moodle_exception('couldnotauthenticateuserlogin', 'auth_googleoauth2', '', $a); } else { throw new moodle_exception('couldnotauthenticate', 'auth_googleoauth2'); } } } else { throw new moodle_exception('couldnotgetgoogleaccesstoken', 'auth_googleoauth2'); } } else { // If you are having issue with the display buttons option, add the button code directly in the theme login page. if (get_config('auth/googleoauth2', 'oauth2displaybuttons') and empty($_POST['username']) and empty($_POST['password'])) { // Display the button on the login page. require_once $CFG->dirroot . '/auth/googleoauth2/lib.php'; // Insert the html code below the login field. // Code/Solution from Elcentra plugin: https://moodle.org/plugins/view/auth_elcentra. global $PAGE, $CFG; $PAGE->requires->jquery(); $content = str_replace(array("\n", "\r"), array("\\\n", "\\\r"), auth_googleoauth2_display_buttons(false)); $PAGE->requires->css('/auth/googleoauth2/style.css'); $PAGE->requires->js_init_code("buttonsCodeOauth2 = '{$content}';"); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/googleoauth2/script.js")); } } }
/** * Authenticate a user via SSO token * * @param string $token * @return bool * @uses $CFG * @uses $USER * @uses $SESSION */ function token_login($token) { global $CFG, $USER, $SESSION; try { $client = new SSATClient($this->wsdlurl, $this->appkey); if (!($ssatuser = $client->validate_token($token))) { return false; } } catch (Exception $e) { return false; } $key = sesskey(); if ($user = get_record('user', 'username', addslashes($ssatuser->user_name), 'mnethostid', $CFG->mnet_localhost_id)) { add_to_log(SITEID, 'user', 'login', "view.php?id={$USER->id}&course=" . SITEID, $user->id, 0, $user->id); $SESSION->ssat_user_id = $ssatuser->user_id; $USER = complete_user_login($user); /// Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } // Should never reach here. return false; }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the course module is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * When $cm parameter specified, this function sets page layout to 'module'. * You need to change it manually later if some other layout needed. * * @param mixed $courseorid id of the course or course object * @param bool $autologinguest default true * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions * @return mixed Void, exit, and die depending on path */ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) { global $CFG, $SESSION, $USER, $FULLME, $PAGE, $SITE, $DB, $OUTPUT; // setup global $COURSE, themes, language and locale if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } } if ($cm) { if ($cm->course != $course->id) { throw new coding_exception('course and cm parameters in require_login() call do not match!!'); } // make sure we have a $cm from get_fast_modinfo as this contains activity access details if (!$cm instanceof cm_info) { // note: nearly all pages call get_fast_modinfo anyway and it does not make any // db queries so this is not really a performance concern, however it is obviously // better if you use get_fast_modinfo to get the cm before calling this. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($cm->id); } $PAGE->set_cm($cm, $course); // set's up global $COURSE $PAGE->set_pagelayout('incourse'); } else { $PAGE->set_course($course); // set's up global $COURSE } } else { // do not touch global $COURSE via $PAGE->set_course(), // the reasons is we need to be able to call require_login() at any time!! $course = $SITE; if ($cm) { throw new coding_exception('cm parameter in require_login() requires valid course parameter!'); } } // If the user is not even logged in yet then make sure they are if (!isloggedin()) { if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { if (!($guest = get_complete_user_data('id', $CFG->siteguest))) { // misconfigured site guest, just redirect to login page redirect(get_login_url()); exit; // never reached } $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; complete_user_login($guest, false); $USER->autologinguest = true; $SESSION->lang = $lang; } else { //NOTE: $USER->site check was obsoleted by session test cookie, // $USER->confirmed test is in login/index.php if ($preventredirect) { throw new require_login_exception('You are not logged in'); } if ($setwantsurltome) { // TODO: switch to PAGE->url $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } redirect(get_login_url()); exit; // never reached } } // loginas as redirection if needed if ($course->id != SITEID and session_is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $course->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } // check whether the user should be changing password (but only if it is REALLY them) if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password() and !$preventredirect) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url redirect($changeurl); } else { //use moodle internal method if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { print_error('nopasswordchangeforced', 'auth'); } } // Check that the user account is properly set up if (user_not_fully_set_up($USER)) { if ($preventredirect) { throw new require_login_exception('User not fully set-up'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); // Do not bother admins with any formalities if (is_siteadmin()) { //set accesstime or the user will appear offline which messes up messaging user_accesstime_log($course->id); return; } // Check that the user has agreed to a site policy if there is one - do not test in case of admins if (!$USER->policyagreed and !is_siteadmin()) { if (!empty($CFG->sitepolicy) and !isguestuser()) { if ($preventredirect) { throw new require_login_exception('Policy not agreed'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } else { if (!empty($CFG->sitepolicyguest) and isguestuser()) { if ($preventredirect) { throw new require_login_exception('Policy not agreed'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } } } // Fetch the system context, the course context, and prefetch its child contexts $sysctx = get_context_instance(CONTEXT_SYSTEM); $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); if ($cm) { $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); } else { $cmcontext = null; } // If the site is currently under maintenance, then print a message if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:config', $sysctx)) { if ($preventredirect) { throw new require_login_exception('Maintenance in progress'); } print_maintenance_message(); } // make sure the course itself is not hidden if ($course->id == SITEID) { // frontpage can not be hidden } else { if (is_role_switched($course->id)) { // when switching roles ignore the hidden flag - user had to be in course to do the switch } else { if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // originally there was also test of parent category visibility, // BUT is was very slow in complex queries involving "my courses" // now it is also possible to simply hide all courses user is not enrolled in :-) if ($preventredirect) { throw new require_login_exception('Course is hidden'); } notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } } // is the user enrolled? if ($course->id == SITEID) { // everybody is enrolled on the frontpage } else { if (session_is_loggedinas()) { // Make sure the REAL person can access this course first $realuser = session_get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } // very simple enrolment caching - changes in course setting are not reflected immediately if (!isset($USER->enrol)) { $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } $access = false; if (is_viewing($coursecontext, $USER)) { // ok, no need to mess with enrol $access = true; } else { if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['enrolled'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['enrolled'][$course->id]); } } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['tempguest'][$course->id]); $USER->access = remove_temp_roles($coursecontext, $USER->access); } } } if ($access) { // cache ok } else { if (is_enrolled($coursecontext, $USER, '', true)) { // active participants may always access // TODO: refactor this into some new function $now = time(); $sql = "SELECT MAX(ue.timeend)\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {user} u ON u.id = ue.userid\n WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now); $until = $DB->get_field_sql($sql, $params); if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) { $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; // remove traces of previous temp guest access $USER->access = remove_temp_roles($coursecontext, $USER->access); } else { $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); // first ask all enabled enrol instances in course if they want to auto enrol user foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_autoenrol($instance); if ($until !== false) { $USER->enrol['enrolled'][$course->id] = $until; $USER->access = remove_temp_roles($coursecontext, $USER->access); $access = true; break; } } // if not enrolled yet try to gain temporary guest access if (!$access) { foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { $USER->enrol['tempguest'][$course->id] = $until; $access = true; break; } } } } } } if (!$access) { if ($preventredirect) { throw new require_login_exception('Not enrolled'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id); } } // Check visibility of activity to current user; includes visible flag, groupmembersonly, // conditional availability, etc if ($cm && !$cm->uservisible) { if ($preventredirect) { throw new require_login_exception('Activity is hidden'); } redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } // Finally access granted, update lastaccess times user_accesstime_log($course->id); }
/** * @author John T. Macklin (viperf117a@yahoo.com) * @version $Id: lib_ldapsso.php,v 1.0 2009/11/11 19:23:07 viperf117a Exp $ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @package moodleauth - Custom LDAP URL SSO PHP Functions */ function confirm_user($user) { // Complete the login process global $CFG, $SESSION; if ($user) { // language setup update_login_count(); if ($user->username == 'guest') { // no predefined language for guests - use existing session or default site lang unset($user->lang); } else { if (!empty($user->lang)) { // unset previous session language - use user preference instead unset($SESSION->lang); } } if (empty($user->confirmed)) { // This account was never confirmed $CFG->registerauth = 'ldapsso'; // User ldapsso to verify registration $user->secret = md5(rand(1, 9876543)); // Set secret for confirmation send_confirmation_email($user); // Genetrate Confirmation Email! print_heading(get_string("mustconfirm")); print_box_start('generalbox centerpara boxwidthnormal boxaligncenter'); echo "<h2>" . get_string('confirmednot') . "</h2>\n"; echo "<p>" . get_string('auth_ldap_sso_confirmednot', 'auth_ldapsso') . "</p>\n"; print_single_button("{$CFG->wwwroot}/login/", null, get_string('continue')); print_box_end(); print_footer(); exit; } $USER = complete_user_login($user); /// Let's set them up. add_to_log(SITEID, 'user', 'login', "view.php?id={$USER->id}&course=" . SITEID, $user->id, 0, $user->id); /// Prepare redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } /// Go to my-moodle page instead of homepage if mymoodleredirect enabled if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and !empty($CFG->mymoodleredirect) and !isguest()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') { $urltogo = $CFG->wwwroot . '/my/'; } } /// check if user password has expired /// Currently supported only for ldap-authentication module $userauth = get_auth_plugin($USER->auth); if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) { if ($userauth->can_change_password()) { $passwordchangeurl = $userauth->change_password_url(); } else { $passwordchangeurl = $CFG->httpswwwroot . '/login/change_password.php'; } $days2expire = $userauth->password_expire($USER->username); if (intval($days2expire) > 0 && intval($days2expire) < intval($userauth->config->expiration_warning)) { print_header("{$site->fullname}: {$loginsite}", "{$site->fullname}", $navigation, '', '', true, "<div class=\"langmenu\">{$langmenu}</div>"); notice_yesno(get_string('auth_passwordwillexpire', 'auth', $days2expire), $passwordchangeurl, $urltogo); print_footer(); exit; } elseif (intval($days2expire) < 0) { print_header("{$site->fullname}: {$loginsite}", "{$site->fullname}", $navigation, '', '', true, "<div class=\"langmenu\">{$langmenu}</div>"); notice_yesno(get_string('auth_passwordisexpired', 'auth'), $passwordchangeurl, $urltogo); print_footer(); exit; } } // Do necessary user updates for 'onlogin' Data Mappings // narrow down what fields we need to update $all_keys = array_keys(get_object_vars($userauth->config)); $updatekeys = array(); // $updatekeys = array('firstname','lastname','idnumber','city','country','description'); foreach ($all_keys as $key) { if (preg_match('/^field_updatelocal_(.+)$/', $key, $match)) { // if we have a field to update and it is set as 'onlogin' if (!empty($userauth->config->{'field_map_' . $match[1]}) and $userauth->config->{$match[0]} === 'onlogin') { array_push($updatekeys, $match[1]); // the actual key name } } } // print_r($all_keys); print_r($updatekeys); unset($all_keys); unset($key); if (!empty($updatekeys)) { $userauth->update_user_record(addslashes($user->username), $updatekeys); } reset_login_count(); // Return to original debugging level $CFG->debug = $origdebug; error_reporting($CFG->debug); redirect($urltogo, 'Redirecting login request!', 0); } }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the coursemodule is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * @uses $CFG * @uses $SESSION * @uses $USER * @uses $FULLME * @uses SITEID * @uses $COURSE * @param mixed $courseorid id of the course or course object * @param bool $autologinguest * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 */ function require_login($courseorid = 0, $autologinguest = true, $cm = null, $setwantsurltome = true) { global $CFG, $SESSION, $USER, $COURSE, $FULLME; /// setup global $COURSE, themes, language and locale course_setup($courseorid); /// If the user is not even logged in yet then make sure they are if (!isloggedin()) { //NOTE: $USER->site check was obsoleted by session test cookie, // $USER->confirmed test is in login/index.php if ($setwantsurltome) { $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests) and ($COURSE->id == SITEID or $COURSE->guest)) { $loginguest = '?loginguest=true'; } else { $loginguest = ''; } if (empty($CFG->loginhttps) or $loginguest) { //do not require https for guest logins redirect($CFG->wwwroot . '/login/index.php' . $loginguest); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/index.php'); } exit; } /// loginas as redirection if needed if ($COURSE->id != SITEID and !empty($USER->realuser)) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $COURSE->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } /// check whether the user should be changing password (but only if it is REALLY them) if (get_user_preferences('auth_forcepasswordchange') && empty($USER->realuser)) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password()) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url redirect($changeurl); } else { //use moodle internal method if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { print_error('nopasswordchangeforced', 'auth'); } } /// Check that the user account is properly set up if (user_not_fully_set_up($USER)) { $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } /// Make sure current IP matches the one for this session (if required) if (!empty($CFG->tracksessionip)) { if ($USER->sessionIP != md5(getremoteaddr())) { print_error('sessionipnomatch', 'error'); } } /// Make sure the USER has a sesskey set up. Used for checking script parameters. sesskey(); // Check that the user has agreed to a site policy if there is one if (!empty($CFG->sitepolicy)) { if (!$USER->policyagreed) { $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } } // Fetch the system context, we are going to use it a lot. $sysctx = get_context_instance(CONTEXT_SYSTEM); /// If the site is currently under maintenance, then print a message if (!has_capability('moodle/site:config', $sysctx)) { if (file_exists($CFG->dataroot . '/' . SITEID . '/maintenance.html')) { print_maintenance_message(); exit; } } /// groupmembersonly access control if (!empty($CFG->enablegroupings) and $cm and $cm->groupmembersonly and !has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { if (isguestuser() or !groups_has_membership($cm)) { print_error('groupmembersonlyerror', 'group', $CFG->wwwroot . '/course/view.php?id=' . $cm->course); } } // Fetch the course context, and prefetch its child contexts if (!isset($COURSE->context)) { if (!($COURSE->context = get_context_instance(CONTEXT_COURSE, $COURSE->id))) { print_error('nocontext'); } } if (!empty($cm) && !isset($cm->context)) { if (!($cm->context = get_context_instance(CONTEXT_MODULE, $cm->id))) { print_error('nocontext'); } } if ($COURSE->id == SITEID) { /// Eliminate hidden site activities straight away if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) { redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; } else { /// Check if the user can be in a particular course if (empty($USER->access['rsw'][$COURSE->context->path])) { // // MDL-13900 - If the course or the parent category are hidden // and the user hasn't the 'course:viewhiddencourses' capability, prevent access // if (!($COURSE->visible && course_parent_visible($COURSE)) && !has_capability('moodle/course:viewhiddencourses', $COURSE->context)) { print_header_simple(); notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } /// Non-guests who don't currently have access, check if they can be allowed in as a guest if ($USER->username != 'guest' and !has_capability('moodle/course:view', $COURSE->context)) { if ($COURSE->guest == 1) { // Temporarily assign them guest role for this context, if it fails later user is asked to enrol $USER->access = load_temp_role($COURSE->context, $CFG->guestroleid, $USER->access); } } /// If the user is a guest then treat them according to the course policy about guests if (has_capability('moodle/legacy:guest', $COURSE->context, NULL, false)) { if (has_capability('moodle/site:doanything', $sysctx)) { // administrators must be able to access any course - even if somebody gives them guest access user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; } switch ($COURSE->guest) { /// Check course policy about guest access case 1: /// Guests always allowed if (!has_capability('moodle/course:view', $COURSE->context)) { // Prohibited by capability print_header_simple(); notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), "{$CFG->wwwroot}/login/index.php"); } if (!empty($cm) and !$cm->visible) { // Not allowed to see module, send to course page redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; // User is allowed to see this course break; case 2: /// Guests allowed with key if (!empty($USER->enrolkey[$COURSE->id])) { // Set by enrol/manual/enrol.php user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return true; } // otherwise drop through to logic below (--> enrol.php) break; default: /// Guests not allowed $strloggedinasguest = get_string('loggedinasguest'); print_header_simple('', '', build_navigation(array(array('name' => $strloggedinasguest, 'link' => null, 'type' => 'misc')))); if (empty($USER->access['rsw'][$COURSE->context->path])) { // Normal guest notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), "{$CFG->wwwroot}/login/index.php"); } else { notify(get_string('guestsnotallowed', '', format_string($COURSE->fullname))); echo '<div class="notifyproblem">' . switchroles_form($COURSE->id) . '</div>'; print_footer($COURSE); exit; } break; } /// For non-guests, check if they have course view access } else { if (has_capability('moodle/course:view', $COURSE->context)) { if (!empty($USER->realuser)) { // Make sure the REAL person can also access this course if (!has_capability('moodle/course:view', $COURSE->context, $USER->realuser)) { print_header_simple(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } /// Make sure they can read this activity too, if specified if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $cm->context)) { redirect($CFG->wwwroot . '/course/view.php?id=' . $cm->course, get_string('activityiscurrentlyhidden')); } user_accesstime_log($COURSE->id); /// Access granted, update lastaccess times return; // User is allowed to see this course } } /// Currently not enrolled in the course, so see if they want to enrol $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/course/enrol.php?id=' . $COURSE->id); die; } }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the course module is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * When $cm parameter specified, this function sets page layout to 'module'. * You need to change it manually later if some other layout needed. * * @package core_access * @category access * * @param mixed $courseorid id of the course or course object * @param bool $autologinguest default true * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions * @return mixed Void, exit, and die depending on path * @throws coding_exception * @throws require_login_exception */ function require_login($courseorid = null, $autologinguest = true, $cm = null, $setwantsurltome = true, $preventredirect = false) { global $CFG, $SESSION, $USER, $PAGE, $SITE, $DB, $OUTPUT; // Must not redirect when byteserving already started. if (!empty($_SERVER['HTTP_RANGE'])) { $preventredirect = true; } if (AJAX_SCRIPT) { // We cannot redirect for AJAX scripts either. $preventredirect = true; } // Setup global $COURSE, themes, language and locale. if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } } if ($cm) { if ($cm->course != $course->id) { throw new coding_exception('course and cm parameters in require_login() call do not match!!'); } // Make sure we have a $cm from get_fast_modinfo as this contains activity access details. if (!$cm instanceof cm_info) { // Note: nearly all pages call get_fast_modinfo anyway and it does not make any // db queries so this is not really a performance concern, however it is obviously // better if you use get_fast_modinfo to get the cm before calling this. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($cm->id); } } } else { // Do not touch global $COURSE via $PAGE->set_course(), // the reasons is we need to be able to call require_login() at any time!! $course = $SITE; if ($cm) { throw new coding_exception('cm parameter in require_login() requires valid course parameter!'); } } // If this is an AJAX request and $setwantsurltome is true then we need to override it and set it to false. // Otherwise the AJAX request URL will be set to $SESSION->wantsurl and events such as self enrolment in the future // risk leading the user back to the AJAX request URL. if ($setwantsurltome && defined('AJAX_SCRIPT') && AJAX_SCRIPT) { $setwantsurltome = false; } // Redirect to the login page if session has expired, only with dbsessions enabled (MDL-35029) to maintain current behaviour. if ((!isloggedin() or isguestuser()) && !empty($SESSION->has_timed_out) && !empty($CFG->dbsessions)) { if ($preventredirect) { throw new require_login_session_timeout_exception(); } else { if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect(get_login_url()); } } // If the user is not even logged in yet then make sure they are. if (!isloggedin()) { if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { if (!($guest = get_complete_user_data('id', $CFG->siteguest))) { // Misconfigured site guest, just redirect to login page. redirect(get_login_url()); exit; // Never reached. } $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; complete_user_login($guest); $USER->autologinguest = true; $SESSION->lang = $lang; } else { // NOTE: $USER->site check was obsoleted by session test cookie, $USER->confirmed test is in login/index.php. if ($preventredirect) { throw new require_login_exception('You are not logged in'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } $referer = get_local_referer(false); if (!empty($referer)) { $SESSION->fromurl = $referer; } // Give auth plugins an opportunity to authenticate or redirect to an external login page $authsequence = get_enabled_auth_plugins(true); // auths, in sequence foreach ($authsequence as $authname) { $authplugin = get_auth_plugin($authname); $authplugin->pre_loginpage_hook(); if (isloggedin()) { break; } } // If we're still not logged in then go to the login page if (!isloggedin()) { redirect(get_login_url()); exit; // Never reached. } } } // Loginas as redirection if needed. if ($course->id != SITEID and \core\session\manager::is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $course->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } // Check whether the user should be changing password (but only if it is REALLY them). if (get_user_preferences('auth_forcepasswordchange') && !\core\session\manager::is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password() and !$preventredirect) { if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } if ($changeurl = $userauth->change_password_url()) { // Use plugin custom url. redirect($changeurl); } else { // Use moodle internal method. if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { if ($userauth->can_change_password()) { throw new moodle_exception('forcepasswordchangenotice'); } else { throw new moodle_exception('nopasswordchangeforced', 'auth'); } } } // Check that the user account is properly set up. If we can't redirect to // edit their profile, perform just the lax check. It will allow them to // use filepicker on the profile edit page. if ($preventredirect) { $usernotfullysetup = user_not_fully_set_up($USER, false); } else { $usernotfullysetup = user_not_fully_set_up($USER, true); } if ($usernotfullysetup) { if ($preventredirect) { throw new moodle_exception('usernotfullysetup'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); // Do not bother admins with any formalities. if (is_siteadmin()) { // Set the global $COURSE. if ($cm) { $PAGE->set_cm($cm, $course); $PAGE->set_pagelayout('incourse'); } else { if (!empty($courseorid)) { $PAGE->set_course($course); } } // Set accesstime or the user will appear offline which messes up messaging. user_accesstime_log($course->id); return; } // Check that the user has agreed to a site policy if there is one - do not test in case of admins. if (!$USER->policyagreed and !is_siteadmin()) { if (!empty($CFG->sitepolicy) and !isguestuser()) { if ($preventredirect) { throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicy); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/policy.php'); } else { if (!empty($CFG->sitepolicyguest) and isguestuser()) { if ($preventredirect) { throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicyguest); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/policy.php'); } } } // Fetch the system context, the course context, and prefetch its child contexts. $sysctx = context_system::instance(); $coursecontext = context_course::instance($course->id, MUST_EXIST); if ($cm) { $cmcontext = context_module::instance($cm->id, MUST_EXIST); } else { $cmcontext = null; } // If the site is currently under maintenance, then print a message. if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:maintenanceaccess', $sysctx)) { if ($preventredirect) { throw new require_login_exception('Maintenance in progress'); } $PAGE->set_context(null); print_maintenance_message(); } // Make sure the course itself is not hidden. if ($course->id == SITEID) { // Frontpage can not be hidden. } else { if (is_role_switched($course->id)) { // When switching roles ignore the hidden flag - user had to be in course to do the switch. } else { if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // Originally there was also test of parent category visibility, BUT is was very slow in complex queries // involving "my courses" now it is also possible to simply hide all courses user is not enrolled in :-). if ($preventredirect) { throw new require_login_exception('Course is hidden'); } $PAGE->set_context(null); // We need to override the navigation URL as the course won't have been added to the navigation and thus // the navigation will mess up when trying to find it. navigation_node::override_active_url(new moodle_url('/')); notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } } // Is the user enrolled? if ($course->id == SITEID) { // Everybody is enrolled on the frontpage. } else { if (\core\session\manager::is_loggedinas()) { // Make sure the REAL person can access this course first. $realuser = \core\session\manager::get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } $PAGE->set_context(null); echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } $access = false; if (is_role_switched($course->id)) { // Ok, user had to be inside this course before the switch. $access = true; } else { if (is_viewing($coursecontext, $USER)) { // Ok, no need to mess with enrol. $access = true; } else { if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] > time()) { $access = true; if (isset($USER->enrol['tempguest'][$course->id])) { unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } } else { // Expired. unset($USER->enrol['enrolled'][$course->id]); } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { $access = true; } else { // Expired. unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } } } if (!$access) { // Cache not ok. $until = enrol_get_enrolment_end($coursecontext->instanceid, $USER->id); if ($until !== false) { // Active participants may always access, a timestamp in the future, 0 (always) or false. if ($until == 0) { $until = ENROL_MAX_TIMESTAMP; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; } else { $params = array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED); $instances = $DB->get_records('enrol', $params, 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); // First ask all enabled enrol instances in course if they want to auto enrol user. foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the enrolment, a timestamp in the future, 0 (always) or false. $until = $enrols[$instance->enrol]->try_autoenrol($instance); if ($until !== false) { if ($until == 0) { $until = ENROL_MAX_TIMESTAMP; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; break; } } // If not enrolled yet try to gain temporary guest access. if (!$access) { foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guest access, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false and $until > time()) { $USER->enrol['tempguest'][$course->id] = $until; $access = true; break; } } } } } } } if (!$access) { if ($preventredirect) { throw new require_login_exception('Not enrolled'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id); } } // Check visibility of activity to current user; includes visible flag, conditional availability, etc. if ($cm && !$cm->uservisible) { if ($preventredirect) { throw new require_login_exception('Activity is hidden'); } if ($course->id != SITEID) { $url = new moodle_url('/course/view.php', array('id' => $course->id)); } else { $url = new moodle_url('/'); } redirect($url, get_string('activityiscurrentlyhidden')); } // Set the global $COURSE. if ($cm) { $PAGE->set_cm($cm, $course); $PAGE->set_pagelayout('incourse'); } else { if (!empty($courseorid)) { $PAGE->set_course($course); } } // Finally access granted, update lastaccess times. user_accesstime_log($course->id); }
/** * This function confirms the remote (ID provider) host's mnet session * by communicating the token and UA over the XMLRPC transport layer, and * returns the local user record on success. * * @param string $token The random session token. * @param mnet_peer $remotepeer The ID provider mnet_peer object. * @return array The local user record. */ function confirm_mnet_session($token, $remotepeer) { global $CFG, $DB; require_once $CFG->dirroot . '/mnet/xmlrpc/client.php'; require_once $CFG->libdir . '/gdlib.php'; // verify the remote host is configured locally before attempting RPC call if (!($remotehost = $DB->get_record('mnet_host', array('wwwroot' => $remotepeer->wwwroot, 'deleted' => 0)))) { print_error('notpermittedtoland', 'mnet'); } // set up the RPC request $mnetrequest = new mnet_xmlrpc_client(); $mnetrequest->set_method('auth/mnet/auth.php/user_authorise'); // set $token and $useragent parameters $mnetrequest->add_param($token); $mnetrequest->add_param(sha1($_SERVER['HTTP_USER_AGENT'])); // Thunderbirds are go! Do RPC call and store response if ($mnetrequest->send($remotepeer) === true) { $remoteuser = (object) $mnetrequest->response; } else { foreach ($mnetrequest->error as $errormessage) { list($code, $message) = array_map('trim', explode(':', $errormessage, 2)); if ($code == 702) { $site = get_site(); print_error('mnet_session_prohibited', 'mnet', $remotepeer->wwwroot, format_string($site->fullname)); exit; } $message .= "ERROR {$code}:<br/>{$errormessage}<br/>"; } print_error("rpcerror", '', '', $message); } unset($mnetrequest); if (empty($remoteuser) or empty($remoteuser->username)) { print_error('unknownerror', 'mnet'); exit; } if (user_not_fully_set_up($remoteuser)) { print_error('notenoughidpinfo', 'mnet'); exit; } $remoteuser = mnet_strip_user($remoteuser, mnet_fields_to_import($remotepeer)); $remoteuser->auth = 'mnet'; $remoteuser->wwwroot = $remotepeer->wwwroot; // the user may roam from Moodle 1.x where lang has _utf8 suffix // also, make sure that the lang is actually installed, otherwise set site default if (isset($remoteuser->lang)) { $remoteuser->lang = clean_param(str_replace('_utf8', '', $remoteuser->lang), PARAM_LANG); } if (empty($remoteuser->lang)) { if (!empty($CFG->lang)) { $remoteuser->lang = $CFG->lang; } else { $remoteuser->lang = 'en'; } } $firsttime = false; // get the local record for the remote user $localuser = $DB->get_record('user', array('username' => $remoteuser->username, 'mnethostid' => $remotehost->id)); // add the remote user to the database if necessary, and if allowed // TODO: refactor into a separate function if (empty($localuser) || !$localuser->id) { /* if (empty($this->config->auto_add_remote_users)) { print_error('nolocaluser', 'mnet'); } See MDL-21327 for why this is commented out */ $remoteuser->mnethostid = $remotehost->id; $remoteuser->firstaccess = time(); // First time user in this server, grab it here $remoteuser->id = $DB->insert_record('user', $remoteuser); $firsttime = true; $localuser = $remoteuser; } // check sso access control list for permission first if (!$this->can_login_remotely($localuser->username, $remotehost->id)) { print_error('sso_mnet_login_refused', 'mnet', '', array('user' => $localuser->username, 'host' => $remotehost->name)); } $fs = get_file_storage(); // update the local user record with remote user data foreach ((array) $remoteuser as $key => $val) { if ($key == '_mnet_userpicture_timemodified' and empty($CFG->disableuserimages) and isset($remoteuser->picture)) { // update the user picture if there is a newer verion at the identity provider $usercontext = get_context_instance(CONTEXT_USER, $localuser->id, MUST_EXIST); if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.png')) { $localtimemodified = $usericonfile->get_timemodified(); } else { if ($usericonfile = $fs->get_file($usercontext->id, 'user', 'icon', 0, '/', 'f1.jpg')) { $localtimemodified = $usericonfile->get_timemodified(); } else { $localtimemodified = 0; } } if (!empty($val) and $localtimemodified < $val) { mnet_debug('refetching the user picture from the identity provider host'); $fetchrequest = new mnet_xmlrpc_client(); $fetchrequest->set_method('auth/mnet/auth.php/fetch_user_image'); $fetchrequest->add_param($localuser->username); if ($fetchrequest->send($remotepeer) === true) { if (strlen($fetchrequest->response['f1']) > 0) { $imagefilename = $CFG->dataroot . '/temp/mnet-usericon-' . $localuser->id; $imagecontents = base64_decode($fetchrequest->response['f1']); file_put_contents($imagefilename, $imagecontents); if (process_new_icon($usercontext, 'user', 'icon', 0, $imagefilename)) { $localuser->picture = 1; } unlink($imagefilename); } // note that since Moodle 2.0 we ignore $fetchrequest->response['f2'] // the mimetype information provided is ignored and the type of the file is detected // by process_new_icon() } } } if ($key == 'myhosts') { $localuser->mnet_foreign_host_array = array(); foreach ($val as $rhost) { $name = clean_param($rhost['name'], PARAM_ALPHANUM); $url = clean_param($rhost['url'], PARAM_URL); $count = clean_param($rhost['count'], PARAM_INT); $url_is_local = stristr($url, $CFG->wwwroot); if (!empty($name) && !empty($count) && empty($url_is_local)) { $localuser->mnet_foreign_host_array[] = array('name' => $name, 'url' => $url, 'count' => $count); } } } $localuser->{$key} = $val; } $localuser->mnethostid = $remotepeer->id; if (empty($localuser->firstaccess)) { // Now firstaccess, grab it here $localuser->firstaccess = time(); } $DB->update_record('user', $localuser); if (!$firsttime) { // repeat customer! let the IDP know about enrolments // we have for this user. // set up the RPC request $mnetrequest = new mnet_xmlrpc_client(); $mnetrequest->set_method('auth/mnet/auth.php/update_enrolments'); // pass username and an assoc array of "my courses" // with info so that the IDP can maintain mnetservice_enrol_enrolments $mnetrequest->add_param($remoteuser->username); $fields = 'id, category, sortorder, fullname, shortname, idnumber, summary, startdate, visible'; $courses = enrol_get_users_courses($localuser->id, false, $fields, 'visible DESC,sortorder ASC'); if (is_array($courses) && !empty($courses)) { // Second request to do the JOINs that we'd have done // inside enrol_get_users_courses() if we had been allowed $sql = "SELECT c.id,\n cc.name AS cat_name, cc.description AS cat_description\n FROM {course} c\n JOIN {course_categories} cc ON c.category = cc.id\n WHERE c.id IN (" . join(',', array_keys($courses)) . ')'; $extra = $DB->get_records_sql($sql); $keys = array_keys($courses); $defaultrole = reset(get_archetype_roles('student')); //$defaultrole = get_default_course_role($ccache[$shortname]); //TODO: rewrite this completely, there is no default course role any more!!! foreach ($keys as $id) { if ($courses[$id]->visible == 0) { unset($courses[$id]); continue; } $courses[$id]->cat_id = $courses[$id]->category; $courses[$id]->defaultroleid = $defaultrole->id; unset($courses[$id]->category); unset($courses[$id]->visible); $courses[$id]->cat_name = $extra[$id]->cat_name; $courses[$id]->cat_description = $extra[$id]->cat_description; $courses[$id]->defaultrolename = $defaultrole->name; // coerce to array $courses[$id] = (array) $courses[$id]; } } else { // if the array is empty, send it anyway // we may be clearing out stale entries $courses = array(); } $mnetrequest->add_param($courses); // Call 0800-RPC Now! -- we don't care too much if it fails // as it's just informational. if ($mnetrequest->send($remotepeer) === false) { // error_log(print_r($mnetrequest->error,1)); } } return $localuser; }
/** * Migrate a single Moodle user to the Program Management system. Will * only do this for users who have an idnumber set. * * @param object $mu Moodle user object * @return boolean Whether user was synchronized or not */ function pm_moodle_user_to_pm($mu) { global $CFG, $DB; require_once $CFG->dirroot . '/lib/moodlelib.php'; require_once elis::lib('data/customfield.class.php'); require_once elispm::lib('data/user.class.php'); require_once elispm::lib('data/usermoodle.class.php'); require_once elis::lib('data/data_filter.class.php'); require_once $CFG->dirroot . '/user/profile/lib.php'; require_once elis::lib('lib.php'); if (!isset($mu->id)) { return true; } // re-fetch, in case this is from a stale event $mu = $DB->get_record('user', array('id' => $mu->id)); if (user_not_fully_set_up($mu) || !$mu->confirmed) { // Prevent the sync if a bare-bones user record is being created by create_user_record // or Moodle user has not yet been confirmed. return true; } //not going to be concerned with city or password for now if (empty($mu->idnumber) && elis::$config->local_elisprogram->auto_assign_user_idnumber) { //make sure the current user's username does not match up with some other user's //idnumber (necessary since usernames and idnumbers aren't bound to one another) if (!$DB->record_exists('user', array('idnumber' => $mu->username))) { $mu->idnumber = $mu->username; $DB->update_record('user', $mu); } } // skip user if no ID number set if (empty($mu->idnumber)) { return true; } // track whether we're syncing an idnumber change over to the PM system $idnumber_updated = false; // track whether an associated Moodle user is linked to the current PM user $moodle_user_exists = false; // determine if the user is already noted as having been associated to a PM user // this will join to Moodle user and PM user table to ensure data correctness $filters = array(); $filters[] = new join_filter('muserid', 'user', 'id'); $filters[] = new join_filter('cuserid', user::TABLE, 'id'); $filters[] = new field_filter('muserid', $mu->id); if ($um = usermoodle::find($filters)) { if ($um->valid()) { $um = $um->current(); //signal that an associated user already exists $moodle_user_exists = true; // determine if the Moodle user idnumber was updated if ($um->idnumber != $mu->idnumber) { //signal that the idnumber was synced over $idnumber_updated = true; // update the PM user with the new idnumber $cmuser = new user(); $cmuser->id = $um->cuserid; $cmuser->idnumber = $mu->idnumber; $cmuser->save(); // update the association table with the new idnumber $um->idnumber = $mu->idnumber; $um->save(); } } } // find the linked PM user //filter for the basic condition on the Moodle user id $condition_filter = new field_filter('id', $mu->id); //filter for joining the association table $association_filter = new join_filter('muserid', 'user', 'id', $condition_filter); //outermost filter $filter = new join_filter('id', usermoodle::TABLE, 'cuserid', $association_filter); $cu = user::find($filter); if ($cu->valid()) { $cu = $cu->current(); } else { // if a user with the same username but different idnumber exists, // we can't sync over because it will violate PM user uniqueness // constraints $cu = user::find(new field_filter('username', $mu->username)); if ($cu->valid()) { return true; } // if no such PM user exists, create a new one $cu = new user(); $cu->transfercredits = 0; $cu->timecreated = time(); } // synchronize standard fields $cu->username = $mu->username; $cu->password = $mu->password; // only need to update the idnumber if it wasn't handled above if (!$idnumber_updated) { $cu->idnumber = $mu->idnumber; } $cu->firstname = $mu->firstname; $cu->lastname = $mu->lastname; $cu->email = $mu->email; $cu->address = $mu->address; $cu->city = $mu->city; $cu->country = $mu->country; if (!empty($mu->phone1)) { $cu->phone = $mu->phone1; } if (!empty($mu->phone2)) { $cu->phone2 = $mu->phone2; } if (!empty($mu->lang)) { $cu->language = $mu->lang; } $cu->timemodified = time(); // synchronize custom profile fields profile_load_data($mu); fix_moodle_profile_fields($mu); $fields = field::get_for_context_level(CONTEXT_ELIS_USER); $fields = $fields ? $fields : array(); require_once elis::plugin_file('elisfields_moodleprofile', 'custom_fields.php'); foreach ($fields as $field) { $field = new field($field); if (!moodle_profile_can_sync($field->shortname)) { continue; } if (isset($field->owners['moodle_profile']) && isset($mu->{"profile_field_{$field->shortname}"})) { // check if should sync user profile field settings if ($field->owners['moodle_profile']->exclude == pm_moodle_profile::sync_from_moodle) { sync_profile_field_settings_from_moodle($field); } $fieldname = "field_{$field->shortname}"; $cu->{$fieldname} = $mu->{"profile_field_{$field->shortname}"}; } } //specifically tell the user save not to use the local_elisprogram_usr_mdl for syncing //because the record hasn't been inserted yet (see below) try { $cu->save(false); } catch (Exception $ex) { if (in_cron()) { mtrace(get_string('record_not_created_reason', 'local_elisprogram', array('message' => $ex->getMessage() . " [{$mu->id}]"))); return false; } else { throw new Exception($ex->getMessage()); } } // if no user association record exists, create one if (!$moodle_user_exists) { $um = new usermoodle(); $um->cuserid = $cu->id; $um->muserid = $mu->id; $um->idnumber = $mu->idnumber; $um->save(); } return true; }
/** * Performs the common access checks and page setup for all * user preference pages. * * @param int $userid The user id to edit taken from the page params. * @param int $courseid The optional course id if we came from a course context. * @return array containing the user and course records. */ function useredit_setup_preference_page($userid, $courseid) { global $PAGE, $SESSION, $DB, $CFG, $OUTPUT, $USER; // Guest can not edit. if (isguestuser()) { print_error('guestnoeditprofile'); } if (!($course = $DB->get_record('course', array('id' => $courseid)))) { print_error('invalidcourseid'); } if ($course->id != SITEID) { require_login($course); } else { if (!isloggedin()) { if (empty($SESSION->wantsurl)) { $SESSION->wantsurl = $CFG->httpswwwroot . '/user/preferences.php'; } redirect(get_login_url()); } else { $PAGE->set_context(context_system::instance()); } } // The user profile we are editing. if (!($user = $DB->get_record('user', array('id' => $userid)))) { print_error('invaliduserid'); } // Guest can not be edited. if (isguestuser($user)) { print_error('guestnoeditprofile'); } // Remote users cannot be edited. if (is_mnet_remote_user($user)) { if (user_not_fully_set_up($user, false)) { $hostwwwroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $user->mnethostid)); print_error('usernotfullysetup', 'mnet', '', $hostwwwroot); } redirect($CFG->wwwroot . "/user/view.php?course={$course->id}"); } $systemcontext = context_system::instance(); $personalcontext = context_user::instance($user->id); // Check access control. if ($user->id == $USER->id) { // Editing own profile - require_login() MUST NOT be used here, it would result in infinite loop! if (!has_capability('moodle/user:editownprofile', $systemcontext)) { print_error('cannotedityourprofile'); } } else { // Teachers, parents, etc. require_capability('moodle/user:editprofile', $personalcontext); // No editing of primary admin! if (is_siteadmin($user) and !is_siteadmin($USER)) { // Only admins may edit other admins. print_error('useradmineditadmin'); } } if ($user->deleted) { echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('userdeleted')); echo $OUTPUT->footer(); die; } $PAGE->set_pagelayout('admin'); $PAGE->set_context($personalcontext); if ($USER->id != $user->id) { $PAGE->navigation->extend_for_user($user); } else { if ($node = $PAGE->navigation->find('myprofile', navigation_node::TYPE_ROOTNODE)) { $node->force_open(); } } return array($user, $course); }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ function loginpage_hook() { global $SESSION, $CFG, $DB, $USER; $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode) && 200 == $authorizationcode) { require_once $CFG->dirroot . '/auth/oauth_simple/lib.php'; $cfg = get_config('auth/oauth_simple'); $accesstoken = $SESSION->access_token; $connection = new TwitterOAuth($cfg->apiurl, $cfg->baseurl, $cfg->consumer_key, $cfg->consumer_secret, $accesstoken['oauth_token'], $accesstoken['oauth_token_secret']); $userinfo = $connection->post($cfg->apifunc); if (!empty($userinfo->{$cfg->username})) { $user = $DB->get_record('user', array('username' => $userinfo->{$cfg->username}, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // Create the user if it doesn't exist. if (empty($user)) { // Deny login if setting "Prevent account creation when authenticating" is on. if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_oauth_simple"); } $username = $userinfo->{$cfg->username}; create_user_record($username, '', 'oauth_simple'); } else { $username = $user->username; } // Authenticate the user. $userid = empty($user) ? 'new user' : $user->id; add_to_log(SITEID, 'auth_oauth_simple', '', '', $username . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { // if (!empty($newuser)) { // $newuser->id = $user->id; // $newuser->id = $user->id; // $DB->update_record('user', $newuser); $DB->update_record('user', $user); // $user = (object) array_merge((array) $user, (array) $newuser); // } complete_user_login($user); // Create event for authenticated user. $event = \auth_oauth_simple\event\user_loggedin::create(array('context' => context_system::instance(), 'objectid' => $user->id, 'relateduserid' => $user->id, 'other' => array('accesstoken' => $accesstoken))); $event->trigger(); // Redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { throw new moodle_exception('invalid access', 'auth_oauth_simple'); } } }
if (empty($CFG->rememberusername) or $CFG->rememberusername == 2 and empty($frm->rememberusername)) { // no permanent cookies, delete old one if exists set_moodle_cookie(''); } else { set_moodle_cookie($USER->username); } } $context = get_context_instance(CONTEXT_SYSTEM); $roles = get_user_roles($context, $USER->id, false); $role = key($roles); $rolename = $roles[$role]->shortname; if ($rolename == 'subadmin') { redirect($CFG->wwwroot . '/my/'); } /// Prepare redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0 or strpos($SESSION->wantsurl, str_replace('http://', 'https://', $CFG->wwwroot)) === 0)) { $urltogo = $SESSION->wantsurl; /// Because it's an address in this site unset($SESSION->wantsurl); } else { // no wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); $home_page = get_home_page(); // Go to my-moodle page instead of site homepage if defaulthomepage set to homepage_my if ($home_page == HOMEPAGE_MY && !is_siteadmin() && !isguestuser()) { if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') {
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ function loginpage_hook() { global $USER, $SESSION, $CFG, $DB; //check the Google authorization code $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_ALPHANUMEXT); //set the params specific to the authentication provider $params = array(); switch ($authprovider) { case 'google': $params['client_id'] = get_config('auth/googleoauth2', 'googleclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'googleclientsecret'); $requestaccesstokenurl = 'https://accounts.google.com/o/oauth2/token'; $params['grant_type'] = 'authorization_code'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/google_redirect.php'; $params['code'] = $authorizationcode; break; case 'facebook': $params['client_id'] = get_config('auth/googleoauth2', 'facebookclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'facebookclientsecret'); $requestaccesstokenurl = 'https://graph.facebook.com/oauth/access_token'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/facebook_redirect.php'; $params['code'] = $authorizationcode; break; case 'messenger': $params['client_id'] = get_config('auth/googleoauth2', 'messengerclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'messengerclientsecret'); $requestaccesstokenurl = 'https://oauth.live.com/token'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/messenger_redirect.php'; $params['code'] = $authorizationcode; $params['grant_type'] = 'authorization_code'; break; default: throw new moodle_exception('unknown_oauth2_provider'); break; } //request by curl an access token and refresh token require_once $CFG->libdir . '/filelib.php'; if ($authprovider == 'messenger') { //Windows Live returns an "Object moved" error with curl->post() encoding $curl = new curl(); $postreturnvalues = $curl->get('https://oauth.live.com/token?client_id=' . urlencode($params['client_id']) . '&redirect_uri=' . urlencode($params['redirect_uri']) . '&client_secret=' . urlencode($params['client_secret']) . '&code=' . urlencode($params['code']) . '&grant_type=authorization_code'); } else { $curl = new curl(); $postreturnvalues = $curl->post($requestaccesstokenurl, $params); } switch ($authprovider) { case 'google': $postreturnvalues = json_decode($postreturnvalues); $accesstoken = $postreturnvalues->access_token; //$refreshtoken = $postreturnvalues->refresh_token; //$expiresin = $postreturnvalues->expires_in; //$tokentype = $postreturnvalues->token_type; break; case 'facebook': parse_str($postreturnvalues, $returnvalues); $accesstoken = $returnvalues['access_token']; break; case 'messenger': $accesstoken = json_decode($postreturnvalues)->access_token; break; default: break; } //with access token request by curl the email address if (!empty($accesstoken)) { //get the username matching the email switch ($authprovider) { case 'google': $params = array(); $params['access_token'] = $accesstoken; $params['alt'] = 'json'; $postreturnvalues = $curl->get('https://www.googleapis.com/userinfo/email', $params); $postreturnvalues = json_decode($postreturnvalues); $useremail = $postreturnvalues->data->email; $verified = $postreturnvalues->data->isVerified; break; case 'facebook': $params = array(); $params['access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://graph.facebook.com/me', $params); $facebookuser = json_decode($postreturnvalues); $useremail = $facebookuser->email; $verified = $facebookuser->verified; break; case 'messenger': $params = array(); $params['access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://apis.live.net/v5.0/me', $params); $messengeruser = json_decode($postreturnvalues); $useremail = $messengeruser->emails->preferred; $verified = 1; //not super good but there are no way to check it yet: //http://social.msdn.microsoft.com/Forums/en-US/messengerconnect/thread/515d546d-1155-4775-95d8-89dadc5ee929 break; default: break; } //throw an error if the email address is not verified if (!$verified) { throw new moodle_exception('emailaddressmustbeverified', 'auth_googleoauth2'); } //if email not existing in user database then create a new username (userX). if (empty($useremail) or $useremail != clean_param($useremail, PARAM_EMAIL)) { throw new moodle_exception('couldnotgetuseremail'); //TODO: display a link for people to retry } //get the user - don't bother with auth = googleoauth2 because //authenticate_user_login() will fail it if it's not 'googleoauth2' $user = $DB->get_record('user', array('email' => $useremail, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); //create the user if it doesn't exist if (empty($user)) { //get following incremented username $lastusernumber = get_config('auth/googleoauth2', 'lastusernumber'); $lastusernumber = empty($lastusernumber) ? 1 : $lastusernumber++; //check the user doesn't exist $nextuser = $DB->get_record('user', array('username' => get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber)); while (!empty($nextuser)) { $lastusernumber = $lastusernumber + 1; $nextuser = $DB->get_record('user', array('username' => get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber)); } set_config('lastusernumber', $lastusernumber, 'auth/googleoauth2'); $username = get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber; //retrieve more information from the provider $newuser = new stdClass(); $newuser->email = $useremail; switch ($authprovider) { case 'google': $params = array(); $params['access_token'] = $accesstoken; $params['alt'] = 'json'; $userinfo = $curl->get('https://www.googleapis.com/oauth2/v1/userinfo', $params); $userinfo = json_decode($userinfo); //email, id, name, verified_email, given_name, family_name, link, gender, locale $newuser->auth = 'googleoauth2'; if (!empty($userinfo->given_name)) { $newuser->firstname = $userinfo->given_name; } if (!empty($userinfo->family_name)) { $newuser->lastname = $userinfo->family_name; } if (!empty($userinfo->locale)) { //$newuser->lang = $userinfo->locale; //TODO: convert the locale into correct Moodle language code } break; case 'facebook': $newuser->firstname = $facebookuser->first_name; $newuser->lastname = $facebookuser->last_name; break; case 'messenger': $newuser->firstname = $messengeruser->first_name; $newuser->lastname = $messengeruser->last_name; break; default: break; } //retrieve country and city if the provider failed to give it if (!isset($newuser->country) or !isset($newuser->city)) { $googleipinfodbkey = get_config('auth/googleoauth2', 'googleipinfodbkey'); if (!empty($googleipinfodbkey)) { $locationdata = $curl->get('http://api.ipinfodb.com/v3/ip-city/?key=' . $googleipinfodbkey . '&ip=' . getremoteaddr() . '&format=json'); $locationdata = json_decode($locationdata); } if (!empty($locationdata)) { //TODO: check that countryCode does match the Moodle country code $newuser->country = isset($newuser->country) ? isset($newuser->country) : $locationdata->countryCode; $newuser->city = isset($newuser->city) ? isset($newuser->city) : $locationdata->cityName; } } } else { $username = $user->username; } //authenticate the user //TODO: delete this log later $userid = empty($user) ? 'new user' : $user->id; add_to_log(SITEID, 'auth_googleoauth2', '', '', $username . '/' . $useremail . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { //set a cookie to remember what auth provider was selected setcookie('MOODLEGOOGLEOAUTH2_' . $CFG->sessioncookie, $authprovider, time() + DAYSECS * 60, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly); //prefill more user information if new user if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); } complete_user_login($user); // Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { throw new moodle_exception('couldnotgetgoogleaccesstoken', 'auth_googleoauth2'); } } }
// The user profile we are editing. if (!($user = $DB->get_record('user', array('id' => $userid)))) { print_error('invaliduserid'); } // Guest can not be edited. if (isguestuser($user)) { print_error('guestnoeditprofile'); } // User interests separated by commas. $user->interests = core_tag_tag::get_item_tags_array('core', 'user', $user->id); // Remote users cannot be edited. We have to perform the strict // user_not_fully_set_up() check, otherwise the remote user could end up in // endless loop between user/view.php and herein. Note that required custom // fields are not supported in MNet environment anyway. if (is_mnet_remote_user($user)) { if (user_not_fully_set_up($user, true)) { $hostwwwroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $user->mnethostid)); print_error('usernotfullysetup', 'mnet', '', $hostwwwroot); } redirect($CFG->wwwroot . "/user/view.php?course={$course->id}"); } // Load the appropriate auth plugin. $userauth = get_auth_plugin($user->auth); if (!$userauth->can_edit_profile()) { print_error('noprofileedit', 'auth'); } if ($editurl = $userauth->edit_profile_url()) { // This internal script not used. redirect($editurl); } if ($course->id == SITEID) {
// The user profile we are editing. if (!($user = $DB->get_record('user', array('id' => $userid)))) { print_error('invaliduserid'); } // Guest can not be edited. if (isguestuser($user)) { print_error('guestnoeditprofile'); } // User interests separated by commas. if (!empty($CFG->usetags)) { require_once $CFG->dirroot . '/tag/lib.php'; $user->interests = tag_get_tags_array('user', $user->id); } // Remote users cannot be edited. if (is_mnet_remote_user($user)) { if (user_not_fully_set_up($user)) { $hostwwwroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $user->mnethostid)); print_error('usernotfullysetup', 'mnet', '', $hostwwwroot); } redirect($CFG->wwwroot . "/user/view.php?course={$course->id}"); } // Load the appropriate auth plugin. $userauth = get_auth_plugin($user->auth); if (!$userauth->can_edit_profile()) { print_error('noprofileedit', 'auth'); } if ($editurl = $userauth->edit_profile_url()) { // This internal script not used. redirect($editurl); } if ($course->id == SITEID) {