Пример #1
0
function requiredfields_submit(Pieform $form, $values)
{
    global $USER, $SESSION;
    if (isset($values['password1'])) {
        $authobj = AuthFactory::create($USER->authinstance);
        // This method should exist, because if it did not then the change
        // password form would not have been shown.
        if ($password = $authobj->change_password($USER, $values['password1'])) {
            $SESSION->add_ok_msg(get_string('passwordsaved'));
        } else {
            throw new SystemException('Attempt by "' . $USER->get('username') . '@' . $USER->get('institution') . 'to change their password failed');
        }
    }
    if (isset($values['username'])) {
        $SESSION->set('resetusername', false);
        if ($values['username'] != $USER->get('username')) {
            $USER->username = $values['username'];
            $USER->commit();
            $otherfield = true;
        }
    }
    if (isset($values['state'])) {
        $current_app_name = explode(".", $_SERVER["HTTP_HOST"]);
        $current_app_short_name = $current_app_name[0];
        $current_app_short_name = str_replace("http://", "", $current_app_short_name);
        $current_app_short_name = str_replace("https://", "", $current_app_short_name);
        Doctrine_Query::create()->update('GcrUsers')->set('state', '?', $values['state'])->set('country', '?', $values['country'])->where('platform_short_name = ?', $current_app_short_name)->andWhere('user_id = ?', $USER->get('id'))->execute();
    }
    if (isset($values['socialprofile_hidden']) && $values['socialprofile_hidden']) {
        // Socialprofile fields. Save them on their own as they are a fieldset.
        set_profile_field($USER->get('id'), 'socialprofile', $values);
        $otherfield = true;
    }
    foreach ($values as $field => $value) {
        if (in_array($field, array('submit', 'sesskey', 'password1', 'password2', 'username', 'socialprofile_service', 'socialprofile_profiletype', 'socialprofile_profileurl', 'socialprofile_hidden', 'state', 'country'))) {
            continue;
        }
        if ($field == 'email') {
            $email = $values['email'];
            // Need to update the admin email on installation
            if ($USER->get('admin')) {
                $oldemail = get_field('usr', 'email', 'id', $USER->get('id'));
                if ($oldemail == '*****@*****.**') {
                    // we are dealing with the dummy email that is set on install
                    update_record('usr', array('email' => $email), array('id' => $USER->get('id')));
                    update_record('artefact_internal_profile_email', array('email' => $email), array('owner' => $USER->get('id')));
                }
            }
            // Check if a validation email has been sent, if not send one
            if (!record_exists('artefact_internal_profile_email', 'owner', $USER->get('id'))) {
                $key = get_random_key();
                $key_url = get_config('wwwroot') . 'artefact/internal/validate.php?email=' . rawurlencode($email) . '&key=' . $key;
                $key_url_decline = $key_url . '&decline=1';
                try {
                    $sitename = get_config('sitename');
                    email_user((object) array('id' => $USER->get('id'), 'username' => $USER->get('username'), 'firstname' => $USER->get('firstname'), 'lastname' => $USER->get('lastname'), 'preferredname' => $USER->get('preferredname'), 'admin' => $USER->get('admin'), 'staff' => $USER->get('staff'), 'email' => $email), null, get_string('emailvalidation_subject', 'artefact.internal'), get_string('emailvalidation_body1', 'artefact.internal', $USER->get('firstname'), $email, $sitename, $key_url, $sitename, $key_url_decline));
                } catch (EmailException $e) {
                    $SESSION->add_error_msg($email);
                }
                insert_record('artefact_internal_profile_email', (object) array('owner' => $USER->get('id'), 'email' => $email, 'verified' => 0, 'principal' => 1, 'key' => $key, 'expiry' => db_format_timestamp(time() + 86400)));
                $SESSION->add_ok_msg(get_string('validationemailsent', 'artefact.internal'));
            }
        } else {
            set_profile_field($USER->get('id'), $field, $value);
            $otherfield = true;
        }
    }
    if (isset($otherfield)) {
        $SESSION->add_ok_msg(get_string('requiredfieldsset', 'auth'));
    }
    // Update the title of user's first blog if first and/or last name have been changed
    $updatedfields = array_keys($values);
    if (in_array('firstname', $updatedfields) || in_array('lastname', $updatedfields)) {
        safe_require('artefact', 'blog');
        $userblogs = get_records_select_array('artefact', 'artefacttype = \'blog\' AND owner = ?', array($USER->get('id')));
        if ($userblogs && count($userblogs) == 1) {
            $defaultblog = new ArtefactTypeBlog($userblogs[0]->id);
            $defaultblog->set('title', get_string('defaultblogtitle', 'artefact.blog', display_name($USER, null, true)));
            $defaultblog->commit();
        }
    }
    redirect();
}
Пример #2
0
function core_install_lastcoredata_defaults()
{
    db_begin();
    $institution = new StdClass();
    $institution->name = 'mahara';
    $institution->displayname = 'No Institution';
    $institution->authplugin = 'internal';
    $institution->theme = 'default';
    insert_record('institution', $institution);
    $auth_instance = new StdClass();
    $auth_instance->instancename = 'Internal';
    $auth_instance->priority = '1';
    $auth_instance->institution = 'mahara';
    $auth_instance->authname = 'internal';
    $auth_instance->id = insert_record('auth_instance', $auth_instance, 'id', true);
    // Insert the root user
    $user = new StdClass();
    $user->id = 0;
    $user->username = '******';
    $user->password = '******';
    $user->salt = '*';
    $user->firstname = 'System';
    $user->lastname = 'User';
    $user->email = '*****@*****.**';
    $user->quota = get_config_plugin('artefact', 'file', 'defaultquota');
    $user->authinstance = $auth_instance->id;
    if (is_mysql()) {
        // gratuitous mysql workaround
        $newid = insert_record('usr', $user, 'id', true);
        set_field('usr', 'id', 0, 'id', $newid);
        execute_sql('ALTER TABLE {usr} AUTO_INCREMENT=1');
    } else {
        insert_record('usr', $user);
    }
    install_system_profile_view();
    // Insert the admin user
    $user = new StdClass();
    $user->username = '******';
    $user->password = '******';
    $user->authinstance = $auth_instance->id;
    $user->passwordchange = 1;
    $user->admin = 1;
    $user->firstname = 'Admin';
    $user->lastname = 'User';
    $user->email = '*****@*****.**';
    $user->quota = get_config_plugin('artefact', 'file', 'defaultquota');
    $user->id = insert_record('usr', $user, 'id', true);
    set_profile_field($user->id, 'email', $user->email);
    set_profile_field($user->id, 'firstname', $user->firstname);
    set_profile_field($user->id, 'lastname', $user->lastname);
    set_config('installed', true);
    handle_event('createuser', $user->id);
    activity_add_admin_defaults(array($user->id));
    db_commit();
    // if we're installing, set up the block categories here and then poll the plugins.
    // if we're upgrading this happens somewhere else.  This is because of dependency issues around
    // the order of installation stuff.
    install_blocktype_extras();
}
Пример #3
0
/**
 * Create user
 *
 * @param object $user stdclass or User object for the usr table
 * @param array  $profile profile field/values to set
 * @param string $institution Institution the user should joined to
 * @param stdclass $remoteauth authinstance record for a remote authinstance
 * @param string $remotename username on the remote site
 * @return integer id of the new user
 */
