/** * Makes user adopting current role. * * @param user $user user to adopt current role * @return $this * @throws \Exception on failing to adopt role */ public function makeAdoptedBy(user $user) { $role = $this; if (!$this->_source->transaction()->wrap(function (datasource\connection $db) use($role, $user) { $userID = $user->getUUID(); $roleID = $role->id; $count = $db->createQuery('user_role')->addCondition('user_uuid=?', true, $userID)->addCondition('role_id=?', true, $roleID)->execute(true)->cell(); if ($count > 0) { // role has been adopted before return true; } $qSet = $db->qualifyDatasetName('user_role'); return $db->test('INSERT INTO ' . $qSet . ' (user_uuid,role_id) VALUES (?,?)', $userID, $roleID) !== false; })) { throw new \RuntimeException(sprintf('adopting role %s by user %s failed', $this->label, $user->getName())); } return $this; }
/** * Processes input of widget updating its internal state. * * @throws http_exception on trying to use widget without authorization * @return $this current instance */ public function processInput() { if (!$this->isUserAuthorized()) { throw new http_exception(403, \de\toxa\txf\_L('You must not manage users!')); } $provider = user::getProvider(); if (!$provider instanceof sql_user) { throw new http_exception(400, \de\toxa\txf\_L('This manager is suitable for managing SQL-based users, only!')); } list($action, $userId) = $this->detectMode(); if ($this->isListing()) { $this->getBrowser()->processInput(); } else { switch ($action) { case 'edit': case 'add': $this->processInputOnEditing($provider, $userId); break; case 'delete': if ($userId === user::current()->getID()) { throw new http_exception(403, \de\toxa\txf\_L('Deleting current user account rejected.')); } user::load($userId)->delete(); txf::redirectTo($this->getUrls()->list); break; default: // TODO implement all else actions (lock, unlock, ...) txf::redirectTo($this->getUrls()->list); } } return $this; }
/** * Retrieves connection to configured datasource containing users database. * * @throws \Exception * @return datasource\connection connection to datasource */ public function datasource() { if (!is_array($this->configuration)) { throw new \RuntimeException(_L('Missing user source configuration.')); } $conf = $this->configuration; $hash = sha1(serialize($conf)); if (!array_key_exists($hash, self::$datasources)) { // gain access on datasource configured to contain users if ($conf['datasource']) { $ds = datasource::selectConfigured($conf['datasource']); } else { $ds = datasource::selectConfigured('default'); } if (!$ds instanceof datasource\pdo) { throw new \UnexpectedValueException(_L('Unsupported kind of datasource for managing users.')); } // apply optionally configured mapping of a user's properties $definition = array('uuid' => 'CHAR(36) NOT NULL', 'loginname' => 'CHAR(64) NOT NULL', 'password' => 'CHAR(128) NOT NULL', 'name' => 'CHAR(128)', 'lock' => 'CHAR(128)', 'email' => 'CHAR(128)'); $mappedDefinition = name_mapping::map($definition, 'txf.sql_user'); // create data set in datasource on demand if (!$ds->createDataset($conf['set'], $mappedDefinition)) { throw $ds->exception(_L('failed to create dataset for managing users')); } // ensure to have a single user at least by default if (!intval($ds->createQuery($conf['set'])->execute(true)->cell())) { $record = name_mapping::map(array('uuid' => uuid::createRandom(), 'loginname' => 'admin', 'password' => blowfish::get('nimda'), 'name' => _L('Administrator'), 'lock' => '', 'email' => ''), 'txf.sql_user'); $currentUser = $this; $ds->transaction()->wrap(function (datasource\connection $conn) use($record, $conf, $currentUser) { $names = array_map(function ($n) use($conn) { return $conn->quoteName($n); }, array_keys($record)); $markers = array_map(function () { return '?'; }, $record); $newUserID = $conn->nextID($conf['set']); $values = array_values($record); array_unshift($values, $newUserID); $sql = sprintf('INSERT INTO %s (id,%s) VALUES (?,%s)', $conn->qualifyDatasetName($conf['set']), implode(',', $names), implode(',', $markers)); if (!$conn->test($sql, $values)) { throw $conn->exception(_L('failed to create default user')); } // load created user for adopting administrator role sql_role::select($conn, 'administrator')->makeAdoptedBy(user::load($newUserID)); return true; }); } self::$datasources[$hash] = $ds; } return self::$datasources[$hash]; }
public function performDelete() { if (!user::current()->isAuthenticated()) { throw new http_exception(403); } $this->prepareControl(); try { $this->getSelectedItem()->delete(); } catch (datasource_exception $e) { view::flash(\de\toxa\txf\_L('Failed deleting selected item.'), 'error'); } catch (\RuntimeException $e) { view::flash(\de\toxa\txf\_L('Selected item does not exist (anymore).'), 'error'); } txf::redirectTo($this->getUrls()->list); }
/** * Indicates whether editor is marked editable. * * @return bool */ public function isEditable() { return user::current()->isAuthenticated() && $this->may['edit']; }
/** * 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 are logged in, already.')); $this->redirect(); } $form = $this->getForm(); if ($form->hasInput()) { if (input::vget('submit') == 'cancel') { $this->redirect(); } $username = input::vget('name'); if ($username) { try { user::setCurrent(user::load($username), input::vget('token')); $this->redirect(); } catch (unauthorized_exception $ex) { if ($ex->isAccountLocked()) { if ($this->resendUnlockMailUrl) { view::flash(sprintf(\de\toxa\txf\_L('Your account is locked! <a href="%s">Resend unlock mail now.</a>'), sprintf($this->resendUnlockMailUrl, $ex->getUser()->getID())), 'error'); } else { view::flash(sprintf(\de\toxa\txf\_L('Your account is locked!')), 'error'); } } else { sleep(3); if ($ex->isUserNotFound()) { view::flash(\de\toxa\txf\_L('User does not exist.'), 'error'); } else { view::flash(\de\toxa\txf\_L('Authentication failed.'), 'error'); } } } } else { view::flash(\de\toxa\txf\_L('Provide login name and password!')); } } else { $session =& txf::session(); $referrer = input::vget('referrer'); $session['referrer'] = url::isRelative($referrer) ? $referrer : null; } return $this; }
/** * 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; }
/** * Processes input of widget updating its internal state. * * @return widget current instance */ public function processInput() { if (user::current()->isAuthenticated()) { user::dropCurrent(); } view::flash(\de\toxa\txf\_L('You logged out successfully.')); $referrer = input::vget('referrer'); $referrer = url::isRelative($referrer) ? $referrer : null; txf::redirectTo(\de\toxa\txf\_1($referrer, 'home')); }