Example #1
0
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'));
            }
        }
    }
}
/**
 * Called when the login form is submitted. Validates the user and password, and
 * if they are valid, starts a new session for the user.
 *
 * @param object $form   The Pieform form object
 * @param array  $values The submitted values
 * @access private
 */
function login_submit(Pieform $form, $values)
{
    global $SESSION, $USER;
    $username = trim($values['login_username']);
    $password = $values['login_password'];
    $authenticated = false;
    try {
        $authenticated = $USER->login($username, $password);
        if (empty($authenticated)) {
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    } catch (AuthUnknownUserException $e) {
        // If the user doesn't exist, check for institutions that
        // want to create users automatically.
        try {
            // Reset the LiveUser object, since we are attempting to create a
            // new user
            $SESSION->destroy_session();
            $USER = new LiveUser();
            $authinstances = get_records_sql_array("\n                SELECT a.id, a.instancename, a.priority, a.authname, a.institution, i.suspended, i.displayname\n                FROM {institution} i JOIN {auth_instance} a ON a.institution = i.name\n                WHERE a.authname != 'internal'\n                ORDER BY a.institution, a.priority, a.instancename", null);
            if ($authinstances == false) {
                throw new AuthUnknownUserException("\"{$username}\" is not known");
            }
            $USER->username = $username;
            reset($authinstances);
            while ((list(, $authinstance) = each($authinstances)) && false == $authenticated) {
                $auth = AuthFactory::create($authinstance->id);
                if (!$auth->can_auto_create_users()) {
                    continue;
                }
                // catch semi-fatal auth errors, but allow next auth instance to be
                // tried
                try {
                    if ($auth->authenticate_user_account($USER, $password)) {
                        $authenticated = true;
                    } else {
                        continue;
                    }
                } catch (AuthInstanceException $e) {
                    continue;
                }
                // Check now to see if the institution has its maximum quota of users
                require_once 'institution.php';
                $institution = new Institution($authinstance->institution);
                if ($institution->isFull()) {
                    $institution->send_admin_institution_is_full_message();
                    throw new AuthUnknownUserException('Institution has too many users');
                }
                $USER->authinstance = $authinstance->id;
                $userdata = $auth->get_user_info($username);
                if (empty($userdata)) {
                    throw new AuthUnknownUserException("\"{$username}\" is not known");
                }
                // Check for a suspended institution
                if ($authinstance->suspended) {
                    $sitename = get_config('sitename');
                    throw new AccessTotallyDeniedException(get_string('accesstotallydenied_institutionsuspended', 'mahara', $authinstance->displayname, $sitename));
                }
                // We have the data - create the user
                $USER->lastlogin = db_format_timestamp(time());
                if (isset($userdata->firstname)) {
                    $USER->firstname = sanitize_firstname($userdata->firstname);
                }
                if (isset($userdata->lastname)) {
                    $USER->lastname = sanitize_firstname($userdata->lastname);
                }
                if (isset($userdata->email)) {
                    $USER->email = sanitize_email($userdata->email);
                } else {
                    // The user will be asked to populate this when they log in.
                    $USER->email = null;
                }
                $profilefields = array();
                foreach (array('studentid', 'preferredname') as $pf) {
                    if (isset($userdata->{$pf})) {
                        $sanitize = 'sanitize_' . $pf;
                        if (($USER->{$pf} = $sanitize($userdata->{$pf})) !== '') {
                            $profilefields[$pf] = $USER->{$pf};
                        }
                    }
                }
                try {
                    // If this authinstance is a parent auth for some xmlrpc authinstance, pass it along to create_user
                    // so that this username also gets recorded as the username for sso from the remote sites.
                    $remoteauth = $auth->is_parent_authority();
                    create_user($USER, $profilefields, $institution, $remoteauth);
                    $USER->reanimate($USER->id, $authinstance->id);
                } catch (Exception $e) {
                    db_rollback();
                    throw $e;
                }
            }
            if (!$authenticated) {
                $SESSION->add_error_msg(get_string('loginfailed'));
                return;
            }
        } catch (AuthUnknownUserException $e) {
            // We weren't able to authenticate the user for some reason that
            // probably isn't their fault (e.g. ldap extension not available
            // when using ldap authentication)
            log_info($e->getMessage());
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    }
    auth_check_admin_section();
    // This is also checked in $USER->login(), but it's good to check it again here in case a buggy auth plugin
    // lets a suspended user through somehow.
    ensure_user_account_is_active();
    // User is allowed to log in
    //$USER->login($userdata);
    auth_check_required_fields();
}
Example #3
0
 /**
  * Grab a delegate object for auth stuff
  */
 public function request_user_authorise($token, $remotewwwroot)
 {
     global $USER, $SESSION;
     $this->must_be_ready();
     $peer = get_peer($remotewwwroot);
     if ($peer->deleted != 0 || $this->config['theyssoin'] != 1) {
         throw new XmlrpcClientException('We don\'t accept SSO connections from ' . institution_display_name($peer->institution));
     }
     $client = new Client();
     $client->set_method('auth/mnet/auth.php/user_authorise')->add_param($token)->add_param(sha1($_SERVER['HTTP_USER_AGENT']))->send($remotewwwroot);
     $remoteuser = (object) $client->response;
     if (empty($remoteuser) or !property_exists($remoteuser, 'username')) {
         // Caught by land.php
         throw new AccessDeniedException();
     }
     $create = false;
     $update = false;
     if ('1' == $this->config['updateuserinfoonlogin']) {
         $update = true;
     }
     // Retrieve a $user object. If that fails, create a blank one.
     try {
         $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();
             }
             $user->find_by_username($remoteuser->username);
         } else {
             $user->find_by_instanceid_username($this->instanceid, $remoteuser->username, true);
         }
         if ($user->get('suspendedcusr')) {
             die_info(get_string('accountsuspended', 'mahara', strftime(get_string('strftimedaydate'), $user->get('suspendedctime')), $user->get('suspendedreason')));
         }
     } 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 {$remotewwwroot} failed - " . "remote user '{$remoteuser->username}' 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;
         //TODO: import institution's expiry?:
         //$institution = new Institution($peer->institution);
         $user->expiry = null;
         $user->expirymailsent = 0;
         $user->lastlogin = time();
         $user->firstname = $remoteuser->firstname;
         $user->lastname = $remoteuser->lastname;
         $user->email = $remoteuser->email;
         $imported = array('firstname', 'lastname', 'email');
         //TODO: import institution's per-user-quota?:
         //$user->quota              = $userrecord->quota;
         $user->authinstance = empty($this->config['parent']) ? $this->instanceid : $this->parent;
         db_begin();
         $user->username = get_new_username($remoteuser->username);
         $user->id = create_user($user, array(), $this->institution, $this, $remoteuser->username);
         $locked = $this->import_user_settings($user, $remoteuser);
         $locked = array_merge($imported, $locked);
         /*
          * 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);
     } elseif ($update) {
         $imported = array('firstname', 'lastname', 'email');
         foreach ($imported as $field) {
             if ($user->{$field} != $remoteuser->{$field}) {
                 $user->{$field} = $remoteuser->{$field};
                 set_profile_field($user->id, $field, $user->{$field});
             }
         }
         if (isset($remoteuser->idnumber)) {
             if ($user->studentid != $remoteuser->idnumber) {
                 $user->studentid = $remoteuser->idnumber;
                 set_profile_field($user->id, 'studentid', $user->studentid);
             }
             $imported[] = 'studentid';
         }
         $locked = $this->import_user_settings($user, $remoteuser);
         $locked = array_merge($imported, $locked);
         $user->lastlastlogin = $user->lastlogin;
         $user->lastlogin = time();
         //TODO: import institution's per-user-quota?:
         //$user->quota              = $userrecord->quota;
         $user->commit();
     }
     if (get_config('usersuniquebyusername')) {
         // Add them to the institution they have SSOed in by
         $user->join_institution($peer->institution);
     }
     // See if we need to create/update a profile Icon image
     if ($create || $update) {
         $client->set_method('auth/mnet/auth.php/fetch_user_image')->add_param($remoteuser->username)->send($remotewwwroot);
         $imageobject = (object) $client->response;
         $u = preg_replace('/[^A-Za-z0-9 ]/', '', $user->username);
         $filename = get_config('dataroot') . 'temp/mpi_' . intval($this->instanceid) . '_' . $u;
         if (array_key_exists('f1', $client->response)) {
             $imagecontents = base64_decode($client->response['f1']);
             if (file_put_contents($filename, $imagecontents)) {
                 $imageexists = false;
                 $icons = false;
                 if ($update) {
                     $newchecksum = sha1_file($filename);
                     $icons = get_records_select_array('artefact', 'artefacttype = \'profileicon\' AND owner = ? ', array($user->id), '', 'id');
                     if (false != $icons) {
                         foreach ($icons as $icon) {
                             $iconfile = get_config('dataroot') . 'artefact/file/profileicons/originals/' . $icon->id % 256 . '/' . $icon->id;
                             $checksum = sha1_file($iconfile);
                             if ($newchecksum == $checksum) {
                                 $imageexists = true;
                                 unlink($filename);
                                 break;
                             }
                         }
                     }
                 }
                 if (false == $imageexists) {
                     $filesize = filesize($filename);
                     if (!$user->quota_allowed($filesize)) {
                         $error = get_string('profileiconuploadexceedsquota', 'artefact.file', get_config('wwwroot'));
                     }
                     require_once 'file.php';
                     $imagesize = getimagesize($filename);
                     if (!$imagesize || !is_image_type($imagesize[2])) {
                         $error = get_string('filenotimage');
                     }
                     $mime = $imagesize['mime'];
                     $width = $imagesize[0];
                     $height = $imagesize[1];
                     $imagemaxwidth = get_config('imagemaxwidth');
                     $imagemaxheight = get_config('imagemaxheight');
                     if ($width > $imagemaxwidth || $height > $imagemaxheight) {
                         $error = get_string('profileiconimagetoobig', 'artefact.file', $width, $height, $imagemaxwidth, $imagemaxheight);
                     }
                     try {
                         $user->quota_add($filesize);
                     } catch (QuotaException $qe) {
                         $error = get_string('profileiconuploadexceedsquota', 'artefact.file', get_config('wwwroot'));
                     }
                     require_once get_config('docroot') . '/artefact/lib.php';
                     require_once get_config('docroot') . '/artefact/file/lib.php';
                     // Entry in artefact table
                     $artefact = new ArtefactTypeProfileIcon();
                     $artefact->set('owner', $user->id);
                     $artefact->set('parent', ArtefactTypeFolder::get_folder_id(get_string('imagesdir', 'artefact.file'), get_string('imagesdirdesc', 'artefact.file'), null, true, $user->id));
                     $artefact->set('title', ArtefactTypeFileBase::get_new_file_title(get_string('profileicon', 'artefact.file'), (int) $artefact->get('parent'), $user->id));
                     // unique title
                     $artefact->set('description', get_string('uploadedprofileicon', 'artefact.file'));
                     $artefact->set('note', get_string('profileicon', 'artefact.file'));
                     $artefact->set('size', $filesize);
                     $artefact->set('filetype', $mime);
                     $artefact->set('width', $width);
                     $artefact->set('height', $height);
                     $artefact->commit();
                     $id = $artefact->get('id');
                     // Move the file into the correct place.
                     $directory = get_config('dataroot') . 'artefact/file/profileicons/originals/' . $id % 256 . '/';
                     check_dir_exists($directory);
                     rename($filename, $directory . $id);
                     if ($create || empty($icons)) {
                         $user->profileicon = $id;
                     }
                 }
                 $user->commit();
             } else {
                 log_warn(get_string('cantcreatetempprofileiconfile', 'artefact.file', $filename));
             }
         }
         if ($update) {
             $locked[] = 'profileicon';
         }
     }
     /*******************************************/
     // We know who our user is now. Bring her back to life.
     $USER->reanimate($user->id, $this->instanceid);
     // Set session variables to let the application know this session was
     // initiated by MNET. Don't forget that users could initiate their
     // sessions without MNET sometimes, which is why this data is stored in
     // the session object.
     $SESSION->set('mnetuser', $user->id);
     $SESSION->set('authinstance', $this->instanceid);
     if (isset($_SERVER['HTTP_REFERER'])) {
         $SESSION->set('mnetuserfrom', $_SERVER['HTTP_REFERER']);
     }
     if ($update && isset($locked)) {
         $SESSION->set('lockedfields', $locked);
     }
     return true;
 }