function create_user($user, $profile = array(), $institution = null, $remoteauth = null, $remotename = null)
{
    db_begin();
    if ($user instanceof User) {
        $user->create();
        $user->quota_init();
        $user->commit();
        $user = $user->to_stdclass();
    } else {
        $user->ctime = db_format_timestamp(time());
        if (empty($user->quota)) {
            $user->quota = get_config_plugin('artefact', 'file', 'defaultquota');
        }
        $user->id = insert_record('usr', $user, 'id', true);
    }
    // Bypass access check for 'copynewuser' institution/site views, because this user may not be logged in yet
    $user->newuser = true;
    if (isset($user->email) && $user->email != '') {
        set_profile_field($user->id, 'email', $user->email);
    }
    if (isset($user->firstname) && $user->firstname != '') {
        set_profile_field($user->id, 'firstname', $user->firstname);
    }
    if (isset($user->lastname) && $user->lastname != '') {
        set_profile_field($user->id, 'lastname', $user->lastname);
    }
    foreach ($profile as $k => $v) {
        if (in_array($k, array('firstname', 'lastname', 'email'))) {
            continue;
        }
        set_profile_field($user->id, $k, $v);
    }
    if (!empty($institution) && $institution != 'mahara') {
        if (is_string($institution)) {
            $institution = new Institution($institution);
        }
        if ($institution->name != 'mahara') {
            $institution->addUserAsMember($user);
            // uses $user->newuser
        }
    }
    if (!empty($remoteauth) && $remoteauth->authname != 'internal') {
        if (isset($remotename) && strlen($remotename) > 0) {
            $un = $remotename;
        } else {
            $un = $user->username;
        }
        delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'remoteusername', $un);
        insert_record('auth_remote_user', (object) array('authinstance' => $user->authinstance, 'remoteusername' => $un, 'localusr' => $user->id));
    }
    // Copy site views to the new user's profile
    $checkviewaccess = !$user->newuser;
    $userobj = new User();
    $userobj->find_by_id($user->id);
    $userobj->copy_views(get_column('view', 'id', 'institution', 'mahara', 'copynewuser', 1), $checkviewaccess);
    handle_event('createuser', $user);
    db_commit();
    return $user->id;
}
Пример #4
0
 /**
  * Attemp to synchronize Users in Mahara with Users in the LDAP server
  *
  * @param boolean $dryrun dummy execution. Do not perform any database operations
  * @return boolean
  */
 public function sync_users($dryrun = false)
 {
     global $CFG;
     require_once get_config('docroot') . 'lib/ddl.php';
     require_once get_config('docroot') . 'lib/institution.php';
     log_info('---------- started usersync for instance ' . $this->instanceid . ' at ' . date('r', time()) . ' ----------');
     // If they haven't activated the cron, return
     if (!$this->get_config('syncuserscron')) {
         log_info('not set to sync users, so exiting');
         return true;
     }
     // Create a temp table to store the users, for better performance
     $temptable = new XMLDBTable('auth_ldap_extusers_temp');
     $temptable->addFieldInfo('extusername', XMLDB_TYPE_CHAR, 64, null, false);
     $temptable->addFieldInfo('firstname', XMLDB_TYPE_TEXT);
     $temptable->addFieldInfo('lastname', XMLDB_TYPE_TEXT);
     $temptable->addFieldInfo('email', XMLDB_TYPE_CHAR, 255);
     $temptable->addFieldInfo('studentid', XMLDB_TYPE_TEXT);
     $temptable->addFieldInfo('preferredname', XMLDB_TYPE_TEXT);
     $temptable->addKeyInfo('extusers', XMLDB_KEY_PRIMARY, array('extusername'));
     $tablecreated = create_temp_table($temptable, false, true);
     if (!$tablecreated) {
         log_warn('Could not create temp table auth_ldap_extusers_temp', false);
         return false;
     }
     $extrafilterattribute = $this->get_config('syncusersextrafilterattribute');
     $doupdate = $this->get_config('syncusersupdate');
     $docreate = $this->get_config('syncuserscreate');
     $tousersgonefromldap = $this->get_config('syncusersgonefromldap');
     $dodelete = false;
     $dosuspend = false;
     switch ($tousersgonefromldap) {
         case 'delete':
             $dodelete = true;
             break;
         case 'suspend':
             $dosuspend = true;
             break;
     }
     if (get_config('auth_ldap_debug_sync_cron')) {
         log_debug("config. LDAP : ");
         var_dump($this->config);
     }
     // fetch ldap users having the filter attribute on (caution maybe mutlivalued
     // do it on a scalable version by keeping the LDAP users names in a temporary table
     $nbldapusers = $this->ldap_get_users_scalable('auth_ldap_extusers_temp', 'extusername', $extrafilterattribute);
     log_info('LDAP users found : ' . $nbldapusers);
     try {
         $nbupdated = $nbcreated = $nbsuspended = $nbdeleted = $nbignored = $nbpresents = $nbunsuspended = $nberrors = 0;
         // Define ldap attributes in user update
         $ldapattributes = $this->get_ldap_user_fields();
         // Match database and ldap entries and update in database if required
         $fieldstoimport = array_keys($ldapattributes);
         // we fetch only Mahara users of this institution concerned by this authinstance (either cas or ldap)
         // and get also their suspended status since we may have to unsuspend them
         // this search cannot be done by a call to get_institutional_admin_search_results
         // that does not support searching by auth instance id and do not return suspended status
         // and is not suitable for a massive number of users
         if (!$doupdate) {
             log_info('user auto-update disabled');
         } else {
             // users to update (known both in LDAP and Mahara usr table)
             $sql = "\n                    select\n                        u.id as id,\n                        u.username as username,\n                        u.suspendedreason as suspendedreason,\n                        u.firstname as dbfirstname,\n                        u.lastname as dblastname,\n                        u.email as dbemail,\n                        u.studentid as dbstudentid,\n                        u.preferredname as dbpreferredname,\n                        e.firstname as ldapfirstname,\n                        e.lastname as ldaplastname,\n                        e.email as ldapemail,\n                        e.studentid as ldapstudentid,\n                        e.preferredname as ldappreferredname\n                    from\n                        {usr} u\n                        inner join {auth_ldap_extusers_temp} e\n                            on u.username = e.extusername\n                    where\n                        u.deleted = 0\n                        and u.authinstance = ?\n                    order by u.username\n                ";
             $rs = get_recordset_sql($sql, array($this->instanceid));
             log_info($rs->RecordCount() . ' users known to Mahara ');
             while ($record = $rs->FetchRow()) {
                 $nbpresents++;
                 $ldapusername = $record['username'];
                 $updated = false;
                 foreach ($fieldstoimport as $field) {
                     $ldapfield = "ldap{$field}";
                     $dbfield = "db{$field}";
                     $sanitizer = "sanitize_{$field}";
                     $record[$ldapfield] = $sanitizer($record[$ldapfield]);
                     if ($record[$ldapfield] != '' && $record[$dbfield] != $record[$ldapfield]) {
                         $updated = true;
                         if (!$dryrun) {
                             set_profile_field($record['id'], $field, $record[$ldapfield]);
                         }
                     }
                 }
                 if ($updated) {
                     log_debug('updating user ' . $ldapusername);
                 } else {
                     log_debug('no change for user ' . $ldapusername);
                 }
                 if (!$dryrun) {
                     if (!empty($record['ldapstudentid'])) {
                         // caution may be missing ?
                         set_field('usr_institution', 'studentid', $record['ldapstudentid'], 'usr', $record['id'], 'institution', $this->institution);
                     }
                 }
                 unset($ldapdetails);
                 $nbupdated++;
                 //unsuspend if was suspended by me at a previous run
                 if (!empty($record['suspendedreason']) && strstr($record['suspendedreason'], AUTH_LDAP_SUSPENDED_REASON) !== false) {
                     log_info('unsuspending user ' . $ldapusername);
                     if (!$dryrun) {
                         unsuspend_user($record['id']);
                     }
                     $nbunsuspended++;
                 }
             }
         }
         if (!$dosuspend && !$dodelete) {
             log_info('user auto-suspend/delete disabled');
         } else {
             //users to delete /suspend
             $sql = "\n                    SELECT u.id, u.username, u.suspendedreason\n                    FROM\n                        {usr} u\n                        LEFT JOIN {auth_ldap_extusers_temp} e\n                        ON e.extusername = u.username\n                    WHERE\n                        u.authinstance = ?\n                        AND u.deleted = 0\n                        AND e.extusername IS NULL\n                    ORDER BY u.username ASC";
             $rs = get_recordset_sql($sql, array($this->instanceid));
             log_info($rs->RecordCount() . ' users no longer in LDAP ');
             while ($record = $rs->FetchRow()) {
                 if ($dosuspend) {
                     if (!$record['suspendedreason']) {
                         //if not already suspended for any reason (me or some manual operation)
                         log_info('suspending user ' . $record['username']);
                         if (!$dryrun) {
                             suspend_user($record['id'], AUTH_LDAP_SUSPENDED_REASON . ' ' . time() . ' (' . format_date(time()) . ')');
                         }
                         $nbsuspended++;
                     } else {
                         log_debug('user ' . $record['username'] . ' already suspended by ' . $record['suspendedreason']);
                     }
                 } else {
                     if ($dodelete) {
                         log_info('deleting user ' . $record['username']);
                         if (!$dryrun) {
                             delete_user($record['id']);
                         }
                         $nbdeleted++;
                     } else {
                         // nothing to do
                         log_debug('ignoring user ' . $record['username']);
                         $nbignored++;
                     }
                 }
             }
         }
         if (!$docreate) {
             log_info('user auto-creation disabled');
         } else {
             // users to create
             $sql = '
                     SELECT
                         e.extusername,
                         e.firstname,
                         e.lastname,
                         e.email,
                         e.studentid,
                         e.preferredname
                     FROM
                         {auth_ldap_extusers_temp} e
                         LEFT JOIN {usr} u
                         ON e.extusername = u.username
                     WHERE u.id IS NULL
                     ORDER BY e.extusername';
             $rs = get_recordset_sql($sql);
             log_info($rs->RecordCount() . ' LDAP users unknown to Mahara  ');
             while ($record = $rs->FetchRow()) {
                 $ldapusername = $record['extusername'];
                 log_info('creating user ' . $ldapusername);
                 // Retrieve information of user from LDAP
                 $todb = new stdClass();
                 $todb->username = $ldapusername;
                 //not returned by LDAP
                 $todb->authinstance = $this->instanceid;
                 $todb->password = '';
                 foreach ($fieldstoimport as $field) {
                     $todb->{$field} = $record[$field];
                 }
                 if (get_config('auth_ldap_debug_sync_cron')) {
                     log_debug("creation de ");
                     var_dump($todb);
                 }
                 //check for used email
                 if (($d1 = get_record('usr', 'email', $todb->email)) || ($d2 = record_exists('artefact_internal_profile_email', 'email', $todb->email))) {
                     if (empty($d1)) {
                         $d1 = get_record('usr', 'id', $d2->owner);
                     }
                     if (get_config('auth_ldap_debug_sync_cron')) {
                         log_debug("collision email ");
                         var_dump($d1);
                     }
                     log_warn(get_string('emailalreadytaken', 'auth.internal') . ' ' . $d1->username . ' ' . $todb->email);
                     $nberrors++;
                 } else {
                     if (!$dryrun) {
                         create_user($todb, array(), $this->institution);
                     }
                     $nbcreated++;
                 }
                 unset($todb);
             }
         }
     } catch (Exception $e) {
         log_info("LDAP (users:{$nbpresents}) (updated:{$nbupdated}) (unsuspended:{$nbunsuspended}) (created:{$nbcreated}) (suspended:{$nbsuspended}) (deleted:{$nbdeleted}) (ignored:{$nbignored}) (errors:{$nberrors})");
         throw $e;
     }
     log_info("LDAP (users:{$nbpresents}) (updated:{$nbupdated}) (unsuspended:{$nbunsuspended}) (created:{$nbcreated}) (suspended:{$nbsuspended}) (deleted:{$nbdeleted}) (ignored:{$nbignored}) (errors:{$nberrors})");
     log_info('---------- ended at ' . date('r', time()) . ' ----------');
     return true;
 }
