/** * Provides functionality for a user to edit their profile */ public function actionEdit() { $model = Users::model()->findByPk(Yii::app()->user->id); if (Cii::get($_POST, 'Users', NULL) !== NULL) { // Load the bcrypt hashing tools if the user is running a version of PHP < 5.5.x if (!function_exists('password_hash')) { require_once YiiBase::getPathOfAlias('ext.bcrypt.bcrypt') . '.php'; } $cost = Cii::getBcryptCost(); if ($_POST['Users']['password'] != '') { $_POST['Users']['password'] = password_hash(Users::model()->encryptHash($_POST['Users']['email'], $_POST['Users']['password'], Yii::app()->params['encryptionKey']), PASSWORD_BCRYPT, array('cost' => $cost)); } else { unset($_POST['Users']['password']); } unset($_POST['Users']['status']); unset($_POST['Users']['user_role']); $model->attributes = Cii::get($_POST, 'Users', array()); $model->about = Cii::get(Cii::get($_POST, 'Users', array()), 'about', NULL); if ($model->save()) { Yii::app()->user->setFlash('success', Yii::t('ciims.controllers.Profile', 'Your profile has been updated!')); $this->redirect($this->createUrl('/profile/' . $model->id)); } else { Yii::app()->user->setFlash('warning', Yii::t('ciims.controllers.Profile', 'There were errors saving your profile. Please correct them before trying to save again.')); } } $this->render('edit', array('model' => $model)); }
/** * Actually creates the users * @return bool If the user was created */ public function acceptInvite() { if (!$this->validate()) { return false; } $user = Users::model()->findByPk($this->id); // Bcrypt the initial password instead of just using the basic hashing mechanism $hash = Users::model()->encryptHash($this->email, $this->password, Yii::app()->params['encryptionKey']); $cost = Cii::getBcryptCost(); $this->password = password_hash($hash, PASSWORD_BCRYPT, array('cost' => $cost)); $user->attributes = array('email' => $this->email, 'password' => $this->password, 'username' => $this->username, 'status' => Users::ACTIVE); return $user->save(); }
/** * Actually creates the users * @param int $user_id The id of the user that was created * @return bool If the user was created */ public function save($user_id) { $this->id = $user_id; if (!$this->validate()) { return false; } if (!function_exists('password_hash')) { require_once YiiBase::getPathOfAlias('ext.bcrypt.bcrypt') . '.php'; } $user = Users::model()->findByPk($this->id); // Bcrypt the initial password instead of just using the basic hashing mechanism $hash = Users::model()->encryptHash($this->email, $this->password, Yii::app()->params['encryptionKey']); $cost = Cii::getBcryptCost(); $this->password = password_hash($hash, PASSWORD_BCRYPT, array('cost' => $cost)); $user->attributes = array('email' => $this->email, 'password' => $this->password, 'firstName' => $this->firstName, 'lastName' => $this->lastName, 'displayName' => $this->displayName, 'status' => Users::ACTIVE); return $user->save(); }
/** * Sets some default values for the user record. * TODO: This should have been moved to CiiModel * @see CActiveRecord::beforeValidate() **/ public function beforeValidate() { // If the password is nulled, or unchanged if ($this->password == NULL || $this->password == Cii::get($this->_oldAttributes, 'password', false)) { if (!$this->isNewRecord) { $this->password = $this->_oldAttributes['password']; } } else { $this->password = password_hash($this->password, PASSWORD_BCRYPT, array('cost' => Cii::getBcryptCost())); if (!$this->isNewRecord) { $emailSettings = new EmailSettings(); $emailSettings->send($this, Yii::t('ciims.models.Users', 'CiiMS Password Change Notification'), 'webroot.themes.' . Cii::getConfig('theme', 'default') . '.views.email.passwordchange', array('user' => $this)); } } return parent::beforeValidate(); }
/** * Registration page * **/ public function actionRegister() { $this->setPageTitle(Yii::t('ciims.controllers.Site', '{{app_name}} | {{label}}', array('{{app_name}}' => Cii::getConfig('name', Yii::app()->name), '{{label}}' => Yii::t('ciims.controllers.Site', 'Sign Up')))); $this->layout = '//layouts/main'; $model = new RegisterForm(); $user = new Users(); $error = ''; if (isset($_POST) && !empty($_POST)) { $model->attributes = $_POST['RegisterForm']; if ($model->validate()) { if (!function_exists('password_hash')) { require_once YiiBase::getPathOfAlias('ext.bcrypt.bcrypt') . '.php'; } // Bcrypt the initial password instead of just using the basic hashing mechanism $hash = Users::model()->encryptHash(Cii::get($_POST['RegisterForm'], 'email'), Cii::get($_POST['RegisterForm'], 'password'), Yii::app()->params['encryptionKey']); $cost = Cii::getBcryptCost(); $password = password_hash($hash, PASSWORD_BCRYPT, array('cost' => $cost)); $user->attributes = array('email' => Cii::get($_POST['RegisterForm'], 'email'), 'password' => $password, 'firstName' => NULL, 'lastName' => NULL, 'displayName' => Cii::get($_POST['RegisterForm'], 'displayName'), 'user_role' => 1, 'status' => Users::INACTIVE); try { if ($user->save()) { $hash = mb_strimwidth(hash("sha256", md5(time() . md5(hash("sha512", time())))), 0, 16); $meta = new UserMetadata(); $meta->user_id = $user->id; $meta->key = 'activationKey'; $meta->value = $hash; $meta->save(); // Send the registration email $this->sendEmail($user, Yii::t('ciims.email', 'Activate Your Account'), '//email/register', array('user' => $user, 'hash' => $hash), true, true); $this->redirect($this->createUrl('/register-success')); return; } } catch (CDbException $e) { $model->addError(null, Yii::t('ciims.controllers.Site', 'The email address has already been associated to an account. Do you want to login instead?')); } } } $this->render('register', array('model' => $model, 'error' => $error, 'user' => $user)); }
/** * Handles setting up all the data necessary for the workflow * @return void */ private function setup($force = false) { // Set a default error code to indicate if anything changes $this->errorCode = NULL; // Indicate if this is a forced procedure $this->force = $force; // Load the current user $this->getUser(); // Get the current bcrypt cost $this->_cost = Cii::getBcryptCost(); // Preload the number of password attempts. As of 1.10.0 $this->getPasswordAttempts(); return; }
/** * Updates a particular model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id the ID of the model to be updated */ public function actionUpdate($id) { $model = $this->loadModel($id); if (Cii::get($_POST, 'Users', NULL) !== NULL) { // Load the bcrypt hashing tools if the user is running a version of PHP < 5.5.x if (!function_exists('password_hash')) { require_once YiiBase::getPathOfAlias('ext.bcrypt.bcrypt') . '.php'; } $cost = Cii::getBcryptCost(); if ($_POST['Users']['password'] != '') { $_POST['Users']['password'] = password_hash(Users::model()->encryptHash($_POST['Users']['email'], $_POST['Users']['password'], Yii::app()->params['encryptionKey']), PASSWORD_BCRYPT, array('cost' => $cost)); } else { unset($_POST['Users']['password']); } $model->attributes = $_POST['Users']; $model->about = Cii::get($_POST['Users'], 'about', NULL); // Handle saving and updating of Metadata via CDbCommand // By wrapping this in a transaction, we can make sure all metadata is saved AND that the operation goes quickly if (Cii::get($_POST, 'UserMetadata') !== NULL) { $connection = Yii::app()->db; $transaction = $connection->beginTransaction(); $rollback = false; $messge = NULL; foreach (Cii::get($_POST, 'UserMetadata') as $k => $v) { // Allow items to be added if (strpos($k, '__new') !== false) { // Prevent new API keys from being generated $k = str_replace('api_key', '', str_replace(' ', '_', str_replace('__new', '', $k))); $command = $connection->createCommand('INSERT INTO user_metadata (`key`, `value`, user_id, created, updated) VALUES (:key, :value, :id, UTC_TIMESTAMP(), UTC_TIMESTAMP())'); $command->bindParam(':value', $v); } else { if ($v == "" && $k) { $command = $connection->createCommand('DELETE FROM user_metadata WHERE `key` = :key AND user_id = :id'); } else { // And updated $command = $connection->createCommand('UPDATE user_metadata SET `value` = :value, updated = UTC_TIMESTAMP() WHERE `key` = :key AND user_id = :id'); $command->bindParam(':value', $v); } } $k = (string) $k; $command->bindParam(':key', $k); $command->bindParam(':id', $id); try { $ret = $command->execute(); } catch (Exception $e) { $transaction->rollBack(); $message = $e->getMessage(); $rollback = true; break; } } // Allow metadata to be saved independently of the actual model if (!$rollback) { $transaction->commit(); } else { Yii::app()->user->setFlash('error', $message); } } if ($model->save()) { Yii::app()->user->setFlash('success', Yii::t('Dashboard.main', 'User has been updated.')); $this->redirect(array('update', 'id' => $model->id)); } else { $transaction->rollBack(); } } $this->render('update', array('model' => $model)); }
/** * Updates the attributes for a given user with $id. Administrators can always access this method. Users can also edit their own information * @param int $id The user's ID * @return array */ public function updateUser($id) { // Verify a user with that ID exists $user = Users::model()->findByPk($id); if ($user === NULL) { throw new CHttpException(404, Yii::t('Api.user', 'A user with the id of {{id}} was not found.', array('{{id}}' => $id))); } // Load the bcrypt hashing tools if the user is running a version of PHP < 5.5.x if (!function_exists('password_hash')) { require_once YiiBase::getPathOfAlias('ext.bcrypt.bcrypt') . '.php'; } $cost = Cii::getBcryptCost(); // If the password is set, permit it to be changed if (Cii::get($_POST, 'password', NULL) != NULL) { $_POST['password'] = password_hash(Users::model()->encryptHash(Cii::get($_POST, 'email', $user->email), Cii::get($_POST, 'password', NULL), Yii::app()->params['encryptionKey']), PASSWORD_BCRYPT, array('cost' => $cost)); } else { unset($_POST['password']); } unset($_POST['activation_key']); if ($this->user->user_role != 6 && $this->user->user_role != 9) { unset($_POST['status']); unset($_POST['user_role']); } $user->attributes = $_POST; if ($user->save()) { return $user->getAPIAttributes(array('password', 'activation_key')); } return $this->returnError(400, NULL, $user->getErrors()); }