/** * Function to enable SSO (it runs before user_login() is called) * If a valid CHOCOLATECHIP cookie is not found, the user will be forced to the * master bakery login page where have to authenticate the user. * * @return logged in USER */ function loginpage_hook() { global $CFG, $USER, $DB; global $key, $cookieDomain, $slaveURL, $masterURL, $defaultCountry; $key = $this->config->skey; $cookieDomain = $this->config->cookiedomain; $masterURL = $this->config->masterurl; $slaveURL = $this->config->slaveurl; $defaultCountry = $this->config->defaultcountry; $mdBakery['slave'] = validateCookie(); if (!empty($mdBakery['slave'])) { $username = $mdBakery['slave']['name']; $user = authenticate_user_login($username, null); if ($user) { complete_user_login($user); $urltogo = $CFG->wwwroot . '/'; $userMail = $USER->email; // If dummie change init url through edit user form $userInit = $USER->idnumber; // Don't check for username because of user freedom for Firstname and Lastname display if ($userMail != $mdBakery['slave']['mail'] || $userInit != $mdBakery['slave']['init']) { $emptyString = " "; // Or just "default" string $user->idnumber = $mdBakery['slave']['init']; $fName = ucfirst($mdBakery['slave']['name']); $user->firstname = $fName; $user->lastname = $emptyString; $user->email = $mdBakery['slave']['mail']; $user->city = $emptyString; $user->country = $defaultCountry; $DB->update_record('user', $user); } redirect($urltogo); } } else { if (isloggedin() && !isguestuser()) { require_logout(); } else { // $master_redirect = $masterURL . 'user/login?return_dest=' . urlencode($slaveURL . 'login/index.php'); // header('Location: ' . $master_redirect); } } }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentioned. */ public function loginpage_hook() { global $USER, $SESSION, $CFG, $DB; $USER->auth = 'apilogin'; //if the user is already logged into the system, then don't do anything if (!$USER->id) { $lib = new auth_apilogin_lib(); $user = $lib->validateToken(); //if valid, then complete the user login so they can enter directly into the site if ($user) { complete_user_login($user); //redirect to the requested page if (!empty($user->redirect)) { redirect($user->redirect); //redirect to the wantsurl if it exists } elseif (!empty($SESSION->wantsurl)) { redirect($SESSION->wantsurl); //redirect to the dashboard } else { redirect($CFG->wwwroot . '/my/'); } //if not valid, then redirect if the user to the login page set in the plugin config //of if not set, then allow moodle to perform the redirect } else { if ($this->config->loginredirect) { $q = (strpos($this->config->loginredirect, '?') === false ? '?' : '&') . 'invalid=1'; redirect($this->config->loginredirect . $q); } } } }
public function execute() { global $CFG; require_once "{$CFG->libdir}/datalib.php"; $user = get_admin(); if (!$user) { cli_error("Unable to find admin user in DB."); } $auth = empty($user->auth) ? 'manual' : $user->auth; if ($auth == 'nologin' or !is_enabled_auth($auth)) { cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'", $user->username)); } $authplugin = get_auth_plugin($auth); $authplugin->sync_roles($user); login_attempt_valid($user); complete_user_login($user); printf("%s:%s\n", session_name(), session_id()); }
public function execute() { global $CFG, $DB; require_once "{$CFG->libdir}/datalib.php"; $username = $this->arguments[0]; $options = $this->expandedOptions; if ($options['id']) { $user = $DB->get_record('user', array('id' => $username), '*', MUST_EXIST); } else { $user = $DB->get_record('user', array('username' => $username), '*', MUST_EXIST); } $auth = empty($user->auth) ? 'manual' : $user->auth; if ($auth == 'nologin' or !is_enabled_auth($auth)) { cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'", $user->username)); } $authplugin = get_auth_plugin($auth); $authplugin->sync_roles($user); login_attempt_valid($user); complete_user_login($user); printf("%s:%s\n", session_name(), session_id()); }
/** * 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); }
/** * 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; }
/** * Function to enable SSO (it runs before user_login() is called) * If a valid Drupal session is not found, the user will be forced to the * login page where some other plugin will have to authenticate the user * * @return int return FALSE */ function loginpage_hook() { global $CFG, $USER, $SESSION, $DB; // Check if we have a Drupal session. $drupalsession = $this->get_drupal_session(); if ($drupalsession == null) { debugging("No drupal session detected, sending to drupal for login.", DEBUG_DEVELOPER); // redirect to drupal login page with destination if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) == 0) { // the URL is set and within Moodle's environment $urltogo = $SESSION->wantsurl; unset($SESSION->wantsurl); $path = ltrim(parse_url($urltogo, PHP_URL_PATH), '/'); $args = parse_url($urltogo, PHP_URL_QUERY); if ($args) { $args = '?' . $args; } // FIX so not hard coded. redirect($this->config->host_uri . "/user/login?moodle_url=true&destination=" . $path . $args); } return; // just send user to login page } // Verify the authenticity of the Drupal session ID // Create JSON cookie used to connect to drupal services. // So we connect to system/connect and we should get a valid drupal user. $apiObj = new RemoteAPI($this->config->host_uri, 1, $drupalsession); // Connect to Drupal with this session $ret = $apiObj->Connect(); if (is_null($ret)) { //should we just return? if (isloggedin() && !isguestuser()) { // the user is logged-off of Drupal but still logged-in on Moodle // so we must now log-off the user from Moodle... require_logout(); } return; } debugging("<pre>Live session detected the user returned is\r\n" . print_r($ret, true) . "</pre>", DEBUG_DEVELOPER); $uid = $ret->user->uid; if ($uid < 1) { //No anon return; } // The Drupal session is valid; now check if Moodle is logged in... if (isloggedin() && !isguestuser()) { return; } $drupaluser = $apiObj->Index("user/{$uid}"); debugging("<pre>The full user data about this user is:\r\n" . print_r($drupaluser, true) . "</pre>", DEBUG_DEVELOPER); //create/update looks up the user and writes updated information to the DB $this->create_update_user($drupaluser); $user = get_complete_user_data('idnumber', $uid); debugging("<pre>the user that should have been created or updated is:\r\n" . print_r($user, true) . "</pre>", DEBUG_DEVELOPER); // Complete the login complete_user_login($user); // redirect if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) == 0) { // the URL is set and within Moodle's environment $urltogo = $SESSION->wantsurl; unset($SESSION->wantsurl); } else { // no wantsurl stored or external link. Go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } redirect($urltogo); }
// unset previous session language - use user preference instead unset($SESSION->lang); } } if (empty($user->confirmed)) { // This account was never confirmed $PAGE->set_title(get_string("mustconfirm")); $PAGE->set_heading($site->fullname); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string("mustconfirm")); echo $OUTPUT->box(get_string("emailconfirmsent", "", $user->email), "generalbox boxaligncenter"); echo $OUTPUT->footer(); die; } /// Let's get them all set up. complete_user_login($user); \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); // sets the username cookie if (!empty($CFG->nolastloggedin)) { // do not store last logged in user in cookie // auth plugins can temporarily override this from loginpage_hook() // do not save $CFG->nolastloggedin in database! } else { 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); } } $urltogo = core_login_get_return_url();
/** * 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; }
/** * 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; }
if (empty($SESSION->sessionverify)) { print_error('installsessionerror', 'admin', "index.php?sessionstarted=1&lang={$CFG->lang}"); } unset($SESSION->sessionverify); } } $adminuser = get_complete_user_data('username', 'admin'); if ($adminuser->password === 'adminsetuppending') { // prevent installation hijacking if ($adminuser->lastip !== getremoteaddr()) { print_error('installhijacked', 'admin'); } // login user and let him set password and admin details $adminuser->newadminuser = 1; message_set_default_message_preferences($adminuser); complete_user_login($adminuser, false); redirect("{$CFG->wwwroot}/user/editadvanced.php?id={$adminuser->id}"); // Edit thyself } else { unset_config('adminsetuppending'); } } else { // just make sure upgrade logging is properly terminated upgrade_finished('upgradesettings.php'); } // Turn xmlstrictheaders back on now. $CFG->xmlstrictheaders = $origxmlstrictheaders; unset($origxmlstrictheaders); // Check for valid admin user - no guest autologin require_login(0, false); $context = get_context_instance(CONTEXT_SYSTEM);
/** * 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'); } } }
require_once $CFG->dirroot . '/course/lib.php'; require_once $CFG->dirroot . '/lib/blocklib.php'; require_once $CFG->dirroot . '/lib/moodlelib.php'; require_once $CFG->dirroot . '/lib/pagelib.php'; require_once 'lib.php'; $update_all = isset($_GET['all_data']); $server_files_version = 1; $json_output = array(); if (isset($_POST['username']) && isset($_POST['password'])) { $userdata = FALSE; $userdata = authenticate_user_login($_POST['username'], $_POST['password']); if ($userdata) { require_once $CFG->dirroot . '/lib/moodlelib.php'; set_moodle_cookie($USER->username); if (function_exists(complete_user_login)) { complete_user_login($userdata); } else { // For old Moodle Servers $USER = $userdata; set_login_session_preferences(); if (function_exists(load_all_capabilities)) { load_all_capabilities(); } } } } if (isset($_GET['version']) || $update_all) { $json_output["version"] = $server_files_version; } if (isset($_GET['admin'])) { //if(is_siteadmin($USER->id)) {
unset($SESSION->lang); } } if (empty($user->confirmed)) { // This account was never confirmed $PAGE->set_title(get_string("mustconfirm")); $PAGE->set_heading($site->fullname); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string("mustconfirm")); echo $OUTPUT->box(get_string("emailconfirmsent", "", $user->email), "generalbox boxaligncenter"); echo $OUTPUT->footer(); die; } /// 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); complete_user_login($user, true); // sets the username cookie /// 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); }
public function loginpage_hook() { global $USER, $SESSION, $CFG, $DB, $PAGE; if (empty($_GET['provider'])) { $token = (new Builder())->setIssuer('NITROCARD')->setAudience('NITROCARD')->setId(substr(md5(strtotime("now")), 0, 10), true)->setIssuedAt(time())->setExpiration(time() + 1800)->set('login', get_config('quiz_nitroreportpdf', 'apilogin'))->set('pass', get_config('quiz_nitroreportpdf', 'apipass'))->set('md5', md5(get_config('quiz_nitroreportpdf', 'pubkey')))->getToken(); $rsa = new Crypt_RSA(); $rsa->setPassword(get_config('quiz_nitroreportpdf', 'passkey')); $rsa->loadKey(get_config('quiz_nitroreportpdf', 'pubkey')); $enc = base64_encode($rsa->encrypt($token)); unset($_COOKIE['nitrocardauth']); //LANG STRINGS FOR JS setcookie('nitrocardauth', '', time() - 3600, '/'); setcookie("nitrocardauth", $enc, time() + 1800, "/"); $PAGE->requires->jquery(); $PAGE->requires->css(new moodle_url($CFG->wwwroot . "/auth/nitrocard/nitrocard.css")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/pgwmodal.min.js")); $PAGE->requires->css(new moodle_url($CFG->wwwroot . "/auth/nitrocard/pgwmodal.css")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/html5-qrcode/lib/html5-qrcode.min.js")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/jquery.json.min.js")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/jquery.jsonrpcclient.js")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/script.js")); $button = '<br /><br /><a href="javascript:void(0);" onclick="javascript:M.auth_nitrocard.main(\'start\');"><img src="' . new moodle_url($CFG->wwwroot . "/auth/nitrocard/login_ico.png") . '"></a><br /><br />'; $PAGE->requires->js_init_call('M.auth_nitrocard.showbutton', array($button)); } elseif ($_GET['provider'] == "nitrocard") { try { //LANG STRINGS FOR JS // setcookie('nitrocard_lang_pleasewait', '', time() - 3600, '/'); $PAGE->requires->jquery(); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/pgwmodal.min.js")); $PAGE->requires->css(new moodle_url($CFG->wwwroot . "/auth/nitrocard/pgwmodal.css")); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/nitrocard/authload.js")); echo '<body onload="$.fn.nitro();"></body>'; $rsa = new Crypt_RSA(); $rsa->setPassword(get_config('quiz_nitroreportpdf', 'passkey')); $rsa->loadKey(get_config('quiz_nitroreportpdf', 'pubkey')); $ckey = $rsa->decrypt(base64_decode($_GET['auth'])); $token = (new Parser())->parse((string) $ckey); if (!$token) { throw new Exception('The data is invalid or time expired.'); } if ($token->getClaim('iss') != "NITROCARD" || $token->getClaim('aud') != "NITROCARD" || strtotime("now") >= $token->getClaim('exp')) { throw new Exception('The data is invalid or time expired.'); } if (substr(strip_tags($token->getClaim('NITROCARDID')), 0, 9) != "NITROCARD" || strlen($token->getClaim('NITROCARDID')) < 98 || strlen($token->getClaim('NITROCARDID')) > 108) { throw new Exception('NitroCard is invalid'); } $card_e = explode('.', $token->getClaim('NITROCARDID')); if (count($card_e) != 5) { throw new Exception('NitroCard is invalid'); } $reqdb = $DB->count_records_sql('SELECT count(fullcardid) FROM {nitrocard_cards} WHERE fullcardid="' . $token->getClaim('NITROCARDID') . '" AND userid="' . $card_e[2] . '" AND cardid="' . $card_e[3] . '"AND hash="' . $card_e[4] . '"'); if ($reqdb == 0) { throw new Exception('NitroCard is invalid'); } else { $info = $DB->get_record_sql('SELECT user FROM {nitrocard_cards} WHERE fullcardid="' . $token->getClaim('NITROCARDID') . '"'); $user = get_complete_user_data('id', $info->user); $USER = complete_user_login($user); $USER->loggedin = true; $USER->site = $CFG->wwwroot; redirect(new moodle_url($CFG->wwwroot)); } } catch (Exception $e) { throw new Exception($e->getMessage()); } } }
/** * Sign up a new user ready for confirmation. * Password is passed in plaintext. * * @param object $user new user object * @param boolean $notify print notice with link and terminate */ function user_signup($user, $notify = true) { global $CFG, $DB, $SESSION; require_once $CFG->dirroot . '/user/profile/lib.php'; require_once $CFG->dirroot . '/user/lib.php'; if (isset($SESSION->wantsurl)) { $wantsurl = $SESSION->wantsurl; } $plainpassword = $user->password; $user->password = hash_internal_user_password($user->password); if (empty($user->calendartype)) { $user->calendartype = $CFG->calendartype; } $user->confirmed = 1; $user->id = user_create_user($user, false, false); user_add_password_history($user->id, $plainpassword); // Save any custom profile field information. profile_save_data($user); // Trigger event. \core\event\user_created::create_from_userid($user->id)->trigger(); $thisuser = authenticate_user_login($user->username, $plainpassword, false, $errorcode); if ($thisuser == false) { print_error('authfailure'); } else { complete_user_login($thisuser); if (isset($wantsurl)) { $urltogo = $wantsurl; if (isset($_SESSION["fiaction"]) && isset($_SESSION["ficourseid"]) && is_numeric($_SESSION["ficourseid"]) && $_SESSION["fiaction"] == "enroll") { $urltogo = $CFG->wwwroot . '/course/enrol.php?id=' . $_SESSION["ficourseid"]; unset($_SESSION['fiaction']); unset($_SESSION['ficourseid']); unset($SESSION->wantsurl); } } else { $urltogo = $CFG->wwwroot . '/'; } redirect($urltogo); } // if ($notify) { // global $CFG, $PAGE, $OUTPUT; // $emailconfirm = get_string('emailconfirm'); // $PAGE->navbar->add($emailconfirm); // $PAGE->set_title($emailconfirm); // $PAGE->set_heading($PAGE->course->fullname); // echo $OUTPUT->header(); // notice(get_string('emailconfirmsent', '', $user->email), "$CFG->wwwroot/index.php"); // } else { // return true; // } }
/** * @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); } }
function RWSLIMUser($r_usrn, $r_pw, $r_csf) { global $RWSECAS; /*********** eClass Modification ************ Extra Comments: LDAP lookup call for the employee id translation for ccid CCID->empid, this is needed because the authentication fails and tries to create a user. ************/ global $CFG; require_once $CFG->dirroot . '/local/eclass/lib/IMS.php'; $ims = new IMS($r_usrn, $r_pw, 'uid=', 'ou=people,dc=ualberta,dc=ca'); $user_info = $ims->get_user_info($r_usrn); $empid = $user_info->employeenumber; /*********** End eClass Modification ********/ if ($RWSECAS) { RWSPLICas($r_usrn, $r_pw, $r_csf); } //$r_usr = authenticate_user_login($r_usrn, $r_pw); $r_usr = authenticate_user_login($empid, $r_pw); //eClass Modification if ($r_usr) { complete_user_login($r_usr); } if (isloggedin()) { RWSSStat("1000"); } else { if ($RWSECAS) { if (isset($_SESSION['rwscas']['cookiejar'])) { $r_ckf = $_SESSION['rwscas']['cookiejar']; if (file_exists($r_ckf)) { unlink($r_ckf); } unset($_SESSION['rwscas']['cookiejar']); } unset($_SESSION['rwscas']); } RWSSErr("2008"); } }
/** * This function processes a user's submitted token to validate the request to set a new password. * If the user's token is validated, they are prompted to set a new password. * @param string $token the one-use identifier which should verify the password reset request as being valid. * @return void */ function core_login_process_password_set($token) { global $DB, $CFG, $OUTPUT, $PAGE, $SESSION; $pwresettime = isset($CFG->pwresettime) ? $CFG->pwresettime : 1800; $sql = "SELECT u.*, upr.token, upr.timerequested, upr.id as tokenid\n FROM {user} u\n JOIN {user_password_resets} upr ON upr.userid = u.id\n WHERE upr.token = ?"; $user = $DB->get_record_sql($sql, array($token)); $forgotpasswordurl = "{$CFG->httpswwwroot}/login/forgot_password.php"; if (empty($user) or $user->timerequested < time() - $pwresettime - DAYSECS) { // There is no valid reset request record - not even a recently expired one. // (suspicious) // Direct the user to the forgot password page to request a password reset. echo $OUTPUT->header(); notice(get_string('noresetrecord'), $forgotpasswordurl); die; // Never reached. } if ($user->timerequested < time() - $pwresettime) { // There is a reset record, but it's expired. // Direct the user to the forgot password page to request a password reset. $pwresetmins = floor($pwresettime / MINSECS); echo $OUTPUT->header(); notice(get_string('resetrecordexpired', '', $pwresetmins), $forgotpasswordurl); die; // Never reached. } if ($user->auth === 'nologin' or !is_enabled_auth($user->auth)) { // Bad luck - user is not able to login, do not let them set password. echo $OUTPUT->header(); print_error('forgotteninvalidurl'); die; // Never reached. } // Check this isn't guest user. if (isguestuser($user)) { print_error('cannotresetguestpwd'); } // Token is correct, and unexpired. $mform = new login_set_password_form(null, null, 'post', '', 'autocomplete="yes"'); $data = $mform->get_data(); if (empty($data)) { // User hasn't submitted form, they got here directly from email link. // Next, display the form. $setdata = new stdClass(); $setdata->username = $user->username; $setdata->username2 = $user->username; $setdata->token = $user->token; $mform->set_data($setdata); $PAGE->verify_https_required(); echo $OUTPUT->header(); echo $OUTPUT->box(get_string('setpasswordinstructions'), 'generalbox boxwidthnormal boxaligncenter'); $mform->display(); echo $OUTPUT->footer(); return; } else { // User has submitted form. // Delete this token so it can't be used again. $DB->delete_records('user_password_resets', array('id' => $user->tokenid)); $userauth = get_auth_plugin($user->auth); if (!$userauth->user_update_password($user, $data->password)) { print_error('errorpasswordupdate', 'auth'); } // Reset login lockout (if present) before a new password is set. login_unlock_account($user); // Clear any requirement to change passwords. unset_user_preference('auth_forcepasswordchange', $user); unset_user_preference('create_password', $user); if (!empty($user->lang)) { // Unset previous session language - use user preference instead. unset($SESSION->lang); } complete_user_login($user); // Triggers the login event. $urltogo = core_login_get_return_url(); unset($SESSION->wantsurl); redirect($urltogo, get_string('passwordset'), 1); } }
function user_authenticated_hook(&$user, $username, $password) { global $redirect, $USER, $SESSION; if ($user->auth != 'joomdle') { return; } /* Login from password change, don't log in to Joomla */ if (array_key_exists('password', $_POST) && array_key_exists('newpassword1', $_POST) && array_key_exists('newpassword2', $_POST)) { return; } complete_user_login($user); $redirectless_sso = get_config('auth/joomdle', 'redirectless_sso'); if ($redirectless_sso) { // redirect-less login $this->log_into_joomla($username, $password); return; } // Normal login $login_data = base64_encode($username . ':' . $password); $redirect_url = get_config('auth/joomdle', 'joomla_url') . '/index.php?option=com_joomdle&view=joomdle&task=login&data=' . $login_data; if (property_exists($SESSION, 'wantsurl')) { $redirect_url .= '&wantsurl=' . urlencode($SESSION->wantsurl); } redirect($redirect_url); }
public function generate_data() { if (is_null($this->get('username')) || $this->get('username') == '') { echo "You must enter a valid username for a moodle administrator account on this site.{$this->eolchar}"; die; } elseif (is_null($this->get('password')) || $this->get('password') == '') { echo "You must enter a valid password for a moodle administrator account on this site.{$this->eolchar}"; die; } else { if (!($user = authenticate_user_login($this->get('username'), $this->get('password')))) { echo "Invalid username or password!{$this->eolchar}"; die; } complete_user_login($user); $systemcontext = get_context_instance(CONTEXT_SYSTEM); if (!is_siteadmin($user->id)) { //TODO: add some proper access control check here!! echo "You do not have administration privileges on this Moodle site. " . "These are required for running the generation script.{$this->eolchar}"; die; } } parent::generate_data(); }
public function test_complete_user_login() { global $USER, $DB; $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); $this->setUser(0); $sink = $this->redirectEvents(); $loginuser = clone $user; $this->setCurrentTimeStart(); @complete_user_login($loginuser); // Hide session header errors. $this->assertSame($loginuser, $USER); $this->assertEquals($user->id, $USER->id); $events = $sink->get_events(); $sink->close(); $this->assertCount(1, $events); $event = reset($events); $this->assertInstanceOf('\\core\\event\\user_loggedin', $event); $this->assertEquals('user', $event->objecttable); $this->assertEquals($user->id, $event->objectid); $this->assertEquals(context_system::instance()->id, $event->contextid); $user = $DB->get_record('user', array('id' => $user->id)); $this->assertTimeCurrent($user->firstaccess); $this->assertTimeCurrent($user->lastaccess); $this->assertTimeCurrent($USER->firstaccess); $this->assertTimeCurrent($USER->lastaccess); $this->assertTimeCurrent($USER->currentlogin); $this->assertSame(sesskey(), $USER->sesskey); $this->assertTimeCurrent($USER->preference['_lastloaded']); $this->assertObjectNotHasAttribute('password', $USER); $this->assertObjectNotHasAttribute('description', $USER); }
/** * 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); }
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'); } }
/** * Handle a login event. * * @param string $oidcuniqid A unique identifier for the user. * @param array $authparams Parameters receieved from the auth request. * @param array $tokenparams Parameters received from the token request. * @param \auth_oidc\jwt $idtoken A JWT object representing the received id_token. */ protected function handlelogin($oidcuniqid, $authparams, $tokenparams, $idtoken) { global $DB, $CFG; $tokenrec = $DB->get_record('auth_oidc_token', ['oidcuniqid' => $oidcuniqid]); if (!empty($tokenrec)) { $username = $tokenrec->username; $this->updatetoken($tokenrec->id, $authparams, $tokenparams); } else { // Use 'upn' if available for username (Azure-specific), or fall back to lower-case oidcuniqid. $username = $idtoken->claim('upn'); if (empty($username)) { $username = strtolower($oidcuniqid); } $matchedwith = $this->check_for_matched($username); if (!empty($matchedwith)) { $matchedwith->aadupn = $username; throw new \moodle_exception('errorusermatched', 'local_o365', null, $matchedwith); } $tokenrec = $this->createtoken($oidcuniqid, $username, $authparams, $tokenparams, $idtoken); } $existinguserparams = ['username' => $username, 'mnethostid' => $CFG->mnet_localhost_id]; if ($DB->record_exists('user', $existinguserparams) !== true) { // User does not exist. Create user if site allows, otherwise fail. if (empty($CFG->authpreventaccountcreation)) { $user = create_user_record($username, null, 'oidc'); } else { // Trigger login failed event. $failurereason = AUTH_LOGIN_NOUSER; $eventdata = ['other' => ['username' => $username, 'reason' => $failurereason]]; $event = \core\event\user_login_failed::create($eventdata); $event->trigger(); throw new \moodle_exception('errorauthloginfailednouser', 'auth_oidc'); } } $user = authenticate_user_login($username, null, true); if (empty($user)) { throw new \moodle_exception('errorauthloginfailednouser', 'auth_oidc'); } complete_user_login($user); return true; }
/** * 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")); } } }
$token = optional_param('token', '', PARAM_TEXT); $tab = optional_param('tab', simplecertificate::DEFAULT_VIEW, PARAM_INT); $sort = optional_param('sort', '', PARAM_RAW); $type = optional_param('type', '', PARAM_ALPHA); $page = optional_param('page', 0, PARAM_INT); $perpage = optional_param('perpage', get_config('simplecertificate', 'perpage'), PARAM_INT); $issuelist = optional_param('issuelist', null, PARAM_ALPHA); $username = optional_param('username', '', PARAM_TEXT); $username = strtolower($username); $auth = new auth_plugin_joomdle(); $logged = $auth->call_method("confirmJoomlaSession", $username, $token); if (!$logged) { return; } $USER = get_complete_user_data('username', $username); complete_user_login($USER); $context = context_module::instance($cm->id); require_capability('mod/simplecertificate:view', $context); $canmanage = has_capability('mod/simplecertificate:manage', $context); $url = new moodle_url('/mod/simplecertificate/view.php', array('id' => $cm->id, 'tab' => $tab, 'page' => $page, 'perpage' => $perpage)); if ($type) { $url->param('type', $type); } if ($sort) { $url->param('sort', $sort); } if ($action) { $url->param('action', $action); } if ($issuelist) { $url->param('issuelist', $issuelist);
} 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; } if ($frm->password == 'changeme') { //force the change set_user_preference('auth_forcepasswordchange', true, $user->id); } /// 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); } }
print_error('installsessionerror', 'admin', "index.php?sessionstarted=1&lang={$CFG->lang}"); } unset($SESSION->sessionverify); } } // at this stage there can be only one admin unless more were added by install - users may change username, so do not rely on that $adminids = explode(',', $CFG->siteadmins); $adminuser = get_complete_user_data('id', reset($adminids)); if ($adminuser->password === 'adminsetuppending') { // prevent installation hijacking if ($adminuser->lastip !== getremoteaddr()) { print_error('installhijacked', 'admin'); } // login user and let him set password and admin details $adminuser->newadminuser = 1; complete_user_login($adminuser); redirect("{$CFG->wwwroot}/user/editadvanced.php?id={$adminuser->id}"); // Edit thyself } else { unset_config('adminsetuppending'); } } else { // just make sure upgrade logging is properly terminated upgrade_finished('upgradesettings.php'); } // Turn xmlstrictheaders back on now. $CFG->xmlstrictheaders = $origxmlstrictheaders; unset($origxmlstrictheaders); // Check for valid admin user - no guest autologin require_login(0, false); $context = get_context_instance(CONTEXT_SYSTEM);
/** * 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 }