Пример #5
0
 /**
  * Given a user and their remote user record, attempt to populate some of
  * the user's profile fields and account settings from the remote data.
  *
  * This does not change the first name, last name or e-mail fields, as these are
  * dealt with differently depending on whether we are creating the user
  * record or updating it.
  *
  * This method attempts to set:
  *
  * * City
  * * Country
  * * Language
  * * Introduction
  * * WYSIWYG editor setting
  *
  * @param User $user
  * @param stdClass $remoteuser
  */
 private function import_user_settings($user, $remoteuser)
 {
     $imported = array();
     // City
     if (!empty($remoteuser->city)) {
         if (get_profile_field($user->id, 'town') != $remoteuser->city) {
             set_profile_field($user->id, 'town', $remoteuser->city);
         }
         $imported[] = 'town';
     }
     // Country
     if (!empty($remoteuser->country)) {
         $validcountries = array_keys(getoptions_country());
         $newcountry = strtolower($remoteuser->country);
         if (in_array($newcountry, $validcountries)) {
             set_profile_field($user->id, 'country', $newcountry);
         }
         $imported[] = 'country';
     }
     // Language
     if (!empty($remoteuser->lang)) {
         $validlanguages = array_keys(get_languages());
         $newlanguage = str_replace('_utf8', '', strtolower($remoteuser->lang)) . '.utf8';
         if (in_array($newlanguage, $validlanguages)) {
             set_account_preference($user->id, 'lang', $newlanguage);
             $user->set_account_preference('lang', $newlanguage);
         }
     }
     // Description
     if (isset($remoteuser->description)) {
         if (get_profile_field($user->id, 'introduction') != $remoteuser->description) {
             set_profile_field($user->id, 'introduction', $remoteuser->description);
         }
         $imported[] = 'introduction';
     }
     // HTML Editor setting
     if (isset($remoteuser->htmleditor)) {
         $htmleditor = $remoteuser->htmleditor ? 1 : 0;
         if ($htmleditor != get_account_preference($user->id, 'wysiwyg')) {
             set_account_preference($user->id, 'wysiwyg', $htmleditor);
             $user->set_account_preference('wysiwyg', $htmleditor);
         }
     }
     return $imported;
 }