Example #4
0
function edituser_institution_validate(Pieform $form, $values)
{
    $user = new User();
    if (!$user->find_by_id($values['id'])) {
        return false;
    }
    global $USER;
    $userinstitutions = $user->get('institutions');
    if (isset($values['add']) && $USER->get('admin') && (empty($userinstitutions) || get_config('usersallowedmultipleinstitutions'))) {
        // check if the institution is full
        require_once get_config('docroot') . 'lib/institution.php';
        $institution = new Institution($values['addinstitution']);
        if ($institution->isFull()) {
            $institution->send_admin_institution_is_full_message();
            $form->set_error(null, get_string('institutionmaxusersexceeded', 'admin'));
        }
    }
}
Example #5
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;
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * Process an authorization request.
  *
  * Operations:
  *     - Auto creates users.
  *     - Sets up user object for linked accounts.
  *
  * @param string $oidcuniqid The OIDC unique identifier received.
  * @param array $tokenparams Received token parameters.
  * @param \auth_oidc\jwt $idtoken Received id token.
  * @return bool Success/Failure.
  */
 public function request_user_authorise($oidcuniqid, $tokenparams, $idtoken)
 {
     global $USER, $SESSION;
     $this->must_be_ready();
     $username = $oidcuniqid;
     $email = $idtoken->claim('email');
     $firstname = $idtoken->claim('given_name');
     $lastname = $idtoken->claim('family_name');
     // Office 365 uses "upn".
     $upn = $idtoken->claim('upn');
     if (!empty($upn)) {
         $username = $upn;
         $email = $upn;
     }
     $create = false;
     try {
         $user = new \User();
         $user->find_by_instanceid_username($this->instanceid, $username, true);
         if ($user->get('suspendedcusr')) {
             die_info(get_string('accountsuspended', 'mahara', strftime(get_string('strftimedaydate'), $user->get('suspendedctime')), $user->get('suspendedreason')));
         }
     } catch (\AuthUnknownUserException $e) {
         if ($this->can_auto_create_users() === true) {
             $institution = new \Institution($this->institution);
             if ($institution->isFull()) {
                 throw new \XmlrpcClientException('OpenID Connect login attempt failed because the institution is full.');
             }
             $user = new \User();
             $create = true;
         } else {
             return false;
         }
     }
     if ($create === true) {
         $user->passwordchange = 0;
         $user->active = 1;
         $user->deleted = 0;
         $user->expiry = null;
         $user->expirymailsent = 0;
         $user->lastlogin = time();
         $user->firstname = $firstname;
         $user->lastname = $lastname;
         $user->email = $email;
         $user->authinstance = $this->instanceid;
         db_begin();
         $user->username = get_new_username($username);
         $user->id = create_user($user, array(), $this->institution, $this, $username);
         $userobj = $user->to_stdclass();
         $userarray = (array) $userobj;
         db_commit();
         $user = new User();
         $user->find_by_id($userobj->id);
     }
     $user->commit();
     $USER->reanimate($user->id, $this->instanceid);
     $SESSION->set('authinstance', $this->instanceid);
     return true;
 }
