public static function login($data) { preg_match('/^userid: "(.*)"$/m', $data, $match); $user_id = $match[1]; preg_match('/^firstname: "(.*)"$/m', $data, $match); $first_name = $match[1]; preg_match('/^surname: "(.*)"$/m', $data, $match); $surname = $match[1]; preg_match('/^username: "******"$/m', $data, $match); $username = $match[1]; $user = User::from_id($user_id); if (!$user) { $user = new User(); $user->user_id = $user_id; } $user->username = $username; $user->first_name = $first_name; $user->surname = $surname; $user->commit(); return $user; }
public function commit() { if ($this->changed == false) { return; } $this->reload_background_fields(); parent::commit(); }
/** * Update the primary email to an user * Add new if not exists * * @param int $userid The user ID * @param string $newemail The new valid email address */ function set_user_primary_email($userid, $newemail) { safe_require('artefact', 'internal'); $user = new User(); $user->find_by_id($userid); db_begin(); // Update user's primary email address if ($newemail !== $user->email) { // Set the current email address to be secondary update_record('artefact_internal_profile_email', (object) array('principal' => 0), (object) array('owner' => $user->id, 'email' => $user->email)); // If the new primary email address is to be verified, remove it delete_records('artefact_internal_profile_email', 'owner', $user->id, 'email', $newemail, 'verified', '0'); // If the new address is one of the user's email addresses, set it as principal if (record_exists('artefact_internal_profile_email', 'owner', $user->id, 'email', $newemail)) { update_record('artefact_internal_profile_email', (object) array('principal' => 1), (object) array('owner' => $user->id, 'email' => $newemail)); } else { // Add new user profile email address set_profile_field($user->id, 'email', $newemail, TRUE); } $user->email = $newemail; $user->commit(); } db_commit(); }
$user->department = $department; $user->organization = $organization; $user->position = $position; $user->resolution = $resolution; $user->firstName = $firstname; $user->lastName = $lastname; $user->academicTitle = $academic_title; $user->fax = $facsimile; $user->street = $street; $user->houseNumber = $housenumber; $user->deliveryPoint = $delivery_point; $user->postalCode = $postal_code; $user->city = $city; $user->country = $country; $user->loginCount = $login_count; $user->commit(); // TODO: uuid ??? $user->setNewUserPasswordTicket(); if ($withPasswordInsertion == 'true' && $password !== '' && $user->validUserPasswordTicket($user->passwordTicket)) { $user->setPassword($password, $user->passwordTicket); echo "<script language='JavaScript'>alert('Password has been updated successfully!');</script>"; } } } if ($action == 'new_pw_ticket') { $user = new user(intval($selected_user)); $user->setNewUserPasswordTicket(); } if (!isset($name) || $selected_user == 'new') { $name = ""; $password = "";
'Contact', 'Phone2', 'PostalCode', 'Employer', 'EmployerType', 'Position' ); // save user data foreach ($userData as $value) { $liveUserValues[$value] = Input::Get($value, 'string', null); $editUser->setProperty($value, $liveUserValues[$value], false); } $backLink = "/$ADMIN/users/edit.php?$typeParam&User="******"$1"', $editUser->getUserName()); Log::Message($logtext, $g_user->getUserId(), 56); // sync base data to the corresponding phorum user $isPhorumUser = Phorum_user::GetByUserName($editUser->getUserName()); if($isPhorumUser) { $editUser->syncPhorumUser(); } if ($editUser->isAdmin() && $customizeRights && $canManage) { $rightsFields = $editUser->GetDefaultConfig(); $permissions = array(); foreach ($rightsFields as $field=>$value) {
/** * Changes the user's password. * * This method is not strictly part of the authentication API, but if * defined allows the method to change a user's password. * * @param object $user The user to change the password for * @param string $password The password to set for the user * @return string The new password, or empty if the password could not be set */ public function change_password(User $user, $password) { $this->must_be_ready(); // Create a salted password and set it for the user $user->salt = substr(md5(rand(1000000, 9999999)), 2, 8); $user->password = $this->encrypt_password($password, $user->salt); $user->passwordchange = 0; $user->commit(); return $user->password; }
/** * Processes a newly uploaded file, copies it to disk, and creates * a new artefact object. * Takes the name of a file input. * Returns false for no errors, or a string describing the error. */ public static function save_uploaded_file($inputname, $data) { require_once 'uploadmanager.php'; $um = new upload_manager($inputname); if ($error = $um->preprocess_file()) { throw new UploadException($error); } $size = $um->file['size']; if (!empty($data->owner)) { global $USER; if ($data->owner == $USER->get('id')) { $owner = $USER; } else { $owner = new User(); $owner->find_by_id($data->owner); } if (!$owner->quota_allowed($size)) { throw new QuotaExceededException(get_string('uploadexceedsquota', 'artefact.file')); } } $data->size = $size; $data->filetype = $um->file['type']; $data->oldextension = $um->original_filename_extension(); $f = self::new_file($um->file['tmp_name'], $data); $f->commit(); $id = $f->get('id'); // Save the file using its id as the filename, and use its id modulo // the number of subdirectories as the directory name. if ($error = $um->save_file(self::get_file_directory($id), $id)) { $f->delete(); throw new UploadException($error); } else { if ($owner) { $owner->quota_add($size); $owner->commit(); } } return $id; }
/** * 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; }
/** * Changes the user's password. * * This method is not strictly part of the authentication API, but if * defined allows the method to change a user's password. * * @param object $user The user to change the password for * @param string $password The password to set for the user * @param boolean $resetpasswordchange Whether to reset the passwordchange variable or not * @return string The new password, or empty if the password could not be set */ public function change_password(User $user, $password, $resetpasswordchange = true, $quickhash = false) { $this->must_be_ready(); // Create a salted password and set it for the user $user->salt = substr(md5(rand(1000000, 9999999)), 2, 8); if ($quickhash) { // $6$ is SHA512, used as a quick hash instead of bcrypt for now. $user->password = $this->encrypt_password($password, $user->salt, '$6$', get_config('passwordsaltmain')); } else { // $2a$ is bcrypt hash. See http://php.net/manual/en/function.crypt.php // It requires a cost, a 2 digit number in the range 04-31 $user->password = $this->encrypt_password($password, $user->salt, '$2a$' . get_config('bcrypt_cost') . '$', get_config('passwordsaltmain')); } if ($resetpasswordchange) { $user->passwordchange = 0; } $user->commit(); return $user->password; }
/** * 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; }
/** * Performs the action; returns true on success, false on error. * * @param $p_context - the current context object * @return bool */ public function takeAction(CampContext &$p_context) { $p_context->default_url->reset_parameter('f_'.$this->m_name); $p_context->url->reset_parameter('f_'.$this->m_name); if (PEAR::isError($this->m_error)) { return false; } $metaUser = $p_context->user; if (!$metaUser->defined) { $this->m_properties['type'] = 'add'; if (!MetaAction::ValidateInput($this->m_properties, 'name', 1, $this->m_error, 'The user name was not filled in.', ACTION_EDIT_USER_ERR_NO_NAME)) { return false; } if (!MetaAction::ValidateInput($this->m_properties, 'uname', 1, $this->m_error, 'The user login name was not filled in.', ACTION_EDIT_USER_ERR_NO_USER_NAME)) { return false; } if (!MetaAction::ValidateInput($this->m_properties, 'password', 6, $this->m_error, 'The user password was not filled in or was too short.', ACTION_EDIT_USER_ERR_NO_PASSWORD)) { return false; } if (!MetaAction::ValidateInput($this->m_properties, 'passwordagain', 6, $this->m_error, 'The password confirmation was not filled in or was too short.', ACTION_EDIT_USER_ERR_NO_PASSWORD_CONFIRMATION)) { return false; } if (!MetaAction::ValidateInput($this->m_properties, 'email', 8, $this->m_error, 'The user email was not filled in or was invalid.', ACTION_EDIT_USER_ERR_NO_EMAIL)) { return false; } if (SystemPref::Get('PLUGIN_RECAPTCHA_SUBSCRIPTIONS_ENABLED') == 'Y') { $captcha = Captcha::factory('ReCAPTCHA'); if (!$captcha->validate()) { $this->m_error = new PEAR_Error('The code you entered is not the same as the one shown.', ACTION_SUBMIT_COMMENT_ERR_INVALID_CAPTCHA_CODE); return false; } } } else { $this->m_properties['type'] = 'edit'; if (isset($this->m_properties['password'])) { if (!MetaAction::ValidateInput($this->m_properties, 'password', 6, $this->m_error, 'The user password was not filled in or was too short.', ACTION_EDIT_USER_ERR_NO_PASSWORD)) { return false; } if (!MetaAction::ValidateInput($this->m_properties, 'passwordagain', 6, $this->m_error, 'The password confirmation was not filled in or was too short.', ACTION_EDIT_USER_ERR_NO_PASSWORD_CONFIRMATION)) { return false; } } } if (isset($this->m_properties['password']) && $this->m_properties['password'] != $this->m_properties['passwordagain']) { $this->m_error = new PEAR_Error("The password and password confirmation do not match.", ACTION_EDIT_USER_ERR_PASSWORD_MISMATCH); return false; } if (!$metaUser->defined) { if (User::UserNameExists($this->m_properties['uname']) || Phorum_user::UserNameExists($this->m_properties['uname'])) { $this->m_error = new PEAR_Error("The login name already exists, please choose a different one.", ACTION_EDIT_USER_ERR_DUPLICATE_USER_NAME); return false; } if (User::EmailExists($this->m_properties['email'])) { $this->m_error = new PEAR_Error("Another user is registered with this e-mail address, please choose a different one.", ACTION_EDIT_USER_ERR_DUPLICATE_EMAIL); return false; } $user = new User(); $phorumUser = new Phorum_user(); if (!$user->create($this->m_data) || !$phorumUser->create($this->m_properties['uname'], $this->m_properties['password'], $this->m_properties['email'], $user->getUserId())) { $user->delete(); $phorumUser->delete(); $this->m_error = new PEAR_Error("There was an internal error creating the account (code 1).", ACTION_EDIT_USER_ERR_INTERNAL); return false; } setcookie("LoginUserId", $user->getUserId(), null, '/'); $user->initLoginKey(); setcookie("LoginUserKey", $user->getKeyId(), null, '/'); $p_context->user = new MetaUser($user->getUserId()); } else { $user = new User($metaUser->identifier); if (!$user->exists()) { $this->m_error = new PEAR_Error("There was an internal error updating the account (code 2).", ACTION_EDIT_USER_ERR_INTERNAL); return false; } $phorumUser = Phorum_user::GetByUserName($user->getUserName()); if (is_null($phorumUser)) { $phorumUser = new Phorum_user(); if (!$phorumUser->create($user->getUserName(), $user->getPassword(), $user->getEmail(), $user->getUserId(), true)) { $this->m_error = new PEAR_Error("There was an internal error updating the account (code 3).", ACTION_EDIT_USER_ERR_INTERNAL); return false; } } foreach ($this->m_properties as $property=>$value) { if (!isset(MetaActionEdit_User::$m_fields[$property]['db_field'])) { continue; } $dbProperty = MetaActionEdit_User::$m_fields[$property]['db_field']; if ($property != 'password' && $property != 'passwordagain') { $user->setProperty($dbProperty, $value, false); if ($property == 'email') { $phorumUser->setProperty('email', $value, false); } } elseif ($property == 'password') { $user->setPassword($this->m_properties['password'], false); $phorumUser->setPassword($this->m_properties['password'], false); } } if (!$user->commit() || !$phorumUser->commit()) { $this->m_error = new PEAR_Error("There was an internal error updating the account (code 4).", ACTION_EDIT_USER_ERR_INTERNAL); return false; } } foreach ($this->m_properties as $property=>$value) { $p_context->default_url->reset_parameter('f_user_'.$property); $p_context->url->reset_parameter('f_user_'.$property); } $this->m_error = ACTION_OK; return true; }