Пример #6
0
function core_install_lastcoredata_defaults()
{
    global $USER;
    db_begin();
    $institution = new StdClass();
    $institution->name = 'mahara';
    $institution->displayname = 'No Institution';
    $institution->authplugin = 'internal';
    $institution->theme = 'default';
    $institution->priority = 0;
    insert_record('institution', $institution);
    $pages = site_content_pages();
    $now = db_format_timestamp(time());
    foreach ($pages as $name) {
        $page = new stdClass();
        $page->name = $name;
        $page->ctime = $now;
        $page->mtime = $now;
        $page->content = get_string($page->name . 'defaultcontent', 'install', get_string('staticpageconfigdefault', 'install'));
        $page->institution = 'mahara';
        insert_record('site_content', $page);
    }
    $auth_instance = new StdClass();
    $auth_instance->instancename = 'Internal';
    $auth_instance->priority = '1';
    $auth_instance->institution = 'mahara';
    $auth_instance->authname = 'internal';
    $auth_instance->id = insert_record('auth_instance', $auth_instance, 'id', true);
    // Insert the root user
    $user = new StdClass();
    $user->id = 0;
    $user->username = '******';
    $user->password = '******';
    $user->salt = '*';
    $user->firstname = 'System';
    $user->lastname = 'User';
    $user->email = '*****@*****.**';
    $user->quota = get_config_plugin('artefact', 'file', 'defaultquota');
    $user->authinstance = $auth_instance->id;
    if (is_mysql()) {
        // gratuitous mysql workaround
        $newid = insert_record('usr', $user, 'id', true);
        set_field('usr', 'id', 0, 'id', $newid);
        execute_sql('ALTER TABLE {usr} AUTO_INCREMENT=1');
    } else {
        insert_record('usr', $user);
    }
    // install the default layout options
    install_view_layout_defaults();
    require_once 'group.php';
    install_system_profile_view();
    install_system_dashboard_view();
    install_system_grouphomepage_view();
    require_once 'license.php';
    install_licenses_default();
    require_once 'skin.php';
    install_skins_default();
    // Insert the admin user
    $user = new StdClass();
    $user->username = '******';
    $user->salt = auth_get_random_salt();
    $user->password = crypt('mahara', '$2a$' . get_config('bcrypt_cost') . '$' . substr(md5(get_config('passwordsaltmain') . $user->salt), 0, 22));
    $user->password = substr($user->password, 0, 7) . substr($user->password, 7 + 22);
    $user->authinstance = $auth_instance->id;
    $user->passwordchange = 1;
    $user->admin = 1;
    $user->firstname = 'Admin';
    $user->lastname = 'User';
    $user->email = '*****@*****.**';
    $user->quota = get_config_plugin('artefact', 'file', 'defaultquota');
    $user->id = insert_record('usr', $user, 'id', true);
    set_profile_field($user->id, 'email', $user->email);
    set_profile_field($user->id, 'firstname', $user->firstname);
    set_profile_field($user->id, 'lastname', $user->lastname);
    handle_event('createuser', $user);
    activity_add_admin_defaults(array($user->id));
    db_commit();
    // if we're installing, set up the block categories here and then poll the plugins.
    // if we're upgrading this happens somewhere else.  This is because of dependency issues around
    // the order of installation stuff.
    install_blocktype_extras();
}
Пример #7
0
/**
 * Update user
 *
 * @param object $user stdclass for the usr table
 * @param object $profile profile field/values to set
 * @param string $remotename username on the remote site
 * @param array $accountprefs user account preferences to set
 * @param bool $forceupdateremote force delete of remotename before update attempted
 * @return array list of updated fields
 */