Example #8
0
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;
    }
}
Example #9
0
/**
 * Called when the login form is submitted. Validates the user and password, and
 * if they are valid, starts a new session for the user.
 *
 * @param object $form   The Pieform form object
 * @param array  $values The submitted values
 * @access private
 */
function login_submit(Pieform $form, $values)
{
    global $SESSION, $USER;
    $username = $values['login_username'];
    $password = $values['login_password'];
    $authenticated = false;
    $oldlastlogin = 0;
    try {
        $authenticated = $USER->login($username, $password);
        if (empty($authenticated)) {
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    } catch (AuthUnknownUserException $e) {
        // If the user doesn't exist, check for institutions that
        // want to create users automatically.
        try {
            // Reset the LiveUser object, since we are attempting to create a
            // new user
            $SESSION->destroy_session();
            $USER = new LiveUser();
            $authinstances = get_records_sql_array('
                SELECT a.id, a.instancename, a.priority, a.authname, a.institution, i.suspended, i.displayname
                FROM {institution} i JOIN {auth_instance} a ON a.institution = i.name
                ORDER BY a.institution, a.priority, a.instancename', null);
            if ($authinstances == false) {
                throw new AuthUnknownUserException("\"{$username}\" is not known");
            }
            $USER->username = $username;
            reset($authinstances);
            while ((list(, $authinstance) = each($authinstances)) && false == $authenticated) {
                $auth = AuthFactory::create($authinstance->id);
                if (!$auth->can_auto_create_users()) {
                    continue;
                }
                if ($auth->authenticate_user_account($USER, $password)) {
                    $authenticated = true;
                } else {
                    continue;
                }
                // Check now to see if the institution has its maximum quota of users
                require_once 'institution.php';
                $institution = new Institution($authinstance->institution);
                if ($institution->isFull()) {
                    throw new AuthUnknownUserException('Institution has too many users');
                }
                $USER->authinstance = $authinstance->id;
                $userdata = $auth->get_user_info($username);
                if (empty($userdata)) {
                    throw new AuthUnknownUserException("\"{$username}\" is not known");
                }
                // Check for a suspended institution
                if ($authinstance->suspended) {
                    $sitename = get_config('sitename');
                    throw new AccessTotallyDeniedException(get_string('accesstotallydenied_institutionsuspended', 'mahara', $authinstance->displayname, $sitename));
                }
                // We have the data - create the user
                $USER->lastlogin = db_format_timestamp(time());
                if (isset($userdata->firstname)) {
                    $USER->firstname = $userdata->firstname;
                }
                if (isset($userdata->lastname)) {
                    $USER->lastname = $userdata->lastname;
                }
                if (isset($userdata->email)) {
                    $USER->email = $userdata->email;
                } else {
                    // The user will be asked to populate this when they log in.
                    $USER->email = null;
                }
                try {
                    create_user($USER, array(), $institution);
                    $USER->reanimate($USER->id, $authinstance->id);
                } catch (Exception $e) {
                    db_rollback();
                    throw $e;
                }
            }
            if (!$authenticated) {
                $SESSION->add_error_msg(get_string('loginfailed'));
                return;
            }
        } catch (AuthUnknownUserException $e) {
            // We weren't able to authenticate the user for some reason that
            // probably isn't their fault (e.g. ldap extension not available
            // when using ldap authentication)
            log_info($e->getMessage());
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    }
    // Only admins in the admin section!
    if (!$USER->get('admin') && (defined('ADMIN') || defined('INSTITUTIONALADMIN') && !$USER->is_institutional_admin())) {
        $SESSION->add_error_msg(get_string('accessforbiddentoadminsection'));
        redirect();
    }
    // Check if the user's account has been deleted
    if ($USER->deleted) {
        $USER->logout();
        die_info(get_string('accountdeleted'));
    }
    // Check if the user's account has expired
    if ($USER->expiry > 0 && time() > $USER->expiry) {
        $USER->logout();
        die_info(get_string('accountexpired'));
    }
    // Check if the user's account has become inactive
    $inactivetime = get_config('defaultaccountinactiveexpire');
    if ($inactivetime && $oldlastlogin > 0 && $oldlastlogin + $inactivetime < time()) {
        $USER->logout();
        die_info(get_string('accountinactive'));
    }
    // Check if the user's account has been suspended
    if ($USER->suspendedcusr) {
        $suspendedctime = $USER->suspendedctime;
        $suspendedreason = $USER->suspendedreason;
        $USER->logout();
        die_info(get_string('accountsuspended', 'mahara', $suspendedctime, $suspendedreason));
    }
    // User is allowed to log in
    //$USER->login($userdata);
    auth_check_password_change();
    auth_check_required_fields();
}
Example #10
0
/**
 * Called when the login form is submitted. Validates the user and password, and
 * if they are valid, starts a new session for the user.
 *
 * @param object $form   The Pieform form object
 * @param array  $values The submitted values
 * @access private
 */
function login_submit(Pieform $form, $values)
{
    global $SESSION, $USER;
    $username = $values['login_username'];
    $password = $values['login_password'];
    $authenticated = false;
    $oldlastlogin = 0;
    try {
        $authenticated = $USER->login($username, $password);
        if (empty($authenticated)) {
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    } catch (AuthUnknownUserException $e) {
        // If the user doesn't exist, check for institutions that
        // want to create users automatically.
        try {
            // Reset the LiveUser object, since we are attempting to create a
            // new user
            $SESSION->destroy_session();
            $USER = new LiveUser();
            $authinstances = get_records_sql_array('
                SELECT a.id, a.instancename, a.priority, a.authname, a.institution, i.suspended, i.displayname
                FROM {institution} i JOIN {auth_instance} a ON a.institution = i.name
                ORDER BY a.institution, a.priority, a.instancename', null);
            if ($authinstances == false) {
                throw new AuthUnknownUserException("\"{$username}\" is not known");
            }
            $USER->username = $username;
            reset($authinstances);
            while ((list(, $authinstance) = each($authinstances)) && false == $authenticated) {
                $auth = AuthFactory::create($authinstance->id);
                if (!$auth->can_auto_create_users()) {
                    continue;
                }
                // catch semi-fatal auth errors, but allow next auth instance to be
                // tried
                try {
                    if ($auth->authenticate_user_account($USER, $password)) {
                        $authenticated = true;
                    } else {
                        continue;
                    }
                } catch (AuthInstanceException $e) {
                    continue;
                }
                // Check now to see if the institution has its maximum quota of users
                require_once 'institution.php';
                $institution = new Institution($authinstance->institution);
                if ($institution->isFull()) {
                    throw new AuthUnknownUserException('Institution has too many users');
                }
                $USER->authinstance = $authinstance->id;
                $userdata = $auth->get_user_info($username);
                if (empty($userdata)) {
                    throw new AuthUnknownUserException("\"{$username}\" is not known");
                }
                // Check for a suspended institution
                if ($authinstance->suspended) {
                    $sitename = get_config('sitename');
                    throw new AccessTotallyDeniedException(get_string('accesstotallydenied_institutionsuspended', 'mahara', $authinstance->displayname, $sitename));
                }
                // We have the data - create the user
                $USER->lastlogin = db_format_timestamp(time());
                if (isset($userdata->firstname)) {
                    $USER->firstname = $userdata->firstname;
                }
                if (isset($userdata->lastname)) {
                    $USER->lastname = $userdata->lastname;
                }
                if (isset($userdata->email)) {
                    $USER->email = $userdata->email;
                } else {
                    // The user will be asked to populate this when they log in.
                    $USER->email = null;
                }
                try {
                    // If this authinstance is a parent auth for some xmlrpc authinstance, pass it along to create_user
                    // so that this username also gets recorded as the username for sso from the remote sites.
                    $remoteauth = count_records('auth_instance_config', 'field', 'parent', 'value', $authinstance->id) ? $authinstance : null;
                    create_user($USER, array(), $institution, $remoteauth);
                    $USER->reanimate($USER->id, $authinstance->id);
                } catch (Exception $e) {
                    db_rollback();
                    throw $e;
                }
            }
            if (!$authenticated) {
                $SESSION->add_error_msg(get_string('loginfailed'));
                return;
            }
        } catch (AuthUnknownUserException $e) {
            // We weren't able to authenticate the user for some reason that
            // probably isn't their fault (e.g. ldap extension not available
            // when using ldap authentication)
            log_info($e->getMessage());
            $SESSION->add_error_msg(get_string('loginfailed'));
            return;
        }
    }
    // Only admins in the admin section!
    if (!$USER->get('admin') && (defined('ADMIN') || defined('INSTITUTIONALADMIN') && !$USER->is_institutional_admin())) {
        $SESSION->add_error_msg(get_string('accessforbiddentoadminsection'));
        redirect();
    }
    // Check if the user's account has been deleted
    if ($USER->deleted) {
        $USER->logout();
        die_info(get_string('accountdeleted'));
    }
    // Check if the user's account has expired
    if ($USER->expiry > 0 && time() > $USER->expiry) {
        $USER->logout();
        die_info(get_string('accountexpired'));
    }
    // Check if the user's account has become inactive
    $inactivetime = get_config('defaultaccountinactiveexpire');
    if ($inactivetime && $oldlastlogin > 0 && $oldlastlogin + $inactivetime < time()) {
        $USER->logout();
        die_info(get_string('accountinactive'));
    }
    // Check if the user's account has been suspended
    if ($USER->suspendedcusr) {
        $suspendedctime = strftime(get_string('strftimedaydate'), $USER->suspendedctime);
        $suspendedreason = $USER->suspendedreason;
        $USER->logout();
        die_info(get_string('accountsuspended', 'mahara', $suspendedctime, $suspendedreason));
    }
    // User is allowed to log in
    //$USER->login($userdata);
    auth_check_required_fields();
    if (get_config('httpswwwroot') && !defined('JSON')) {
        // If we are using HTTPS for logins we need to go back to
        // non-HTTPS URLs. Otherwise, Javascript (and possibly CSS)
        // breaks. Don't use get_full_script_path(), as it doesn't
        // work if someone sets httpswwwroot to something like
        // 'https://x.y.z.w:443/...'  (unlikely, but
        // possible). get_full_script_path() doesn't gives us the
        // ':443' part and things break horribly.
        $parts = parse_url(get_config('httpswwwroot'));
        $httpsrequest = rtrim($parts['path'], '/');
        redirect(hsc(substr(get_script_path(), strlen($httpsrequest))));
    }
}
Example #11
0
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'));
            }
        }
    }
}