/**
 * 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();
}
Exemple #2
0
 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;
 }
Exemple #3
0
 /**
  * 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();
 }
Exemple #4
0
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');
}