function update_user($user, $profile, $remotename = null, $accountprefs = array(), $forceupdateremote = false, $quickhash = false)
{
    require_once get_config('docroot') . 'auth/session.php';
    if (!empty($user->id)) {
        $oldrecord = get_record('usr', 'id', $user->id);
    } else {
        $oldrecord = get_record('usr', 'username', $user->username);
    }
    $userid = $oldrecord->id;
    db_begin();
    // Log the user out, otherwise they can overwrite all this on the next request
    remove_user_sessions($userid);
    $updated = array();
    $newrecord = new StdClass();
    foreach (get_object_vars($user) as $k => $v) {
        if (!empty($v) && ($k == 'password' || empty($oldrecord->{$k}) || $oldrecord->{$k} != $v)) {
            $newrecord->{$k} = $v;
            $updated[$k] = $v;
        }
        if (!empty($v) && $k === 'email' && $oldrecord->{$k} != $v) {
            set_user_primary_email($userid, $v);
        }
    }
    if (count(get_object_vars($newrecord))) {
        $newrecord->id = $userid;
        update_record('usr', $newrecord);
        if (!empty($newrecord->password)) {
            $newrecord->authinstance = $user->authinstance;
            reset_password($newrecord, false, $quickhash);
        }
    }
    foreach (get_object_vars($profile) as $k => $v) {
        if (get_profile_field($userid, $k) != $v) {
            set_profile_field($userid, $k, $v);
            $updated[$k] = $v;
        }
    }
    if ($remotename) {
        $oldremote = get_field('auth_remote_user', 'remoteusername', 'authinstance', $oldrecord->authinstance, 'localusr', $userid);
        if ($remotename != $oldremote) {
            $updated['remoteuser'] = $remotename;
        }
        delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'localusr', $userid);
        // force the update of the remoteuser - for the case of a series of user updates swapping the remoteuser name
        if ($forceupdateremote) {
            delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'remoteusername', $remotename);
        } else {
            // remote username must not already exist
            if (record_exists('auth_remote_user', 'remoteusername', $remotename, 'authinstance', $user->authinstance)) {
                throw new InvalidArgumentException("user_update: remoteusername already in use: " . $remotename);
            }
        }
        insert_record('auth_remote_user', (object) array('authinstance' => $user->authinstance, 'remoteusername' => $remotename, 'localusr' => $userid));
    }
    // Update account preferences
    if (!empty($accountprefs)) {
        $expectedprefs = expected_account_preferences();
        foreach ($expectedprefs as $eprefkey => $epref) {
            if (isset($accountprefs[$eprefkey]) && $accountprefs[$eprefkey] != get_account_preference($userid, $eprefkey)) {
                set_account_preference($userid, $eprefkey, $accountprefs[$eprefkey]);
                $updated[$eprefkey] = $accountprefs[$eprefkey];
            }
        }
    }
    db_commit();
    return $updated;
}
Пример #8
0
 /**
  * Grab a delegate object for auth stuff
  */
 public function request_user_authorise($attributes)
 {
     global $USER, $SESSION;
     $this->must_be_ready();
     if (empty($attributes) or !array_key_exists($this->config['user_attribute'], $attributes) or !array_key_exists($this->config['institutionattribute'], $attributes)) {
         throw new AccessDeniedException();
     }
     $remoteuser = $attributes[$this->config['user_attribute']][0];
     $firstname = isset($attributes[$this->config['firstnamefield']][0]) ? $attributes[$this->config['firstnamefield']][0] : null;
     $lastname = isset($attributes[$this->config['surnamefield']][0]) ? $attributes[$this->config['surnamefield']][0] : null;
     $email = isset($attributes[$this->config['emailfield']][0]) ? $attributes[$this->config['emailfield']][0] : null;
     $institutionname = $this->institution;
     $create = false;
     $update = false;
     // Retrieve a $user object. If that fails, create a blank one.
     try {
         $isremote = $this->config['remoteuser'] ? true : false;
         $user = new User();
         if (get_config('usersuniquebyusername')) {
             // When turned on, this setting means that it doesn't matter
             // which other application the user SSOs from, they will be
             // given the same account in Mahara.
             //
             // This setting is one that has security implications unless
             // only turned on by people who know what they're doing. In
             // particular, every system linked to Mahara should be making
             // sure that same username == same person.  This happens for
             // example if two Moodles are using the same LDAP server for
             // authentication.
             //
             // If this setting is on, it must NOT be possible to self
             // register on the site for ANY institution - otherwise users
             // could simply pick usernames of people's accounts they wished
             // to steal.
             if ($institutions = get_column('institution', 'name', 'registerallowed', '1')) {
                 log_warn("usersuniquebyusername is turned on but registration is allowed for an institution. " . "No institution can have registration allowed for it, for security reasons.\n" . "The following institutions have registration enabled:\n  " . join("\n  ", $institutions));
                 throw new AccessDeniedException();
             }
             if (!get_config('usersallowedmultipleinstitutions')) {
                 log_warn("usersuniquebyusername is turned on but usersallowedmultipleinstitutions is off. " . "This makes no sense, as users will then change institution every time they log in from " . "somewhere else. Please turn this setting on in Site Options");
                 throw new AccessDeniedException();
             }
         } else {
             if (!$isremote) {
                 log_warn("usersuniquebyusername is turned off but remoteuser has not been set on for this institution: {$institutionname}. " . "This is a security risk as users from different institutions with different IdPs can hijack " . "each others accounts.  Fix this in the institution level auth/saml settings.");
                 throw new AccessDeniedException();
             }
         }
         if ($isremote) {
             $user->find_by_instanceid_username($this->instanceid, $remoteuser, $isremote);
         } else {
             $user->find_by_username($remoteuser);
         }
         if ($user->get('suspendedcusr')) {
             die_info(get_string('accountsuspended', 'mahara', strftime(get_string('strftimedaydate'), $user->get('suspendedctime')), $user->get('suspendedreason')));
         }
         if ('1' == $this->config['updateuserinfoonlogin']) {
             $update = true;
         }
     } catch (AuthUnknownUserException $e) {
         if (!empty($this->config['weautocreateusers'])) {
             $institution = new Institution($this->institution);
             if ($institution->isFull()) {
                 $institution->send_admin_institution_is_full_message();
                 throw new XmlrpcClientException('SSO attempt from ' . $institution->displayname . ' failed - institution is full');
             }
             $user = new User();
             $create = true;
         } else {
             log_debug("User authorisation request from SAML failed - " . "remote user '{$remoteuser}' is unknown to us and auto creation of users is turned off");
             return false;
         }
     }
     /*******************************************/
     if ($create) {
         $user->passwordchange = 1;
         $user->active = 1;
         $user->deleted = 0;
         $user->expiry = null;
         $user->expirymailsent = 0;
         $user->lastlogin = time();
         $user->firstname = $firstname;
         $user->lastname = $lastname;
         $user->email = $email;
         // must have these values
         if (empty($firstname) || empty($lastname) || empty($email)) {
             throw new AccessDeniedException(get_string('errormissinguserattributes1', 'auth.saml', get_config('sitename')));
         }
         $user->authinstance = empty($this->config['parent']) ? $this->instanceid : $this->parent;
         db_begin();
         $user->username = get_new_username($remoteuser, 40);
         $user->id = create_user($user, array(), $institutionname, $this, $remoteuser);
         /*
          * We need to convert the object to a stdclass with its own
          * custom method because it uses overloaders in its implementation
          * and its properties wouldn't be visible to a simple cast operation
          * like (array)$user
          */
         $userobj = $user->to_stdclass();
         $userarray = (array) $userobj;
         db_commit();
         // Now we have fired the create event, we need to re-get the data
         // for this user
         $user = new User();
         $user->find_by_id($userobj->id);
         if (get_config('usersuniquebyusername')) {
             // Add them to the institution they have SSOed in by
             $user->join_institution($institutionname);
         }
     } elseif ($update) {
         if (!empty($firstname)) {
             set_profile_field($user->id, 'firstname', $firstname);
             $user->firstname = $firstname;
         }
         if (!empty($lastname)) {
             set_profile_field($user->id, 'lastname', $lastname);
             $user->lastname = $lastname;
         }
         if (!empty($email)) {
             set_profile_field($user->id, 'email', $email);
             $user->email = $email;
         }
         $user->lastlastlogin = $user->lastlogin;
         $user->lastlogin = time();
     }
     $user->commit();
     /*******************************************/
     // We know who our user is now. Bring em back to life.
     $result = $USER->reanimate($user->id, $this->instanceid);
     log_debug("remote user '{$remoteuser}' is now reanimated as '{$USER->username}' ");
     $SESSION->set('authinstance', $this->instanceid);
     return true;
 }
