/** * Called when the login form is submitted. Validates the user and password, and * if they are valid, starts a new session for the user. * * @param object $form The Pieform form object * @param array $values The submitted values * @access private */ function login_submit(Pieform $form, $values) { global $SESSION, $USER; $username = trim($values['login_username']); $password = $values['login_password']; $authenticated = false; try { $authenticated = $USER->login($username, $password); if (empty($authenticated)) { $SESSION->add_error_msg(get_string('loginfailed')); return; } } catch (AuthUnknownUserException $e) { // If the user doesn't exist, check for institutions that // want to create users automatically. try { // Reset the LiveUser object, since we are attempting to create a // new user $SESSION->destroy_session(); $USER = new LiveUser(); $authinstances = get_records_sql_array("\n SELECT a.id, a.instancename, a.priority, a.authname, a.institution, i.suspended, i.displayname\n FROM {institution} i JOIN {auth_instance} a ON a.institution = i.name\n WHERE a.authname != 'internal'\n ORDER BY a.institution, a.priority, a.instancename", null); if ($authinstances == false) { throw new AuthUnknownUserException("\"{$username}\" is not known"); } $USER->username = $username; reset($authinstances); while ((list(, $authinstance) = each($authinstances)) && false == $authenticated) { $auth = AuthFactory::create($authinstance->id); if (!$auth->can_auto_create_users()) { continue; } // catch semi-fatal auth errors, but allow next auth instance to be // tried try { if ($auth->authenticate_user_account($USER, $password)) { $authenticated = true; } else { continue; } } catch (AuthInstanceException $e) { continue; } // Check now to see if the institution has its maximum quota of users require_once 'institution.php'; $institution = new Institution($authinstance->institution); if ($institution->isFull()) { $institution->send_admin_institution_is_full_message(); throw new AuthUnknownUserException('Institution has too many users'); } $USER->authinstance = $authinstance->id; $userdata = $auth->get_user_info($username); if (empty($userdata)) { throw new AuthUnknownUserException("\"{$username}\" is not known"); } // Check for a suspended institution if ($authinstance->suspended) { $sitename = get_config('sitename'); throw new AccessTotallyDeniedException(get_string('accesstotallydenied_institutionsuspended', 'mahara', $authinstance->displayname, $sitename)); } // We have the data - create the user $USER->lastlogin = db_format_timestamp(time()); if (isset($userdata->firstname)) { $USER->firstname = sanitize_firstname($userdata->firstname); } if (isset($userdata->lastname)) { $USER->lastname = sanitize_firstname($userdata->lastname); } if (isset($userdata->email)) { $USER->email = sanitize_email($userdata->email); } else { // The user will be asked to populate this when they log in. $USER->email = null; } $profilefields = array(); foreach (array('studentid', 'preferredname') as $pf) { if (isset($userdata->{$pf})) { $sanitize = 'sanitize_' . $pf; if (($USER->{$pf} = $sanitize($userdata->{$pf})) !== '') { $profilefields[$pf] = $USER->{$pf}; } } } try { // If this authinstance is a parent auth for some xmlrpc authinstance, pass it along to create_user // so that this username also gets recorded as the username for sso from the remote sites. $remoteauth = $auth->is_parent_authority(); create_user($USER, $profilefields, $institution, $remoteauth); $USER->reanimate($USER->id, $authinstance->id); } catch (Exception $e) { db_rollback(); throw $e; } } if (!$authenticated) { $SESSION->add_error_msg(get_string('loginfailed')); return; } } catch (AuthUnknownUserException $e) { // We weren't able to authenticate the user for some reason that // probably isn't their fault (e.g. ldap extension not available // when using ldap authentication) log_info($e->getMessage()); $SESSION->add_error_msg(get_string('loginfailed')); return; } } auth_check_admin_section(); // This is also checked in $USER->login(), but it's good to check it again here in case a buggy auth plugin // lets a suspended user through somehow. ensure_user_account_is_active(); // User is allowed to log in //$USER->login($userdata); auth_check_required_fields(); }
public function login($email) { // This will do one of 3 things // 1 - If a user has an account, log them in // 2 - If a user doesn't have an account, and there is an auth method (which also has weautocreate), create acc and login // 3 - If a user doesn't have an account, and there is more than one auth method, show a registration page $sql = "SELECT\n a.id, i.name AS institutionname\n FROM\n {auth_instance} a\n JOIN\n {institution} i ON a.institution = i.name\n WHERE\n a.authname = 'browserid' AND\n i.suspended = 0"; $authinstances = get_records_sql_array($sql, array()); if (!$authinstances) { throw new ConfigException(get_string('browseridnotenabled', 'auth.browserid')); } $autocreate = array(); // Remember the authinstances that are happy to create users foreach ($authinstances as $authinstance) { $auth = AuthFactory::create($authinstance->id); $institutionjoin = ''; $institutionwhere = ''; $sqlvalues = array($email); if ($authinstance->institutionname != 'mahara') { // Make sure that user is in the right institution $institutionjoin = 'JOIN {usr_institution} ui ON ui.usr = u.id'; $institutionwhere = 'AND ui.institution = ?'; $sqlvalues[] = $authinstance->institutionname; } $sql = "SELECT\n u.*,\n " . db_format_tsfield('u.expiry', 'expiry') . ",\n " . db_format_tsfield('u.lastlogin', 'lastlogin') . ",\n " . db_format_tsfield('u.lastlastlogin', 'lastlastlogin') . ",\n " . db_format_tsfield('u.lastaccess', 'lastaccess') . ",\n " . db_format_tsfield('u.suspendedctime', 'suspendedctime') . ",\n " . db_format_tsfield('u.ctime', 'ctime') . "\n FROM\n {usr} u\n JOIN\n {artefact_internal_profile_email} a ON a.owner = u.id\n {$institutionjoin}\n WHERE\n a.verified = 1 AND\n a.email = ?\n {$institutionwhere}"; $user = get_record_sql($sql, $sqlvalues); if (!$user) { if ($auth->weautocreateusers) { if ($authinstance->institutionname == 'mahara') { array_unshift($autocreate, $auth); // Try "No Instititution" first when creating users below } else { $autocreate[] = $auth; } } continue; // skip to the next auth_instance } if (is_site_closed($user->admin)) { return false; } ensure_user_account_is_active($user); $this->authenticate($user, $auth->instanceid); return true; } foreach ($autocreate as $auth) { if (!($user = $auth->create_new_user($email))) { continue; } $this->authenticate($user, $auth->instanceid); return; } // Autocreation failed; try registration. list($form, $registerconfirm) = auth_generate_registration_form('register', 'browserid', '/register.php'); if (!$form) { throw new AuthUnknownUserException(get_string('emailnotfound', 'auth.browserid', $email)); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { throw new AuthUnknownUserException(get_string('emailalreadytaken', 'auth.internal', $email)); } $form['elements']['email'] = array('type' => 'hidden', 'value' => $email); $form['elements']['authtype'] = array('type' => 'hidden', 'value' => 'browserid'); list($formhtml, $js) = auth_generate_registration_form_js($form, $registerconfirm); $registerdescription = get_string('registerwelcome'); if ($registerterms = get_config('registerterms')) { $registerdescription .= ' ' . get_string('registeragreeterms'); } $registerdescription .= ' ' . get_string('registerprivacy'); $smarty = smarty(); $smarty->assign('register_form', $formhtml); $smarty->assign('registerdescription', $registerdescription); if ($registerterms) { $smarty->assign('termsandconditions', get_site_page_content('termsandconditions')); } $smarty->assign('PAGEHEADING', get_string('register', 'auth.browserid')); $smarty->assign('INLINEJAVASCRIPT', $js); $smarty->display('register.tpl'); die; }
/** * When a user creates a security context by whatever method, we do some * standard stuff * * @param object $user Record from the usr table * @param integer $authinstance The ID of the authinstance that the user * signed in with * @return void */ protected function authenticate($user, $authinstance) { // Before we update anything in the DB, we should make sure the user is allowed to log in ensure_user_account_is_active($user); $this->authenticated = true; // If the user has reauthenticated and they were an MNET user, we // don't set these variables, because we wish to remember that they // originally SSO-ed in from their other authinstance. See the // session timeout code in auth_setup() for more info. if ($this->SESSION->get('mnetuser') != $user->id) { $this->SESSION->set('mnetuser', null); $this->SESSION->set('authinstance', $authinstance); } $this->populate($user); session_regenerate_id(true); $time = time(); $this->lastlastlogin = $this->lastlogin; $this->lastlogin = $time; $this->lastaccess = $time; $this->sessionid = session_id(); $this->logout_time = $time + get_config('session_timeout'); $this->sesskey = get_random_key(); // We need a user->id before we load_c*_preferences if (empty($user->id)) { $this->commit(); } $this->activityprefs = load_activity_preferences($user->id); $this->accountprefs = load_account_preferences($user->id); // Record the successful login in the usr_login_data table insert_record('usr_login_data', (object) array('usr' => $user->id, 'ctime' => db_format_timestamp($time))); // If user has chosen a language while logged out, save it as their lang pref. $sessionlang = $this->SESSION->get('lang'); if (!empty($sessionlang) && $sessionlang != 'default' && (empty($this->accountprefs['lang']) || $sessionlang != $this->accountprefs['lang'])) { $this->set_account_preference('lang', $sessionlang); } $this->reset_institutions(); $this->reset_grouproles(); $this->load_views(); $this->store_sessionid(); // This user may have logged in to reactivate themselves, so now we know they're active, reset // the fields that may have been changed by cron. if (!$this->active || $this->inactivemailsent) { // Properties will be reloaded by the call to $this->commit() below execute_sql('UPDATE {usr} SET active = 1, inactivemailsent = 0 WHERE id = ?', array($user->id)); } $this->commit(); // finally, after all is done, call the (maybe non existant) hook on their auth plugin $authobj = AuthFactory::create($authinstance); $authobj->login(); }
function forgotpasschange_submit(Pieform $form, $values) { global $SESSION, $USER; unset($SESSION->forgotpasskey); try { $user = new User(); $user->find_by_id($values['user']); } catch (AuthUnknownUserException $e) { throw new UserException('Request to change the password for a user who does not exist'); } $authobj = AuthFactory::create($user->authinstance); if ($password = $authobj->change_password($user, $values['password1'])) { // Remove the password request(s) for the user delete_records('usr_password_request', 'usr', $values['user']); ensure_user_account_is_active($user); $USER->reanimate($user->id, $user->authinstance); // Destroy other sessions of the user remove_user_sessions($USER->get('id')); $SESSION->add_ok_msg(get_string('passwordchangedok')); redirect(); exit; } throw new SystemException('User "' . $user->username . ' tried to change their password, but the attempt failed'); }