/** * Retrieves base DN of current datasource. * * @return ldap_user current instance * @throws \RuntimeException */ public function elevateForPasswordChange() { if ($this->server instanceof LDAP\server) { exception::enterSensitive(); $dn = $this->setup->read('pwchanger.dn'); $pw = $this->setup->read('pwchanger.token'); if ($dn && $pw) { if ($this->server->simpleBindAs($dn, $pw)->getBoundAs() !== $dn) { throw new \RuntimeException('failed to elevate user for changing password'); } exception::leaveSensitive(); return $this; } throw new \RuntimeException('missing configuration for elevating user on link to datasource'); } throw new \RuntimeException('request for elevating user on unconfigured link to datasource'); }
/** * Processes input while editing/adding user record. * * @param sql_user $provider provider used on creating new user record * @param int|false $userId ID of user to edit, false/0 on adding new user * @return sql_user|null edited or created user, null if creating user failed */ protected function processInputOnEditing($provider, $userId) { if ($userId) { $user = user::load($userId); $userData = array('id' => $user->getID(), 'loginname' => $user->getLoginName(), 'name' => $user->getName(), 'email' => $user->getProperty('email')); } else { $user = null; $userData = array(); } $form = $this->getForm($userData); if ($form->hasInput()) { if (input::vget('submit') == 'cancel') { txf::redirectTo($this->getUrls()->list); } /* * read in and normalize all provided information on user */ $loginName = $user ? $userData['loginname'] : trim(input::vget('loginname')); $name = trim(input::vget('name')); $email = trim(input::vget('email')); $passwordA = trim(input::vget('password')); $passwordB = trim(input::vget('repeat')); /* * validate all information on user */ if ($loginName === '') { $form->setRowError('loginname', \de\toxa\txf\_L('Provide login name of user!')); } else { if (strlen($loginName) > 64) { $form->setRowError('loginname', \de\toxa\txf\_L('Provided login name is too long!')); } } if ($name && strlen($name) > 128) { $form->setRowError('loginname', \de\toxa\txf\_L('Provided full name is too long!')); } if ($email) { if (strlen($name) > 128) { $form->setRowError('loginname', \de\toxa\txf\_L('Provided mail address is too long!')); } else { if (!\de\toxa\txf\mail::isValidAddress($email)) { $form->setRowError('email', \de\toxa\txf\_L('Provided mail address is invalid!')); } } } // validate optionally provided password if (!$user || $passwordA || $passwordB) { if ($passwordA === '' || $passwordB === '') { if ($user) { $form->setRowError('password', \de\toxa\txf\_l('Provide new password twice for excluding typos.')); } else { $form->setRowError('password', \de\toxa\txf\_l('Provide password of new user and repeat for excluding typos.')); } } else { if ($passwordA !== $passwordB) { $form->setRowError('password', \de\toxa\txf\_L('Doubly entered passwords don\'t match.')); } else { try { if (is_callable($this->passwordValidator)) { call_user_func($this->passwordValidator, $passwordA); } else { $this->passwordValidatorDefault($passwordA); } } catch (\InvalidArgumentException $e) { $form->setRowError('password', $e->getMessage()); } } } } /* * save changes to datasource */ $hasError = $form->hasAnyRowError(); if (!$hasError) { exception::enterSensitive(); if ($user) { try { $user->datasource()->transaction()->wrap(function (datasource\connection $conn) use($user, $name, $email, $passwordA) { $user->setProperty('name', $name); $user->setProperty('email', $email); if (trim($passwordA) !== '') { $user->changePassword($passwordA); if ($user->getUUID() === user::current()->getUUID()) { try { user::current()->authenticate($passwordA); } catch (unauthorized_exception $e) { view::flash(\de\toxa\txf\_L('Updating current session for using changed password failed. Probably you need to login, again.'), 'error'); } } } view::flash(\de\toxa\txf\_L('Successfully changed information on selected user.')); return true; }); } catch (\Exception $e) { $hasError = true; view::flash(\de\toxa\txf\_L('Failed to save information on user in datasource.'), 'error'); } } else { try { $user = $provider->create(array('loginname' => $loginName, 'name' => $name, 'password' => $passwordA, 'email' => $email, 'lock' => '')); view::flash(\de\toxa\txf\_L('Successfully created new user.')); } catch (\Exception $e) { $hasError = true; view::flash(\de\toxa\txf\_L('Failed to create new user record in datasource.'), 'error'); } } exception::leaveSensitive(); } if (!$hasError) { txf::redirectTo($this->getUrls()->list); } } return $user; }
/** * Renders exception without utilizing template engine. * * @param \Exception $exception * @return string */ protected static function simpleRenderException(\Exception $exception) { $trace = exception::reduceExceptionTrace($exception, true); return sprintf(<<<EOT <div class="exception-no-skin"> \t<h2>%s (%d)</h2> \t<p>in <strong>%s</strong> at line %s</p> \t<pre>%s</pre> </div> EOT , $exception->getMessage(), $exception->getCode(), exception::reducePathname($exception->getFile()), $exception->getLine(), $trace); }
public function changePassword($newToken) { exception::enterSensitive(); if (preg_match('/\\s/', $newToken) || strlen($newToken) < 8 || strlen($newToken) > 16) { throw new \InvalidArgumentException('invalid password'); } $db = $this->datasource(); $conf = $this->configuration; $sql = sprintf('UPDATE %s SET %s=? WHERE %s=?', $db->qualifyDatasetName($conf['set']), $db->quoteName(name_mapping::mapSingle('password', 'txf.sql_user')), $db->quoteName(name_mapping::mapSingle('id', 'txf.sql_user'))); if ($db->test($sql, blowfish::get($newToken), $this->getID())) { $this->saveCredentials($newToken); $this->record = null; } exception::leaveSensitive(); return true; }
/** * Processes input of widget updating its internal state. * * @return $this current instance */ public function processInput() { if (!user::current()->isAuthenticated()) { view::flash(\de\toxa\txf\_L('You must be logged in.')); $this->redirect(); } $form = $this->getForm(); if ($form->hasInput()) { if (input::vget('submit') == 'cancel') { $this->redirect(); } $passwordOld = trim(input::vget('old')); $passwordNewA = trim(input::vget('new')); $passwordNewB = trim(input::vget('repeat')); if ($passwordOld === '') { $form->setRowError('old', \de\toxa\txf\_L('Provide current password!')); } if ($passwordNewA === '' || $passwordNewB === '') { $form->setRowError('new', \de\toxa\txf\_l('Provide new password twice for excluding typos.')); } else { if ($passwordNewA !== $passwordNewB) { $form->setRowError('new', \de\toxa\txf\_L('Doubly entered passwords don\'t match.')); } else { try { if (is_callable($this->passwordValidator)) { call_user_func($this->passwordValidator, $passwordNewA); } else { $this->passwordValidatorDefault($passwordNewA); } } catch (\InvalidArgumentException $e) { $form->setRowError('new', $e->getMessage()); } } } exception::enterSensitive(); if (!$form->hasAnyRowError()) { try { $user = user::load(user::current()->getID()); try { $user->authenticate($passwordOld); } catch (unauthorized_exception $e) { $form->setRowError('old', \de\toxa\txf\_L('Authenticating request using old password failed.')); } } catch (unauthorized_exception $e) { $form->setRowError('old', \de\toxa\txf\_L('Current user isn\'t available.')); } } $hasError = false; if (!$form->hasAnyRowError()) { try { user::current()->changePassword($passwordNewA); view::flash(\de\toxa\txf\_L('Password has been changed successfully.')); try { user::current()->authenticate($passwordNewA); } catch (unauthorized_exception $e) { view::flash(\de\toxa\txf\_L('Updating current session for using changed password failed. Probably you need to login, again.'), 'error'); } } catch (\RuntimeException $e) { $hasError = true; view::flash(\de\toxa\txf\_L('Your input is okay, but changing password failed nevertheless.'), 'error'); } } exception::leaveSensitive(); if (!$hasError && !$form->hasAnyRowError()) { $this->redirect(); } } else { $session =& txf::session(); $referrer = input::vget('referrer'); $session['referrer'] = url::isRelative($referrer) ? $referrer : null; } return $this; }