Пример #9
0
 /**
  * Attempt to authenticate user
  *
  * @param string $user The username to authenticate with
  * @param string $password The password being used for authentication
  * @return bool            True/False based on whether the user
  *                         authenticated successfully
  * @throws AuthUnknownUserException If the user does not exist
  */
 public function authenticate_user_account($user, $password)
 {
     $this->must_be_ready();
     $username = $user->username;
     // check ldap functionality exists
     if (!function_exists('ldap_bind')) {
         throw new AuthUnknownUserException('LDAP is not available in your PHP environment. Check that it is properly installed');
     }
     // empty username or password is not allowed.
     if (empty($username) or empty($password)) {
         return false;
     }
     // For update user info on login
     $update = false;
     if ('1' == $this->config['updateuserinfoonlogin']) {
         $update = true;
     }
     // Missed out AD bit, someone might want to put it back :-)
     // attempt ldap connection
     $ldapconnection = $this->ldap_connect();
     if ($ldapconnection) {
         $ldap_user_dn = $this->ldap_find_userdn($ldapconnection, $username);
         //if ldap_user_dn is empty, user does not exist
         if (!$ldap_user_dn) {
             ldap_close($ldapconnection);
             return false;
         }
         // Try to bind with current username and password
         $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, $password);
         ldap_close($ldapconnection);
         if ($ldap_login) {
             if ($update) {
                 // Define ldap attributes
                 $ldapattributes = array();
                 $ldapattributes['firstname'] = $this->config['firstnamefield'];
                 $ldapattributes['lastname'] = $this->config['surnamefield'];
                 $ldapattributes['email'] = $this->config['emailfield'];
                 // Retrieve information of user from LDAP
                 $ldapdetails = $this->get_userinfo_ldap($username, $ldapattributes);
                 // Match database and ldap entries and update in database if required
                 $fieldstoimport = array('firstname', 'lastname', 'email');
                 foreach ($fieldstoimport as $field) {
                     if ($user->{$field} != $ldapdetails[$field]) {
                         $user->{$field} = $ldapdetails[$field];
                         set_profile_field($user->id, $field, $user->{$field});
                     }
                 }
             }
             return true;
         }
     } else {
         @ldap_close($ldapconnection);
         // let's do some logging too
         log_warn("LDAP connection failed: " . $this->config['host_url'] . '/' . $this->config['contexts']);
         throw new AuthInstanceException(get_string('cannotconnect', 'auth.ldap'));
     }
     return false;
     // No match
 }
