public function init() { /* Initialize action controller here */ parent::init(); $this->auth = AuthFactory::create(AuthFactory::$AGENT, $this->db, $this->_request); $this->chatRequestModel = new Chat_Request($this->db); $this->chatSessionModel = new Chat_Session($this->db); $this->appChatRequestModel = new App_ChatRequest(); $this->leadModel = new App_Lead(); $this->agentModel = new App_Agent(); }
public function init() { parent::init(); $this->auth = AuthFactory::create(AuthFactory::$OWNER, $this->db, $this->_request); $this->model = new Owner_Owner($this->db); $this->model->setRequestObject($this->_request); $this->ownerModel = new App_Owner(); $this->timezoneModel = new App_Timezone(); $this->timezoneGroupModel = new App_TimezoneGroup(); $this->businessTypeModel = new App_BusinessType(); $this->numberOfHitModel = new App_NumberOfHit(); $this->leadModel = new App_Lead(); $this->memberModel = new App_Member(); $this->baseUrlDashboard = $this->baseUrl . "/js/leadschat-dashboard"; }
function adduser_validate(Pieform $form, $values) { global $USER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $SESSION->add_error_msg(get_string('institutionmaxusersexceeded', 'admin')); redirect('/admin/users/add.php'); } $username = $values['username']; $firstname = $values['firstname']; $lastname = $values['lastname']; $email = $values['email']; $password = $values['password']; if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('username', get_string('addusererrorinvalidusername', 'admin')); return; } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', strtolower($username))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); return; } if (!$form->get_error('firstname') && !preg_match('/\\S/', $firstname)) { $form->set_error('firstname', $form->i18n('required')); } if (!$form->get_error('lastname') && !preg_match('/\\S/', $lastname)) { $form->set_error('lastname', $form->i18n('required')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); return; } }
/** * Installs a site using $CFG->dataroot and $CFG->dbprefix * As we are setting up the behat test environment, these settings * are replaced by $CFG->behat_dataroot and $CFG->behat_dbprefix * * @throws SystemException * @return void */ public static function install_site() { if (!defined('BEHAT_UTIL')) { throw new SystemException('This method can be only used by Behat CLI tool'); } if (table_exists(new XMLDBTable('config'))) { behat_error(BEHAT_EXITCODE_INSTALLED); } // New dataroot. self::reset_dataroot(); // Determine what we will install $upgrades = check_upgrades(); $upgrades['firstcoredata'] = true; $upgrades['localpreinst'] = true; $upgrades['lastcoredata'] = true; $upgrades['localpostinst'] = true; upgrade_mahara($upgrades); $userobj = new User(); $userobj = $userobj->find_by_username('admin'); $userobj->email = self::$sitedefaultinfo['admin']['email']; $userobj->commit(); // Password changes should be performed by the authfactory $authobj = AuthFactory::create($userobj->authinstance); $authobj->change_password($userobj, self::$sitedefaultinfo['admin']['password'], true); // Set site name set_config('sitename', self::$sitedefaultinfo['sitename']); // We need to keep the installed dataroot artefact files. // So each time we reset the dataroot before running a test, the default files are still installed. self::save_original_data_files(); // Disable some settings that are not wanted on test sites. set_config('sendemail', false); // Keeps the current version of database and dataroot. self::store_versions_hash(); // Stores the database contents for fast reset. self::store_database_state(); }
function auth_register_submit(Pieform $form, $values) { global $SESSION; safe_require('auth', 'internal'); $values['key'] = get_random_key(); $values['lang'] = $SESSION->get('lang'); // If the institution requires approval, mark the record as pending // @todo the expiry date should be configurable if ($confirm = get_config('requireregistrationconfirm') || get_field('institution', 'registerconfirm', 'name', $values['institution'])) { if (isset($values['authtype']) && $values['authtype'] != 'internal') { $authinstance = get_record('auth_instance', 'institution', $values['institution'], 'authname', $values['authtype'] ? $values['authtype'] : 'internal'); $auth = AuthFactory::create($authinstance->id); $confirm = !$auth->weautocreateusers; } if ($confirm) { $values['pending'] = 1; $values['expiry'] = db_format_timestamp(time() + 86400 * 14); // now + 2 weeks } else { $values['pending'] = 0; $values['expiry'] = db_format_timestamp(time() + 86400); } } else { $values['pending'] = 0; $values['expiry'] = db_format_timestamp(time() + 86400); } if (function_exists('local_register_submit')) { local_register_submit($values); } try { if (!record_exists('usr_registration', 'email', $values['email'])) { insert_record('usr_registration', $values); } else { update_record('usr_registration', $values, array('email' => $values['email'])); } $user = (object) $values; $user->admin = 0; $user->staff = 0; // If the institution requires approval, notify institutional admins. if ($confirm) { $fullname = sprintf("%s %s", trim($user->firstname), trim($user->lastname)); $institution = new Institution($values['institution']); $pendingregistrationslink = sprintf("%sadmin/users/pendingregistrations.php?institution=%s", get_config('wwwroot'), $values['institution']); // list of admins for this institution if (count($institution->admins()) > 0) { $admins = $institution->admins(); } else { // use site admins if the institution doesn't have any $admins = get_column('usr', 'id', 'admin', 1, 'deleted', 0); } require_once get_config('libroot') . 'pieforms/pieform/elements/expiry.php'; $expirytime = pieform_element_expiry_get_expiry_from_seconds(get_config('defaultregistrationexpirylifetime')); if ($expirytime == null) { $expirystring = get_config('defaultregistrationexpirylifetime') . ' ' . get_string('seconds', 'performance'); } else { if ($expirytime['units'] == 'noenddate') { $expirystring = get_string('element.expiry.noenddate', 'pieforms'); } else { $expirystring = $expirytime['number'] . ' ' . get_string('element.expiry.' . $expirytime['units'], 'pieforms'); } } // email each admin // @TODO Respect the notification preferences of the admins. foreach ($admins as $admin) { $adminuser = new User(); $adminuser->find_by_id($admin); email_user($adminuser, null, get_string('pendingregistrationadminemailsubject', 'auth.internal', $institution->displayname, get_config('sitename')), get_string('pendingregistrationadminemailtext', 'auth.internal', $adminuser->firstname, $institution->displayname, $pendingregistrationslink, $expirystring, $fullname, $values['email'], $values['reason'], get_config('sitename')), get_string('pendingregistrationadminemailhtml', 'auth.internal', $adminuser->firstname, $institution->displayname, $pendingregistrationslink, $pendingregistrationslink, $expirystring, $fullname, $values['email'], $values['reason'], get_config('sitename'))); } email_user($user, null, get_string('approvalemailsubject', 'auth.internal', get_config('sitename')), get_string('approvalemailmessagetext', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('sitename')), get_string('approvalemailmessagehtml', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('sitename'))); $_SESSION['registeredokawaiting'] = true; } else { if (isset($values['authtype']) && $values['authtype'] == 'browserid') { redirect('/register.php?key=' . $values['key']); } else { email_user($user, null, get_string('registeredemailsubject', 'auth.internal', get_config('sitename')), get_string('registeredemailmessagetext', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('wwwroot'), $values['key'], get_config('sitename')), get_string('registeredemailmessagehtml', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('wwwroot'), $values['key'], get_config('wwwroot'), $values['key'], get_config('sitename'))); } // Add a marker in the session to say that the user has registered $_SESSION['registered'] = true; } } catch (EmailException $e) { log_warn($e); die_info(get_string('registrationunsuccessful', 'auth.internal')); } catch (SQLException $e) { log_warn($e); die_info(get_string('registrationunsuccessful', 'auth.internal')); } redirect($values['goto']); }
function adduser_validate(Pieform $form, $values) { global $USER, $TRANSPORTER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $institution->send_admin_institution_is_full_message(); $form->set_error('authinstance', get_string('institutionmaxusersexceeded', 'admin')); return; } $username = $values['username']; $firstname = sanitize_firstname($values['firstname']); $lastname = sanitize_lastname($values['lastname']); $email = sanitize_email($values['email']); $password = $values['password']; if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $maxquotaenabled = get_config_plugin('artefact', 'file', 'maxquotaenabled'); $maxquota = get_config_plugin('artefact', 'file', 'maxquota'); if ($maxquotaenabled && $values['quota'] > $maxquota) { $form->set_error('quota', get_string('maxquotaexceededform', 'artefact.file', display_size($maxquota))); } } if (method_exists($authobj, 'is_username_valid_admin')) { if (!$authobj->is_username_valid_admin($username)) { $form->set_error('username', get_string('usernameinvalidadminform', 'auth.internal')); } } else { if (method_exists($authobj, 'is_username_valid')) { if (!$authobj->is_username_valid($username)) { $form->set_error('username', get_string('usernameinvalidform', 'auth.internal')); } } } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', array(strtolower($username)))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); } if (isset($_POST['createmethod']) && $_POST['createmethod'] == 'leap2a') { $form->set_error('firstname', null); $form->set_error('lastname', null); $form->set_error('email', null); if (!$values['leap2afile'] && ($_FILES['leap2afile']['error'] == UPLOAD_ERR_INI_SIZE || $_FILES['leap2afile']['error'] == UPLOAD_ERR_FORM_SIZE)) { $form->reply(PIEFORM_ERR, array('message' => get_string('uploadedfiletoobig'), 'goto' => '/admin/users/add.php')); $form->set_error('leap2afile', get_string('uploadedfiletoobig')); return; } else { if (!$values['leap2afile']) { $form->set_error('leap2afile', $form->i18n('rule', 'required', 'required')); return; } } if ($values['leap2afile']['type'] == 'application/octet-stream') { require_once 'file.php'; $mimetype = file_mime_type($values['leap2afile']['tmp_name']); } else { $mimetype = trim($values['leap2afile']['type'], '"'); } $date = time(); $niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $values['username']); safe_require('import', 'leap'); $fakeimportrecord = (object) array('data' => array('importfile' => $values['leap2afile']['tmp_name'], 'importfilename' => $values['leap2afile']['name'], 'importid' => $niceuser . '-' . $date, 'mimetype' => $mimetype)); $TRANSPORTER = new LocalImporterTransport($fakeimportrecord); try { $TRANSPORTER->extract_file(); PluginImportLeap::validate_transported_data($TRANSPORTER); } catch (Exception $e) { $form->set_error('leap2afile', $e->getMessage()); } } else { if (!$form->get_error('firstname') && empty($firstname)) { $form->set_error('firstname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('lastname') && empty($lastname)) { $form->set_error('lastname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('email')) { if (!$form->get_error('email') && empty($email)) { $form->set_error('email', get_string('invalidemailaddress', 'artefact.internal')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } } } }
function edituser_site_submit(Pieform $form, $values) { global $USER, $authobj, $SESSION; if (!($user = get_record('usr', 'id', $values['id']))) { return false; } if (is_using_probation()) { // Value should be between 0 and 10 inclusive $user->probation = ensure_valid_probation_points($values['probationpoints']); } if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $user->quota = $values['quota']; // check if the user has gone over the quota notify limit $quotanotifylimit = get_config_plugin('artefact', 'file', 'quotanotifylimit'); if ($quotanotifylimit <= 0 || $quotanotifylimit >= 100) { $quotanotifylimit = 100; } $user->quotausedpercent = $user->quotaused / $user->quota * 100; $overlimit = false; if ($quotanotifylimit <= $user->quotausedpercent) { $overlimit = true; } $notified = get_field('usr_account_preference', 'value', 'field', 'quota_exceeded_notified', 'usr', $user->id); if ($overlimit && '1' !== $notified) { require_once get_config('docroot') . 'artefact/file/lib.php'; ArtefactTypeFile::notify_users_threshold_exceeded(array($user), false); // no need to email admin as we can alert them right now $SESSION->add_error_msg(get_string('useroverquotathreshold', 'artefact.file', display_name($user))); } else { if ($notified && !$overlimit) { set_account_preference($user->id, 'quota_exceeded_notified', false); } } } $unexpire = $user->expiry && strtotime($user->expiry) < time() && (empty($values['expiry']) || $values['expiry'] > time()); $newexpiry = db_format_timestamp($values['expiry']); if ($user->expiry != $newexpiry) { $user->expiry = $newexpiry; if ($unexpire) { $user->expirymailsent = 0; $user->lastaccess = db_format_timestamp(time()); } } // Try to kick the user from any active login sessions, before saving data. require_once get_config('docroot') . 'auth/session.php'; remove_user_sessions($user->id); if ($USER->get('admin')) { // Not editable by institutional admins $user->staff = (int) ($values['staff'] == 'on'); $user->admin = (int) ($values['admin'] == 'on'); if ($user->admin) { activity_add_admin_defaults(array($user->id)); } } if ($values['maildisabled'] == 0 && get_account_preference($user->id, 'maildisabled') == 1) { // Reset the sent and bounce counts otherwise mail will be disabled // on the next send attempt $u = new StdClass(); $u->email = $user->email; $u->id = $user->id; update_bounce_count($u, true); update_send_count($u, true); } set_account_preference($user->id, 'maildisabled', $values['maildisabled']); // process the change of the authinstance and or the remoteuser if (isset($values['authinstance']) && isset($values['remoteusername'])) { // Authinstance can be changed by institutional admins if both the // old and new authinstances belong to the admin's institutions $authinst = get_records_select_assoc('auth_instance', 'id = ? OR id = ?', array($values['authinstance'], $user->authinstance)); // But don't bother if the auth instance doesn't take a remote username $authobj = AuthFactory::create($values['authinstance']); if ($USER->get('admin') || $USER->is_institutional_admin($authinst[$values['authinstance']]->institution) && ($USER->is_institutional_admin($authinst[$user->authinstance]->institution) || $user->authinstance == 1)) { if ($authobj->needs_remote_username()) { // determine the current remoteuser $current_remotename = get_field('auth_remote_user', 'remoteusername', 'authinstance', $user->authinstance, 'localusr', $user->id); if (!$current_remotename) { $current_remotename = $user->username; } // if the remoteuser is empty if (strlen(trim($values['remoteusername'])) == 0) { delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'localusr', $user->id); } // what should the new remoteuser be $new_remoteuser = get_field('auth_remote_user', 'remoteusername', 'authinstance', $values['authinstance'], 'localusr', $user->id); // save the remotename for the target existence check $target_remotename = $new_remoteuser; if (!$new_remoteuser) { $new_remoteuser = $user->username; } if (strlen(trim($values['remoteusername'])) > 0) { // value changed on page - use it if ($values['remoteusername'] != $current_remotename) { $new_remoteuser = $values['remoteusername']; } } // only update remote name if the input actually changed on the page or it doesn't yet exist if ($current_remotename != $new_remoteuser || !$target_remotename) { // only remove the ones related to this traget authinstance as we now allow multiple // for dual login mechanisms delete_records('auth_remote_user', 'authinstance', $values['authinstance'], 'localusr', $user->id); insert_record('auth_remote_user', (object) array('authinstance' => $values['authinstance'], 'remoteusername' => $new_remoteuser, 'localusr' => $user->id)); } } // update the ai on the user master $user->authinstance = $values['authinstance']; // update the global $authobj to match the new authinstance // this is used by the password/username change methods // if either/both has been requested at the same time $authobj = AuthFactory::create($user->authinstance); } } // Only change the pw if the new auth instance allows for it if (method_exists($authobj, 'change_password')) { $user->passwordchange = (int) (isset($values['passwordchange']) && $values['passwordchange'] == 'on' ? 1 : 0); if (isset($values['password']) && $values['password'] !== '') { $userobj = new User(); $userobj = $userobj->find_by_id($user->id); $user->password = $authobj->change_password($userobj, $values['password']); $user->salt = $userobj->salt; unset($userobj); } } else { // inform the user that the chosen auth instance doesn't allow password changes // but only if they tried changing it if (isset($values['password']) && $values['password'] !== '') { $SESSION->add_error_msg(get_string('passwordchangenotallowed', 'admin')); // Set empty pw with salt $user->password = ''; $user->salt = auth_get_random_salt(); } } if (isset($values['username']) && $values['username'] !== '') { $userobj = new User(); $userobj = $userobj->find_by_id($user->id); if ($userobj->username != $values['username']) { // Only change the username if the auth instance allows for it if (method_exists($authobj, 'change_username')) { // check the existence of the chosen username try { if ($authobj->user_exists($values['username'])) { // set an error message if it is already in use $SESSION->add_error_msg(get_string('usernameexists', 'account')); } } catch (AuthUnknownUserException $e) { // update the username otherwise $user->username = $authobj->change_username($userobj, $values['username']); } } else { // inform the user that the chosen auth instance doesn't allow username changes $SESSION->add_error_msg(get_string('usernamechangenotallowed', 'admin')); } } unset($userobj); } // OVERWRITE 4: insert if (isset($values['email']) && !empty($values['email']) && $values['email'] != $user->email) { global $CFG; $user->email = $values['email']; $mhr_user = $CFG->current_app->getUserById($user->id); $mhr_user->setEmailAddress($values['email']); } // END OVERWRITE 4 db_begin(); update_record('usr', $user); delete_records('usr_tag', 'usr', $user->id); if (is_array($values['tags'])) { $values['tags'] = check_case_sensitive($values['tags'], 'usr_tag'); foreach (array_unique($values['tags']) as $tag) { if (empty($tag)) { continue; } insert_record('usr_tag', (object) array('usr' => $user->id, 'tag' => strtolower($tag))); } } db_commit(); $SESSION->add_ok_msg(get_string('usersitesettingschanged', 'admin')); redirect('/admin/users/edit.php?id=' . $user->id); }
function create_registered_user($profilefields = array()) { global $registration, $SESSION, $USER; require_once get_config('libroot') . 'user.php'; db_begin(); // Move the user record to the usr table from the registration table $registrationid = $registration->id; unset($registration->id); unset($registration->expiry); if ($expirytime = get_config('defaultregistrationexpirylifetime')) { $registration->expiry = db_format_timestamp(time() + $expirytime); } $registration->lastlogin = db_format_timestamp(time()); $authinstance = get_record('auth_instance', 'institution', $registration->institution, 'authname', $registration->authtype ? $registration->authtype : 'internal'); if (false == $authinstance) { throw new ConfigException('No ' . ($registration->authtype ? $registration->authtype : 'internal') . ' auth instance for institution'); } if (!empty($registration->extra)) { // Additional user settings were added during confirmation $extrafields = unserialize($registration->extra); } $user = new User(); $user->active = 1; $user->authinstance = $authinstance->id; $user->firstname = $registration->firstname; $user->lastname = $registration->lastname; $user->email = $registration->email; $user->username = get_new_username($user->firstname . $user->lastname); $user->passwordchange = 1; // Points that indicate the user is a "new user" who should be restricted from spammy activities. // We count these down when they do good things; when they have 0 they're no longer a "new user" if (is_using_probation()) { $user->probation = get_config('probationstartingpoints'); } else { $user->probation = 0; } if ($registration->institution != 'mahara') { if (count_records_select('institution', "name != 'mahara'") == 1 || $registration->pending == 2) { if (get_config_plugin('artefact', 'file', 'institutionaloverride')) { $user->quota = get_field('institution', 'defaultquota', 'name', $registration->institution); } } } create_user($user, $profilefields); // If the institution is 'mahara' then don't do anything if ($registration->institution != 'mahara') { $institutions = get_records_select_array('institution', "name != 'mahara'"); // If there is only one available, join it without requiring approval if (count($institutions) == 1) { $user->join_institution($registration->institution); } else { if ($registration->pending == 2) { if (get_config('requireregistrationconfirm') || get_field('institution', 'registerconfirm', 'name', $registration->institution)) { $user->join_institution($registration->institution); } } else { if ($registration->authtype && $registration->authtype != 'internal') { $auth = AuthFactory::create($authinstance->id); if ($auth->weautocreateusers) { $user->join_institution($registration->institution); } else { $user->add_institution_request($registration->institution); } } else { $user->add_institution_request($registration->institution); } } } if (!empty($extrafields->institutionstaff)) { // If the user isn't a member yet, this does nothing, but that's okay, it'll // only be set after successful confirmation. set_field('usr_institution', 'staff', 1, 'usr', $user->id, 'institution', $registration->institution); } } if (!empty($registration->lang) && $registration->lang != 'default') { set_account_preference($user->id, 'lang', $registration->lang); } // Delete the old registration record delete_records('usr_registration', 'id', $registrationid); db_commit(); // Log the user in and send them to the homepage $USER = new LiveUser(); $USER->reanimate($user->id, $authinstance->id); if (function_exists('local_post_register')) { local_post_register($registration); } $SESSION->add_ok_msg(get_string('registrationcomplete', 'mahara', get_config('sitename'))); $SESSION->set('resetusername', true); redirect(); }
$settings->options = $options; $settings->info = get_string('cliinstallerdescription', 'admin'); $cli->setup($settings); // Check whether we need to do anything if (table_exists(new XMLDBTable('config'))) { cli::cli_exit(get_string('maharainstalled', 'admin'), false); } // Check initial password and e-mail address before we install try { $adminpassword = $cli->get_cli_param('adminpassword'); $adminemail = $cli->get_cli_param('adminemail'); } catch (ParameterException $e) { cli::cli_exit($e->getMessage(), true); } // Determine what we will install $upgrades = check_upgrades(); $upgrades['firstcoredata'] = true; $upgrades['localpreinst'] = true; $upgrades['lastcoredata'] = true; $upgrades['localpostinst'] = true; // Actually perform the installation log_info(get_string('cliinstallingmahara', 'admin')); upgrade_mahara($upgrades); // Set initial password and e-mail address $userobj = new User(); $userobj = $userobj->find_by_username('admin'); $userobj->email = $adminemail; $userobj->commit(); // Password changes should be performed by the authfactory $authobj = AuthFactory::create($userobj->authinstance); $authobj->change_password($userobj, $adminpassword, true);
/** * Gets data about users who have been online in the last while. * * The time is configured by setting the 'accessidletimeout' configuration * option. * * Limits the number of users to display based on the 'onlineuserssideblockmaxusers' * site configuration option and the Institution specific 'showonlineusers' setting. * If the user belongs to no institution (other than the standard 'mahara' one) then * the decision will be to show ALL users by default. * */ function onlineusers_sideblock() { global $USER; // Determine what level of users to show // 0 = none, 1 = institution/s only, 2 = all users $showusers = 2; $institutions = $USER->institutions; if (!empty($institutions)) { $showusers = 0; foreach ($institutions as $i) { if ($i->showonlineusers == 2) { $showusers = 2; break; } if ($i->showonlineusers == 1) { $showusers = 1; } } } $maxonlineusers = get_config('onlineuserssideblockmaxusers'); switch ($showusers) { case 0: // show none return array('users' => array(), 'count' => 0, 'lastminutes' => floor(get_config('accessidletimeout') / 60)); case 1: // show institution only $sql = 'SELECT DISTINCT u.* FROM {usr} u JOIN {usr_institution} i ON u.id = i.usr WHERE i.institution IN (' . join(',', array_map('db_quote', array_keys($institutions))) . ') AND lastaccess > ? AND deleted = 0 ORDER BY lastaccess DESC'; break; case 2: // show all $sql = 'SELECT * FROM {usr} WHERE lastaccess > ? AND deleted = 0 ORDER BY lastaccess DESC'; break; } $onlineusers = get_records_sql_array($sql, array(db_format_timestamp(time() - get_config('accessidletimeout'))), 0, $maxonlineusers); if ($onlineusers) { foreach ($onlineusers as &$user) { $user->profileiconurl = profile_icon_url($user, 20, 20); // If the user is an MNET user, show where they've come from $authobj = AuthFactory::create($user->authinstance); if ($authobj->authname == 'xmlrpc') { $peer = get_peer($authobj->wwwroot); $user->loggedinfrom = $peer->name; } } } else { $onlineusers = array(); } return array('users' => $onlineusers, 'count' => count($onlineusers), 'lastminutes' => floor(get_config('accessidletimeout') / 60)); }
/** * Given a form, an array of values with 'password1' and 'password2' * indices and a user, validate that the user can change their password to * the one in $values. * * This provides one place where validation of passwords can be done. This is * used by: * - registration * - user forgot password * - user changing password on their account page * - user forced to change their password by the <kbd>passwordchange</kbd> * flag on the <kbd>usr</kbd> table. * * The password is checked for: * - Being in valid form according to the rules of the authentication method * for the user * - Not being an easy password (a blacklist of strings, NOT a length check or * similar), including being the user's username * - Both values being equal * * @param Pieform $form The form to validate * @param array $values The values passed through * @param string $authplugin The authentication plugin that the user uses */ function password_validate(Pieform $form, $values, $user) { $authobj = AuthFactory::create($user->authinstance); if (!$form->get_error('password1') && !$authobj->is_password_valid($values['password1'])) { $form->set_error('password1', get_string('passwordinvalidform', "auth.{$authobj->type}")); } $suckypasswords = array('mahara', 'password', $user->username, 'abc123'); if (!$form->get_error('password1') && in_array($values['password1'], $suckypasswords)) { $form->set_error('password1', get_string('passwordtooeasy')); } if (!$form->get_error('password1') && $values['password1'] != $values['password2']) { $form->set_error('password2', get_string('passwordsdonotmatch')); } }
/** * Gets data about users who have been online in the last while. * * The time is configured by setting the 'accessidletimeout' configuration * option. * * NOTE: currently returns all online users, this might not be desirable on a * really busy site. */ function onlineusers_sideblock() { global $USER; $onlineusers = get_records_select_array('usr', 'deleted = 0 AND lastaccess > ?', array(db_format_timestamp(time() - get_config('accessidletimeout'))), 'lastaccess DESC'); if ($onlineusers) { foreach ($onlineusers as &$user) { // Use 'profileiconbyid' for the current user, just in case they change their profile icon if ($user->id == $USER->get('id')) { $user->profileiconurl = get_config('wwwroot') . 'thumb.php?type=profileiconbyid&id=' . (int) $user->profileicon . '&size=20x20'; } else { $user->profileiconurl = get_config('wwwroot') . 'thumb.php?type=profileicon&id=' . $user->id . '&size=20x20'; } // If the user is an MNET user, show where they've come from $authobj = AuthFactory::create($user->authinstance); if ($authobj->authname == 'xmlrpc') { $peer = get_peer($authobj->wwwroot); $user->loggedinfrom = $peer->name; } } } else { $onlineusers = array(); } return array('users' => $onlineusers, 'count' => count($onlineusers), 'lastminutes' => floor(get_config('accessidletimeout') / 60)); }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } require_once 'pear/File.php'; require_once 'pear/File/CSV.php'; // Don't be tempted to use 'explode' here. There may be > 1 underscore. $break = strpos($values['authinstance'], '_'); $authinstance = substr($values['authinstance'], 0, $break); $institution = substr($values['authinstance'], $break + 1); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $usernames = array(); $emails = array(); $conf = File_CSV::discoverFormat($values['file']['tmp_name']); $i = 0; while ($line = File_CSV::readQuoted($values['file']['tmp_name'], $conf)) { $i++; if (!is_array($line)) { // Note: the CSV parser returns true on some errors and false on // others! Yes that's retarded. No I didn't write it :( $form->set_error('file', get_string('uploadcsverrorincorrectnumberoffields', 'admin', $i)); return; } // Get the format of the file if ($i == 1) { foreach ($line as &$potentialkey) { $potentialkey = trim($potentialkey); if (!in_array($potentialkey, $ALLOWEDKEYS)) { $form->set_error('file', get_string('uploadcsverrorinvalidfieldname', 'admin', $potentialkey)); return; } } // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'password'); $mandatoryfields = array_merge($mandatoryfields, array_keys(ArtefactTypeProfile::get_mandatory_fields())); if ($lockedprofilefields = get_column('institution_locked_profile_field', 'profilefield', 'name', $institution)) { $mandatoryfields = array_merge($mandatoryfields, $lockedprofilefields); } // Add in the locked profile fields for this institution foreach ($mandatoryfields as $field) { if (!in_array($field, $line)) { $form->set_error('file', get_string('uploadcsverrorrequiredfieldnotspecified', 'admin', $field)); return; } } // The format line is valid $FORMAT = $line; log_info('FORMAT:'); log_info($FORMAT); } else { // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $formatkeylookup = array_flip($FORMAT); $username = $line[$formatkeylookup['username']]; $password = $line[$formatkeylookup['password']]; $email = $line[$formatkeylookup['email']]; $authobj = AuthFactory::create($authinstance); if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('file', get_string('uploadcsverrorinvalidusername', 'admin', $i)); return; } if (record_exists_select('usr', 'LOWER(username) = ?', strtolower($username)) || isset($usernames[strtolower($username)])) { $form->set_error('file', get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username)); return; } if (record_exists('usr', 'email', $email) || isset($emails[$email])) { $form->set_error('file', get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email)); } // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('file', get_string('uploadcsverrorinvalidpassword', 'admin', $i)); return; } $usernames[strtolower($username)] = 1; $emails[$email] = 1; // All OK! $CSVDATA[] = $line; } } if ($i == 1) { // There was only the title row :( $form->set_error('file', get_string('uploadcsverrornorecords', 'admin')); return; } if ($CSVDATA === null) { // Oops! Couldn't get CSV data for some reason $form->set_error('file', get_string('uploadcsverrorunspecifiedproblem', 'admin')); } }
function adduser_validate(Pieform $form, $values) { global $USER, $TRANSPORTER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $form->set_error('authinstance', get_string('institutionmaxusersexceeded', 'admin')); return; } $username = $values['username']; $firstname = $values['firstname']; $lastname = $values['lastname']; $email = $values['email']; $password = $values['password']; if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('username', get_string('usernameinvalidform', 'auth.internal')); } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', strtolower($username))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); } if (isset($_POST['createmethod']) && $_POST['createmethod'] == 'leap2a') { $form->set_error('firstname', null); $form->set_error('lastname', null); $form->set_error('email', null); if (!$values['leap2afile']) { $form->set_error('leap2afile', $form->i18n('rule', 'required', 'required')); return; } if ($values['leap2afile']['type'] == 'application/octet-stream') { require_once 'file.php'; $mimetype = file_mime_type($values['leap2afile']['tmp_name']); } else { $mimetype = $values['leap2afile']['type']; } $date = time(); $niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $values['username']); safe_require('import', 'leap'); $fakeimportrecord = (object) array('data' => array('importfile' => $values['leap2afile']['tmp_name'], 'importfilename' => $values['leap2afile']['name'], 'importid' => $niceuser . '-' . $date, 'mimetype' => $mimetype)); $TRANSPORTER = new LocalImporterTransport($fakeimportrecord); try { $TRANSPORTER->extract_file(); PluginImportLeap::validate_transported_data($TRANSPORTER); } catch (Exception $e) { $form->set_error('leap2afile', $e->getMessage()); } } else { if (!$form->get_error('firstname') && !preg_match('/\\S/', $firstname)) { $form->set_error('firstname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('lastname') && !preg_match('/\\S/', $lastname)) { $form->set_error('lastname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('email')) { require_once 'phpmailer/class.phpmailer.php'; if (!$form->get_error('email') && !PHPMailer::ValidateAddress($email)) { $form->set_error('email', get_string('invalidemailaddress', 'artefact.internal')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } } } }
/** * Get user records for online users page * * @param integer $limit * @param integer $offset * * @returns array Total number of users, along with $limit or fewer user records. */ function get_onlineusers($limit = 10, $offset = 0, $orderby = 'firstname,lastname') { global $USER; // Determine what level of users to show // 0 = none, 1 = institution/s only, 2 = all users $showusers = 2; $institutions = $USER->institutions; if (!empty($institutions)) { $showusers = 0; foreach ($institutions as $i) { if ($i->showonlineusers == 2) { $showusers = 2; break; } if ($i->showonlineusers == 1) { $showusers = 1; } } } $result = array('count' => 0, 'limit' => $limit, 'offset' => $offset, 'data' => false); switch ($showusers) { case 0: // show none return $result; case 1: // show institution only $sql = "SELECT DISTINCT u.* FROM {usr} u JOIN {usr_institution} i ON id = i.usr\n WHERE deleted = 0 AND lastaccess > ? AND i.institution IN (" . join(',', array_map('db_quote', array_keys($institutions))) . ")\n ORDER BY {$orderby}"; $countsql = 'SELECT count(DISTINCT id) FROM {usr} JOIN {usr_institution} i ON id = i.usr WHERE deleted = 0 AND lastaccess > ? AND i.institution IN (' . join(',', array_map('db_quote', array_keys($institutions))) . ')'; break; case 2: // show all $sql = "SELECT * FROM {usr} WHERE deleted = 0 AND lastaccess > ? ORDER BY {$orderby}"; $countsql = 'SELECT count(id) FROM {usr} WHERE deleted = 0 AND lastaccess > ?'; break; } $lastaccess = db_format_timestamp(time() - get_config('accessidletimeout')); if (!($result['count'] = count_records_sql($countsql, array($lastaccess)))) { return $result; } $onlineusers = get_records_sql_array($sql, array($lastaccess), $offset, $limit); if ($onlineusers) { foreach ($onlineusers as &$user) { $user->profileiconurl = profile_icon_url($user, 20, 20); // If the user is an MNET user, show where they've come from $authobj = AuthFactory::create($user->authinstance); if ($authobj->authname == 'xmlrpc') { $peer = get_peer($authobj->wwwroot); $user->loggedinfrom = $peer->name; } } } else { $onlineusers = array(); } $result['data'] = array_map(create_function('$a', 'return $a->id;'), $onlineusers); return $result; }
/** * Synchronize users and groups with the LDAP server */ public static function auth_ldap_sync_cron() { $auths = get_records_array('auth_instance', 'authname', 'ldap', 'id', 'id'); if (!$auths) { return; } foreach ($auths as $auth) { /* @var $authobj AuthLdap */ $authobj = AuthFactory::create($auth->id); // Each instance will decide for itself whether it should sync users and/or groups // User sync needs to be called before group sync in order for new users to wind // up in the correct groups $authobj->sync_users(); $authobj->sync_groups(); } }
/** * 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) { $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); $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); $this->reset_institutions(); $this->reset_grouproles(); $this->commit(); // finally, after all is done, call the (maybe non existant) hook on their auth plugin $authobj = AuthFactory::create($authinstance); $authobj->login(); }
/** * Add the users to the system. Make sure that they have to change their * password on next login also. */ function uploadcsv_submit(Pieform $form, $values) { global $USER, $SESSION, $CSVDATA, $FORMAT, $UPDATES; $formatkeylookup = array_flip($FORMAT); $authinstance = (int) $values['authinstance']; $authrecord = get_record('auth_instance', 'id', $authinstance); $authobj = AuthFactory::create($authinstance); $institution = new Institution($authobj->institution); $maxusers = $institution->maxuseraccounts; if (!empty($maxusers)) { $members = count_records_sql(' SELECT COUNT(*) FROM {usr} u INNER JOIN {usr_institution} i ON u.id = i.usr WHERE i.institution = ? AND u.deleted = 0', array($institution->name)); if ($members + count($CSVDATA) > $maxusers) { $SESSION->add_error_msg(get_string('uploadcsvfailedusersexceedmaxallowed', 'admin')); redirect('/admin/users/uploadcsv.php'); } } if ($values['updateusers']) { log_info('Updating users from the CSV file'); } else { log_info('Inserting users from the CSV file'); } db_begin(); $addedusers = array(); $cfgsendemail = get_config('sendemail'); if (empty($values['emailusers'])) { // Temporarily disable email sent during user creation, e.g. institution membership $GLOBALS['CFG']->sendemail = false; } $key = 0; $steps_total = $values['updateusers'] ? 5 : 4; $steps_done = $steps_total - 3; $num_lines = sizeof($CSVDATA); foreach ($CSVDATA as $record) { if (!($key % 25)) { // This part has three times the weight of the other two steps. set_progress_info('uploaduserscsv', $num_lines * $steps_done + $key * 3, $num_lines * $steps_total, get_string('committingchanges', 'admin')); } $key++; $user = new StdClass(); foreach ($FORMAT as $field) { if ($field == 'username' || $field == 'firstname' || $field == 'lastname' || $field == 'password' || $field == 'email' || $field == 'studentid' || $field == 'preferredname') { $user->{$field} = $record[$formatkeylookup[$field]]; } } $user->authinstance = $authinstance; if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $user->quota = $values['quota']; } $profilefields = new StdClass(); $remoteuser = null; foreach ($FORMAT as $field) { if ($field == 'username' || $field == 'password') { continue; } if ($field == 'remoteuser') { if (!empty($record[$formatkeylookup[$field]])) { $remoteuser = $record[$formatkeylookup[$field]]; } continue; } $profilefields->{$field} = $record[$formatkeylookup[$field]]; } if (!$values['updateusers'] || !isset($UPDATES[$user->username])) { $user->passwordchange = (int) $values['forcepasswordchange']; $user->id = create_user($user, $profilefields, $institution, $authrecord, $remoteuser, $values, true); $addedusers[] = $user; log_debug('added user ' . $user->username); } else { if (isset($UPDATES[$user->username])) { $updated = update_user($user, $profilefields, $remoteuser, $values, true, true); if (empty($updated)) { // Nothing changed for this user unset($UPDATES[$user->username]); } else { $UPDATES[$user->username] = $updated; log_debug('updated user ' . $user->username . ' (' . implode(', ', array_keys($updated)) . ')'); } } } set_time_limit(10); } db_commit(); // Reenable email set_config('sendemail', $cfgsendemail); // Only send e-mail to users after we're sure they have been inserted // successfully $straccountcreatedtext = $values['forcepasswordchange'] ? 'accountcreatedchangepasswordtext' : 'accountcreatedtext'; $straccountcreatedhtml = $values['forcepasswordchange'] ? 'accountcreatedchangepasswordhtml' : 'accountcreatedhtml'; if ($values['emailusers'] && $addedusers) { foreach ($addedusers as $user) { $failedusers = array(); try { email_user($user, null, get_string('accountcreated', 'mahara', get_config('sitename')), get_string($straccountcreatedtext, 'mahara', $user->firstname, get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('sitename')), get_string($straccountcreatedhtml, 'mahara', $user->firstname, get_config('wwwroot'), get_config('sitename'), $user->username, $user->password, get_config('wwwroot'), get_config('wwwroot'), get_config('sitename'))); } catch (EmailException $e) { log_info($e->getMessage()); $failedusers[] = $user; } } if ($failedusers) { $message = get_string('uploadcsvsomeuserscouldnotbeemailed', 'admin') . "\n<ul>\n"; foreach ($failedusers as $user) { $message .= '<li>' . full_name($user) . ' <' . hsc($user->email) . "></li>\n"; } $message .= "</ul>\n"; $SESSION->add_info_msg($message, false); } } log_info('Added ' . count($addedusers) . ' users, updated ' . count($UPDATES) . ' users.'); $SESSION->add_ok_msg(get_string('csvfileprocessedsuccessfully', 'admin')); if ($UPDATES) { $updatemsg = smarty_core(); $updatemsg->assign('added', count($addedusers)); $updatemsg->assign('updates', $UPDATES); $SESSION->add_info_msg($updatemsg->fetch('admin/users/csvupdatemessage.tpl'), false); } else { $SESSION->add_ok_msg(get_string('numbernewusersadded', 'admin', count($addedusers))); } set_progress_done('uploaduserscsv'); redirect('/admin/users/uploadcsv.php'); }
/** * Create test users from one place to share between update * and favourites */ function create_user2_for_update() { //can run this test only if test usernames don't exist foreach (array('veryimprobabletestusername2', 'veryimprobabletestusername2_updated') as $username) { $existinguser = get_record('usr', 'username', $username); if (!empty($existinguser)) { delete_user($existinguser->id); } } $user2 = new stdClass(); $user2->authinstance = $this->authinstance->id; $user2->username = '******'; if ($dbuser2 = get_record('usr', 'username', $user2->username)) { return $dbuser2; } $user2->password = '******'; $user2->firstname = 'testfirstname2'; $user2->lastname = 'testlastname2'; $user2->email = '*****@*****.**'; $profilefields = new StdClass(); db_begin(); $userid = create_user($user2, $profilefields, $this->institution, $this->authinstance); db_commit(); $dbuser2 = get_record('usr', 'username', $user2->username); $this->assertTrue($dbuser2 instanceof stdClass); $userobj = new User(); $userobj = $userobj->find_by_id($dbuser2->id); $authobj_tmp = AuthFactory::create($dbuser2->authinstance); $authobj_tmp->change_password($userobj, $dbuser2->password, false); $this->created_users[] = $dbuser2->id; $dbuser2 = get_record('usr', 'username', $user2->username); return $dbuser2; }
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; }
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'); }
function accountprefs_submit(Pieform $form, $values) { global $USER; $authobj = AuthFactory::create($USER->authinstance); db_begin(); if (isset($values['password1']) && $values['password1'] !== '') { global $authclass; $password = $authobj->change_password($USER, $values['password1']); $USER->password = $password; $USER->passwordchange = 0; $USER->commit(); } // use this as looping through values is not safe. $expectedprefs = expected_account_preferences(); foreach (array_keys($expectedprefs) as $pref) { if (isset($values[$pref])) { $USER->set_account_preference($pref, $values[$pref]); } } $returndata = array(); if (isset($values['username']) && $values['username'] != $USER->get('username')) { $USER->username = $values['username']; $USER->commit(); $returndata['username'] = $values['username']; } db_commit(); $returndata['message'] = get_string('prefssaved', 'account'); $form->json_reply(PIEFORM_OK, $returndata); }
/** * Create a test user * @param array $record * @throws SystemException if creating failed * @return int new user id */ public function create_user($record) { // Data validation // Set default auth method for a new user is 'internal' for 'No institution' if not set if (empty($record['institution']) || empty($record['authname'])) { $record['institution'] = 'mahara'; $record['authname'] = 'internal'; } if (!($auth = get_record('auth_instance', 'institution', $record['institution'], 'authname', $record['authname']))) { throw new SystemException("The authentication method authname" . $record['authname'] . " for institution '" . $record['institution'] . "' does not exist."); } $record['authinstance'] = $auth->id; // Don't exceed max user accounts for the institution $institution = new Institution($record['institution']); if ($institution->isFull()) { throw new SystemException("Can not add new users to the institution '" . $record['institution'] . "' as it is full."); } $record['firstname'] = sanitize_firstname($record['firstname']); $record['lastname'] = sanitize_lastname($record['lastname']); $record['email'] = sanitize_email($record['email']); $authobj = AuthFactory::create($auth->id); if (method_exists($authobj, 'is_username_valid_admin') && !$authobj->is_username_valid_admin($record['username'])) { throw new SystemException("New username'" . $record['username'] . "' is not valid."); } if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($record['username'])) { throw new SystemException("New username'" . $record['username'] . "' is not valid."); } if (record_exists_select('usr', 'LOWER(username) = ?', array(strtolower($record['username'])))) { throw new ErrorException("The username'" . $record['username'] . "' has been taken."); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($record['password'])) { throw new ErrorException("The password'" . $record['password'] . "' is not valid."); } if (record_exists('usr', 'email', $record['email']) || record_exists('artefact_internal_profile_email', 'email', $record['email'])) { throw new ErrorException("The email'" . $record['email'] . "' has been taken."); } // Create new user db_begin(); raise_time_limit(180); $user = (object) array('authinstance' => $record['authinstance'], 'username' => $record['username'], 'firstname' => $record['firstname'], 'lastname' => $record['lastname'], 'email' => $record['email'], 'password' => $record['password'], 'passwordchange' => 0); if ($record['institution'] == 'mahara') { if ($record['role'] == 'admin') { $user->admin = 1; } else { if ($record['role'] == 'staff') { $user->staff = 1; } } } $remoteauth = $record['authname'] != 'internal'; if (!isset($record['remoteusername'])) { $record['remoteusername'] = null; } $user->id = create_user($user, array(), $record['institution'], $remoteauth, $record['remoteusername'], $record); if (isset($user->admin) && $user->admin) { require_once 'activity.php'; activity_add_admin_defaults(array($user->id)); } if ($record['institution'] != 'mahara') { if ($record['role'] == 'admin') { set_field('usr_institution', 'admin', 1, 'usr', $user->id, 'institution', $record['institution']); } else { if ($record['role'] == 'staff') { set_field('usr_institution', 'staff', 1, 'usr', $user->id, 'institution', $record['institution']); } } } db_commit(); $this->usercounter++; return $user->id; }
function changeauth_submit(Pieform $form, $values) { global $users, $SESSION, $authinstances, $USER; $newauth = AuthFactory::create($values['authinstance']); $needspassword = method_exists($newauth, 'change_password'); $updated = 0; $needpassword = 0; db_begin(); $newauthinst = get_records_select_assoc('auth_instance', 'id = ?', array($values['authinstance'])); if ($USER->get('admin') || $USER->is_institutional_admin($newauthinst[$values['authinstance']]->institution)) { foreach ($users as $user) { if ($user->authinstance != $values['authinstance']) { // Authinstance can be changed by institutional admins if both the // old and new authinstances belong to the admin's institutions $authinst = get_field('auth_instance', 'institution', 'id', $user->authinstance); if ($USER->get('admin') || $USER->is_institutional_admin($authinst)) { // determine the current remoteusername $current_remotename = get_field('auth_remote_user', 'remoteusername', 'authinstance', $user->authinstance, 'localusr', $user->id); if (!$current_remotename) { $current_remotename = $user->username; } // remove row if new authinstance row already exists to avoid doubleups delete_records('auth_remote_user', 'authinstance', $values['authinstance'], 'localusr', $user->id); insert_record('auth_remote_user', (object) array('authinstance' => $values['authinstance'], 'remoteusername' => $current_remotename, 'localusr' => $user->id)); } if ($user->haspassword && !$needspassword) { $user->password = ''; } else { if ($needspassword && !$user->haspassword) { $needpassword++; } } $user->authinstance = $values['authinstance']; update_record('usr', $user, 'id'); $updated++; } } } db_commit(); if ($needpassword) { // Inform the user that they may need to reset passwords $SESSION->add_info_msg(get_string('bulkchangeauthmethodresetpassword', 'admin', $needpassword)); } $message = get_string('bulkchangeauthmethodsuccess', 'admin', $updated); $form->reply(PIEFORM_OK, array('message' => $message)); }
function accountprefs_submit(Pieform $form, $values) { global $USER, $SESSION; $authobj = AuthFactory::create($USER->authinstance); db_begin(); $ispasswordchanged = false; if (isset($values['password1']) && $values['password1'] !== '') { global $authclass; $password = $authobj->change_password($USER, $values['password1']); $USER->password = $password; $USER->passwordchange = 0; $USER->commit(); $ispasswordchanged = true; } // use this as looping through values is not safe. $expectedprefs = expected_account_preferences(); if ($values['maildisabled'] == 0 && get_account_preference($USER->get('id'), 'maildisabled') == 1) { // Reset the sent and bounce counts otherwise mail will be disabled // on the next send attempt $u = new StdClass(); $u->email = $USER->get('email'); $u->id = $USER->get('id'); update_bounce_count($u, true); update_send_count($u, true); } // Remember the user's language & theme prefs, so we can reload the page if they change them $oldlang = $USER->get_account_preference('lang'); $oldtheme = $USER->get_account_preference('theme'); $oldgroupsideblockmaxgroups = $USER->get_account_preference('groupsideblockmaxgroups'); $oldgroupsideblocksortby = $USER->get_account_preference('groupsideblocksortby'); if (get_config('allowmobileuploads')) { // Make sure the mobile token is formatted / saved correctly $values['mobileuploadtoken'] = array_filter($values['mobileuploadtoken']); $new_token_pref = empty($values['mobileuploadtoken']) ? null : '|' . join('|', $values['mobileuploadtoken']) . '|'; $USER->set_account_preference('mobileuploadtoken', $new_token_pref); unset($values['mobileuploadtoken']); } // Set user account preferences foreach ($expectedprefs as $eprefkey => $epref) { if (isset($values[$eprefkey]) && $values[$eprefkey] !== get_account_preference($USER->get('id'), $eprefkey)) { $USER->set_account_preference($eprefkey, $values[$eprefkey]); } } $returndata = array(); if (isset($values['username']) && $values['username'] != $USER->get('username')) { $USER->username = $values['username']; $USER->commit(); $returndata['username'] = $values['username']; } $reload = false; if (get_config('cleanurls') && isset($values['urlid']) && $values['urlid'] != $USER->get('urlid')) { $USER->urlid = $values['urlid']; $USER->commit(); $reload = true; } if ($ispasswordchanged) { // Destroy other sessions of the user require_once get_config('docroot') . 'auth/session.php'; remove_user_sessions($USER->get('id')); } db_commit(); $returndata['message'] = get_string('prefssaved', 'account'); if (isset($values['theme']) && $values['theme'] != $oldtheme) { $USER->update_theme(); $reload = true; } if (isset($values['lang']) && $values['lang'] != $oldlang) { // The session language pref is used when the user has no user pref, // and when logged out. $SESSION->set('lang', $values['lang']); $returndata['message'] = get_string_from_language($values['lang'], 'prefssaved', 'account'); $reload = true; } if (isset($values['groupsideblockmaxgroups']) && $values['groupsideblockmaxgroups'] != $oldgroupsideblockmaxgroups) { $reload = true; } if ($values['groupsideblocksortby'] != $oldgroupsideblocksortby) { $reload = true; } $reload = plugin_account_prefs_submit($form, $values) || $reload; if (!empty($reload)) { // Use PIEFORM_CANCEL here to force a page reload and show the new language. $returndata['location'] = get_config('wwwroot') . 'account/index.php'; $SESSION->add_ok_msg($returndata['message']); $form->json_reply(PIEFORM_CANCEL, $returndata); } $form->json_reply(PIEFORM_OK, $returndata); }
/** * 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(); }
/** * Take a username and password and try to authenticate the * user * * Copied and modified from core LiveUser->login() * * @param string $username * @param string $password * @return bool */ function login_test_all_user_authinstance($username, $password) { global $USER; // do the normal user lookup $sql = 'SELECT *, ' . db_format_tsfield('expiry') . ', ' . db_format_tsfield('lastlogin') . ', ' . db_format_tsfield('lastlastlogin') . ', ' . db_format_tsfield('lastaccess') . ', ' . db_format_tsfield('suspendedctime') . ', ' . db_format_tsfield('ctime') . ' FROM {usr} WHERE LOWER(username) = ?'; $user = get_record_sql($sql, array(strtolower($username))); // throw out unknown users if ($user == false) { throw new AuthUnknownUserException("\"{$username}\" is not known"); } // stop right here if the site is closed for any reason $siteclosedforupgrade = get_config('siteclosed'); if ($siteclosedforupgrade && get_config('disablelogin')) { global $SESSION; $SESSION->add_error_msg(get_string('siteclosedlogindisabled', 'mahara', get_config('wwwroot') . 'admin/upgrade.php'), false); return false; } if ($siteclosedforupgrade || get_config('siteclosedbyadmin')) { global $SESSION; $SESSION->add_error_msg(get_string('siteclosed')); return false; } // Build up a list of authinstance that can be tried for this user - typically // internal, or ldap - definitely NOT none, saml, or xmlrpc $instances = array(); // all other candidtate auth_instances $sql = 'SELECT ai.* from {auth_instance} ai INNER JOIN {auth_remote_user} aru ON ai.id = aru.authinstance WHERE ai.authname NOT IN(\'saml\', \'xmlrpc\', \'none\') AND aru.localusr = ?'; $authinstances = get_records_sql_array($sql, array($user->id)); foreach ($authinstances as $authinstance) { $instances[] = $authinstance->id; } // determine the internal authinstance ID associated with the base 'mahara' // 'no institution' - use this is a default fallback login attempt $authinstance = get_record('auth_instance', 'institution', 'mahara', 'authname', 'internal'); $instances[] = $authinstance->id; // test each auth_instance candidate associated with this user foreach ($instances as $authinstanceid) { $auth = AuthFactory::create($authinstanceid); // catch the AuthInstanceException that allows authentication plugins to // fail but pass onto the next possible plugin try { if ($auth->authenticate_user_account($user, $password)) { $USER->reanimate($user->id, $auth->instanceid); // Check for a suspended institution - should never be for 'mahara' $authinstance = get_record_sql(' SELECT i.suspended, i.displayname FROM {institution} i JOIN {auth_instance} a ON a.institution = i.name WHERE a.id = ?', array($authinstanceid)); if ($authinstance->suspended) { continue; } // we havea winner return true; } } catch (AuthInstanceException $e) { // auth fail - try the next one continue; } } // all fail return false; }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER, $CSVERRORS; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } require_once 'csvfile.php'; $authinstance = (int) $values['authinstance']; $institution = get_field('auth_instance', 'institution', 'id', $authinstance); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $usernames = array(); $emails = array(); $csvusers = new CsvFile($values['file']['tmp_name']); $csvusers->set('allowedkeys', $ALLOWEDKEYS); // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'password'); $mandatoryfields = array_merge($mandatoryfields, array_keys(ArtefactTypeProfile::get_mandatory_fields())); if ($lockedprofilefields = get_column('institution_locked_profile_field', 'profilefield', 'name', $institution)) { $mandatoryfields = array_merge($mandatoryfields, $lockedprofilefields); } $csvusers->set('mandatoryfields', $mandatoryfields); $csvdata = $csvusers->get_data(); if (!empty($csvdata->errors['file'])) { $form->set_error('file', $csvdata->errors['file']); return; } foreach ($csvdata->data as $key => $line) { // If headers exists, increment i = key + 2 for actual line number $i = $csvusers->get('headerExists') ? $key + 2 : $key + 1; // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $formatkeylookup = array_flip($csvdata->format); $username = $line[$formatkeylookup['username']]; $password = $line[$formatkeylookup['password']]; $email = $line[$formatkeylookup['email']]; $authobj = AuthFactory::create($authinstance); if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $CSVERRORS[] = get_string('uploadcsverrorinvalidusername', 'admin', $i); } if (record_exists_select('usr', 'LOWER(username) = ?', strtolower($username)) || isset($usernames[strtolower($username)])) { $CSVERRORS[] = get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email) || isset($emails[$email])) { $CSVERRORS[] = get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email); } // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $CSVERRORS[] = get_string('uploadcsverrorinvalidpassword', 'admin', $i); } $usernames[strtolower($username)] = 1; $emails[$email] = 1; } if (!empty($CSVERRORS)) { $form->set_error('file', implode("<br />\n", $CSVERRORS)); return; } $FORMAT = $csvdata->format; $CSVDATA = $csvdata->data; }
function accountprefs_submit(Pieform $form, $values) { global $USER; $authobj = AuthFactory::create($USER->authinstance); db_begin(); if (isset($values['password1']) && $values['password1'] !== '') { global $authclass; $password = $authobj->change_password($USER, $values['password1']); $USER->password = $password; $USER->passwordchange = 0; $USER->commit(); } // use this as looping through values is not safe. $expectedprefs = expected_account_preferences(); if ($values['maildisabled'] == 0 && get_account_preference($USER->get('id'), 'maildisabled') == 1) { // Reset the sent and bounce counts otherwise mail will be disabled // on the next send attempt $u = new StdClass(); $u->email = $USER->get('email'); $u->id = $USER->get('id'); update_bounce_count($u, true); update_send_count($u, true); } foreach (array_keys($expectedprefs) as $pref) { if (isset($values[$pref])) { $USER->set_account_preference($pref, $values[$pref]); } } $returndata = array(); if (isset($values['username']) && $values['username'] != $USER->get('username')) { $USER->username = $values['username']; $USER->commit(); $returndata['username'] = $values['username']; } db_commit(); $returndata['message'] = get_string('prefssaved', 'account'); $form->json_reply(PIEFORM_OK, $returndata); }