Пример #10
0
/**
 * Changes the password for a user, given that it is valid.
 *
 * @param array $values The submitted form values
 */
function change_password_submit(Pieform $form, $values)
{
    global $USER, $SESSION;
    $authobj = AuthFactory::create($USER->authinstance);
    // This method should exist, because if it did not then the change
    // password form would not have been shown.
    if ($password = $authobj->change_password($USER, $values['password1'])) {
        $SESSION->add_ok_msg(get_string('passwordsaved'));
        if (!empty($values['email'])) {
            $USER->email = $values['email'];
            $USER->commit();
            set_profile_field($USER->id, 'email', $values['email']);
        }
        redirect();
    }
    // TODO: Exception is the wrong type here!
    throw new Exception('Attempt by "' . $USER->get('username') . '@' . $USER->get('institution') . 'to change their password failed');
}
Пример #11
0
function requiredfields_submit(Pieform $form, $values)
{
    global $USER, $SESSION;
    if (isset($values['password1'])) {
        $authobj = AuthFactory::create($USER->authinstance);
        // This method should exist, because if it did not then the change
        // password form would not have been shown.
        if ($password = $authobj->change_password($USER, $values['password1'])) {
            $SESSION->add_ok_msg(get_string('passwordsaved'));
        } else {
            throw new SystemException('Attempt by "' . $USER->get('username') . '@' . $USER->get('institution') . 'to change their password failed');
        }
    }
    if (isset($values['username'])) {
        $SESSION->set('resetusername', false);
        if ($values['username'] != $USER->get('username')) {
            $USER->username = $values['username'];
            $USER->commit();
            $otherfield = true;
        }
    }
    foreach ($values as $field => $value) {
        if (in_array($field, array('submit', 'sesskey', 'password1', 'password2', 'username'))) {
            continue;
        }
        if ($field == 'email') {
            $USER->email = $values['email'];
            $USER->commit();
        }
        set_profile_field($USER->get('id'), $field, $value);
        $otherfield = true;
    }
    if (isset($otherfield)) {
        $SESSION->add_ok_msg(get_string('requiredfieldsset', 'auth'));
    }
    redirect();
}
Пример #12
0
 $nbpresents++;
 $ldapusername = $record['username'];
 if ($doupdate) {
     $cli->cli_print('updating user ' . $ldapusername);
     // Retrieve information of user from LDAP
     $ldapdetails = $instance->get_user_info($ldapusername, $ldapattributes);
     // this method returns an object and we want an array below
     $ldapdetails = (array) $ldapdetails;
     foreach ($fieldstoimport as $field) {
         if (isset($ldapdetails[$field])) {
             // some LDAP values missing ?
             $sanitizer = "sanitize_{$field}";
             $ldapdetails[$field] = $sanitizer($ldapdetails[$field]);
             if (!empty($ldapdetails[$field]) && $record[$field] != $ldapdetails[$field]) {
                 if (!$dryrun) {
                     set_profile_field($record['id'], $field, $ldapdetails[$field]);
                 }
             }
         } else {
             // signal the error
             $cli->cli_print('user ' . $ldapusername . ' has no LDAP value for ' . $field);
             $nberrors++;
         }
     }
     //we also must update the student id in table usr_institution
     //this call consumes ~1400 bytes that are not returned to pool ?
     if (!$dryrun) {
         if (isset($ldapdetails['studentid'])) {
             // caution may be missing ?
             set_field('usr_institution', 'studentid', $ldapdetails['studentid'], 'usr', $record['id'], 'institution', $institutionname);
         }