From 2cbf0c32b7e962730b2040485d2963833236c629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Fri, 20 Feb 2015 09:36:41 +0100 Subject: [PATCH] ran php-cs-fixer on everything except extensions --- UsrModule.php | 446 +++--- commands/UsrCommand.php | 98 +- components/CaptchaFormBehavior.php | 43 +- components/DicewareAction.php | 37 +- components/ExampleUserIdentity.php | 1330 +++++++++-------- components/ExpiredPasswordBehavior.php | 97 +- components/FormModelBehavior.php | 145 +- components/IActivatedIdentity.php | 109 +- components/IEditableIdentity.php | 41 +- components/IHybridauthIdentity.php | 35 +- components/IManagedIdentity.php | 54 +- components/IOneTimePasswordIdentity.php | 43 +- components/IPasswordHistoryIdentity.php | 29 +- components/IPictureIdentity.php | 64 +- components/OneTimePasswordAction.php | 106 +- components/OneTimePasswordFormBehavior.php | 417 +++--- components/UsrAlerts.php | 28 +- controllers/DefaultController.php | 699 ++++----- controllers/HybridauthController.php | 94 +- controllers/ManagerController.php | 357 ++--- controllers/UsrController.php | 88 +- messages/config.php | 36 +- messages/cs/usr.php | 2 +- messages/de/usr.php | 2 +- messages/es/auth.php | 2 +- messages/es/manager.php | 2 +- messages/es/usr.php | 2 +- messages/it/usr.php | 2 +- messages/pl/auth.php | 2 +- messages/pl/manager.php | 2 +- messages/pl/usr.php | 2 +- messages/ru/usr.php | 2 +- .../m130701_104658_create_table_users.php | 56 +- ...58_create_table_user_remote_identities.php | 34 +- ...703_104658_users_add_one_time_password.php | 25 +- ...04658_create_table_user_used_passwords.php | 29 +- ...658_create_table_user_profile_pictures.php | 43 +- ...04658_create_table_user_login_attempts.php | 1 - models/BasePasswordForm.php | 256 ++-- models/BaseUsrForm.php | 230 +-- models/ExampleUser.php | 237 +-- models/ExampleUserLoginAttempt.php | 113 +- models/ExampleUserProfilePicture.php | 117 +- models/ExampleUserRemoteIdentity.php | 145 +- models/ExampleUserUsedPassword.php | 106 +- models/HybridauthForm.php | 279 ++-- models/LoginForm.php | 252 ++-- models/OneTimePasswordForm.php | 255 ++-- models/PasswordForm.php | 165 +- models/ProfileForm.php | 335 +++-- models/RecoveryForm.php | 299 ++-- models/SearchForm.php | 133 +- tests/User.php | 8 +- tests/UserLoginAttempt.php | 8 +- tests/UserRemoteIdentity.php | 8 +- tests/UserUsedPassword.php | 8 +- tests/bootstrap.php | 6 +- tests/config.php | 48 +- tests/fixtures/init.php | 36 +- tests/fixtures/tbl_user_used_passwords.php | 10 +- tests/fixtures/tbl_users.php | 60 +- tests/unit/BehaviorsTest.php | 216 +-- tests/unit/LoginFormTest.php | 166 +- tests/unit/ModuleTest.php | 24 +- tests/unit/PasswordFormTest.php | 122 +- tests/unit/ProfileFormTest.php | 152 +- tests/unit/RecoveryFormTest.php | 144 +- tests/unit/UserIdentityTest.php | 248 +-- views/default/_captcha.php | 6 +- views/default/_form.php | 52 +- views/default/_login_remote.php | 16 +- views/default/_newpassword.php | 12 +- views/default/generateOTPSecret.php | 29 +- views/default/index.php | 9 +- views/default/login.php | 47 +- views/default/recovery.php | 47 +- views/default/reset.php | 33 +- views/default/updateProfile.php | 33 +- views/default/verifyOTP.php | 37 +- views/default/viewProfile.php | 41 +- views/emails/it/recovery.php | 24 +- views/emails/it/verify.php | 24 +- views/emails/oneTimePassword.php | 1 - views/emails/pl/recovery.php | 23 +- views/emails/pl/verify.php | 23 +- views/emails/recovery.php | 25 +- views/emails/verify.php | 25 +- views/hybridauth/associate.php | 74 +- views/hybridauth/confirm.php | 68 +- views/hybridauth/login.php | 36 +- views/layouts/email.php | 16 +- views/manager/_search.php | 52 +- views/manager/index.php | 208 +-- views/manager/update.php | 124 +- 94 files changed, 5041 insertions(+), 4834 deletions(-) diff --git a/UsrModule.php b/UsrModule.php index d95bbdf..cd6bdbe 100644 --- a/UsrModule.php +++ b/UsrModule.php @@ -82,113 +82,113 @@ */ class UsrModule extends CWebModule { - /** - * @var boolean Is new user registration enabled. - */ - public $registrationEnabled = true; - /** - * @var boolean Does every new user needs to verify supplied email. - */ - public $requireVerifiedEmail = true; - /** - * @var boolean Is password recovery permitted. - */ - public $recoveryEnabled = true; - /** - * @var integer For how long the user will be logged in without any activity, in seconds. Defaults to 3600*24*30 seconds (30 days). - */ - public $rememberMeDuration = 2592000; - /** - * @var array Set of rules to measure the password strength when choosing new password in the registration or recovery forms. - * Rules should NOT include attribute name, it will be added when they are used. - * If null, defaults to minimum 8 characters and at least one of each: lower and upper case character and a digit. - * @see BasePasswordForm - */ - public $passwordStrengthRules; - /** - * @var array Set of rules that restricts what images can be uploaded as user picture. If null, picture upload is disabled. - * Rules should NOT include attribute name, it will be added when they are used. - * This should probably include a 'file' validator, like in the following example: - * array( - * array('file', 'allowEmpty' => true, 'types'=>'jpg, gif, png', 'maxSize'=>2*1024*1024, 'safe' => false, 'maxFiles' => 1), - * ), - * @see CFileValidator - */ - public $pictureUploadRules; - /** - * @var string Class name of user identity object used to authenticate user. - */ - public $userIdentityClass = 'CUserIdentity'; - /** - * @var string Class name for input form widgets. - */ - public $formClass = 'CActiveForm'; - /** - * @var string Class name for detail view widget. - */ - public $detailViewClass = 'zii.widgets.CDetailView'; - /** - * @var string CSS class for html forms. - */ - public $formCssClass = 'form'; - /** - * @var array static properties of CHtml class, such as errorSummaryCss and errorMessageCss. - */ - public $htmlCss; - /** - * @var string CSS class prefix for flash messages. Set to 'alert alert-' if using Twitter Bootstrap. - */ - public $alertCssClassPrefix = 'flash-'; - /** - * @var string CSS class for the form submit buttons. - */ - public $submitButtonCssClass = ''; - /** + /** + * @var boolean Is new user registration enabled. + */ + public $registrationEnabled = true; + /** + * @var boolean Does every new user needs to verify supplied email. + */ + public $requireVerifiedEmail = true; + /** + * @var boolean Is password recovery permitted. + */ + public $recoveryEnabled = true; + /** + * @var integer For how long the user will be logged in without any activity, in seconds. Defaults to 3600*24*30 seconds (30 days). + */ + public $rememberMeDuration = 2592000; + /** + * @var array Set of rules to measure the password strength when choosing new password in the registration or recovery forms. + * Rules should NOT include attribute name, it will be added when they are used. + * If null, defaults to minimum 8 characters and at least one of each: lower and upper case character and a digit. + * @see BasePasswordForm + */ + public $passwordStrengthRules; + /** + * @var array Set of rules that restricts what images can be uploaded as user picture. If null, picture upload is disabled. + * Rules should NOT include attribute name, it will be added when they are used. + * This should probably include a 'file' validator, like in the following example: + * array( + * array('file', 'allowEmpty' => true, 'types'=>'jpg, gif, png', 'maxSize'=>2*1024*1024, 'safe' => false, 'maxFiles' => 1), + * ), + * @see CFileValidator + */ + public $pictureUploadRules; + /** + * @var string Class name of user identity object used to authenticate user. + */ + public $userIdentityClass = 'CUserIdentity'; + /** + * @var string Class name for input form widgets. + */ + public $formClass = 'CActiveForm'; + /** + * @var string Class name for detail view widget. + */ + public $detailViewClass = 'zii.widgets.CDetailView'; + /** + * @var string CSS class for html forms. + */ + public $formCssClass = 'form'; + /** + * @var array static properties of CHtml class, such as errorSummaryCss and errorMessageCss. + */ + public $htmlCss; + /** + * @var string CSS class prefix for flash messages. Set to 'alert alert-' if using Twitter Bootstrap. + */ + public $alertCssClassPrefix = 'flash-'; + /** + * @var string CSS class for the form submit buttons. + */ + public $submitButtonCssClass = ''; + /** * @var array configuration for PHPMailer, values which are arrays will trigger methods * for each value instead of setting properties. - * For a full reference, please resolve to PHPMailer documentation. - */ - public $mailerConfig = array( - 'SetLanguage' => array('en'), - 'SetFrom' => array('from@example.com', 'Administrator'), - 'AddReplyTo' => array('replyto@example.com','Administrator'), - 'IsMail' => array(), - // SMTP options - //'IsSMTP' => array(), - //'Host' => 'localhost', - //'Port' => 25, - //'Username' => 'login', - //'Password' => 'password', - // extension properties - 'setPathViews' => array('usr.views.emails'), - 'setPathLayouts' => array('usr.views.layouts'), - ); - /** - * @var boolean If true a link for generating passwords will be rendered under new password field. - */ - public $dicewareEnabled = true; - /** - * @var integer Number of words in password generated using the diceware component. - */ - public $dicewareLength = 4; - /** - * @var boolean Should an extra digit be added in password generated using the diceware component. - */ - public $dicewareExtraDigit = true; - /** - * @var integer Should an extra random character be added in password generated using the diceware component. - */ - public $dicewareExtraChar = false; - /** + * For a full reference, please resolve to PHPMailer documentation. + */ + public $mailerConfig = array( + 'SetLanguage' => array('en'), + 'SetFrom' => array('from@example.com', 'Administrator'), + 'AddReplyTo' => array('replyto@example.com','Administrator'), + 'IsMail' => array(), + // SMTP options + //'IsSMTP' => array(), + //'Host' => 'localhost', + //'Port' => 25, + //'Username' => 'login', + //'Password' => 'password', + // extension properties + 'setPathViews' => array('usr.views.emails'), + 'setPathLayouts' => array('usr.views.layouts'), + ); + /** + * @var boolean If true a link for generating passwords will be rendered under new password field. + */ + public $dicewareEnabled = true; + /** + * @var integer Number of words in password generated using the diceware component. + */ + public $dicewareLength = 4; + /** + * @var boolean Should an extra digit be added in password generated using the diceware component. + */ + public $dicewareExtraDigit = true; + /** + * @var integer Should an extra random character be added in password generated using the diceware component. + */ + public $dicewareExtraChar = false; + /** * @var array Available Hybridauth providers, indexed by name, defined as * array( * 'enabled'=>true|false, * 'keys'=>array('id'=>string, 'key'=>string, 'secret'=>string), * 'scope'=>string, * ) - * @see http://hybridauth.sourceforge.net/userguide.html - */ - public $hybridauthProviders = array(); + * @see http://hybridauth.sourceforge.net/userguide.html + */ + public $hybridauthProviders = array(); /** * @var array list of identity attribute names that should be passed to UserIdentity::find() * to find a local identity matching a remote one. @@ -198,13 +198,13 @@ class UsrModule extends CWebModule */ public $associateByAttributes = array('email'); - /** + /** * @var array If not null, CAPTCHA will be enabled on the registration and recovery form * and this will be passed as arguments to the CCaptcha widget. * Remember to include the 'captchaAction'=>'/usr/default/captcha' property. * Adjust the module id. - */ - public $captcha; + */ + public $captcha; /** * @var array Extra behaviors to attach to the profile form. If the view/update views are overriden in a theme * this can be used to display/update extra profile fields. @see FormModelBehavior @@ -225,56 +225,56 @@ class UsrModule extends CWebModule 'reset' => array('view' => 'reset'), 'verifyOTP' => array('view' => 'verifyOTP'), ); - /** - * @var Hybrid_Auth set if $hybridauthProviders are not empty - */ - protected $_hybridauth; + /** + * @var Hybrid_Auth set if $hybridauthProviders are not empty + */ + protected $_hybridauth; - /** - * @inheritdoc - */ - public $controllerMap = array( - 'login' => 'usr.controllers.DefaultController', - 'logout' => 'usr.controllers.DefaultController', - 'reset' => 'usr.controllers.DefaultController', - 'recovery' => 'usr.controllers.DefaultController', - 'register' => 'usr.controllers.DefaultController', - 'profile' => 'usr.controllers.DefaultController', - 'profilePicture' => 'usr.controllers.DefaultController', - 'password' => 'usr.controllers.DefaultController', - ); + /** + * @inheritdoc + */ + public $controllerMap = array( + 'login' => 'usr.controllers.DefaultController', + 'logout' => 'usr.controllers.DefaultController', + 'reset' => 'usr.controllers.DefaultController', + 'recovery' => 'usr.controllers.DefaultController', + 'register' => 'usr.controllers.DefaultController', + 'profile' => 'usr.controllers.DefaultController', + 'profilePicture' => 'usr.controllers.DefaultController', + 'password' => 'usr.controllers.DefaultController', + ); - /** - * @inheritdoc - */ - public function getVersion() - { - return '1.1.0'; - } + /** + * @inheritdoc + */ + public function getVersion() + { + return '1.1.0'; + } - /** - * @inheritdoc - */ - public function init() - { - parent::init(); - $this->setImport(array( - 'usr.models.*', - 'usr.components.*', - )); - $this->setComponents(array( - 'mailer' => array( - 'class' => 'usr.extensions.mailer.EMailer', - 'pathViews' => 'usr.views.emails', - 'pathLayouts' => 'usr.views.layouts', - ), - ), false); - if (is_array($this->htmlCss)) { - foreach($this->htmlCss as $name=>$value) { - CHtml::$$name = $value; - } - } - $this->setupMailer(); + /** + * @inheritdoc + */ + public function init() + { + parent::init(); + $this->setImport(array( + 'usr.models.*', + 'usr.components.*', + )); + $this->setComponents(array( + 'mailer' => array( + 'class' => 'usr.extensions.mailer.EMailer', + 'pathViews' => 'usr.views.emails', + 'pathLayouts' => 'usr.views.layouts', + ), + ), false); + if (is_array($this->htmlCss)) { + foreach ($this->htmlCss as $name => $value) { + CHtml::$$name = $value; + } + } + $this->setupMailer(); if ($this->hybridauthEnabled()) { $hybridauthConfig = array( 'base_url' => Yii::app()->createAbsoluteUrl('/'.$this->id.'/hybridauth/callback'), @@ -282,97 +282,99 @@ public function init() //'debug_mode' => YII_DEBUG, //'debug_file' => Yii::app()->runtimePath . '/hybridauth.log', ); - require dirname(__FILE__) . '/extensions/Hybrid/Auth.php'; + require dirname(__FILE__).'/extensions/Hybrid/Auth.php'; $this->_hybridauth = new Hybrid_Auth($hybridauthConfig); } - } + } + + public function setupMailer() + { + $mailerConfig = array_merge(array( + 'IsHTML' => array(true), + 'CharSet' => 'UTF-8', + 'IsMail' => array(), + 'setPathViews' => array('usr.views.emails'), + 'setPathLayouts' => array('usr.views.layouts'), + ), $this->mailerConfig); + foreach ($mailerConfig as $key => $value) { + if (is_array($value)) { + call_user_func_array(array($this->mailer, $key), $value); + } else { + $this->mailer->$key = $value; + } + } + } - public function setupMailer() - { - $mailerConfig = array_merge(array( - 'IsHTML' => array(true), - 'CharSet' => 'UTF-8', - 'IsMail' => array(), - 'setPathViews' => array('usr.views.emails'), - 'setPathLayouts' => array('usr.views.layouts'), - ), $this->mailerConfig); - foreach($mailerConfig as $key=>$value) { - if (is_array($value)) { - call_user_func_array(array($this->mailer, $key), $value); - } else { - $this->mailer->$key = $value; - } - } - } + /** + * Checks if any Hybridauth provider has been configured. + * @return boolean + */ + public function hybridauthEnabled() + { + $providers = array_filter($this->hybridauthProviders, function ($p) {return !isset($p['enabled']) || $p['enabled'];}); - /** - * Checks if any Hybridauth provider has been configured. - * @return boolean - */ - public function hybridauthEnabled() - { - $providers = array_filter($this->hybridauthProviders, function($p){return !isset($p['enabled']) || $p['enabled'];}); - return !empty($providers); - } + return !empty($providers); + } - /** - * Gets the Hybridauth object - * @return Hybrid_Auth - */ - public function getHybridAuth() - { - return $this->_hybridauth; - } + /** + * Gets the Hybridauth object + * @return Hybrid_Auth + */ + public function getHybridAuth() + { + return $this->_hybridauth; + } - /** - * A factory to create pre-configured form models. Only model class names from the nineinchnick\usr\models namespace are allowed. - * Sets scenario, password strength rules for models extending BasePasswordForm and attaches behaviors. - * - * @param string $class without the namespace - * @param string $scenario - * @return Model - */ - public function createFormModel($class, $scenario='') - { - /** @var CFormModel */ - $form = new $class($scenario); - if ($form instanceof BaseUsrForm) { + /** + * A factory to create pre-configured form models. Only model class names from the nineinchnick\usr\models namespace are allowed. + * Sets scenario, password strength rules for models extending BasePasswordForm and attaches behaviors. + * + * @param string $class without the namespace + * @param string $scenario + * @return Model + */ + public function createFormModel($class, $scenario = '') + { + /** @var CFormModel */ + $form = new $class($scenario); + if ($form instanceof BaseUsrForm) { $form->webUser = Yii::app()->user; } - $form->userIdentityClass = $this->userIdentityClass; - if ($form instanceof BasePasswordForm) { - $form->passwordStrengthRules = $this->passwordStrengthRules; - } - switch($class) { - default: - break; - case 'ProfileForm': - $form->pictureUploadRules = $this->pictureUploadRules; + $form->userIdentityClass = $this->userIdentityClass; + if ($form instanceof BasePasswordForm) { + $form->passwordStrengthRules = $this->passwordStrengthRules; + } + switch ($class) { + default: + break; + case 'ProfileForm': + $form->pictureUploadRules = $this->pictureUploadRules; if (!empty($this->profileFormBehaviors)) { - foreach($this->profileFormBehaviors as $name=>$config) { + foreach ($this->profileFormBehaviors as $name => $config) { $form->attachBehavior($name, $config); } } - case 'RecoveryForm': - if ($this->captcha !== null && CCaptcha::checkRequirements()) { - $form->attachBehavior('captcha', array( - 'class' => 'CaptchaFormBehavior', - 'ruleOptions' => $class == 'ProfileForm' ? array('on'=>'register') : array('except'=>'reset,verify'), - )); - } - break; - case 'LoginForm': - if ($this->loginFormBehaviors!==null && is_array($this->loginFormBehaviors)) { + case 'RecoveryForm': + if ($this->captcha !== null && CCaptcha::checkRequirements()) { + $form->attachBehavior('captcha', array( + 'class' => 'CaptchaFormBehavior', + 'ruleOptions' => $class == 'ProfileForm' ? array('on' => 'register') : array('except' => 'reset,verify'), + )); + } + break; + case 'LoginForm': + if ($this->loginFormBehaviors !== null && is_array($this->loginFormBehaviors)) { foreach ($this->loginFormBehaviors as $name => $config) { $form->attachBehavior($name, $config); } } - break; + break; case 'HybridauthForm': $form->setValidProviders($this->hybridauthProviders); $form->setHybridAuth($this->getHybridAuth()); break; - } - return $form; - } + } + + return $form; + } } diff --git a/commands/UsrCommand.php b/commands/UsrCommand.php index 6182dbe..ffe0c58 100644 --- a/commands/UsrCommand.php +++ b/commands/UsrCommand.php @@ -4,22 +4,26 @@ class UsrCommand extends CConsoleCommand { public function actionPassword($count = 1, $length = null, $extra_digit = null, $extra_char = null) { - $usrModule = Yii::app()->getModule('usr'); - if ($length === null) - $length = $usrModule->dicewareLength; - if ($extra_digit === null) - $extra_digit = $usrModule->dicewareExtraDigit; - if ($extra_char === null) - $extra_char = $usrModule->dicewareExtraChar; + $usrModule = Yii::app()->getModule('usr'); + if ($length === null) { + $length = $usrModule->dicewareLength; + } + if ($extra_digit === null) { + $extra_digit = $usrModule->dicewareExtraDigit; + } + if ($extra_char === null) { + $extra_char = $usrModule->dicewareExtraChar; + } - require dirname(__FILE__) . '/../extensions/diceware/Diceware.php'; - $diceware = new \nineinchnick\diceware\Diceware(Yii::app()->language); - for ($i = 0; $i < $count; $i++) - echo $diceware->get_phrase($length, $extra_digit, $extra_char) . "\n"; - } + require dirname(__FILE__).'/../extensions/diceware/Diceware.php'; + $diceware = new \nineinchnick\diceware\Diceware(Yii::app()->language); + for ($i = 0; $i < $count; $i++) { + echo $diceware->get_phrase($length, $extra_digit, $extra_char)."\n"; + } + } /** - * usr.manage + * usr.manage * |-usr.create * |-usr.read * |-usr.update @@ -32,15 +36,15 @@ public function actionPassword($count = 1, $length = null, $extra_digit = null, public function getTemplateAuthItems() { return array( - array('name'=> 'usr.manage', 'child' => null, 'type'=>CAuthItem::TYPE_TASK), - array('name'=> 'usr.create', 'child' => 'usr.manage'), - array('name'=> 'usr.read', 'child' => 'usr.manage'), - array('name'=> 'usr.update', 'child' => 'usr.manage'), - array('name'=> 'usr.update.status', 'child' => 'usr.update'), - array('name'=> 'usr.update.auth', 'child' => 'usr.update'), - array('name'=> 'usr.update.attributes','child' => 'usr.update'), - array('name'=> 'usr.update.password', 'child' => 'usr.update'), - array('name'=> 'usr.delete', 'child' => 'usr.manage'), + array('name' => 'usr.manage', 'child' => null, 'type' => CAuthItem::TYPE_TASK), + array('name' => 'usr.create', 'child' => 'usr.manage'), + array('name' => 'usr.read', 'child' => 'usr.manage'), + array('name' => 'usr.update', 'child' => 'usr.manage'), + array('name' => 'usr.update.status', 'child' => 'usr.update'), + array('name' => 'usr.update.auth', 'child' => 'usr.update'), + array('name' => 'usr.update.attributes','child' => 'usr.update'), + array('name' => 'usr.update.password', 'child' => 'usr.update'), + array('name' => 'usr.delete', 'child' => 'usr.manage'), ); } @@ -61,50 +65,51 @@ public function getTemplateAuthItemDescriptions() public function actionCreateAuthItems() { - $auth = Yii::app()->authManager; + $auth = Yii::app()->authManager; $newAuthItems = array(); $descriptions = $this->getTemplateAuthItemDescriptions(); - foreach($this->getTemplateAuthItems() as $template) { + foreach ($this->getTemplateAuthItems() as $template) { $newAuthItems[$template['name']] = $template; } - $existingAuthItems = $auth->getAuthItems(); - foreach($existingAuthItems as $name=>$existingAuthItem) { - if (isset($newAuthItems[$name])) + $existingAuthItems = $auth->getAuthItems(); + foreach ($existingAuthItems as $name => $existingAuthItem) { + if (isset($newAuthItems[$name])) { unset($newAuthItems[$name]); + } } - foreach($newAuthItems as $template) { - $type = isset($template['type']) ? $template['type'] : CAuthItem::TYPE_OPERATION; - $bizRule = isset($template['bizRule']) ? $template['bizRule'] : null; + foreach ($newAuthItems as $template) { + $type = isset($template['type']) ? $template['type'] : CAuthItem::TYPE_OPERATION; + $bizRule = isset($template['bizRule']) ? $template['bizRule'] : null; $auth->createAuthItem($template['name'], $type, $descriptions[$template['name']], $bizRule); if (isset($template['child']) && $template['child'] !== null) { $auth->addItemChild($template['child'], $template['name']); } } - } + } public function actionRemoveAuthItems() { - $auth = Yii::app()->authManager; + $auth = Yii::app()->authManager; - foreach($this->getTemplateAuthItems() as $template) { + foreach ($this->getTemplateAuthItems() as $template) { $auth->removeAuthItem($template['name']); } } /** * Creating users using this command DOES NOT send the activation email. - * @param string $profile a POST (username=XX&password=YY) or JSON object with the profile form, can contain the password field - * @param string $authItems a comma separated list of auth items to assign + * @param string $profile a POST (username=XX&password=YY) or JSON object with the profile form, can contain the password field + * @param string $authItems a comma separated list of auth items to assign * @param boolean $generatePassword if true, a random password will be generated even if profile contains one */ public function actionRegister($profile, $authItems = null, $generatePassword = false, $unlock = false) { $module = Yii::app()->getModule('usr'); - /** @var ProfileForm */ - $model = $module->createFormModel('ProfileForm', 'register'); - /** @var PasswordForm */ - $passwordForm = $module->createFormModel('PasswordForm', 'register'); + /** @var ProfileForm */ + $model = $module->createFormModel('ProfileForm', 'register'); + /** @var PasswordForm */ + $passwordForm = $module->createFormModel('PasswordForm', 'register'); if (($profileData = json_decode($profile)) === null) { parse_str($profile, $profileData); @@ -114,7 +119,7 @@ public function actionRegister($profile, $authItems = null, $generatePassword = $passwordForm->setAttributes(array('newPassword' => $profile['password'], 'newVerify' => $profile['password'])); } if ($generatePassword) { - require dirname(__FILE__) . '/../extensions/diceware/Diceware.php'; + require dirname(__FILE__).'/../extensions/diceware/Diceware.php'; $diceware = new \nineinchnick\diceware\Diceware(Yii::app()->language); $password = $diceware->get_phrase($module->dicewareLength, $module->dicewareExtraDigit, $module->dicewareExtraChar); $passwordForm->setAttributes(array('newPassword' => $password, 'newVerify' => $password)); @@ -125,28 +130,33 @@ public function actionRegister($profile, $authItems = null, $generatePassword = if (!$model->save() || !$passwordForm->resetPassword($model->getIdentity())) { $trx->rollback(); echo Yii::t('UsrModule.usr', 'Failed to register a new user.')."\n"; + return false; } else { $trx->commit(); echo $model->username.' '.$passwordForm->newPassword."\n"; $identity = $model->getIdentity(); if ($authItems !== null) { - $authItems = array_map('trim', explode(',', trim($authItems," \t\n\r\b\x0B,"))); + $authItems = array_map('trim', explode(',', trim($authItems, " \t\n\r\b\x0B,"))); $authManager = Yii::app()->authManager; - foreach($authItems as $authItemName) { + foreach ($authItems as $authItemName) { $authManager->assign($authItemName, $identity->getId()); } } if ($unlock) { - if (!$identity->isActive()) + if (!$identity->isActive()) { $identity->toggleStatus($identity::STATUS_IS_ACTIVE); - if ($identity->isDisabled()) + } + if ($identity->isDisabled()) { $identity->toggleStatus($identity::STATUS_IS_DISABLED); + } } + return true; } } echo "Invalid data: ".print_r($model->getErrors(), true)."\n"; + return false; } } diff --git a/components/CaptchaFormBehavior.php b/components/CaptchaFormBehavior.php index 3849b9f..d03d89b 100644 --- a/components/CaptchaFormBehavior.php +++ b/components/CaptchaFormBehavior.php @@ -15,27 +15,28 @@ */ class CaptchaFormBehavior extends FormModelBehavior { - public $verifyCode; + public $verifyCode; - /** - * @inheritdoc - */ - public function filterRules($rules = array()) - { - $module = Yii::app()->controller !== null ? Yii::app()->controller->module : null; - $behaviorRules = array( - array('verifyCode', 'captcha', 'captchaAction'=>($module !== null ? $module->getId() : 'usr').'/default/captcha'), - ); - return array_merge($rules, $this->applyRuleOptions($behaviorRules)); - } + /** + * @inheritdoc + */ + public function filterRules($rules = array()) + { + $module = Yii::app()->controller !== null ? Yii::app()->controller->module : null; + $behaviorRules = array( + array('verifyCode', 'captcha', 'captchaAction' => ($module !== null ? $module->getId() : 'usr').'/default/captcha'), + ); - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'verifyCode' => Yii::t('UsrModule.usr','Verification code'), - ); - } + return array_merge($rules, $this->applyRuleOptions($behaviorRules)); + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'verifyCode' => Yii::t('UsrModule.usr', 'Verification code'), + ); + } } diff --git a/components/DicewareAction.php b/components/DicewareAction.php index 4f525ce..9f29200 100644 --- a/components/DicewareAction.php +++ b/components/DicewareAction.php @@ -5,23 +5,24 @@ */ class DicewareAction extends CAction { - /** - * @var integer Number of words in password generated using the diceware component. - */ - public $length; - /** - * @var boolean Should an extra digit be added in password generated using the diceware component. - */ - public $extraDigit; - /** - * @var integer Should an extra random character be added in password generated using the diceware component. - */ - public $extraChar; + /** + * @var integer Number of words in password generated using the diceware component. + */ + public $length; + /** + * @var boolean Should an extra digit be added in password generated using the diceware component. + */ + public $extraDigit; + /** + * @var integer Should an extra random character be added in password generated using the diceware component. + */ + public $extraChar; - public function run() { - require dirname(__FILE__) . '/../extensions/diceware/Diceware.php'; - $diceware = new \nineinchnick\diceware\Diceware(Yii::app()->language); - $password = $diceware->get_phrase($this->length, $this->extraDigit, $this->extraChar); - echo json_encode($password); - } + public function run() + { + require dirname(__FILE__).'/../extensions/diceware/Diceware.php'; + $diceware = new \nineinchnick\diceware\Diceware(Yii::app()->language); + $password = $diceware->get_phrase($this->length, $this->extraDigit, $this->extraChar); + echo json_encode($password); + } } diff --git a/components/ExampleUserIdentity.php b/components/ExampleUserIdentity.php index 56a5769..6a69f8f 100644 --- a/components/ExampleUserIdentity.php +++ b/components/ExampleUserIdentity.php @@ -8,63 +8,65 @@ * data can identity the user. */ abstract class ExampleUserIdentity extends CUserIdentity - implements IPasswordHistoryIdentity, - IActivatedIdentity, - IEditableIdentity, - IHybridauthIdentity, - IOneTimePasswordIdentity, - IPictureIdentity, - IManagedIdentity + implements IPasswordHistoryIdentity, + IActivatedIdentity, + IEditableIdentity, + IHybridauthIdentity, + IOneTimePasswordIdentity, + IPictureIdentity, + IManagedIdentity { - const ERROR_USER_DISABLED=1000; - const ERROR_USER_INACTIVE=1001; - const ERROR_USER_LOCKED=1002; + const ERROR_USER_DISABLED = 1000; + const ERROR_USER_INACTIVE = 1001; + const ERROR_USER_LOCKED = 1002; const MAX_FAILED_LOGIN_ATTEMPTS = 5; const LOGIN_ATTEMPTS_COUNT_SECONDS = 1800; - public $email = null; - public $firstName = null; - public $lastName = null; - private $_id = null; - private $_activeRecord = null; - - protected static function createFromUser(User $user) - { - $identity = new UserIdentity($user->username, null); - $identity->initFromUser($user); - return $identity; - } - - protected function initFromUser(User $user) - { - $this->_activeRecord = $user; - $this->id = $user->getPrimaryKey(); - $this->username = $user->username; - $this->email = $user->email; - $this->firstName = $user->firstname; - $this->lastName = $user->lastname; - } - - protected function getActiveRecord() - { - if ($this->_activeRecord === null && $this->_id !== null) { - $this->_activeRecord = User::model()->findByPk($this->_id); - } - return $this->_activeRecord; - } - - // {{{ IUserIdentity + public $email = null; + public $firstName = null; + public $lastName = null; + private $_id = null; + private $_activeRecord = null; + + protected static function createFromUser(User $user) + { + $identity = new UserIdentity($user->username, null); + $identity->initFromUser($user); + + return $identity; + } + + protected function initFromUser(User $user) + { + $this->_activeRecord = $user; + $this->id = $user->getPrimaryKey(); + $this->username = $user->username; + $this->email = $user->email; + $this->firstName = $user->firstname; + $this->lastName = $user->lastname; + } + + protected function getActiveRecord() + { + if ($this->_activeRecord === null && $this->_id !== null) { + $this->_activeRecord = User::model()->findByPk($this->_id); + } + + return $this->_activeRecord; + } + + // {{{ IUserIdentity /** * @inheritdoc */ public function authenticate() { - $record = User::model()->findByAttributes(array('username'=>$this->username)); + $record = User::model()->findByAttributes(array('username' => $this->username)); $authenticated = $record !== null && $record->verifyPassword($this->password); - $attempt = new UserLoginAttempt; + $attempt = new UserLoginAttempt(); $attempt->username = $this->username; $attempt->user_id = $record === null ? null : $record->id; $attempt->is_successful = $authenticated; @@ -72,389 +74,414 @@ public function authenticate() if (UserLoginAttempt::hasTooManyFailedAttempts($this->username, self::MAX_FAILED_LOGIN_ATTEMPTS, self::LOGIN_ATTEMPTS_COUNT_SECONDS)) { // this is the first check not to reveal if the specified user account exists or not - $this->errorCode=self::ERROR_USER_LOCKED; - $this->errorMessage=Yii::t('UsrModule.usr','User account has been locked due to too many failed login attempts. Try again later.'); + $this->errorCode = self::ERROR_USER_LOCKED; + $this->errorMessage = Yii::t('UsrModule.usr', 'User account has been locked due to too many failed login attempts. Try again later.'); } elseif (!$authenticated) { - $this->errorCode=self::ERROR_USERNAME_INVALID; - $this->errorMessage=Yii::t('UsrModule.usr','Invalid username or password.'); + $this->errorCode = self::ERROR_USERNAME_INVALID; + $this->errorMessage = Yii::t('UsrModule.usr', 'Invalid username or password.'); } elseif ($record->is_disabled) { - $this->errorCode=self::ERROR_USER_DISABLED; - $this->errorMessage=Yii::t('UsrModule.usr','User account has been disabled.'); - } else if (!$record->is_active) { - $this->errorCode=self::ERROR_USER_INACTIVE; - $this->errorMessage=Yii::t('UsrModule.usr','User account has not been activated yet.'); + $this->errorCode = self::ERROR_USER_DISABLED; + $this->errorMessage = Yii::t('UsrModule.usr', 'User account has been disabled.'); + } elseif (!$record->is_active) { + $this->errorCode = self::ERROR_USER_INACTIVE; + $this->errorMessage = Yii::t('UsrModule.usr', 'User account has not been activated yet.'); } else { - $this->errorCode=self::ERROR_NONE; - $this->errorMessage=''; + $this->errorCode = self::ERROR_NONE; + $this->errorMessage = ''; $this->initFromUser($record); - $record->saveAttributes(array('last_visit_on'=>date('Y-m-d H:i:s'))); + $record->saveAttributes(array('last_visit_on' => date('Y-m-d H:i:s'))); } + return $this->getIsAuthenticated(); } - public function setId($id) - { - $this->_id = $id; - } - - /** - * @return int|string current user ID - */ - public function getId() - { - return $this->_id; - } - - // }}} - - // {{{ PasswordHistoryIdentityInterface - - /** - * Returns the date when specified password was last set or null if it was never used before. - * If null is passed, returns date of setting current password. - * @param string $password new password or null if checking when the current password has been set - * @return string date in YYYY-MM-DD format or null if password was never used. - */ - public function getPasswordDate($password = null) - { - if (($record=$this->getActiveRecord()) === null) - return null; - - if ($password === null) { - return $record->password_set_on; - } else { - foreach($record->userUsedPasswords as $usedPassword) { - if ($usedPassword->verifyPassword($password)) - return $usedPassword->set_on; - } - } - return null; - } - - /** - * Changes the password and updates last password change date. - * Saves old password so it couldn't be used again. - * @param string $password new password - * @return boolean - */ - public function resetPassword($password) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - $hashedPassword = User::hashPassword($password); - $usedPassword = new UserUsedPassword; - $usedPassword->setAttributes(array( - 'user_id'=>$this->_id, - 'password'=>$hashedPassword, - 'set_on'=>date('Y-m-d H:i:s'), - ), false); - return $usedPassword->save() && $record->saveAttributes(array( - 'password'=>$hashedPassword, - 'password_set_on'=>date('Y-m-d H:i:s'), - )); - } - - // }}} - - // {{{ EditableIdentityInterface - - /** - * Saves a new or existing identity. Does not set or change the password. - * @see IPasswordHistoryIdentity::resetPassword() - * Should detect if the email changed and mark it as not verified. - * @param boolean $requireVerifiedEmail - * @return boolean - */ - public function save($requireVerifiedEmail=false) - { - if ($this->_id === null) { - $record = new User; - $record->password = 'x'; - $record->is_active = $requireVerifiedEmail ? 0 : 1; - } else { - $record = $this->getActiveRecord(); - } - if ($record!==null) { - $record->setAttributes(array( - 'username' => $this->username, - 'email' => $this->email, - 'firstname' => $this->firstName, - 'lastname' => $this->lastName, - )); - if ($record->save()) { - $this->_id = $record->getPrimaryKey(); - $this->initFromUser($record); - return true; - } - Yii::log('Failed to save user: '.print_r($record->getErrors(),true), 'warning'); - } else { - Yii::log('Trying to save UserIdentity but no matching User has been found', 'warning'); - } - return false; - } - - /** - * Sets attributes like username, email, first and last name. - * Password should be changed using only the resetPassword() method from the IPasswordHistoryIdentity. - * @param array $attributes - * @return boolean - */ - public function setAttributes(array $attributes) - { - $allowedAttributes = array('username','email','firstName','lastName'); - foreach($attributes as $name=>$value) { - if (in_array($name, $allowedAttributes)) - $this->$name = $value; - } - return true; - } - - /** - * Returns attributes like username, email, first and last name. - * @return array - */ - public function getAttributes() - { - return array( - 'username' => $this->username, - 'email' => $this->email, - 'firstName' => $this->firstName, - 'lastName' => $this->lastName, - ); - } - - // }}} - - // {{{ ActivatedIdentityInterface + public function setId($id) + { + $this->_id = $id; + } + + /** + * @return int|string current user ID + */ + public function getId() + { + return $this->_id; + } + + // }}} + + // {{{ PasswordHistoryIdentityInterface + + /** + * Returns the date when specified password was last set or null if it was never used before. + * If null is passed, returns date of setting current password. + * @param string $password new password or null if checking when the current password has been set + * @return string date in YYYY-MM-DD format or null if password was never used. + */ + public function getPasswordDate($password = null) + { + if (($record = $this->getActiveRecord()) === null) { + return null; + } + + if ($password === null) { + return $record->password_set_on; + } else { + foreach ($record->userUsedPasswords as $usedPassword) { + if ($usedPassword->verifyPassword($password)) { + return $usedPassword->set_on; + } + } + } + + return null; + } + + /** + * Changes the password and updates last password change date. + * Saves old password so it couldn't be used again. + * @param string $password new password + * @return boolean + */ + public function resetPassword($password) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + $hashedPassword = User::hashPassword($password); + $usedPassword = new UserUsedPassword(); + $usedPassword->setAttributes(array( + 'user_id' => $this->_id, + 'password' => $hashedPassword, + 'set_on' => date('Y-m-d H:i:s'), + ), false); + + return $usedPassword->save() && $record->saveAttributes(array( + 'password' => $hashedPassword, + 'password_set_on' => date('Y-m-d H:i:s'), + )); + } + + // }}} + + // {{{ EditableIdentityInterface + + /** + * Saves a new or existing identity. Does not set or change the password. + * @see IPasswordHistoryIdentity::resetPassword() + * Should detect if the email changed and mark it as not verified. + * @param boolean $requireVerifiedEmail + * @return boolean + */ + public function save($requireVerifiedEmail = false) + { + if ($this->_id === null) { + $record = new User(); + $record->password = 'x'; + $record->is_active = $requireVerifiedEmail ? 0 : 1; + } else { + $record = $this->getActiveRecord(); + } + if ($record !== null) { + $record->setAttributes(array( + 'username' => $this->username, + 'email' => $this->email, + 'firstname' => $this->firstName, + 'lastname' => $this->lastName, + )); + if ($record->save()) { + $this->_id = $record->getPrimaryKey(); + $this->initFromUser($record); + + return true; + } + Yii::log('Failed to save user: '.print_r($record->getErrors(), true), 'warning'); + } else { + Yii::log('Trying to save UserIdentity but no matching User has been found', 'warning'); + } + + return false; + } + + /** + * Sets attributes like username, email, first and last name. + * Password should be changed using only the resetPassword() method from the IPasswordHistoryIdentity. + * @param array $attributes + * @return boolean + */ + public function setAttributes(array $attributes) + { + $allowedAttributes = array('username','email','firstName','lastName'); + foreach ($attributes as $name => $value) { + if (in_array($name, $allowedAttributes)) { + $this->$name = $value; + } + } + + return true; + } + + /** + * Returns attributes like username, email, first and last name. + * @return array + */ + public function getAttributes() + { + return array( + 'username' => $this->username, + 'email' => $this->email, + 'firstName' => $this->firstName, + 'lastName' => $this->lastName, + ); + } + + // }}} + + // {{{ ActivatedIdentityInterface /** * @inheritdoc */ - public static function find(array $attributes) - { - $records = User::model()->findAllByAttributes($attributes); - if (count($records)!==1) { + public static function find(array $attributes) + { + $records = User::model()->findAllByAttributes($attributes); + if (count($records) !== 1) { return null; } $record = reset($records); - return self::createFromUser($record); - } - - /** - * Checkes if user account is active. This should not include disabled (banned) status. - * This could include if the email address has been verified. - * Same checks should be done in the authenticate() method, because this method is not called before logging in. - * @return boolean - */ - public function isActive() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return (bool)$record->is_active; - } - - /** - * Checkes if user account is disabled (banned). This should not include active status. - * @return boolean - */ - public function isDisabled() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return (bool)$record->is_disabled; - } - - /** - * Checkes if user email address is verified. - * @return boolean - */ - public function isVerified() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return (bool)$record->email_verified; - } - - /** - * Generates and saves a new activation key used for verifying email and restoring lost password. - * The activation key is then sent by email to the user. - * - * Note: only the last generated activation key should be valid and an activation key - * should have it's generation date saved to verify it's age later. - * - * @return string - */ - public function getActivationKey() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - $activationKey = md5(time().mt_rand().$record->username); - if (!$record->saveAttributes(array('activation_key' => $activationKey))) { - return false; - } - return $activationKey; - } - - /** - * Verifies if specified activation key matches the saved one and if it's not too old. - * This method should not alter any saved data. - * @return integer the verification error code. If there is an error, the error code will be non-zero. - */ - public function verifyActivationKey($activationKey) - { - if (($record=$this->getActiveRecord())===null) { - return self::ERROR_AKEY_INVALID; - } - return $record->activation_key === $activationKey ? self::ERROR_AKEY_NONE : self::ERROR_AKEY_INVALID; - } - - /** - * Verify users email address, which could also activate his account and allow him to log in. - * Call only after verifying the activation key. - * @param boolean $requireVerifiedEmail - * @return boolean - */ - public function verifyEmail($requireVerifiedEmail=false) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - /** - * Only update $record if it's not already been updated, otherwise - * saveAttributes will return false, incorrectly suggesting - * failure. - */ - if (!$record->email_verified) { - $attributes = array('email_verified' => 1); - - if ($requireVerifiedEmail && !$record->is_active) { - $attributes['is_active'] = 1; - } - if (!$record->saveAttributes($attributes)) { - return false; - } - } - return true; - } - - /** - * Returns user email address. - * @return string - */ - public function getEmail() - { - return $this->email; - } - - // }}} - - // {{{ OneTimePasswordIdentityInterface - - /** - * Returns current secret used to generate one time passwords. If it's null, two step auth is disabled. - * @return string - */ - public function getOneTimePasswordSecret() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return $record->one_time_password_secret; - } - - /** - * Sets current secret used to generate one time passwords. If it's null, two step auth is disabled. - * @param string $secret - * @return boolean - */ - public function setOneTimePasswordSecret($secret) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return $record->saveAttributes(array('one_time_password_secret' => $secret)); - } - - /** - * Returns previously used one time password and value of counter used to generate current one time password, used in counter mode. - * @return array array(string, integer) - */ - public function getOneTimePassword() - { - if (($record=$this->getActiveRecord())===null) { - return array(null, null); - } - return array( - $record->one_time_password_code, - $record->one_time_password_counter === null ? 1 : $record->one_time_password_counter, - ); - } - - /** - * Sets previously used one time password and value of counter used to generate current one time password, used in counter mode. - * @return boolean - */ - public function setOneTimePassword($password, $counter = 1) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return $record->saveAttributes(array( - 'one_time_password_code' => $password, - 'one_time_password_counter' => $counter, - )); - } - - // }}} - - // {{{ HybridauthIdentityInterface - - /** - * Loads a specific user identity connected to specified provider by an identifier. - * @param string $provider - * @param string $identifier - * @return object a user identity object or null if not found. - */ - public static function findByProvider($provider, $identifier) - { - $criteria = new CDbCriteria; - $criteria->with['userRemoteIdentities'] = array('alias'=>'ur'); - $criteria->compare('ur.provider',$provider); - $criteria->compare('ur.identifier',$identifier); - $record = User::model()->find($criteria); - return $record === null ? null : self::createFromUser($record); - } - - /** - * @inheritdoc - */ - public function addRemoteIdentity($provider, $identifier) - { - if ($this->_id===null) - return false; - UserRemoteIdentity::model()->deleteAllByAttributes(array('provider'=>$provider, 'identifier'=>$identifier)); - $model = new UserRemoteIdentity; - $model->setAttributes(array( - 'user_id' => $this->_id, - 'provider' => $provider, - 'identifier' => $identifier, - ), false); - return $model->save(); - } + + return self::createFromUser($record); + } + + /** + * Checkes if user account is active. This should not include disabled (banned) status. + * This could include if the email address has been verified. + * Same checks should be done in the authenticate() method, because this method is not called before logging in. + * @return boolean + */ + public function isActive() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return (bool) $record->is_active; + } + + /** + * Checkes if user account is disabled (banned). This should not include active status. + * @return boolean + */ + public function isDisabled() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return (bool) $record->is_disabled; + } + + /** + * Checkes if user email address is verified. + * @return boolean + */ + public function isVerified() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return (bool) $record->email_verified; + } + + /** + * Generates and saves a new activation key used for verifying email and restoring lost password. + * The activation key is then sent by email to the user. + * + * Note: only the last generated activation key should be valid and an activation key + * should have it's generation date saved to verify it's age later. + * + * @return string + */ + public function getActivationKey() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + $activationKey = md5(time().mt_rand().$record->username); + if (!$record->saveAttributes(array('activation_key' => $activationKey))) { + return false; + } + + return $activationKey; + } + + /** + * Verifies if specified activation key matches the saved one and if it's not too old. + * This method should not alter any saved data. + * @return integer the verification error code. If there is an error, the error code will be non-zero. + */ + public function verifyActivationKey($activationKey) + { + if (($record = $this->getActiveRecord()) === null) { + return self::ERROR_AKEY_INVALID; + } + + return $record->activation_key === $activationKey ? self::ERROR_AKEY_NONE : self::ERROR_AKEY_INVALID; + } + + /** + * Verify users email address, which could also activate his account and allow him to log in. + * Call only after verifying the activation key. + * @param boolean $requireVerifiedEmail + * @return boolean + */ + public function verifyEmail($requireVerifiedEmail = false) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + /** + * Only update $record if it's not already been updated, otherwise + * saveAttributes will return false, incorrectly suggesting + * failure. + */ + if (!$record->email_verified) { + $attributes = array('email_verified' => 1); + + if ($requireVerifiedEmail && !$record->is_active) { + $attributes['is_active'] = 1; + } + if (!$record->saveAttributes($attributes)) { + return false; + } + } + + return true; + } + + /** + * Returns user email address. + * @return string + */ + public function getEmail() + { + return $this->email; + } + + // }}} + + // {{{ OneTimePasswordIdentityInterface + + /** + * Returns current secret used to generate one time passwords. If it's null, two step auth is disabled. + * @return string + */ + public function getOneTimePasswordSecret() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return $record->one_time_password_secret; + } + + /** + * Sets current secret used to generate one time passwords. If it's null, two step auth is disabled. + * @param string $secret + * @return boolean + */ + public function setOneTimePasswordSecret($secret) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return $record->saveAttributes(array('one_time_password_secret' => $secret)); + } + + /** + * Returns previously used one time password and value of counter used to generate current one time password, used in counter mode. + * @return array array(string, integer) + */ + public function getOneTimePassword() + { + if (($record = $this->getActiveRecord()) === null) { + return array(null, null); + } + + return array( + $record->one_time_password_code, + $record->one_time_password_counter === null ? 1 : $record->one_time_password_counter, + ); + } + + /** + * Sets previously used one time password and value of counter used to generate current one time password, used in counter mode. + * @return boolean + */ + public function setOneTimePassword($password, $counter = 1) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return $record->saveAttributes(array( + 'one_time_password_code' => $password, + 'one_time_password_counter' => $counter, + )); + } + + // }}} + + // {{{ HybridauthIdentityInterface + + /** + * Loads a specific user identity connected to specified provider by an identifier. + * @param string $provider + * @param string $identifier + * @return object a user identity object or null if not found. + */ + public static function findByProvider($provider, $identifier) + { + $criteria = new CDbCriteria(); + $criteria->with['userRemoteIdentities'] = array('alias' => 'ur'); + $criteria->compare('ur.provider', $provider); + $criteria->compare('ur.identifier', $identifier); + $record = User::model()->find($criteria); + + return $record === null ? null : self::createFromUser($record); + } + + /** + * @inheritdoc + */ + public function addRemoteIdentity($provider, $identifier) + { + if ($this->_id === null) { + return false; + } + UserRemoteIdentity::model()->deleteAllByAttributes(array('provider' => $provider, 'identifier' => $identifier)); + $model = new UserRemoteIdentity(); + $model->setAttributes(array( + 'user_id' => $this->_id, + 'provider' => $provider, + 'identifier' => $identifier, + ), false); + + return $model->save(); + } /** * @inheritdoc */ public function removeRemoteIdentity($provider) { - if ($this->_id===null) - return false; - UserRemoteIdentity::model()->deleteAllByAttributes(array('provider'=>$provider, 'user_id'=>$this->_id)); + if ($this->_id === null) { + return false; + } + UserRemoteIdentity::model()->deleteAllByAttributes(array('provider' => $provider, 'user_id' => $this->_id)); + return true; } @@ -463,19 +490,22 @@ public function removeRemoteIdentity($provider) */ public function hasRemoteIdentity($provider) { - if ($this->_id===null) - return false; - return 0 != UserRemoteIdentity::model()->countByAttributes(array('provider'=>$provider, 'user_id'=>$this->_id)); + if ($this->_id === null) { + return false; + } + + return 0 != UserRemoteIdentity::model()->countByAttributes(array('provider' => $provider, 'user_id' => $this->_id)); } /** * Similar to @see getAttributes() but reads the remote profile instead of current identity. - * @param mixed $remoteProfie + * @param mixed $remoteProfie * @return array */ public static function getRemoteAttributes($remoteProfile) { - $email = (isset($remoteProfile->emailVerifier) && $remoteProfile->emailVerifier !== null) ? $remoteProfile->emailVerifier : $remoteProfile->email; + $email = (isset($remoteProfile->emailVerifier) && $remoteProfile->emailVerifier !== null) ? $remoteProfile->emailVerifier : $remoteProfile->email; + return array( 'username' => $email, 'email' => $email, @@ -484,239 +514,247 @@ public static function getRemoteAttributes($remoteProfile) ); } - // }}} - - // {{{ IPictureIdentity - - /** - * @inheritdoc - */ - public function savePicture($picture) - { - if (($record=$this->getActiveRecord())===null) { - return null; - } - $pictureRecord = $record->userProfilePictures(array('condition'=>'original_picture_id IS NULL')); - if (!empty($pictureRecord)) { - $pictureRecord = $pictureRecord[0]; - } else { - $pictureRecord = new UserProfilePicture; - $pictureRecord->user_id = $this->_id; - } - $picturePath = $picture->getTempName(); - $pictureRecord->filename = $picture; - $pictureRecord->mimetype = CFileHelper::getMimeType($picturePath); - $pictureRecord->contents = base64_encode(file_get_contents($picturePath)); - - if (($size = @getimagesize($picturePath)) !== false) { - list($width, $height, $type, $attr) = $size; - $pictureRecord->width = $width; - $pictureRecord->height = $height; - } else { - $pictureRecord->width = 0; - $pictureRecord->height = 0; - } - return $pictureRecord->save() && $this->saveThumbnail($picture, $pictureRecord); - } - - protected function saveThumbnail($picture, $pictureRecord) - { - // skip thumbnail if couldn't read size of original picture - if ($pictureRecord->width == 0 || $pictureRecord->height == 0) { - return true; - } - // calculate thumbnail dimensions with max width and height at 80 - $max_width = 80; - $max_height = 80; - - $width = $pictureRecord->width; - $height = $pictureRecord->height; - if ($width > $max_width || $height > $max_height ) { - if ($width > $height) { - $height = floor($height / ($width / $max_width)); - $width = $max_width; - } else { - $width = floor($width / ($height / $max_height)); - $height = $max_height; - } - } - - // create the thumbnail image (always a jpeg) - $thumbImage = imagecreatetruecolor($width, $height); - $sourceImage = imagecreatefromstring(base64_decode($pictureRecord->contents)); - imagecopyresized($thumbImage, $sourceImage, 0, 0, 0, 0, $width, $height, $pictureRecord->width, $pictureRecord->height); - ob_start(); - imagejpeg($thumbImage); - $contents = ob_get_clean(); - - // update existing thumbnail or create a new one - $thumbnail = $pictureRecord->thumbnails; - if (!empty($thumbnail)) { - $thumbnail = $thumbnail[0]; - } else { - $thumbnail = new UserProfilePicture; - $thumbnail->original_picture_id = $pictureRecord->id; - $thumbnail->user_id = $pictureRecord->user_id; - $thumbnail->filename = $pictureRecord->filename; - $thumbnail->mimetype = 'image/jpeg'; - } - $thumbnail->width = $width; - $thumbnail->height = $height; - $thumbnail->contents = base64_encode($contents); - return $thumbnail->save(); - } - - /** - * @inheritdoc - */ - public function getPictureUrl($width=null, $height=null) - { - if (($record=$this->getActiveRecord())===null) { - return null; - } - // try to locate biggest picture smaller than specified dimensions - $criteria = array('select' => 'id', 'order' => 'width DESC', 'limit' => 1,); - if ($width !== null && $height !== null) { - $criteria['condition'] = 'width <= :width AND height <= :height'; - $criteria['params'] = array(':width'=>$width, ':height'=>$height); - } - $pictures = $record->userProfilePictures($criteria); - if (!empty($pictures)) { - return array( - 'url' => Yii::app()->createAbsoluteUrl('/usr/profilePicture', array('id'=>$pictures[0]->id)), - 'width' => $pictures[0]->width, - 'height'=> $pictures[0]->height, - ); - } - - // if no picture has been found, use a Gravatar - $hash = md5(strtolower(trim($record->email))); - // more at http://gravatar.com/site/implement/images/ - $options = array( - //'forcedefault' => 'y', - 'rating'=> 'g', - 'd' => 'retro', - 's' => $width, - ); - $host = Yii::app()->request->isSecureConnection ? 'https://secure.gravatar.com' : 'http://gravatar.com'; - return array( - 'url' => $host.'/avatar/'.$hash.'?'.http_build_query($options), - 'width' => $width, - 'height'=> $height, - ); - } - - /** - * @inheritdoc - */ - public function getPicture($id, $currentIdentity=true) - { - $criteria = new CDbCriteria; - $criteria->addColumnCondition(array('id'=>$id)); - if ($currentIdentity) { - $criteria->addColumnCondition(array('user_id'=>$this->_id)); - } - if (($picture=UserProfilePicture::model()->find($criteria)) === null) { - return null; - } - return array( - 'mimetype'=>$picture->mimetype, - 'width'=>$picture->width, - 'height'=>$picture->height, - 'picture'=>base64_decode($picture->contents), - ); - } - - /** - * @inheritdoc - */ - public function removePicture($id=null) - { - if ($this->_id===null) { - return 0; - } - $attributes = array('user_id'=>$this->_id); - if ($id !== null) { - $attributes['id'] = $id; - } - return UserProfilePicture::model()->deleteAllByAttributes($attributes); - } - - // }}} - - // {{{ IManagedIdentity - - /** - * @inheritdoc - */ - public function getDataProvider(SearchForm $searchForm) - { - $criteria=new CDbCriteria; - - $criteria->compare('id', $searchForm->id); - $criteria->compare('username', $searchForm->username,true); - $criteria->compare('email', $searchForm->email,true); - $criteria->compare('firstname', $searchForm->firstName,true); - $criteria->compare('lastname', $searchForm->lastName,true); - $criteria->compare('created_on', $searchForm->createdOn); - $criteria->compare('updated_on', $searchForm->updatedOn); - $criteria->compare('last_visit_on', $searchForm->lastVisitOn); - $criteria->compare('email_verified', $searchForm->emailVerified); - $criteria->compare('is_active', $searchForm->isActive); - $criteria->compare('is_disabled', $searchForm->isDisabled); - $dataProvider = new CActiveDataProvider('User', array('criteria'=>$criteria, 'keyAttribute'=>'id')); - $identities = array(); - foreach($dataProvider->getData() as $row) { - $identities[] = self::createFromUser($row); - } - $dataProvider->setData($identities); - return $dataProvider; - } - - /** - * @inheritdoc - */ - public function toggleStatus($status) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - switch($status) { - case self::STATUS_EMAIL_VERIFIED: $attributes['email_verified'] = !$record->email_verified; break; - case self::STATUS_IS_ACTIVE: $attributes['is_active'] = !$record->is_active; break; - case self::STATUS_IS_DISABLED: $attributes['is_disabled'] = !$record->is_disabled; break; - } - return $record->saveAttributes($attributes); - } - - /** - * @inheritdoc - */ - public function delete() - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - return $record->delete(); - } - - /** - * @inheritdoc - */ - public function getTimestamps($key=null) - { - if (($record=$this->getActiveRecord())===null) { - return false; - } - $timestamps = array( - 'createdOn' => $record->created_on, - 'updatedOn' => $record->updated_on, - 'lastVisitOn' => $record->last_visit_on, - 'passwordSetOn' => $record->password_set_on, - ); - // can't use isset, since it returns false for null values - return $key === null || !array_key_exists($key, $timestamps) ? $timestamps : $timestamps[$key]; - } - - // }}} + // }}} + + // {{{ IPictureIdentity + + /** + * @inheritdoc + */ + public function savePicture($picture) + { + if (($record = $this->getActiveRecord()) === null) { + return null; + } + $pictureRecord = $record->userProfilePictures(array('condition' => 'original_picture_id IS NULL')); + if (!empty($pictureRecord)) { + $pictureRecord = $pictureRecord[0]; + } else { + $pictureRecord = new UserProfilePicture(); + $pictureRecord->user_id = $this->_id; + } + $picturePath = $picture->getTempName(); + $pictureRecord->filename = $picture; + $pictureRecord->mimetype = CFileHelper::getMimeType($picturePath); + $pictureRecord->contents = base64_encode(file_get_contents($picturePath)); + + if (($size = @getimagesize($picturePath)) !== false) { + list($width, $height, $type, $attr) = $size; + $pictureRecord->width = $width; + $pictureRecord->height = $height; + } else { + $pictureRecord->width = 0; + $pictureRecord->height = 0; + } + + return $pictureRecord->save() && $this->saveThumbnail($picture, $pictureRecord); + } + + protected function saveThumbnail($picture, $pictureRecord) + { + // skip thumbnail if couldn't read size of original picture + if ($pictureRecord->width == 0 || $pictureRecord->height == 0) { + return true; + } + // calculate thumbnail dimensions with max width and height at 80 + $max_width = 80; + $max_height = 80; + + $width = $pictureRecord->width; + $height = $pictureRecord->height; + if ($width > $max_width || $height > $max_height) { + if ($width > $height) { + $height = floor($height / ($width / $max_width)); + $width = $max_width; + } else { + $width = floor($width / ($height / $max_height)); + $height = $max_height; + } + } + + // create the thumbnail image (always a jpeg) + $thumbImage = imagecreatetruecolor($width, $height); + $sourceImage = imagecreatefromstring(base64_decode($pictureRecord->contents)); + imagecopyresized($thumbImage, $sourceImage, 0, 0, 0, 0, $width, $height, $pictureRecord->width, $pictureRecord->height); + ob_start(); + imagejpeg($thumbImage); + $contents = ob_get_clean(); + + // update existing thumbnail or create a new one + $thumbnail = $pictureRecord->thumbnails; + if (!empty($thumbnail)) { + $thumbnail = $thumbnail[0]; + } else { + $thumbnail = new UserProfilePicture(); + $thumbnail->original_picture_id = $pictureRecord->id; + $thumbnail->user_id = $pictureRecord->user_id; + $thumbnail->filename = $pictureRecord->filename; + $thumbnail->mimetype = 'image/jpeg'; + } + $thumbnail->width = $width; + $thumbnail->height = $height; + $thumbnail->contents = base64_encode($contents); + + return $thumbnail->save(); + } + + /** + * @inheritdoc + */ + public function getPictureUrl($width = null, $height = null) + { + if (($record = $this->getActiveRecord()) === null) { + return null; + } + // try to locate biggest picture smaller than specified dimensions + $criteria = array('select' => 'id', 'order' => 'width DESC', 'limit' => 1); + if ($width !== null && $height !== null) { + $criteria['condition'] = 'width <= :width AND height <= :height'; + $criteria['params'] = array(':width' => $width, ':height' => $height); + } + $pictures = $record->userProfilePictures($criteria); + if (!empty($pictures)) { + return array( + 'url' => Yii::app()->createAbsoluteUrl('/usr/profilePicture', array('id' => $pictures[0]->id)), + 'width' => $pictures[0]->width, + 'height' => $pictures[0]->height, + ); + } + + // if no picture has been found, use a Gravatar + $hash = md5(strtolower(trim($record->email))); + // more at http://gravatar.com/site/implement/images/ + $options = array( + //'forcedefault' => 'y', + 'rating' => 'g', + 'd' => 'retro', + 's' => $width, + ); + $host = Yii::app()->request->isSecureConnection ? 'https://secure.gravatar.com' : 'http://gravatar.com'; + + return array( + 'url' => $host.'/avatar/'.$hash.'?'.http_build_query($options), + 'width' => $width, + 'height' => $height, + ); + } + + /** + * @inheritdoc + */ + public function getPicture($id, $currentIdentity = true) + { + $criteria = new CDbCriteria(); + $criteria->addColumnCondition(array('id' => $id)); + if ($currentIdentity) { + $criteria->addColumnCondition(array('user_id' => $this->_id)); + } + if (($picture = UserProfilePicture::model()->find($criteria)) === null) { + return null; + } + + return array( + 'mimetype' => $picture->mimetype, + 'width' => $picture->width, + 'height' => $picture->height, + 'picture' => base64_decode($picture->contents), + ); + } + + /** + * @inheritdoc + */ + public function removePicture($id = null) + { + if ($this->_id === null) { + return 0; + } + $attributes = array('user_id' => $this->_id); + if ($id !== null) { + $attributes['id'] = $id; + } + + return UserProfilePicture::model()->deleteAllByAttributes($attributes); + } + + // }}} + + // {{{ IManagedIdentity + + /** + * @inheritdoc + */ + public function getDataProvider(SearchForm $searchForm) + { + $criteria = new CDbCriteria(); + + $criteria->compare('id', $searchForm->id); + $criteria->compare('username', $searchForm->username, true); + $criteria->compare('email', $searchForm->email, true); + $criteria->compare('firstname', $searchForm->firstName, true); + $criteria->compare('lastname', $searchForm->lastName, true); + $criteria->compare('created_on', $searchForm->createdOn); + $criteria->compare('updated_on', $searchForm->updatedOn); + $criteria->compare('last_visit_on', $searchForm->lastVisitOn); + $criteria->compare('email_verified', $searchForm->emailVerified); + $criteria->compare('is_active', $searchForm->isActive); + $criteria->compare('is_disabled', $searchForm->isDisabled); + $dataProvider = new CActiveDataProvider('User', array('criteria' => $criteria, 'keyAttribute' => 'id')); + $identities = array(); + foreach ($dataProvider->getData() as $row) { + $identities[] = self::createFromUser($row); + } + $dataProvider->setData($identities); + + return $dataProvider; + } + + /** + * @inheritdoc + */ + public function toggleStatus($status) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + switch ($status) { + case self::STATUS_EMAIL_VERIFIED: $attributes['email_verified'] = !$record->email_verified; break; + case self::STATUS_IS_ACTIVE: $attributes['is_active'] = !$record->is_active; break; + case self::STATUS_IS_DISABLED: $attributes['is_disabled'] = !$record->is_disabled; break; + } + + return $record->saveAttributes($attributes); + } + + /** + * @inheritdoc + */ + public function delete() + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + + return $record->delete(); + } + + /** + * @inheritdoc + */ + public function getTimestamps($key = null) + { + if (($record = $this->getActiveRecord()) === null) { + return false; + } + $timestamps = array( + 'createdOn' => $record->created_on, + 'updatedOn' => $record->updated_on, + 'lastVisitOn' => $record->last_visit_on, + 'passwordSetOn' => $record->password_set_on, + ); + // can't use isset, since it returns false for null values + return $key === null || !array_key_exists($key, $timestamps) ? $timestamps : $timestamps[$key]; + } + + // }}} } diff --git a/components/ExpiredPasswordBehavior.php b/components/ExpiredPasswordBehavior.php index 2ff0ab2..1fbe027 100644 --- a/components/ExpiredPasswordBehavior.php +++ b/components/ExpiredPasswordBehavior.php @@ -18,57 +18,60 @@ */ class ExpiredPasswordBehavior extends FormModelBehavior { - private $_passwordTimeout; + private $_passwordTimeout; - /** - * @return integer Number of days after which user is requred to reset his password after logging in. - */ - public function getPasswordTimeout() - { - return $this->_passwordTimeout; - } + /** + * @return integer Number of days after which user is requred to reset his password after logging in. + */ + public function getPasswordTimeout() + { + return $this->_passwordTimeout; + } - /** - * @param $value integer Number of days after which user is requred to reset his password after logging in. - */ - public function setPasswordTimeout($value) - { - $this->_passwordTimeout = $value; - } + /** + * @param $value integer Number of days after which user is requred to reset his password after logging in. + */ + public function setPasswordTimeout($value) + { + $this->_passwordTimeout = $value; + } - /** - * @inheritdoc - */ - public function filterRules($rules = array()) - { - $behaviorRules = array( - array('password', 'passwordHasNotExpired', 'except'=>'reset, hybridauth, verifyOTP'), - ); - return array_merge($rules, $this->applyRuleOptions($behaviorRules)); - } + /** + * @inheritdoc + */ + public function filterRules($rules = array()) + { + $behaviorRules = array( + array('password', 'passwordHasNotExpired', 'except' => 'reset, hybridauth, verifyOTP'), + ); - public function passwordHasNotExpired() - { - if($this->owner->hasErrors()) { - return; - } + return array_merge($rules, $this->applyRuleOptions($behaviorRules)); + } - $identity = $this->owner->getIdentity(); - if (!($identity instanceof IPasswordHistoryIdentity)) - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($identity),'{interface}'=>'IPasswordHistoryIdentity'))); - $lastUsed = $identity->getPasswordDate(); - $lastUsedDate = new DateTime($lastUsed); - $today = new DateTime(); - if ($lastUsed === null || $today->diff($lastUsedDate)->days >= $this->passwordTimeout) { - if ($lastUsed === null) { - $this->owner->addError('password',Yii::t('UsrModule.usr','This is the first time you login. Current password needs to be changed.')); - } else { - $this->owner->addError('password',Yii::t('UsrModule.usr','Current password has been used too long and needs to be changed.')); - } - $this->owner->scenario = 'reset'; - return false; - } + public function passwordHasNotExpired() + { + if ($this->owner->hasErrors()) { + return; + } - return true; - } + $identity = $this->owner->getIdentity(); + if (!($identity instanceof IPasswordHistoryIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($identity), '{interface}' => 'IPasswordHistoryIdentity'))); + } + $lastUsed = $identity->getPasswordDate(); + $lastUsedDate = new DateTime($lastUsed); + $today = new DateTime(); + if ($lastUsed === null || $today->diff($lastUsedDate)->days >= $this->passwordTimeout) { + if ($lastUsed === null) { + $this->owner->addError('password', Yii::t('UsrModule.usr', 'This is the first time you login. Current password needs to be changed.')); + } else { + $this->owner->addError('password', Yii::t('UsrModule.usr', 'Current password has been used too long and needs to be changed.')); + } + $this->owner->scenario = 'reset'; + + return false; + } + + return true; + } } diff --git a/components/FormModelBehavior.php b/components/FormModelBehavior.php index ff7f3c5..6142582 100644 --- a/components/FormModelBehavior.php +++ b/components/FormModelBehavior.php @@ -15,54 +15,54 @@ */ abstract class FormModelBehavior extends CModelBehavior { - private static $_names=array(); + private static $_names = array(); - private $_ruleOptions = array(); + private $_ruleOptions = array(); - /** - * Adds validation rules for attributes of this behavior or removes rules from the owner model. - * @return array validation rules - * @see CModel::rules() - */ - public function filterRules($rules = array()) - { - return $rules; - } + /** + * Adds validation rules for attributes of this behavior or removes rules from the owner model. + * @return array validation rules + * @see CModel::rules() + */ + public function filterRules($rules = array()) + { + return $rules; + } - /** - * Labels for attributes of this behavior, that should be merged with labels in the owner model. - * @return array attribute labels (name => label) - * @see CModel::attributeLabels() - */ - public function attributeLabels() - { - return array(); - } + /** + * Labels for attributes of this behavior, that should be merged with labels in the owner model. + * @return array attribute labels (name => label) + * @see CModel::attributeLabels() + */ + public function attributeLabels() + { + return array(); + } - /** - * Returns the list of attribute names. - * By default, this method returns all public non-static properties of the class. - * You may override this method to change the default behavior. - * @return array list of attribute names. - */ - public function attributeNames() - { - $className=get_class($this); - if(!isset(self::$_names[$className])) - { - $class=new ReflectionClass(get_class($this)); - $names=array(); - foreach($class->getProperties() as $property) - { - $name=$property->getName(); - if($property->isPublic() && !$property->isStatic()) - $names[]=$name; - } - return self::$_names[$className]=$names; - } - else - return self::$_names[$className]; - } + /** + * Returns the list of attribute names. + * By default, this method returns all public non-static properties of the class. + * You may override this method to change the default behavior. + * @return array list of attribute names. + */ + public function attributeNames() + { + $className = get_class($this); + if (!isset(self::$_names[$className])) { + $class = new ReflectionClass(get_class($this)); + $names = array(); + foreach ($class->getProperties() as $property) { + $name = $property->getName(); + if ($property->isPublic() && !$property->isStatic()) { + $names[] = $name; + } + } + + return self::$_names[$className] = $names; + } else { + return self::$_names[$className]; + } + } /** * Lists valid model scenarios. @@ -73,34 +73,35 @@ public function getAvailableScenarios() return array(); } - /** - * Adds current rule options to the given set of rules. - * @param array $rules - * @return array - */ - public function applyRuleOptions($rules) - { - foreach($rules as $key=>$rule) { - foreach($this->_ruleOptions as $name=>$value) { - $rules[$key][$name] = $value; - } - } - return $rules; - } + /** + * Adds current rule options to the given set of rules. + * @param array $rules + * @return array + */ + public function applyRuleOptions($rules) + { + foreach ($rules as $key => $rule) { + foreach ($this->_ruleOptions as $name => $value) { + $rules[$key][$name] = $value; + } + } - /** - * @return array - */ - public function getRuleOptions() - { - return $this->_ruleOptions; - } + return $rules; + } + + /** + * @return array + */ + public function getRuleOptions() + { + return $this->_ruleOptions; + } - /** - * @param $value array - */ - public function setRuleOptions(array $value) - { - $this->_ruleOptions = $value; - } + /** + * @param $value array + */ + public function setRuleOptions(array $value) + { + $this->_ruleOptions = $value; + } } diff --git a/components/IActivatedIdentity.php b/components/IActivatedIdentity.php index 92a41dc..2f4b0b1 100644 --- a/components/IActivatedIdentity.php +++ b/components/IActivatedIdentity.php @@ -2,61 +2,60 @@ interface IActivatedIdentity { - const ERROR_AKEY_NONE=0; - const ERROR_AKEY_INVALID=1; - const ERROR_AKEY_TOO_OLD=2; + const ERROR_AKEY_NONE = 0; + const ERROR_AKEY_INVALID = 1; + const ERROR_AKEY_TOO_OLD = 2; - /** - * Loads a specific user identity using one of supplied attributes, such as username or email. + /** + * Loads a specific user identity using one of supplied attributes, such as username or email. * Note: should only return a result if exactly one match has been found. - * @param array $attributes contains at least one of keys: 'username', 'email' - * @return object a user identity object or null if not found. - */ - public static function find(array $attributes); - /** - * Checkes if user account is active. This should not include disabled (banned) status. - * This could include if the email address has been verified. - * Same checks should be done in the authenticate() method, because this method is not called before logging in. - * @return boolean - */ - public function isActive(); - /** - * Checkes if user account is disabled (banned). This should not include active status. - * @return boolean - */ - public function isDisabled(); - /** - * Checkes if user email address is verified. - * @return boolean - */ - public function isVerified(); - /** - * Generates and saves a new activation key used for verifying email and restoring lost password. - * The activation key is then sent by email to the user. - * - * Note: only the last generated activation key should be valid and an activation key - * should have it's generation date saved to verify it's age later. - * - * @return string - */ - public function getActivationKey(); - /** - * Verifies if specified activation key matches the saved one and if it's not too old. - * This method should not alter any saved data. - * @return integer the verification error code. If there is an error, the error code will be non-zero. - */ - public function verifyActivationKey($activationKey); - /** - * Verify users email address, which could also activate his account and allow him to log in. - * Call only after verifying the activation key. - * @param boolean $requireVerifiedEmail - * @return boolean - */ - public function verifyEmail($requireVerifiedEmail=false); - /** - * Returns user email address. - * @return string - */ - public function getEmail(); + * @param array $attributes contains at least one of keys: 'username', 'email' + * @return object a user identity object or null if not found. + */ + public static function find(array $attributes); + /** + * Checkes if user account is active. This should not include disabled (banned) status. + * This could include if the email address has been verified. + * Same checks should be done in the authenticate() method, because this method is not called before logging in. + * @return boolean + */ + public function isActive(); + /** + * Checkes if user account is disabled (banned). This should not include active status. + * @return boolean + */ + public function isDisabled(); + /** + * Checkes if user email address is verified. + * @return boolean + */ + public function isVerified(); + /** + * Generates and saves a new activation key used for verifying email and restoring lost password. + * The activation key is then sent by email to the user. + * + * Note: only the last generated activation key should be valid and an activation key + * should have it's generation date saved to verify it's age later. + * + * @return string + */ + public function getActivationKey(); + /** + * Verifies if specified activation key matches the saved one and if it's not too old. + * This method should not alter any saved data. + * @return integer the verification error code. If there is an error, the error code will be non-zero. + */ + public function verifyActivationKey($activationKey); + /** + * Verify users email address, which could also activate his account and allow him to log in. + * Call only after verifying the activation key. + * @param boolean $requireVerifiedEmail + * @return boolean + */ + public function verifyEmail($requireVerifiedEmail = false); + /** + * Returns user email address. + * @return string + */ + public function getEmail(); } - diff --git a/components/IEditableIdentity.php b/components/IEditableIdentity.php index 1370f50..c816a12 100644 --- a/components/IEditableIdentity.php +++ b/components/IEditableIdentity.php @@ -2,25 +2,24 @@ interface IEditableIdentity { - /** - * Saves a new or existing identity. Does not set or change the password. - * @see IPasswordHistoryIdentity::resetPassword() - * Should detect if the email changed and mark it as not verified. - * @param boolean $requireVerifiedEmail - * @return boolean - */ - public function save($requireVerifiedEmail=false); - /** - * Returns attributes like username, email, first and last name. - * @return array - */ - public function getAttributes(); - /** - * Sets attributes like username, email, first and last name. - * Password should be changed using only the resetPassword() method from the IPasswordHistoryIdentity interface. - * @param array $attributes - * @return boolean - */ - public function setAttributes(array $attributes); + /** + * Saves a new or existing identity. Does not set or change the password. + * @see IPasswordHistoryIdentity::resetPassword() + * Should detect if the email changed and mark it as not verified. + * @param boolean $requireVerifiedEmail + * @return boolean + */ + public function save($requireVerifiedEmail = false); + /** + * Returns attributes like username, email, first and last name. + * @return array + */ + public function getAttributes(); + /** + * Sets attributes like username, email, first and last name. + * Password should be changed using only the resetPassword() method from the IPasswordHistoryIdentity interface. + * @param array $attributes + * @return boolean + */ + public function setAttributes(array $attributes); } - diff --git a/components/IHybridauthIdentity.php b/components/IHybridauthIdentity.php index 7e15eb1..8cb959b 100644 --- a/components/IHybridauthIdentity.php +++ b/components/IHybridauthIdentity.php @@ -2,38 +2,37 @@ interface IHybridauthIdentity { - /** - * Loads a specific user identity connected to specified provider by an identifier. - * @param string $provider - * @param string $identifier - * @return object a user identity object or null if not found. - */ - public static function findByProvider($provider, $identifier); - /** - * Associates current identity with a remote one identified by a provider name and identifier. + /** + * Loads a specific user identity connected to specified provider by an identifier. + * @param string $provider + * @param string $identifier + * @return object a user identity object or null if not found. + */ + public static function findByProvider($provider, $identifier); + /** + * Associates current identity with a remote one identified by a provider name and identifier. * If another user already has such association, it is removed, since provider and identifier must be a unique pair. - * @param string $provider - * @param string $identifier - * @return boolean - */ - public function addRemoteIdentity($provider, $identifier); + * @param string $provider + * @param string $identifier + * @return boolean + */ + public function addRemoteIdentity($provider, $identifier); /** * Removes association between current identity and a remote one for the selected provider. - * @param string $provider + * @param string $provider * @return boolean */ public function removeRemoteIdentity($provider); /** * Checkes if there is an association between this identity and a remote one for the selected provider. - * @param string $provider + * @param string $provider * @return boolean */ public function hasRemoteIdentity($provider); /** * Similar to @see getAttributes() but reads the remote profile instead of current identity. - * @param mixed $remoteProfie + * @param mixed $remoteProfie * @return array */ public static function getRemoteAttributes($remoteProfile); } - diff --git a/components/IManagedIdentity.php b/components/IManagedIdentity.php index 24f18ad..d94d438 100644 --- a/components/IManagedIdentity.php +++ b/components/IManagedIdentity.php @@ -2,31 +2,31 @@ interface IManagedIdentity { - const STATUS_EMAIL_VERIFIED = 'email_verified'; - const STATUS_IS_ACTIVE = 'is_active'; - const STATUS_IS_DISABLED = 'is_disabled'; - /** - * Returns a data provider filled with UserIdentity instances. - * @param SearchForm $searchForm - * @return CDataProvider - */ - public function getDataProvider(SearchForm $searchForm); - /** - * Toggles email verification, active or disabled status. - * @param string $status on of following consts: self::STATUS_EMAIL_VERIFIED, self::STATUS_IS_ACTIVE, self::STATUS_IS_DISABLED - * @return boolean - */ - public function toggleStatus($status); - /** - * Removes a user account. Note this could fail if there are constraints set up in the db that prevent - * removing a user that still has some relations pointing to it. - * @return boolean - */ - public function delete(); - /** - * Retrieves various timestamps, like time of creation, last update, last login. - * @param string $key if not null, returns a single value if one of: createdOn, updatedOn, lastVisitOn - * @return array|string single date or array with keys: createdOn, updatedOn, lastVisitOn - */ - public function getTimestamps($key=null); + const STATUS_EMAIL_VERIFIED = 'email_verified'; + const STATUS_IS_ACTIVE = 'is_active'; + const STATUS_IS_DISABLED = 'is_disabled'; + /** + * Returns a data provider filled with UserIdentity instances. + * @param SearchForm $searchForm + * @return CDataProvider + */ + public function getDataProvider(SearchForm $searchForm); + /** + * Toggles email verification, active or disabled status. + * @param string $status on of following consts: self::STATUS_EMAIL_VERIFIED, self::STATUS_IS_ACTIVE, self::STATUS_IS_DISABLED + * @return boolean + */ + public function toggleStatus($status); + /** + * Removes a user account. Note this could fail if there are constraints set up in the db that prevent + * removing a user that still has some relations pointing to it. + * @return boolean + */ + public function delete(); + /** + * Retrieves various timestamps, like time of creation, last update, last login. + * @param string $key if not null, returns a single value if one of: createdOn, updatedOn, lastVisitOn + * @return array|string single date or array with keys: createdOn, updatedOn, lastVisitOn + */ + public function getTimestamps($key = null); } diff --git a/components/IOneTimePasswordIdentity.php b/components/IOneTimePasswordIdentity.php index c1e581c..6940589 100644 --- a/components/IOneTimePasswordIdentity.php +++ b/components/IOneTimePasswordIdentity.php @@ -2,29 +2,28 @@ interface IOneTimePasswordIdentity { - /** - * Returns current secret used to generate one time passwords. If it's null, two step auth is disabled. - * @return string - */ - public function getOneTimePasswordSecret(); + /** + * Returns current secret used to generate one time passwords. If it's null, two step auth is disabled. + * @return string + */ + public function getOneTimePasswordSecret(); - /** - * Sets current secret used to generate one time passwords. If it's null, two step auth is disabled. - * @param string $secret - * @return boolean - */ - public function setOneTimePasswordSecret($secret); + /** + * Sets current secret used to generate one time passwords. If it's null, two step auth is disabled. + * @param string $secret + * @return boolean + */ + public function setOneTimePasswordSecret($secret); - /** - * Returns previously used one time password and value of counter used to generate current one time password, used in counter mode. - * @return array array(string, integer) - */ - public function getOneTimePassword(); + /** + * Returns previously used one time password and value of counter used to generate current one time password, used in counter mode. + * @return array array(string, integer) + */ + public function getOneTimePassword(); - /** - * Sets previously used one time password and value of counter used to generate current one time password, used in counter mode. - * @return boolean - */ - public function setOneTimePassword($password, $counter = 0); + /** + * Sets previously used one time password and value of counter used to generate current one time password, used in counter mode. + * @return boolean + */ + public function setOneTimePassword($password, $counter = 0); } - diff --git a/components/IPasswordHistoryIdentity.php b/components/IPasswordHistoryIdentity.php index e8e7e10..3d51659 100644 --- a/components/IPasswordHistoryIdentity.php +++ b/components/IPasswordHistoryIdentity.php @@ -2,19 +2,18 @@ interface IPasswordHistoryIdentity { - /** - * Returns the date when specified password was last set or null if it was never used before. - * If null is passed, returns date of setting current password. - * @param string $password new password or null if checking when the current password has been set - * @return string date in YYYY-MM-DD format or null if password was never used. - */ - public function getPasswordDate($password = null); - /** - * Changes the password and updates last password change date. - * Saves old password so it couldn't be used again. - * @param string $password new password - * @return boolean - */ - public function resetPassword($password); + /** + * Returns the date when specified password was last set or null if it was never used before. + * If null is passed, returns date of setting current password. + * @param string $password new password or null if checking when the current password has been set + * @return string date in YYYY-MM-DD format or null if password was never used. + */ + public function getPasswordDate($password = null); + /** + * Changes the password and updates last password change date. + * Saves old password so it couldn't be used again. + * @param string $password new password + * @return boolean + */ + public function resetPassword($password); } - diff --git a/components/IPictureIdentity.php b/components/IPictureIdentity.php index 44879bc..5b1275f 100644 --- a/components/IPictureIdentity.php +++ b/components/IPictureIdentity.php @@ -2,39 +2,39 @@ interface IPictureIdentity { - /** - * Saves an uploaded picture. This method can be left unimplemented (throw an exception) to disable image upload, - * just remember to remove any rules from the UsrModule::$pictureUploadRules module property. - * Although the $picture argument is an instance of CUploadedFile it could be created manually, so the implementation - * shouldn't call saveAs() method. Copy the file manually from the path obtained by getTempName(). - * @param CUploadedFile $picture - * @return boolean - */ - public function savePicture($picture); + /** + * Saves an uploaded picture. This method can be left unimplemented (throw an exception) to disable image upload, + * just remember to remove any rules from the UsrModule::$pictureUploadRules module property. + * Although the $picture argument is an instance of CUploadedFile it could be created manually, so the implementation + * shouldn't call saveAs() method. Copy the file manually from the path obtained by getTempName(). + * @param CUploadedFile $picture + * @return boolean + */ + public function savePicture($picture); - /** - * Returns an URL to the profile picture and the actual width and height of the picture it points to. - * It may be an url to the profilePicture action in the default controller or some external service - * like Gravatar or one of the social sites that this identity is associated with. - * @see DefaultController::actionProfilePicture() - * @param integer $width maximum width, if null, gets the biggest picture - * @param integer $height maximum height, if null, gets the biggest picture - * @return array with keys: url, width, height - */ - public function getPictureUrl($width=null, $height=null); + /** + * Returns an URL to the profile picture and the actual width and height of the picture it points to. + * It may be an url to the profilePicture action in the default controller or some external service + * like Gravatar or one of the social sites that this identity is associated with. + * @see DefaultController::actionProfilePicture() + * @param integer $width maximum width, if null, gets the biggest picture + * @param integer $height maximum height, if null, gets the biggest picture + * @return array with keys: url, width, height + */ + public function getPictureUrl($width = null, $height = null); - /** - * Returns a picture with some metadata like dimensions and mimetype. - * @param string $id - * @param boolean $currentIdentity if true, only pictures for the current identity will be returned - * @return array with keys: mimetype, width, height, picture - */ - public function getPicture($id, $currentIdentity=true); + /** + * Returns a picture with some metadata like dimensions and mimetype. + * @param string $id + * @param boolean $currentIdentity if true, only pictures for the current identity will be returned + * @return array with keys: mimetype, width, height, picture + */ + public function getPicture($id, $currentIdentity = true); - /** - * Removes one or all profile pictures. - * @param string $id if null, removes all profile pictures - * @return integer number of pictures removed - */ - public function removePicture($id=null); + /** + * Removes one or all profile pictures. + * @param string $id if null, removes all profile pictures + * @return integer number of pictures removed + */ + public function removePicture($id = null); } diff --git a/components/OneTimePasswordAction.php b/components/OneTimePasswordAction.php index d30397a..58802c4 100644 --- a/components/OneTimePasswordAction.php +++ b/components/OneTimePasswordAction.php @@ -11,73 +11,77 @@ class OneTimePasswordAction extends CAction */ public $configuration; - public function run() { - if (Yii::app()->user->isGuest) - $this->controller->redirect(array('login')); + public function run() + { + if (Yii::app()->user->isGuest) { + $this->controller->redirect(array('login')); + } $this->configuration = array_merge(array( 'authenticator' => null, 'mode' => null, 'required' => null, 'timeout' => null, ), $this->configuration); - if ($this->configuration['required']) - $this->controller->redirect(array('profile')); + if ($this->configuration['required']) { + $this->controller->redirect(array('profile')); + } - $model = new OneTimePasswordForm; - /** @var IUserIdentity */ - $identity = $model->getIdentity(); - /** - * Disable OTP when a secret is set. - */ - if ($identity->getOneTimePasswordSecret() !== null) { - $identity->setOneTimePasswordSecret(null); - Yii::app()->request->cookies->remove(OneTimePasswordFormBehavior::OTP_COOKIE); - $this->controller->redirect('profile'); - return; - } + $model = new OneTimePasswordForm(); + /** @var IUserIdentity */ + $identity = $model->getIdentity(); + /** + * Disable OTP when a secret is set. + */ + if ($identity->getOneTimePasswordSecret() !== null) { + $identity->setOneTimePasswordSecret(null); + Yii::app()->request->cookies->remove(OneTimePasswordFormBehavior::OTP_COOKIE); + $this->controller->redirect('profile'); - $model->setMode($this->configuration['mode'])->setAuthenticator($this->configuration['authenticator']); + return; + } - /** - * When no secret has been set yet, generate a new secret and save it in session. - * Do it if it hasn't been done yet. - */ - if (($secret=Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret']) === null) { - $secret = Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret'] = $this->configuration['authenticator']->generateSecret(); + $model->setMode($this->configuration['mode'])->setAuthenticator($this->configuration['authenticator']); - $model->setSecret($secret); - if ($this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_COUNTER) { - $this->controller->sendEmail($model, 'oneTimePassword'); - } - } - $model->setSecret($secret); + /** + * When no secret has been set yet, generate a new secret and save it in session. + * Do it if it hasn't been done yet. + */ + if (($secret = Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret']) === null) { + $secret = Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret'] = $this->configuration['authenticator']->generateSecret(); - if (isset($_POST['OneTimePasswordForm'])) { - $model->setAttributes($_POST['OneTimePasswordForm']); - if ($model->validate()) { - // save secret - $identity->setOneTimePasswordSecret($secret); - Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret'] = null; - // save current code as used - $identity->setOneTimePassword($model->oneTimePassword, $this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME ? floor(time() / 30) : $model->getPreviousCounter() + 1); - $this->controller->redirect('profile'); - } - } - if (YII_DEBUG) { - $model->oneTimePassword = $this->configuration['authenticator']->getCode($secret, $this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME ? null : $model->getPreviousCounter()); - } + $model->setSecret($secret); + if ($this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_COUNTER) { + $this->controller->sendEmail($model, 'oneTimePassword'); + } + } + $model->setSecret($secret); - if ($this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME) { - $hostInfo = Yii::app()->request->hostInfo; - $url = $model->getUrl($identity->username, parse_url($hostInfo, PHP_URL_HOST), $secret); - } else { - $url = ''; - } + if (isset($_POST['OneTimePasswordForm'])) { + $model->setAttributes($_POST['OneTimePasswordForm']); + if ($model->validate()) { + // save secret + $identity->setOneTimePasswordSecret($secret); + Yii::app()->session[OneTimePasswordFormBehavior::OTP_SECRET_PREFIX.'newSecret'] = null; + // save current code as used + $identity->setOneTimePassword($model->oneTimePassword, $this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME ? floor(time() / 30) : $model->getPreviousCounter() + 1); + $this->controller->redirect('profile'); + } + } + if (YII_DEBUG) { + $model->oneTimePassword = $this->configuration['authenticator']->getCode($secret, $this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME ? null : $model->getPreviousCounter()); + } + + if ($this->configuration['mode'] === OneTimePasswordFormBehavior::OTP_TIME) { + $hostInfo = Yii::app()->request->hostInfo; + $url = $model->getUrl($identity->username, parse_url($hostInfo, PHP_URL_HOST), $secret); + } else { + $url = ''; + } $this->controller->render('generateOTPSecret', array( 'model' => $model, 'url' => $url, 'mode' => $this->configuration['mode'], )); - } + } } diff --git a/components/OneTimePasswordFormBehavior.php b/components/OneTimePasswordFormBehavior.php index d8810c9..4ad2931 100644 --- a/components/OneTimePasswordFormBehavior.php +++ b/components/OneTimePasswordFormBehavior.php @@ -22,16 +22,16 @@ */ class OneTimePasswordFormBehavior extends FormModelBehavior { - const OTP_SECRET_PREFIX = 'UsrModule.oneTimePassword.'; - const OTP_COOKIE = 'otp'; - const OTP_NONE = 'none'; - const OTP_TIME = 'time'; - const OTP_COUNTER = 'counter'; + const OTP_SECRET_PREFIX = 'UsrModule.oneTimePassword.'; + const OTP_COOKIE = 'otp'; + const OTP_NONE = 'none'; + const OTP_TIME = 'time'; + const OTP_COUNTER = 'counter'; /** * @var string One time password as a token entered by the user. */ - public $oneTimePassword; + public $oneTimePassword; /** * @var GoogleAuthenticator If null, set to a new instance of GoogleAuthenticator class. */ @@ -52,206 +52,225 @@ class OneTimePasswordFormBehavior extends FormModelBehavior */ public $timeout; - private $_oneTimePasswordConfig = array( - 'secret' => null, - 'previousCode' => null, - 'previousCounter' => null, - ); - - private $_controller; - - /** - * @inheritdoc - */ - public function events() { - return array_merge(parent::events(), array( - 'onAfterValidate'=>'afterValidate', - )); - } - - /** - * @inheritdoc - */ - public function filterRules($rules = array()) - { - $behaviorRules = array( - array('oneTimePassword', 'filter', 'filter'=>'trim', 'on'=>'verifyOTP'), - array('oneTimePassword', 'default', 'setOnEmpty'=>true, 'value' => null, 'on'=>'verifyOTP'), - array('oneTimePassword', 'required', 'on'=>'verifyOTP'), - array('oneTimePassword', 'validOneTimePassword', 'except'=>'hybridauth'), - ); - return array_merge($rules, $this->applyRuleOptions($behaviorRules)); - } - - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'oneTimePassword' => Yii::t('UsrModule.usr','One Time Password'), - ); - } - - public function getController() - { - return $this->_controller; - } - - public function setController($value) - { - $this->_controller = $value; - } - - public function getOneTimePasswordConfig() - { - return $this->_oneTimePasswordConfig; - } + private $_oneTimePasswordConfig = array( + 'secret' => null, + 'previousCode' => null, + 'previousCounter' => null, + ); + + private $_controller; + + /** + * @inheritdoc + */ + public function events() + { + return array_merge(parent::events(), array( + 'onAfterValidate' => 'afterValidate', + )); + } + + /** + * @inheritdoc + */ + public function filterRules($rules = array()) + { + $behaviorRules = array( + array('oneTimePassword', 'filter', 'filter' => 'trim', 'on' => 'verifyOTP'), + array('oneTimePassword', 'default', 'setOnEmpty' => true, 'value' => null, 'on' => 'verifyOTP'), + array('oneTimePassword', 'required', 'on' => 'verifyOTP'), + array('oneTimePassword', 'validOneTimePassword', 'except' => 'hybridauth'), + ); + + return array_merge($rules, $this->applyRuleOptions($behaviorRules)); + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'oneTimePassword' => Yii::t('UsrModule.usr', 'One Time Password'), + ); + } + + public function getController() + { + return $this->_controller; + } + + public function setController($value) + { + $this->_controller = $value; + } + + public function getOneTimePasswordConfig() + { + return $this->_oneTimePasswordConfig; + } public static function getDefaultAuthenticator() { - require dirname(__FILE__) . '/extensions/GoogleAuthenticator.php/lib/GoogleAuthenticator.php'; - return new GoogleAuthenticator; + require dirname(__FILE__).'/extensions/GoogleAuthenticator.php/lib/GoogleAuthenticator.php'; + + return new GoogleAuthenticator(); + } + + public function setOneTimePasswordConfig(array $config) + { + foreach ($config as $key => $value) { + if ($this->_oneTimePasswordConfig[$key] === null) { + $this->_oneTimePasswordConfig[$key] = $value; + } + } + + return $this; } - public function setOneTimePasswordConfig(array $config) - { - foreach($config as $key => $value) { - if ($this->_oneTimePasswordConfig[$key] === null) - $this->_oneTimePasswordConfig[$key] = $value; - } - return $this; - } - - protected function loadOneTimePasswordConfig() - { - $identity = $this->owner->getIdentity(); - if (!($identity instanceof IOneTimePasswordIdentity)) - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($identity),'{interface}'=>'IOneTimePasswordIdentity'))); - list($previousCode, $previousCounter) = $identity->getOneTimePassword(); - $this->setOneTimePasswordConfig(array( - 'secret' => $identity->getOneTimePasswordSecret(), - 'previousCode' => $previousCode, - 'previousCounter' => $previousCounter, - )); + protected function loadOneTimePasswordConfig() + { + $identity = $this->owner->getIdentity(); + if (!($identity instanceof IOneTimePasswordIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($identity), '{interface}' => 'IOneTimePasswordIdentity'))); + } + list($previousCode, $previousCounter) = $identity->getOneTimePassword(); + $this->setOneTimePasswordConfig(array( + 'secret' => $identity->getOneTimePasswordSecret(), + 'previousCode' => $previousCode, + 'previousCounter' => $previousCounter, + )); if ($this->authenticator === null) { $this->authenticator = self::getDefaultAuthenticator(); } - return $this; - } - - public function getOTP($key) - { - if ($this->_oneTimePasswordConfig[$key] === null) { - $this->loadOneTimePasswordConfig(); - } - return $this->_oneTimePasswordConfig[$key]; - } - - public function getNewCode() - { - $this->loadOneTimePasswordConfig(); - // extracts: $secret, $previousCode, $previousCounter - extract($this->_oneTimePasswordConfig); - return $this->authenticator->getCode($secret, $this->mode == OneTimePasswordFormBehavior::OTP_TIME ? null : $previousCounter); - } - - public function validOneTimePassword($attribute,$params) - { - if($this->owner->hasErrors()) { - return; - } - $this->loadOneTimePasswordConfig(); - // extracts: $secret, $previousCode, $previousCounter - extract($this->_oneTimePasswordConfig); - - if (($this->mode !== OneTimePasswordFormBehavior::OTP_TIME && $this->mode !== OneTimePasswordFormBehavior::OTP_COUNTER) || (!$this->required && $secret === null)) { - return true; - } - if ($this->required && $secret === null) { - // generate and save a new secret only if required to do so, in other cases user must verify that the secret works - $secret = $this->_oneTimePasswordConfig['secret'] = $this->authenticator->generateSecret(); - $this->owner->getIdentity()->setOneTimePasswordSecret($secret); - } - - if ($this->isValidOTPCookie(Yii::app()->request->cookies->itemAt(OneTimePasswordFormBehavior::OTP_COOKIE), $this->owner->username, $secret, $this->timeout)) { - return true; - } - if (empty($this->owner->$attribute)) { - $this->owner->addError($attribute,Yii::t('UsrModule.usr','Enter a valid one time password.')); - $this->owner->scenario = 'verifyOTP'; - if ($mode === OneTimePasswordFormBehavior::OTP_COUNTER) { - $this->_controller->sendEmail($this, 'oneTimePassword'); - } - if (YII_DEBUG) { - $this->oneTimePassword = $this->authenticator->getCode($secret, $this->mode === OneTimePasswordFormBehavior::OTP_TIME ? null : $previousCounter); - } - return false; - } - if ($this->mode === OneTimePasswordFormBehavior::OTP_TIME) { - $valid = $this->authenticator->checkCode($secret, $this->owner->$attribute); - } elseif ($this->mode === OneTimePasswordFormBehavior::OTP_COUNTER) { - $valid = $this->authenticator->getCode($secret, $previousCounter) == $this->owner->$attribute; - } else { - $valid = false; - } - if (!$valid) { - $this->owner->addError($attribute,Yii::t('UsrModule.usr','Entered code is invalid.')); - $this->owner->scenario = 'verifyOTP'; - return false; - } - if ($this->owner->$attribute == $previousCode) { - if ($this->mode === OneTimePasswordFormBehavior::OTP_TIME) { - $message = Yii::t('UsrModule.usr','Please wait until next code will be generated.'); - } elseif ($this->mode === OneTimePasswordFormBehavior::OTP_COUNTER) { - $message = Yii::t('UsrModule.usr','Please log in again to request a new code.'); - } - $this->owner->addError($attribute,Yii::t('UsrModule.usr','Entered code has already been used.').' '.$message); - $this->owner->scenario = 'verifyOTP'; - return false; - } - $this->owner->getIdentity()->setOneTimePassword($this->owner->$attribute, $this->mode === OneTimePasswordFormBehavior::OTP_TIME ? floor(time() / 30) : $previousCounter + 1); - return true; - } - - protected function afterValidate($event) - { - if ($this->owner->scenario === 'hybridauth') - return; - - // extracts: $secret, $previousCode, $previousCounter - extract($this->_oneTimePasswordConfig); - - $cookie = $this->createOTPCookie($this->owner->username, $secret, $this->timeout); - Yii::app()->request->cookies->add($cookie->name, $cookie); - } - - public function createOTPCookie($username, $secret, $timeout, $time = null) { - if ($time === null) - $time = time(); - $cookie=new CHttpCookie(OneTimePasswordFormBehavior::OTP_COOKIE,''); - $cookie->expire=time() + ($timeout <= 0 ? 10*365*24*3600 : $timeout); - $cookie->httpOnly=true; - $data=array('username'=>$username, 'time'=>$time, 'timeout'=>$timeout); - $cookie->value=$time.':'.Yii::app()->getSecurityManager()->computeHMAC(serialize($data), $secret); - return $cookie; - } - - public function isValidOTPCookie($cookie, $username, $secret, $timeout, $time = null) { - if ($time === null) - $time = time(); - - if(!$cookie || empty($cookie->value) || !is_string($cookie->value)) { - return false; - } - $parts = explode(":",$cookie->value,2); - if (count($parts)!=2) { - return false; - } - list($creationTime,$hash) = $parts; - $data=array('username'=>$username, 'time'=>(int)$creationTime, 'timeout'=>$timeout); - $validHash = Yii::app()->getSecurityManager()->computeHMAC(serialize($data), $secret); - return ($timeout <= 0 || $creationTime + $timeout >= $time) && $hash === $validHash; - } + return $this; + } + + public function getOTP($key) + { + if ($this->_oneTimePasswordConfig[$key] === null) { + $this->loadOneTimePasswordConfig(); + } + + return $this->_oneTimePasswordConfig[$key]; + } + + public function getNewCode() + { + $this->loadOneTimePasswordConfig(); + // extracts: $secret, $previousCode, $previousCounter + extract($this->_oneTimePasswordConfig); + + return $this->authenticator->getCode($secret, $this->mode == OneTimePasswordFormBehavior::OTP_TIME ? null : $previousCounter); + } + + public function validOneTimePassword($attribute, $params) + { + if ($this->owner->hasErrors()) { + return; + } + $this->loadOneTimePasswordConfig(); + // extracts: $secret, $previousCode, $previousCounter + extract($this->_oneTimePasswordConfig); + + if (($this->mode !== OneTimePasswordFormBehavior::OTP_TIME && $this->mode !== OneTimePasswordFormBehavior::OTP_COUNTER) || (!$this->required && $secret === null)) { + return true; + } + if ($this->required && $secret === null) { + // generate and save a new secret only if required to do so, in other cases user must verify that the secret works + $secret = $this->_oneTimePasswordConfig['secret'] = $this->authenticator->generateSecret(); + $this->owner->getIdentity()->setOneTimePasswordSecret($secret); + } + + if ($this->isValidOTPCookie(Yii::app()->request->cookies->itemAt(OneTimePasswordFormBehavior::OTP_COOKIE), $this->owner->username, $secret, $this->timeout)) { + return true; + } + if (empty($this->owner->$attribute)) { + $this->owner->addError($attribute, Yii::t('UsrModule.usr', 'Enter a valid one time password.')); + $this->owner->scenario = 'verifyOTP'; + if ($mode === OneTimePasswordFormBehavior::OTP_COUNTER) { + $this->_controller->sendEmail($this, 'oneTimePassword'); + } + if (YII_DEBUG) { + $this->oneTimePassword = $this->authenticator->getCode($secret, $this->mode === OneTimePasswordFormBehavior::OTP_TIME ? null : $previousCounter); + } + + return false; + } + if ($this->mode === OneTimePasswordFormBehavior::OTP_TIME) { + $valid = $this->authenticator->checkCode($secret, $this->owner->$attribute); + } elseif ($this->mode === OneTimePasswordFormBehavior::OTP_COUNTER) { + $valid = $this->authenticator->getCode($secret, $previousCounter) == $this->owner->$attribute; + } else { + $valid = false; + } + if (!$valid) { + $this->owner->addError($attribute, Yii::t('UsrModule.usr', 'Entered code is invalid.')); + $this->owner->scenario = 'verifyOTP'; + + return false; + } + if ($this->owner->$attribute == $previousCode) { + if ($this->mode === OneTimePasswordFormBehavior::OTP_TIME) { + $message = Yii::t('UsrModule.usr', 'Please wait until next code will be generated.'); + } elseif ($this->mode === OneTimePasswordFormBehavior::OTP_COUNTER) { + $message = Yii::t('UsrModule.usr', 'Please log in again to request a new code.'); + } + $this->owner->addError($attribute, Yii::t('UsrModule.usr', 'Entered code has already been used.').' '.$message); + $this->owner->scenario = 'verifyOTP'; + + return false; + } + $this->owner->getIdentity()->setOneTimePassword($this->owner->$attribute, $this->mode === OneTimePasswordFormBehavior::OTP_TIME ? floor(time() / 30) : $previousCounter + 1); + + return true; + } + + protected function afterValidate($event) + { + if ($this->owner->scenario === 'hybridauth') { + return; + } + + // extracts: $secret, $previousCode, $previousCounter + extract($this->_oneTimePasswordConfig); + + $cookie = $this->createOTPCookie($this->owner->username, $secret, $this->timeout); + Yii::app()->request->cookies->add($cookie->name, $cookie); + } + + public function createOTPCookie($username, $secret, $timeout, $time = null) + { + if ($time === null) { + $time = time(); + } + $cookie = new CHttpCookie(OneTimePasswordFormBehavior::OTP_COOKIE, ''); + $cookie->expire = time() + ($timeout <= 0 ? 10*365*24*3600 : $timeout); + $cookie->httpOnly = true; + $data = array('username' => $username, 'time' => $time, 'timeout' => $timeout); + $cookie->value = $time.':'.Yii::app()->getSecurityManager()->computeHMAC(serialize($data), $secret); + + return $cookie; + } + + public function isValidOTPCookie($cookie, $username, $secret, $timeout, $time = null) + { + if ($time === null) { + $time = time(); + } + + if (!$cookie || empty($cookie->value) || !is_string($cookie->value)) { + return false; + } + $parts = explode(":", $cookie->value, 2); + if (count($parts) != 2) { + return false; + } + list($creationTime, $hash) = $parts; + $data = array('username' => $username, 'time' => (int) $creationTime, 'timeout' => $timeout); + $validHash = Yii::app()->getSecurityManager()->computeHMAC(serialize($data), $secret); + + return ($timeout <= 0 || $creationTime + $timeout >= $time) && $hash === $validHash; + } } diff --git a/components/UsrAlerts.php b/components/UsrAlerts.php index 74ed3bf..7170b8d 100644 --- a/components/UsrAlerts.php +++ b/components/UsrAlerts.php @@ -12,18 +12,18 @@ */ class UsrAlerts extends CWidget { - public $cssClassPrefix; - /** - * Renders the widget. - */ - public function run() - { - if (($flashMessages = Yii::app()->user->getFlashes())) { - echo ''; - } - } + public $cssClassPrefix; + /** + * Renders the widget. + */ + public function run() + { + if (($flashMessages = Yii::app()->user->getFlashes())) { + echo ''; + } + } } diff --git a/controllers/DefaultController.php b/controllers/DefaultController.php index cc56ea7..ed59448 100644 --- a/controllers/DefaultController.php +++ b/controllers/DefaultController.php @@ -8,53 +8,53 @@ */ class DefaultController extends UsrController { - /** - * @inheritdoc - */ - public function getId() - { - // use constant id to allow mapping fake controller names to this one, @see UsrModule::$controllerMap - return 'default'; - } + /** + * @inheritdoc + */ + public function getId() + { + // use constant id to allow mapping fake controller names to this one, @see UsrModule::$controllerMap + return 'default'; + } - /** - * @inheritdoc - */ - public function getUniqueId() - { - // use constant id to allow mapping fake controller names to this one, @see UsrModule::$controllerMap - return $this->getModule() ? $this->getModule()->getId().'/default' : 'default'; - } + /** + * @inheritdoc + */ + public function getUniqueId() + { + // use constant id to allow mapping fake controller names to this one, @see UsrModule::$controllerMap + return $this->getModule() ? $this->getModule()->getId().'/default' : 'default'; + } - /** - * @inheritdoc - */ - public function run($actionID) - { - return parent::run(($id=parent::getId()) !== 'default' ? $id : $actionID); - } + /** + * @inheritdoc + */ + public function run($actionID) + { + return parent::run(($id = parent::getId()) !== 'default' ? $id : $actionID); + } - public function actions() - { - $actions = array(); - if ($this->module->captcha !== null) { - // captcha action renders the CAPTCHA image displayed on the register and recovery page - $actions['captcha'] = array( - 'class'=>'CCaptchaAction', - 'backColor'=>0xFFFFFF, - 'testLimit'=>0, - ); - } - if ($this->module->dicewareEnabled) { - // DicewareAction generates a random passphrase - $actions['password'] = array( - 'class'=>'DicewareAction', - 'length'=>$this->module->dicewareLength, - 'extraDigit'=>$this->module->dicewareExtraDigit, - 'extraChar'=>$this->module->dicewareExtraChar, - ); - } - if (isset($this->module->loginFormBehaviors['oneTimePasswordBehavior'])) { + public function actions() + { + $actions = array(); + if ($this->module->captcha !== null) { + // captcha action renders the CAPTCHA image displayed on the register and recovery page + $actions['captcha'] = array( + 'class' => 'CCaptchaAction', + 'backColor' => 0xFFFFFF, + 'testLimit' => 0, + ); + } + if ($this->module->dicewareEnabled) { + // DicewareAction generates a random passphrase + $actions['password'] = array( + 'class' => 'DicewareAction', + 'length' => $this->module->dicewareLength, + 'extraDigit' => $this->module->dicewareExtraDigit, + 'extraChar' => $this->module->dicewareExtraChar, + ); + } + if (isset($this->module->loginFormBehaviors['oneTimePasswordBehavior'])) { $configuration = $this->module->loginFormBehaviors['oneTimePasswordBehavior']; if (!isset($configuration['authenticator'])) { $configuration['authenticator'] = OneTimePasswordFormBehavior::getDefaultAuthenticator(); @@ -62,325 +62,340 @@ public function actions() if ($configuration['mode'] != OneTimePasswordFormBehavior::OTP_NONE) { // OneTimePasswordAction allows toggling two step auth in user profile $actions['toggleOneTimePassword'] = array( - 'class'=>'OneTimePasswordAction', + 'class' => 'OneTimePasswordAction', 'configuration' => $configuration, ); } - } - return $actions; - } + } - /** - * Redirect user depending on whether is he logged in or not. - * Performs additional authorization checks. - * @param CAction $action the action to be executed. - * @return boolean whether the action should continue to be executed. - */ - public function beforeAction($action) - { - if (!parent::beforeAction($action)) - return false; - switch($action->id) { - case 'index': - case 'profile': - if (Yii::app()->user->isGuest) { - $this->redirect(array('login')); - return false; - } - break; - case 'login': - case 'recovery': - if ($action->id === 'recovery' && !$this->module->recoveryEnabled) { - throw new CHttpException(403,Yii::t('UsrModule.usr', 'Password recovery has not been enabled.')); - } - if (!Yii::app()->user->isGuest) { + return $actions; + } + + /** + * Redirect user depending on whether is he logged in or not. + * Performs additional authorization checks. + * @param CAction $action the action to be executed. + * @return boolean whether the action should continue to be executed. + */ + public function beforeAction($action) + { + if (!parent::beforeAction($action)) { + return false; + } + switch ($action->id) { + case 'index': + case 'profile': + if (Yii::app()->user->isGuest) { + $this->redirect(array('login')); + + return false; + } + break; + case 'login': + case 'recovery': + if ($action->id === 'recovery' && !$this->module->recoveryEnabled) { + throw new CHttpException(403, Yii::t('UsrModule.usr', 'Password recovery has not been enabled.')); + } + if (!Yii::app()->user->isGuest) { $this->redirect(Yii::app()->user->returnUrl !== Yii::app()->request->getRequestUri() ? Yii::app()->user->returnUrl : array(Yii::app()->defaultController)); - return false; - } - break; - case 'register': - if (!$this->module->registrationEnabled) { - throw new CHttpException(403,Yii::t('UsrModule.usr', 'Registration has not been enabled.')); - } - if (!Yii::app()->user->isGuest) { - $this->redirect(array('profile')); - return false; - } - break; - case 'verify': - if (!isset($_GET['activationKey'])) { - throw new CHttpException(400,Yii::t('UsrModule.usr', 'Activation key is missing.')); - } - break; - } - return true; - } - /** - * Users are redirected to their profile if logged in and to login page otherwise. - */ - public function actionIndex() - { - $this->redirect(array('profile')); - } + return false; + } + break; + case 'register': + if (!$this->module->registrationEnabled) { + throw new CHttpException(403, Yii::t('UsrModule.usr', 'Registration has not been enabled.')); + } + if (!Yii::app()->user->isGuest) { + $this->redirect(array('profile')); + + return false; + } + break; + case 'verify': + if (!isset($_GET['activationKey'])) { + throw new CHttpException(400, Yii::t('UsrModule.usr', 'Activation key is missing.')); + } + break; + } + + return true; + } + + /** + * Users are redirected to their profile if logged in and to login page otherwise. + */ + public function actionIndex() + { + $this->redirect(array('profile')); + } - /** - * Performs user login, expired password reset or one time password verification. - * @param string $scenario - * @return string - */ - public function actionLogin($scenario = null) - { - /** @var LoginForm */ - $model = $this->module->createFormModel('LoginForm'); - if ($scenario !== null && in_array($scenario, $model->getAvailableScenarios())) { - $model->scenario = $scenario; - } + /** + * Performs user login, expired password reset or one time password verification. + * @param string $scenario + * @return string + */ + public function actionLogin($scenario = null) + { + /** @var LoginForm */ + $model = $this->module->createFormModel('LoginForm'); + if ($scenario !== null && in_array($scenario, $model->getAvailableScenarios())) { + $model->scenario = $scenario; + } - if (isset($_POST['ajax']) && $_POST['ajax']==='login-form') { - echo CActiveForm::validate($model); - Yii::app()->end(); - } + if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') { + echo CActiveForm::validate($model); + Yii::app()->end(); + } - if (isset($_POST['LoginForm'])) { - $model->setAttributes($_POST['LoginForm']); - if ($model->validate()) { - if (($model->scenario !== 'reset' || $model->resetPassword()) && $model->login($this->module->rememberMeDuration)) { + if (isset($_POST['LoginForm'])) { + $model->setAttributes($_POST['LoginForm']); + if ($model->validate()) { + if (($model->scenario !== 'reset' || $model->resetPassword()) && $model->login($this->module->rememberMeDuration)) { $this->afterLogin(); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to change password or log in using new password.')); - } - } - } + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to change password or log in using new password.')); + } + } + } list($view, $params) = $this->getScenarioView($model->scenario, 'login'); - $this->render($view, array_merge(array('model'=>$model), $params)); - } + $this->render($view, array_merge(array('model' => $model), $params)); + } - /** - * Logs out the current user and redirect to homepage. - */ - public function actionLogout() - { - if (!Yii::app()->user->isGuest) - Yii::app()->user->logout(); - $this->redirect(Yii::app()->homeUrl); - } + /** + * Logs out the current user and redirect to homepage. + */ + public function actionLogout() + { + if (!Yii::app()->user->isGuest) { + Yii::app()->user->logout(); + } + $this->redirect(Yii::app()->homeUrl); + } - /** - * Processes a request for password recovery email or resetting the password. - * @return string - */ - public function actionRecovery() - { - /** @var RecoveryForm */ - $model = $this->module->createFormModel('RecoveryForm'); + /** + * Processes a request for password recovery email or resetting the password. + * @return string + */ + public function actionRecovery() + { + /** @var RecoveryForm */ + $model = $this->module->createFormModel('RecoveryForm'); - if (isset($_POST['ajax']) && $_POST['ajax']==='recovery-form') { - echo CActiveForm::validate($model); - Yii::app()->end(); - } + if (isset($_POST['ajax']) && $_POST['ajax'] === 'recovery-form') { + echo CActiveForm::validate($model); + Yii::app()->end(); + } - if (isset($_GET['activationKey'])) { - $model->scenario = 'reset'; - $model->setAttributes($_GET); - } - if (isset($_POST['RecoveryForm'])) { - $model->setAttributes($_POST['RecoveryForm']); - /** - * If the activation key is missing that means the user is requesting a recovery email. - */ - if ($model->activationKey !== null) - $model->scenario = 'reset'; - if ($model->validate()) { - if ($model->scenario !== 'reset') { - /** - * Send email appropriate to the activation status. If verification is required, that must happen - * before password recovery. Also allows re-sending of verification emails. - */ - if ($this->sendEmail($model, $model->identity->isActive() ? 'recovery' : 'verify')) { - Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the email address associated with the specified user account.')); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } - } else { - // a valid recovery form means the user confirmed his email address - $model->getIdentity()->verifyEmail($this->module->requireVerifiedEmail); - // regenerate the activation key to prevent reply attack - $model->getIdentity()->getActivationKey(); - if ($model->resetPassword() && $model->login()) { + if (isset($_GET['activationKey'])) { + $model->scenario = 'reset'; + $model->setAttributes($_GET); + } + if (isset($_POST['RecoveryForm'])) { + $model->setAttributes($_POST['RecoveryForm']); + /** + * If the activation key is missing that means the user is requesting a recovery email. + */ + if ($model->activationKey !== null) { + $model->scenario = 'reset'; + } + if ($model->validate()) { + if ($model->scenario !== 'reset') { + /** + * Send email appropriate to the activation status. If verification is required, that must happen + * before password recovery. Also allows re-sending of verification emails. + */ + if ($this->sendEmail($model, $model->identity->isActive() ? 'recovery' : 'verify')) { + Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the email address associated with the specified user account.')); + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } + } else { + // a valid recovery form means the user confirmed his email address + $model->getIdentity()->verifyEmail($this->module->requireVerifiedEmail); + // regenerate the activation key to prevent reply attack + $model->getIdentity()->getActivationKey(); + if ($model->resetPassword() && $model->login()) { $this->afterLogin(); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to change password or log in using new password.')); - } - } - $this->redirect(array('recovery')); - } - } - $this->render('recovery',array('model'=>$model)); - } + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to change password or log in using new password.')); + } + } + $this->redirect(array('recovery')); + } + } + $this->render('recovery', array('model' => $model)); + } - /** - * Processes email verification. - * @return string - */ - public function actionVerify() - { - /** @var RecoveryForm */ - $model = $this->module->createFormModel('RecoveryForm', 'verify'); - $model->setAttributes($_GET); - if ($model->validate() && $model->getIdentity()->verifyEmail($this->module->requireVerifiedEmail)) { - // regenerate the activation key to prevent reply attack - $model->getIdentity()->getActivationKey(); - Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'Your email address has been successfully verified.')); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to verify your email address.')); - } - $this->redirect(array(Yii::app()->user->isGuest ? 'login' : 'profile')); - } + /** + * Processes email verification. + * @return string + */ + public function actionVerify() + { + /** @var RecoveryForm */ + $model = $this->module->createFormModel('RecoveryForm', 'verify'); + $model->setAttributes($_GET); + if ($model->validate() && $model->getIdentity()->verifyEmail($this->module->requireVerifiedEmail)) { + // regenerate the activation key to prevent reply attack + $model->getIdentity()->getActivationKey(); + Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'Your email address has been successfully verified.')); + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to verify your email address.')); + } + $this->redirect(array(Yii::app()->user->isGuest ? 'login' : 'profile')); + } - /** - * Performs user sign-up. - * @return string - */ - public function actionRegister() - { - /** @var ProfileForm */ - $model = $this->module->createFormModel('ProfileForm', 'register'); - /** @var PasswordForm */ - $passwordForm = $this->module->createFormModel('PasswordForm', 'register'); + /** + * Performs user sign-up. + * @return string + */ + public function actionRegister() + { + /** @var ProfileForm */ + $model = $this->module->createFormModel('ProfileForm', 'register'); + /** @var PasswordForm */ + $passwordForm = $this->module->createFormModel('PasswordForm', 'register'); - if (isset($_POST['ajax']) && $_POST['ajax']==='profile-form') { - echo CActiveForm::validate(array($model, $passwordForm)); - Yii::app()->end(); - } - if (isset($_POST['ProfileForm'])) { - $model->setAttributes($_POST['ProfileForm']); - if ($model->getIdentity() instanceof IPictureIdentity && !empty($model->pictureUploadRules)) { - $model->picture = CUploadedFile::getInstance($model, 'picture'); - } - if (isset($_POST['PasswordForm'])) - $passwordForm->setAttributes($_POST['PasswordForm']); - if ($model->validate() && $passwordForm->validate()) { - $trx = Yii::app()->db->beginTransaction(); - if (!$model->save($this->module->requireVerifiedEmail) || !$passwordForm->resetPassword($model->getIdentity())) { - $trx->rollback(); - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to register a new user.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } else { - $trx->commit(); - if ($this->module->requireVerifiedEmail) { - if ($this->sendEmail($model, 'verify')) { - Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.')); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } - } - if ($model->getIdentity()->isActive()) { - if ($model->login()) { + if (isset($_POST['ajax']) && $_POST['ajax'] === 'profile-form') { + echo CActiveForm::validate(array($model, $passwordForm)); + Yii::app()->end(); + } + if (isset($_POST['ProfileForm'])) { + $model->setAttributes($_POST['ProfileForm']); + if ($model->getIdentity() instanceof IPictureIdentity && !empty($model->pictureUploadRules)) { + $model->picture = CUploadedFile::getInstance($model, 'picture'); + } + if (isset($_POST['PasswordForm'])) { + $passwordForm->setAttributes($_POST['PasswordForm']); + } + if ($model->validate() && $passwordForm->validate()) { + $trx = Yii::app()->db->beginTransaction(); + if (!$model->save($this->module->requireVerifiedEmail) || !$passwordForm->resetPassword($model->getIdentity())) { + $trx->rollback(); + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to register a new user.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } else { + $trx->commit(); + if ($this->module->requireVerifiedEmail) { + if ($this->sendEmail($model, 'verify')) { + Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.')); + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } + } + if ($model->getIdentity()->isActive()) { + if ($model->login()) { $this->afterLogin(); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to log in.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } - } else { - if (!Yii::app()->user->hasFlash('success')) - Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'Please wait for the account to be activated. A notification will be send to provided email address.')); - $this->redirect(array('login')); - } - } - } - } - $this->render('updateProfile',array('model'=>$model, 'passwordForm'=>$passwordForm)); - } + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to log in.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } + } else { + if (!Yii::app()->user->hasFlash('success')) { + Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'Please wait for the account to be activated. A notification will be send to provided email address.')); + } + $this->redirect(array('login')); + } + } + } + } + $this->render('updateProfile', array('model' => $model, 'passwordForm' => $passwordForm)); + } - /** - * Allows users to view or update their profile. - * @param boolean $update - * @return string - */ - public function actionProfile($update=false) - { - /** @var ProfileForm */ - $model = $this->module->createFormModel('ProfileForm'); - $model->setAttributes($model->getIdentity()->getAttributes()); - /** @var PasswordForm */ - $passwordForm = $this->module->createFormModel('PasswordForm'); + /** + * Allows users to view or update their profile. + * @param boolean $update + * @return string + */ + public function actionProfile($update = false) + { + /** @var ProfileForm */ + $model = $this->module->createFormModel('ProfileForm'); + $model->setAttributes($model->getIdentity()->getAttributes()); + /** @var PasswordForm */ + $passwordForm = $this->module->createFormModel('PasswordForm'); - if (isset($_POST['ProfileForm']) && isset($_POST['ProfileForm']['password'])) - $passwordForm->password = $_POST['ProfileForm']['password']; - if (isset($_POST['ajax']) && $_POST['ajax']==='profile-form') { - $models = array($model); - if (isset($_POST['PasswordForm']) && trim($_POST['PasswordForm']['newPassword']) !== '') { - $models[] = $passwordForm; - } - echo CActiveForm::validate($models); - Yii::app()->end(); - } - $flashes = array('success'=>array(), 'error'=>array()); - /** - * Only try to set new password if it has been specified in the form. - * The current password could have been used to authorize other changes. - */ - if (isset($_POST['PasswordForm']) && trim($_POST['PasswordForm']['newPassword']) !== '') { - $passwordForm->setAttributes($_POST['PasswordForm']); - if ($passwordForm->validate() && $passwordForm->resetPassword($model->getIdentity())) { - $flashes['success'][] = Yii::t('UsrModule.usr', 'Changes have been saved successfully.'); - } else { - $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to change password.'); - } - } - if (isset($_POST['ProfileForm']) && empty($flashes['error'])) { - $model->setAttributes($_POST['ProfileForm']); - if ($model->getIdentity() instanceof IPictureIdentity && !empty($model->pictureUploadRules)) { - $model->picture = CUploadedFile::getInstance($model, 'picture'); - } - if ($model->validate()) { - $oldEmail = $model->getIdentity()->getEmail(); - if ($model->save($this->module->requireVerifiedEmail)) { - if ($this->module->requireVerifiedEmail && $oldEmail != $model->email) { - if ($this->sendEmail($model, 'verify')) { - $flashes['success'][] = Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.'); - } else { - $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.'); - } - } - $flashes['success'][] = Yii::t('UsrModule.usr', 'Changes have been saved successfully.'); - if (!empty($flashes['success'])) - Yii::app()->user->setFlash('success', implode('
',$flashes['success'])); - if (!empty($flashes['error'])) - Yii::app()->user->setFlash('error', implode('
',$flashes['error'])); - $this->redirect(array('profile')); - } else { - $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to update profile.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.'); - } - } - } - if (!empty($flashes['success'])) - Yii::app()->user->setFlash('success', implode('
',$flashes['success'])); - if (!empty($flashes['error'])) - Yii::app()->user->setFlash('error', implode('
',$flashes['error'])); - if ($update) { - $this->render('updateProfile',array('model'=>$model, 'passwordForm'=>$passwordForm)); - } else { - $this->render('viewProfile',array('model'=>$model)); - } - } + if (isset($_POST['ProfileForm']) && isset($_POST['ProfileForm']['password'])) { + $passwordForm->password = $_POST['ProfileForm']['password']; + } + if (isset($_POST['ajax']) && $_POST['ajax'] === 'profile-form') { + $models = array($model); + if (isset($_POST['PasswordForm']) && trim($_POST['PasswordForm']['newPassword']) !== '') { + $models[] = $passwordForm; + } + echo CActiveForm::validate($models); + Yii::app()->end(); + } + $flashes = array('success' => array(), 'error' => array()); + /** + * Only try to set new password if it has been specified in the form. + * The current password could have been used to authorize other changes. + */ + if (isset($_POST['PasswordForm']) && trim($_POST['PasswordForm']['newPassword']) !== '') { + $passwordForm->setAttributes($_POST['PasswordForm']); + if ($passwordForm->validate() && $passwordForm->resetPassword($model->getIdentity())) { + $flashes['success'][] = Yii::t('UsrModule.usr', 'Changes have been saved successfully.'); + } else { + $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to change password.'); + } + } + if (isset($_POST['ProfileForm']) && empty($flashes['error'])) { + $model->setAttributes($_POST['ProfileForm']); + if ($model->getIdentity() instanceof IPictureIdentity && !empty($model->pictureUploadRules)) { + $model->picture = CUploadedFile::getInstance($model, 'picture'); + } + if ($model->validate()) { + $oldEmail = $model->getIdentity()->getEmail(); + if ($model->save($this->module->requireVerifiedEmail)) { + if ($this->module->requireVerifiedEmail && $oldEmail != $model->email) { + if ($this->sendEmail($model, 'verify')) { + $flashes['success'][] = Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.'); + } else { + $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.'); + } + } + $flashes['success'][] = Yii::t('UsrModule.usr', 'Changes have been saved successfully.'); + if (!empty($flashes['success'])) { + Yii::app()->user->setFlash('success', implode('
', $flashes['success'])); + } + if (!empty($flashes['error'])) { + Yii::app()->user->setFlash('error', implode('
', $flashes['error'])); + } + $this->redirect(array('profile')); + } else { + $flashes['error'][] = Yii::t('UsrModule.usr', 'Failed to update profile.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.'); + } + } + } + if (!empty($flashes['success'])) { + Yii::app()->user->setFlash('success', implode('
', $flashes['success'])); + } + if (!empty($flashes['error'])) { + Yii::app()->user->setFlash('error', implode('
', $flashes['error'])); + } + if ($update) { + $this->render('updateProfile', array('model' => $model, 'passwordForm' => $passwordForm)); + } else { + $this->render('viewProfile', array('model' => $model)); + } + } - /** - * Allows users to view their profile picture. - * @param integer $id - * @return string - */ - public function actionProfilePicture($id) - { - /** @var ProfileForm */ - $model = $this->module->createFormModel('ProfileForm'); - if (!(($identity=$model->getIdentity()) instanceof IPictureIdentity)) { - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($identity),'{interface}'=>'IPictureIdentity'))); - } - $picture = $identity->getPicture($id); - if ($picture === null) { - throw new CHttpException(404, Yii::t('UsrModule.usr', 'Picture with id {id} is not found.', array('{id}'=>$id))); - } - header('Content-Type:'.$picture['mimetype']); - echo $picture['picture']; - } + /** + * Allows users to view their profile picture. + * @param integer $id + * @return string + */ + public function actionProfilePicture($id) + { + /** @var ProfileForm */ + $model = $this->module->createFormModel('ProfileForm'); + if (!(($identity = $model->getIdentity()) instanceof IPictureIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($identity), '{interface}' => 'IPictureIdentity'))); + } + $picture = $identity->getPicture($id); + if ($picture === null) { + throw new CHttpException(404, Yii::t('UsrModule.usr', 'Picture with id {id} is not found.', array('{id}' => $id))); + } + header('Content-Type:'.$picture['mimetype']); + echo $picture['picture']; + } } diff --git a/controllers/HybridauthController.php b/controllers/HybridauthController.php index 2d2a781..c9d0aa1 100644 --- a/controllers/HybridauthController.php +++ b/controllers/HybridauthController.php @@ -13,22 +13,22 @@ public function actionIndex() $this->redirect('default/login'); } - public function actionPopup($provider=null) + public function actionPopup($provider = null) { /** @var HybridauthForm */ $remoteLogin = $this->module->createFormModel('HybridauthForm'); - if ($provider!==null) { + if ($provider !== null) { $remoteLogin->provider = $provider; $remoteLogin->scenario = strtolower($remoteLogin->provider); - if($remoteLogin->validate()) { + if ($remoteLogin->validate()) { $remoteLogin->login(); } } // if we got here that means Hybridauth did not perform a redirect, // either there was an error or the user is already authenticated - $url = $this->createUrl('login', array('provider'=>$provider)); + $url = $this->createUrl('login', array('provider' => $provider)); $message = Yii::t('UsrModule.usr', 'Redirecting, please wait...'); echo "$message"; Yii::app()->end(); @@ -40,25 +40,27 @@ public function actionPopup($provider=null) * if there are any form errors. * @param string $provider name of the remote provider */ - public function actionLogin($provider=null) + public function actionLogin($provider = null) { - if ($provider!==null) + if ($provider !== null) { $_POST['HybridauthForm']['provider'] = $provider; + } /** @var HybridauthForm */ $remoteLogin = $this->module->createFormModel('HybridauthForm'); /** @var LoginForm */ $localLogin = $this->module->createFormModel('LoginForm', 'hybridauth'); /** @var ProfileForm */ $localProfile = $this->module->createFormModel('ProfileForm', 'register'); - $localProfile->detachBehavior('captcha'); + $localProfile->detachBehavior('captcha'); - if(isset($_POST['ajax'])) { - if ($_POST['ajax']==='remoteLogin-form') + if (isset($_POST['ajax'])) { + if ($_POST['ajax'] === 'remoteLogin-form') { echo CActiveForm::validate($remoteLogin); - elseif ($_POST['ajax']==='localProfile-form') + } elseif ($_POST['ajax'] === 'localProfile-form') { echo CActiveForm::validate($localProfile); - else + } else { echo CActiveForm::validate($localLogin); + } Yii::app()->end(); } @@ -66,19 +68,19 @@ public function actionLogin($provider=null) $remoteLogin->setAttributes($_POST['HybridauthForm']); $remoteLogin->scenario = strtolower($remoteLogin->provider); - if($remoteLogin->validate()) { + if ($remoteLogin->validate()) { if ($remoteLogin->login()) { // user is already associated with remote identity and has been logged in $this->afterLogin(); - } elseif (($adapter=$remoteLogin->getHybridAuthAdapter()) === null || !$adapter->isUserConnected()) { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to log in using {provider}.', array('{provider}'=>$remoteLogin->provider))); - $this->redirect(array('login', 'provider'=>$remoteLogin->provider)); + } elseif (($adapter = $remoteLogin->getHybridAuthAdapter()) === null || !$adapter->isUserConnected()) { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to log in using {provider}.', array('{provider}' => $remoteLogin->provider))); + $this->redirect(array('login', 'provider' => $remoteLogin->provider)); } if (!Yii::app()->user->isGuest) { // user is already logged in and needs to be associated with remote identity if (!$remoteLogin->associate(Yii::app()->user->getId())) { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}'=>$remoteLogin->provider))); - $this->redirect(array('login', 'provider'=>$remoteLogin->provider)); + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}' => $remoteLogin->provider))); + $this->redirect(array('login', 'provider' => $remoteLogin->provider)); } $this->afterLogin(); } @@ -87,7 +89,7 @@ public function actionLogin($provider=null) $remoteProfile = $remoteLogin->getHybridAuthAdapter()->getUserProfile(); $remoteProfileAttributes = $userIdentityClass::getRemoteAttributes($remoteProfile); $searchAttributes = array(); - foreach($this->module->associateByAttributes as $name) { + foreach ($this->module->associateByAttributes as $name) { if (isset($remoteProfileAttributes[$name])) { $searchAttributes[$name] = $remoteProfileAttributes[$name]; } @@ -103,18 +105,19 @@ public function actionLogin($provider=null) $localProfile = $this->registerLocalProfile($localProfile, $remoteLogin, $localIdentity); } $this->render('associate', array( - 'remoteLogin'=>$remoteLogin, - 'localLogin'=>$localLogin, - 'localProfile'=>$localProfile, - 'localIdentity'=>$localIdentity, + 'remoteLogin' => $remoteLogin, + 'localLogin' => $localLogin, + 'localProfile' => $localProfile, + 'localIdentity' => $localIdentity, )); + return; } } $this->render('login', array( - 'remoteLogin'=>$remoteLogin, - 'localLogin'=>$localLogin, - 'localProfile'=>$localProfile, + 'remoteLogin' => $remoteLogin, + 'localLogin' => $localLogin, + 'localProfile' => $localProfile, )); } @@ -122,24 +125,24 @@ public function actionLogin($provider=null) * This action actually removes association with a remote profile instead of logging out. * @param string $provider name of the remote provider */ - public function actionLogout($provider=null, $returnUrl=null) + public function actionLogout($provider = null, $returnUrl = null) { - /** @var ProfileForm */ - $model = $this->module->createFormModel('ProfileForm'); + /** @var ProfileForm */ + $model = $this->module->createFormModel('ProfileForm'); // HybridauthForm creates an association using lowercase provider $model->getIdentity()->removeRemoteIdentity(strtolower($provider)); - $this->redirect($returnUrl !== null ? $returnUrl : Yii::app()->homeUrl); + $this->redirect($returnUrl !== null ? $returnUrl : Yii::app()->homeUrl); } /** - * @param LoginForm $localLogin - * @param HybridauthForm $remoteLogin - * @param boolean|IUserIdentity $localIdentity if not false, try to authenticate this identity instead - * @return LoginForm validated $localLogin + * @param LoginForm $localLogin + * @param HybridauthForm $remoteLogin + * @param boolean|IUserIdentity $localIdentity if not false, try to authenticate this identity instead + * @return LoginForm validated $localLogin */ protected function performLocalLogin(LoginForm $localLogin, HybridauthForm $remoteLogin, $localIdentity = false) { - if(!isset($_POST['LoginForm'])) { + if (!isset($_POST['LoginForm'])) { return $localLogin; } if (is_object($localIdentity)) { @@ -150,15 +153,16 @@ protected function performLocalLogin(LoginForm $localLogin, HybridauthForm $remo } } $localLogin->setAttributes($_POST['LoginForm']); - if($localLogin->validate() && $localLogin->login()) { + if ($localLogin->validate() && $localLogin->login()) { // don't forget to associate the new profile with remote provider if (!$remoteLogin->associate($localLogin->getIdentity()->getId())) { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}'=>$remoteLogin->provider))); - $this->redirect(array('login', 'provider'=>$remoteLogin->provider)); + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}' => $remoteLogin->provider))); + $this->redirect(array('login', 'provider' => $remoteLogin->provider)); } $this->afterLogin(); } + return $localLogin; } @@ -169,6 +173,7 @@ protected function registerLocalProfile(ProfileForm $localProfile, HybridauthFor $remoteProfile = $remoteLogin->getHybridAuthAdapter()->getUserProfile(); $localProfile->setAttributes($userIdentityClass::getRemoteAttributes($remoteProfile)); $localProfile->validate(); + return $localProfile; } @@ -189,6 +194,7 @@ protected function registerLocalProfile(ProfileForm $localProfile, HybridauthFor if (!$localProfile->save($this->module->requireVerifiedEmail)) { $trx->rollback(); Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to register a new user.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + return $localProfile; } @@ -203,28 +209,30 @@ protected function registerLocalProfile(ProfileForm $localProfile, HybridauthFor // don't forget to associate the new profile with remote provider if (!$remoteLogin->associate($localProfile->getIdentity()->getId())) { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}'=>$remoteLogin->provider))); - $this->redirect(array('login', 'provider'=>$remoteLogin->provider)); + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to associate current user with {provider}.', array('{provider}' => $remoteLogin->provider))); + $this->redirect(array('login', 'provider' => $remoteLogin->provider)); } if ($localProfile->getIdentity()->isActive()) { // don't use the $localProfile->login() method because there is no password set so we can't authenticate this identity - if (Yii::app()->user->login($localProfile->getIdentity(),0)) { + if (Yii::app()->user->login($localProfile->getIdentity(), 0)) { $this->afterLogin(); } else { Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to log in.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); } } else { - if (!Yii::app()->user->hasFlash('success')) + if (!Yii::app()->user->hasFlash('success')) { Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'Please wait for the account to be activated. A notification will be send to provided email address.')); - $this->redirect(array('login', 'provider'=>$remoteLogin->provider)); + } + $this->redirect(array('login', 'provider' => $remoteLogin->provider)); } + return $localProfile; } public function actionCallback() { - require dirname(__FILE__) . '/../extensions/Hybrid/Endpoint.php'; + require dirname(__FILE__).'/../extensions/Hybrid/Endpoint.php'; Hybrid_Endpoint::process(); } } diff --git a/controllers/ManagerController.php b/controllers/ManagerController.php index 94e23a7..1bd1e57 100644 --- a/controllers/ManagerController.php +++ b/controllers/ManagerController.php @@ -4,42 +4,42 @@ class ManagerController extends UsrController { - /** - * @var string the default layout for the views. Defaults to '//layouts/column2', meaning - * using two-column layout. See 'protected/views/layouts/column2.php'. - */ - public $layout='//layouts/column2'; - /** - * @var array context menu items. This property will be assigned to {@link CMenu::items}. - */ - public $menu=array(); - - /** - * @return array action filters - */ - public function filters() - { - return array( - 'accessControl', - 'postOnly + delete', - ); - } - - /** - * Specifies the access control rules. - * This method is used by the 'accessControl' filter. - * @return array access control rules - */ - public function accessRules() - { - return array( - array('allow', 'actions'=>array('index'), 'roles'=>array('usr.read')), - array('allow', 'actions'=>array('update'), 'users'=>array('@')), - array('allow', 'actions'=>array('delete'), 'roles'=>array('usr.delete')), - array('allow', 'actions'=>array('verify', 'activate', 'disable'), 'roles'=>array('usr.update.status')), - array('deny', 'users'=>array('*')), - ); - } + /** + * @var string the default layout for the views. Defaults to '//layouts/column2', meaning + * using two-column layout. See 'protected/views/layouts/column2.php'. + */ + public $layout = '//layouts/column2'; + /** + * @var array context menu items. This property will be assigned to {@link CMenu::items}. + */ + public $menu = array(); + + /** + * @return array action filters + */ + public function filters() + { + return array( + 'accessControl', + 'postOnly + delete', + ); + } + + /** + * Specifies the access control rules. + * This method is used by the 'accessControl' filter. + * @return array access control rules + */ + public function accessRules() + { + return array( + array('allow', 'actions' => array('index'), 'roles' => array('usr.read')), + array('allow', 'actions' => array('update'), 'users' => array('@')), + array('allow', 'actions' => array('delete'), 'roles' => array('usr.delete')), + array('allow', 'actions' => array('verify', 'activate', 'disable'), 'roles' => array('usr.update.status')), + array('deny', 'users' => array('*')), + ); + } /** * @inheritdoc @@ -47,8 +47,9 @@ public function accessRules() protected function afterAction($action) { if (in_array($action->id, array('delete', 'verify', 'activate', 'disable'))) { - if(!isset($_GET['ajax'])) + if (!isset($_GET['ajax'])) { $this->redirect(isset($_REQUEST['returnUrl']) ? $_REQUEST['returnUrl'] : array('index')); + } } } @@ -59,7 +60,7 @@ protected function updateAuthItems($id, $profileForm) $assignedRoles = $id === null ? array() : $authManager->getAuthItems(CAuthItem::TYPE_ROLE, $id); if (isset($_POST['roles']) && is_array($_POST['roles'])) { - foreach($_POST['roles'] as $roleName) { + foreach ($_POST['roles'] as $roleName) { if (!isset($assignedRoles[$roleName])) { $authManager->assign($roleName, $identity->getId()); } else { @@ -67,154 +68,156 @@ protected function updateAuthItems($id, $profileForm) } } } - foreach($assignedRoles as $roleName=>$role) { + foreach ($assignedRoles as $roleName => $role) { $authManager->revoke($roleName, $identity->getId()); } } - /** - * Updates a particular model. - * If update is successful, the browser will be redirected to the 'index' page. - * @param integer $id the ID of the model to be updated - */ - public function actionUpdate($id=null) - { - if (!Yii::app()->user->checkAccess($id === null ? 'usr.create' : 'usr.update')) { - throw new CHttpException(403, Yii::t('yii','You are not authorized to perform this action.')); - } - - /** @var ProfileForm */ - $profileForm = $this->module->createFormModel('ProfileForm', 'register'); - $profileForm->detachBehavior('captcha'); - if ($id !== null) { - $profileForm->setIdentity($identity=$this->loadModel($id)); - $profileForm->setAttributes($identity->getAttributes()); - } - /** @var PasswordForm */ - $passwordForm = $this->module->createFormModel('PasswordForm', 'register'); - - if(isset($_POST['ajax']) && $_POST['ajax']==='profile-form') { - echo CActiveForm::validate($profileForm); - Yii::app()->end(); - } - /** - * @todo Check for detailed auth items - */ - $canUpdateAttributes = Yii::app()->user->checkAccess('usr.update.attributes'); - $canUpdatePassword = Yii::app()->user->checkAccess('usr.update.password'); - $canUpdateAuth = Yii::app()->user->checkAccess('usr.update.auth'); - - if(isset($_POST['ProfileForm'])) { - $profileForm->setAttributes($_POST['ProfileForm']); - if ($profileForm->getIdentity() instanceof IPictureIdentity && !empty($profileForm->pictureUploadRules)) { - $profileForm->picture = CUploadedFile::getInstance($profileForm, 'picture'); - } - if ($canUpdatePassword && isset($_POST['PasswordForm']) && isset($_POST['PasswordForm']['newPassword']) && ($p=trim($_POST['PasswordForm']['newPassword']))!=='') { - $passwordForm->setAttributes($_POST['PasswordForm']); - $updatePassword = true; - } else { - $updatePassword = false; - } - if ($profileForm->validate() && (!$updatePassword || $passwordForm->validate())) { - $trx = Yii::app()->db->beginTransaction(); - $oldEmail = $profileForm->getIdentity()->getEmail(); - if (($canUpdateAttributes && !$profileForm->save($this->module->requireVerifiedEmail)) || ($updatePassword && !$passwordForm->resetPassword($profileForm->getIdentity()))) { - $trx->rollback(); - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to register a new user.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } else { - if ($canUpdateAuth) { + /** + * Updates a particular model. + * If update is successful, the browser will be redirected to the 'index' page. + * @param integer $id the ID of the model to be updated + */ + public function actionUpdate($id = null) + { + if (!Yii::app()->user->checkAccess($id === null ? 'usr.create' : 'usr.update')) { + throw new CHttpException(403, Yii::t('yii', 'You are not authorized to perform this action.')); + } + + /** @var ProfileForm */ + $profileForm = $this->module->createFormModel('ProfileForm', 'register'); + $profileForm->detachBehavior('captcha'); + if ($id !== null) { + $profileForm->setIdentity($identity = $this->loadModel($id)); + $profileForm->setAttributes($identity->getAttributes()); + } + /** @var PasswordForm */ + $passwordForm = $this->module->createFormModel('PasswordForm', 'register'); + + if (isset($_POST['ajax']) && $_POST['ajax'] === 'profile-form') { + echo CActiveForm::validate($profileForm); + Yii::app()->end(); + } + /** + * @todo Check for detailed auth items + */ + $canUpdateAttributes = Yii::app()->user->checkAccess('usr.update.attributes'); + $canUpdatePassword = Yii::app()->user->checkAccess('usr.update.password'); + $canUpdateAuth = Yii::app()->user->checkAccess('usr.update.auth'); + + if (isset($_POST['ProfileForm'])) { + $profileForm->setAttributes($_POST['ProfileForm']); + if ($profileForm->getIdentity() instanceof IPictureIdentity && !empty($profileForm->pictureUploadRules)) { + $profileForm->picture = CUploadedFile::getInstance($profileForm, 'picture'); + } + if ($canUpdatePassword && isset($_POST['PasswordForm']) && isset($_POST['PasswordForm']['newPassword']) && ($p = trim($_POST['PasswordForm']['newPassword'])) !== '') { + $passwordForm->setAttributes($_POST['PasswordForm']); + $updatePassword = true; + } else { + $updatePassword = false; + } + if ($profileForm->validate() && (!$updatePassword || $passwordForm->validate())) { + $trx = Yii::app()->db->beginTransaction(); + $oldEmail = $profileForm->getIdentity()->getEmail(); + if (($canUpdateAttributes && !$profileForm->save($this->module->requireVerifiedEmail)) || ($updatePassword && !$passwordForm->resetPassword($profileForm->getIdentity()))) { + $trx->rollback(); + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to register a new user.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } else { + if ($canUpdateAuth) { $this->updateAuthItems($id, $profileForm); - } - $trx->commit(); - if ($this->module->requireVerifiedEmail && $oldEmail != $profileForm->getIdentity()->email) { - if ($this->sendEmail($profileForm, 'verify')) { - Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.')); - } else { - Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); - } - } - if (!Yii::app()->user->hasFlash('success')) { - Yii::app()->user->setFlash('success', Yii::t('UsrModule.manager', 'User account has been successfully created or updated.')); - } - $this->redirect(array('index')); - } - } - } + } + $trx->commit(); + if ($this->module->requireVerifiedEmail && $oldEmail != $profileForm->getIdentity()->email) { + if ($this->sendEmail($profileForm, 'verify')) { + Yii::app()->user->setFlash('success', Yii::t('UsrModule.usr', 'An email containing further instructions has been sent to the provided email address.')); + } else { + Yii::app()->user->setFlash('error', Yii::t('UsrModule.usr', 'Failed to send an email.').' '.Yii::t('UsrModule.usr', 'Try again or contact the site administrator.')); + } + } + if (!Yii::app()->user->hasFlash('success')) { + Yii::app()->user->setFlash('success', Yii::t('UsrModule.manager', 'User account has been successfully created or updated.')); + } + $this->redirect(array('index')); + } + } + } $this->render('update', array( 'id' => $id, 'profileForm' => $profileForm, 'passwordForm' => $passwordForm, )); - } - - /** - * Deletes a particular model. - * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id the ID of the model to be deleted - */ - public function actionDelete($id) - { - if (!$this->loadModel($id)->delete()) { - throw new CHttpException(409,'User account could not be deleted.'); - } - } - - /** - * Toggles email verification status for a particular user. - * @param integer $id the ID of the user which email verification status is to be toggled - */ - public function actionVerify($id) - { - $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_EMAIL_VERIFIED); - } - - /** - * Toggles active status for a particular user. - * @param integer $id the ID of the user which active status is to be toggled - */ - public function actionActivate($id) - { - $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_IS_ACTIVE); - } - - /** - * Toggles disabled status for a particular user. - * @param integer $id the ID of the user which disabled status is to be toggled - */ - public function actionDisable($id) - { - $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_IS_DISABLED); - } - - /** - * Manages all models. - */ - public function actionIndex() - { - $model = $this->module->createFormModel('SearchForm'); - if (isset($_REQUEST['SearchForm'])) { - $model->attributes = $_REQUEST['SearchForm']; - $model->validate(); - $errors = $model->getErrors(); - $model->unsetAttributes(array_keys($errors)); - } - - $this->render('index', array('model'=>$model)); - } - - /** - * Returns the data model based on the primary key given in the GET variable. - * If the data model is not found, an HTTP exception will be raised. - * @param integer $id the ID of the model to be loaded - * @return User the loaded model - * @throws CHttpException - */ - public function loadModel($id) - { - $searchForm = $this->module->createFormModel('SearchForm'); - if(($model = $searchForm->getIdentity($id))===null) - throw new CHttpException(404,'The requested page does not exist.'); - return $model; - } + } + + /** + * Deletes a particular model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id the ID of the model to be deleted + */ + public function actionDelete($id) + { + if (!$this->loadModel($id)->delete()) { + throw new CHttpException(409, 'User account could not be deleted.'); + } + } + + /** + * Toggles email verification status for a particular user. + * @param integer $id the ID of the user which email verification status is to be toggled + */ + public function actionVerify($id) + { + $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_EMAIL_VERIFIED); + } + + /** + * Toggles active status for a particular user. + * @param integer $id the ID of the user which active status is to be toggled + */ + public function actionActivate($id) + { + $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_IS_ACTIVE); + } + + /** + * Toggles disabled status for a particular user. + * @param integer $id the ID of the user which disabled status is to be toggled + */ + public function actionDisable($id) + { + $this->loadModel($id)->toggleStatus(IManagedIdentity::STATUS_IS_DISABLED); + } + + /** + * Manages all models. + */ + public function actionIndex() + { + $model = $this->module->createFormModel('SearchForm'); + if (isset($_REQUEST['SearchForm'])) { + $model->attributes = $_REQUEST['SearchForm']; + $model->validate(); + $errors = $model->getErrors(); + $model->unsetAttributes(array_keys($errors)); + } + + $this->render('index', array('model' => $model)); + } + + /** + * Returns the data model based on the primary key given in the GET variable. + * If the data model is not found, an HTTP exception will be raised. + * @param integer $id the ID of the model to be loaded + * @return User the loaded model + * @throws CHttpException + */ + public function loadModel($id) + { + $searchForm = $this->module->createFormModel('SearchForm'); + if (($model = $searchForm->getIdentity($id)) === null) { + throw new CHttpException(404, 'The requested page does not exist.'); + } + + return $model; + } } diff --git a/controllers/UsrController.php b/controllers/UsrController.php index 1b4f3fc..ae1c169 100644 --- a/controllers/UsrController.php +++ b/controllers/UsrController.php @@ -2,52 +2,53 @@ abstract class UsrController extends CController { - /** - * Sends out an email containing instructions and link to the email verification - * or password recovery page, containing an activation key. - * @param CFormModel $model it must have a getIdentity() method - * @param strign $mode 'recovery', 'verify' or 'oneTimePassword' - * @return boolean if sending the email succeeded - */ - public function sendEmail(CFormModel $model, $mode) - { - $mail = $this->module->mailer; - $mail->AddAddress($model->getIdentity()->getEmail(), $model->getIdentity()->getName()); - $params = array( - 'siteUrl' => $this->createAbsoluteUrl('/'), - ); - switch($mode) { - default: return false; - case 'recovery': - case 'verify': - $mail->Subject = $mode == 'recovery' ? Yii::t('UsrModule.usr', 'Password recovery') : Yii::t('UsrModule.usr', 'Email address verification'); - $params['actionUrl'] = $this->createAbsoluteUrl('default/'.$mode, array( - 'activationKey'=>$model->getIdentity()->getActivationKey(), - 'username'=>$model->getIdentity()->getName(), - )); - break; - case 'oneTimePassword': - $mail->Subject = Yii::t('UsrModule.usr', 'One Time Password'); - $params['code'] = $model->getNewCode(); - break; - } - $body = $this->renderPartial($mail->getPathViews().'.'.$mode, $params, true); - $full = $this->renderPartial($mail->getPathLayouts().'.email', array('content'=>$body), true); - $mail->MsgHTML($full); - if ($mail->Send()) { - return true; - } else { - Yii::log($mail->ErrorInfo, 'error'); - return false; - } - } + /** + * Sends out an email containing instructions and link to the email verification + * or password recovery page, containing an activation key. + * @param CFormModel $model it must have a getIdentity() method + * @param strign $mode 'recovery', 'verify' or 'oneTimePassword' + * @return boolean if sending the email succeeded + */ + public function sendEmail(CFormModel $model, $mode) + { + $mail = $this->module->mailer; + $mail->AddAddress($model->getIdentity()->getEmail(), $model->getIdentity()->getName()); + $params = array( + 'siteUrl' => $this->createAbsoluteUrl('/'), + ); + switch ($mode) { + default: return false; + case 'recovery': + case 'verify': + $mail->Subject = $mode == 'recovery' ? Yii::t('UsrModule.usr', 'Password recovery') : Yii::t('UsrModule.usr', 'Email address verification'); + $params['actionUrl'] = $this->createAbsoluteUrl('default/'.$mode, array( + 'activationKey' => $model->getIdentity()->getActivationKey(), + 'username' => $model->getIdentity()->getName(), + )); + break; + case 'oneTimePassword': + $mail->Subject = Yii::t('UsrModule.usr', 'One Time Password'); + $params['code'] = $model->getNewCode(); + break; + } + $body = $this->renderPartial($mail->getPathViews().'.'.$mode, $params, true); + $full = $this->renderPartial($mail->getPathLayouts().'.email', array('content' => $body), true); + $mail->MsgHTML($full); + if ($mail->Send()) { + return true; + } else { + Yii::log($mail->ErrorInfo, 'error'); + + return false; + } + } /** * Retreive view name and params based on scenario name and module configuration. * - * @param string $scenario - * @param string $default default view name if scenario is null - * @return array two values, view name (string) and view params (array) + * @param string $scenario + * @param string $default default view name if scenario is null + * @return array two values, view name (string) and view params (array) */ public function getScenarioView($scenario, $default) { @@ -65,6 +66,7 @@ public function getScenarioView($scenario, $default) } else { $view = $scenario; } + return array($view, $config); } @@ -75,7 +77,7 @@ public function afterLogin() { $returnUrl = Yii::app()->user->returnUrl; $returnUrlParts = explode('/', is_array($returnUrl) ? reset($returnUrl) : $returnUrl); - $url = end($returnUrlParts)=='index.php' ? '/' : Yii::app()->user->returnUrl; + $url = end($returnUrlParts) == 'index.php' ? '/' : Yii::app()->user->returnUrl; $this->redirect($url); } } diff --git a/messages/config.php b/messages/config.php index ed9beec..11ee2d8 100644 --- a/messages/config.php +++ b/messages/config.php @@ -4,22 +4,22 @@ * for the Yii framework. It is used by the 'yiic message' command. */ return array( - 'sourcePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', - 'messagePath'=>dirname(__FILE__), - 'languages'=>array('cs', 'de', 'it', 'pl', 'ru'), - 'fileTypes'=>array('php'), - 'overwrite'=>true, - 'exclude'=>array( - '.svn', - '.git', - '.gitignore', - 'yiilite.php', - 'yiit.php', - 'yiic.php', - '/models/Example', - '/messages', - '/tests', - '/migrations', - '/extensions', - ), + 'sourcePath' => dirname(__FILE__).DIRECTORY_SEPARATOR.'..', + 'messagePath' => dirname(__FILE__), + 'languages' => array('cs', 'de', 'it', 'pl', 'ru'), + 'fileTypes' => array('php'), + 'overwrite' => true, + 'exclude' => array( + '.svn', + '.git', + '.gitignore', + 'yiilite.php', + 'yiit.php', + 'yiic.php', + '/models/Example', + '/messages', + '/tests', + '/migrations', + '/extensions', + ), ); diff --git a/messages/cs/usr.php b/messages/cs/usr.php index 054ef32..e91ffa7 100644 --- a/messages/cs/usr.php +++ b/messages/cs/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'Change password' => 'Změna hesla', 'Current password' => 'Aktuální heslo', 'New password' => 'Nové heslo', diff --git a/messages/de/usr.php b/messages/de/usr.php index 8229d5f..a001fb4 100644 --- a/messages/de/usr.php +++ b/messages/de/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'A one time password has been sent to your email. Enter it below.' => 'Ein einmaliges Passwort wurde an Ihre Emailadresse geschickt. Bitte unten bestätigen', 'Create a new account' => 'Neuen Acoount anlegen', 'Current password' => 'Aktuelles Passwort', diff --git a/messages/es/auth.php b/messages/es/auth.php index 49b016f..90ade2a 100644 --- a/messages/es/auth.php +++ b/messages/es/auth.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'Create users' => 'Crear usuarios', 'Delete any user' => 'Eliminar cualquier usuario', 'Manage users' => 'Gestionar usuarios', diff --git a/messages/es/manager.php b/messages/es/manager.php index 8924b41..f773fd6 100644 --- a/messages/es/manager.php +++ b/messages/es/manager.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'Activate' => 'Activar', 'Active' => 'Activo', 'Advanced Search' => 'Búsqueda avanzada', diff --git a/messages/es/usr.php b/messages/es/usr.php index 2cd56e3..5fc5ca6 100644 --- a/messages/es/usr.php +++ b/messages/es/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'A matching local account has been found. Please type in your password to associate it.' => 'Se ha encontrado una cuenta local que coincide. Por favor, escriba su contraseña para asociarlo.', 'A one time password has been sent to your email. Enter it below.' => 'Una contraseña temporal ha sido enviada a su correo electrónico. Escribirla a continuación.', 'Activation Key' => 'Clave de activación', diff --git a/messages/it/usr.php b/messages/it/usr.php index 5d706a7..3f8f4e8 100644 --- a/messages/it/usr.php +++ b/messages/it/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'A one time password has been sent to your email. Enter it below.' => 'Una password a singlo utilizzo è stata inviata la vostro indirizzo email. Inseritela nel campo sottostante.', 'Create a new account' => 'Crea nuovo account', 'Current password' => 'Password Corrente', diff --git a/messages/pl/auth.php b/messages/pl/auth.php index 8e42686..1e104af 100644 --- a/messages/pl/auth.php +++ b/messages/pl/auth.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'Create users' => 'Tworzy użytkowników', 'Delete any user' => 'Usuwa dowolnego użytkownika', 'Manage users' => 'Zarządza użytkownikami', diff --git a/messages/pl/manager.php b/messages/pl/manager.php index 1c5f67f..2af5df0 100644 --- a/messages/pl/manager.php +++ b/messages/pl/manager.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'Active' => 'Aktywny', 'Advanced Search' => 'Szukanie zaawansowane', 'Any' => 'Dowolnie', diff --git a/messages/pl/usr.php b/messages/pl/usr.php index e6afe9c..385ef79 100644 --- a/messages/pl/usr.php +++ b/messages/pl/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( 'A matching local account has been found. Please type in your password to associate it.' => 'Znaleziono pasujące lokalne konto użytkownika. Podaj hasło, aby je powiązać.', 'A one time password has been sent to your email. Enter it below.' => 'Hasło jednorazowe zostało wysłane na Twój email. Wprowadź je poniżej.', 'Activation Key' => 'Klucz aktywacyjny', diff --git a/messages/ru/usr.php b/messages/ru/usr.php index caf59ff..2b70851 100644 --- a/messages/ru/usr.php +++ b/messages/ru/usr.php @@ -16,7 +16,7 @@ * * NOTE, this file must be saved in UTF-8 encoding. */ -return array ( +return array( // 'A one time password has been sent to your email. Enter it below.' => '', // 'Create a new account' => '', // 'Current password' => '', diff --git a/migrations/m130701_104658_create_table_users.php b/migrations/m130701_104658_create_table_users.php index ee9c59a..880f680 100644 --- a/migrations/m130701_104658_create_table_users.php +++ b/migrations/m130701_104658_create_table_users.php @@ -2,33 +2,33 @@ class m130701_104658_create_table_users extends CDbMigration { - public function safeUp() - { - $this->createTable('{{users}}', array( - 'id'=>'pk', - 'username'=>'string NOT NULL', - 'password'=>'string NOT NULL', - 'email'=>'string NOT NULL', - 'firstname'=>'string', - 'lastname'=>'string', - 'activation_key'=>'string', - 'created_on'=>'timestamp', - 'updated_on'=>'timestamp', - 'last_visit_on'=>'timestamp', - 'password_set_on'=>'timestamp', - 'email_verified'=>'boolean NOT NULL DEFAULT 0', - 'is_active'=>'boolean NOT NULL DEFAULT 0', - 'is_disabled'=>'boolean NOT NULL DEFAULT 0', - )); - $this->createIndex('{{users}}_username_idx', '{{users}}', 'username', true); - $this->createIndex('{{users}}_email_idx', '{{users}}', 'email', true); - $this->createIndex('{{users}}_email_verified_idx', '{{users}}', 'email_verified'); - $this->createIndex('{{users}}_is_active_idx', '{{users}}', 'is_active'); - $this->createIndex('{{users}}_is_disabled_idx', '{{users}}', 'is_disabled'); - } + public function safeUp() + { + $this->createTable('{{users}}', array( + 'id' => 'pk', + 'username' => 'string NOT NULL', + 'password' => 'string NOT NULL', + 'email' => 'string NOT NULL', + 'firstname' => 'string', + 'lastname' => 'string', + 'activation_key' => 'string', + 'created_on' => 'timestamp', + 'updated_on' => 'timestamp', + 'last_visit_on' => 'timestamp', + 'password_set_on' => 'timestamp', + 'email_verified' => 'boolean NOT NULL DEFAULT 0', + 'is_active' => 'boolean NOT NULL DEFAULT 0', + 'is_disabled' => 'boolean NOT NULL DEFAULT 0', + )); + $this->createIndex('{{users}}_username_idx', '{{users}}', 'username', true); + $this->createIndex('{{users}}_email_idx', '{{users}}', 'email', true); + $this->createIndex('{{users}}_email_verified_idx', '{{users}}', 'email_verified'); + $this->createIndex('{{users}}_is_active_idx', '{{users}}', 'is_active'); + $this->createIndex('{{users}}_is_disabled_idx', '{{users}}', 'is_disabled'); + } - public function safeDown() - { - $this->dropTable('{{users}}'); - } + public function safeDown() + { + $this->dropTable('{{users}}'); + } } diff --git a/migrations/m130702_104658_create_table_user_remote_identities.php b/migrations/m130702_104658_create_table_user_remote_identities.php index ca3d224..b88ab94 100644 --- a/migrations/m130702_104658_create_table_user_remote_identities.php +++ b/migrations/m130702_104658_create_table_user_remote_identities.php @@ -2,22 +2,22 @@ class m130702_104658_create_table_user_remote_identities extends CDbMigration { - public function safeUp() - { - $this->createTable('{{user_remote_identities}}', array( - 'id'=>'pk', - 'user_id'=>'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', - 'provider'=>'varchar(100) NOT NULL', - 'identifier'=>'varchar(100) NOT NULL', - 'created_on'=>'timestamp NOT NULL', - 'last_used_on'=>'timestamp', - )); - $this->createIndex('{{user_remote_identities}}_provider_identifier_idx', '{{user_remote_identities}}', 'provider, identifier', true); - $this->createIndex('{{user_remote_identities}}_user_id_idx', '{{user_remote_identities}}', 'user_id'); - } + public function safeUp() + { + $this->createTable('{{user_remote_identities}}', array( + 'id' => 'pk', + 'user_id' => 'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', + 'provider' => 'varchar(100) NOT NULL', + 'identifier' => 'varchar(100) NOT NULL', + 'created_on' => 'timestamp NOT NULL', + 'last_used_on' => 'timestamp', + )); + $this->createIndex('{{user_remote_identities}}_provider_identifier_idx', '{{user_remote_identities}}', 'provider, identifier', true); + $this->createIndex('{{user_remote_identities}}_user_id_idx', '{{user_remote_identities}}', 'user_id'); + } - public function safeDown() - { - $this->dropTable('{{user_remote_identities}}'); - } + public function safeDown() + { + $this->dropTable('{{user_remote_identities}}'); + } } diff --git a/migrations/m130703_104658_users_add_one_time_password.php b/migrations/m130703_104658_users_add_one_time_password.php index 5da0462..3e65b60 100644 --- a/migrations/m130703_104658_users_add_one_time_password.php +++ b/migrations/m130703_104658_users_add_one_time_password.php @@ -2,18 +2,17 @@ class m130703_104658_users_add_one_time_password extends CDbMigration { - public function safeUp() - { - $this->addColumn('{{users}}', 'one_time_password_secret', 'string'); - $this->addColumn('{{users}}', 'one_time_password_code', 'string'); - $this->addColumn('{{users}}', 'one_time_password_counter', 'integer NOT NULL DEFAULT 0'); - } + public function safeUp() + { + $this->addColumn('{{users}}', 'one_time_password_secret', 'string'); + $this->addColumn('{{users}}', 'one_time_password_code', 'string'); + $this->addColumn('{{users}}', 'one_time_password_counter', 'integer NOT NULL DEFAULT 0'); + } - public function safeDown() - { - $this->dropColumn('{{users}}', 'one_time_password_counter'); - $this->dropColumn('{{users}}', 'one_time_password_code'); - $this->dropColumn('{{users}}', 'one_time_password_secret'); - } + public function safeDown() + { + $this->dropColumn('{{users}}', 'one_time_password_counter'); + $this->dropColumn('{{users}}', 'one_time_password_code'); + $this->dropColumn('{{users}}', 'one_time_password_secret'); + } } - diff --git a/migrations/m130704_104658_create_table_user_used_passwords.php b/migrations/m130704_104658_create_table_user_used_passwords.php index 8639b66..b3ace09 100644 --- a/migrations/m130704_104658_create_table_user_used_passwords.php +++ b/migrations/m130704_104658_create_table_user_used_passwords.php @@ -2,20 +2,19 @@ class m130704_104658_create_table_user_used_passwords extends CDbMigration { - public function safeUp() - { - $this->createTable('{{user_used_passwords}}', array( - 'id'=>'pk', - 'user_id'=>'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', - 'password'=>'string NOT NULL', - 'set_on'=>'timestamp NOT NULL', - )); - $this->createIndex('{{user_used_passwords}}_user_id_idx', '{{user_used_passwords}}', 'user_id'); - } + public function safeUp() + { + $this->createTable('{{user_used_passwords}}', array( + 'id' => 'pk', + 'user_id' => 'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', + 'password' => 'string NOT NULL', + 'set_on' => 'timestamp NOT NULL', + )); + $this->createIndex('{{user_used_passwords}}_user_id_idx', '{{user_used_passwords}}', 'user_id'); + } - public function safeDown() - { - $this->dropTable('{{user_used_passwords}}'); - } + public function safeDown() + { + $this->dropTable('{{user_used_passwords}}'); + } } - diff --git a/migrations/m130705_104658_create_table_user_profile_pictures.php b/migrations/m130705_104658_create_table_user_profile_pictures.php index 940d26c..f160315 100644 --- a/migrations/m130705_104658_create_table_user_profile_pictures.php +++ b/migrations/m130705_104658_create_table_user_profile_pictures.php @@ -2,27 +2,26 @@ class m130705_104658_create_table_user_profile_pictures extends CDbMigration { - public function safeUp() - { - $this->createTable('{{user_profile_pictures}}', array( - 'id' => 'pk', - 'user_id'=>'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', - 'original_picture_id'=>'integer REFERENCES {{user_profile_pictures}} (id) ON UPDATE CASCADE ON DELETE CASCADE', - 'filename' => 'string NOT NULL', - 'width' => 'integer NOT NULL', - 'height' => 'integer NOT NULL', - 'mimetype' => 'string NOT NULL', - 'created_on' => 'timestamp NOT NULL', - 'contents' => 'text NOT NULL', - )); - $this->createIndex('{{user_profile_pictures}}_user_id_idx', '{{user_profile_pictures}}', 'user_id'); - $this->createIndex('{{user_profile_pictures}}_original_picture_id_idx', '{{user_profile_pictures}}', 'original_picture_id'); - $this->createIndex('{{user_profile_pictures}}_width_height_idx', '{{user_profile_pictures}}', 'width, height'); - } + public function safeUp() + { + $this->createTable('{{user_profile_pictures}}', array( + 'id' => 'pk', + 'user_id' => 'integer NOT NULL REFERENCES {{users}} (id) ON UPDATE CASCADE ON DELETE CASCADE', + 'original_picture_id' => 'integer REFERENCES {{user_profile_pictures}} (id) ON UPDATE CASCADE ON DELETE CASCADE', + 'filename' => 'string NOT NULL', + 'width' => 'integer NOT NULL', + 'height' => 'integer NOT NULL', + 'mimetype' => 'string NOT NULL', + 'created_on' => 'timestamp NOT NULL', + 'contents' => 'text NOT NULL', + )); + $this->createIndex('{{user_profile_pictures}}_user_id_idx', '{{user_profile_pictures}}', 'user_id'); + $this->createIndex('{{user_profile_pictures}}_original_picture_id_idx', '{{user_profile_pictures}}', 'original_picture_id'); + $this->createIndex('{{user_profile_pictures}}_width_height_idx', '{{user_profile_pictures}}', 'width, height'); + } - public function safeDown() - { - $this->dropTable('{{user_profile_pictures}}'); - } + public function safeDown() + { + $this->dropTable('{{user_profile_pictures}}'); + } } - diff --git a/migrations/m130706_104658_create_table_user_login_attempts.php b/migrations/m130706_104658_create_table_user_login_attempts.php index d69da04..7752fab 100644 --- a/migrations/m130706_104658_create_table_user_login_attempts.php +++ b/migrations/m130706_104658_create_table_user_login_attempts.php @@ -22,5 +22,4 @@ public function safeDown() { $this->dropTable('{{user_login_attempts}}'); } - } diff --git a/models/BasePasswordForm.php b/models/BasePasswordForm.php index 83c5f96..441d4c6 100644 --- a/models/BasePasswordForm.php +++ b/models/BasePasswordForm.php @@ -6,133 +6,141 @@ */ abstract class BasePasswordForm extends BaseUsrForm { - public $newPassword; - public $newVerify; - - /** - * @var array Password strength validation rules. - */ - private $_passwordStrengthRules; - - /** - * Returns default password strength rules. This is called from the rules() method. - * If no rules has been set in the module configuration, uses sane defaults - * of 8 characters containing at least one capital, lower case letter and number. - * @return array - */ - public function getPasswordStrengthRules() - { - if ($this->_passwordStrengthRules === null) { - $this->_passwordStrengthRules = array( - array('newPassword', 'length', 'min' => 8, 'message' => Yii::t('UsrModule.usr', 'New password must contain at least 8 characters.')), - array('newPassword', 'match', 'pattern' => '/^.*(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/', 'message' => Yii::t('UsrModule.usr', 'New password must contain at least one lower and upper case character and a digit.')), - ); - } - return $this->_passwordStrengthRules; - } - - /** - * Sets rules to validate password strength. Rules should NOT contain attribute name as this method adds it. - * @param array $rules - */ - public function setPasswordStrengthRules($rules) - { - $this->_passwordStrengthRules = array(); - if (!is_array($rules)) - return; - foreach($rules as $rule) { - $this->_passwordStrengthRules[] = array_merge(array('newPassword'), $rule); - } - } - - /** - * Declares the validation rules. - * The rules state that username and password are required, - * and password needs to be authenticated. - * @return array - */ - public function rules() - { - $rules = array_merge( - array( - array('newPassword, newVerify', 'filter', 'filter'=>'trim'), - array('newPassword, newVerify', 'required'), - array('newPassword', 'unusedNewPassword'), - ), - $this->passwordStrengthRules, - array( - array('newVerify', 'compare', 'compareAttribute'=>'newPassword', 'message' => Yii::t('UsrModule.usr', 'Please type the same new password twice to verify it.')), - ) - ); - return $rules; - } - - /** - * Adds specified scenario to the given set of rules. - * @param array $rules - * @param string $scenario - * @return array - */ - public function rulesAddScenario(array $rules, $scenario) - { - foreach($rules as $key=>$rule) { - $rules[$key]['on'] = $scenario; - } - return $rules; - } - - /** - * Declares attribute labels. - * @return array - */ - public function attributeLabels() - { - return array_merge(parent::attributeLabels(), array( - 'newPassword' => Yii::t('UsrModule.usr','New password'), - 'newVerify' => Yii::t('UsrModule.usr','Verify'), - )); - } - - /** - * Depending on context, could return a new or existing identity - * or the identity of currently logged in user. - * @return IdentityInterface - */ - abstract public function getIdentity(); - - /** - * @return boolean whether password reset was successful - */ - abstract public function resetPassword(); - - /** - * Checkes if current password hasn't been used before. - * This is the 'unusedNewPassword' validator as declared in rules(). - * @return boolean - */ - public function unusedNewPassword() - { - if($this->hasErrors()) { - return; - } - - /** @var IUserIdentity */ - $identity = $this->getIdentity(); - // check if new password hasn't been used before - if ($identity instanceof IPasswordHistoryIdentity) { - if (($lastUsed = $identity->getPasswordDate($this->newPassword)) !== null) { - $this->addError('newPassword',Yii::t('UsrModule.usr','New password has been used before, last set on {date}.', array('{date}'=>$lastUsed))); - return false; - } - return true; - } - // check if new password is not the same as current one + public $newPassword; + public $newVerify; + + /** + * @var array Password strength validation rules. + */ + private $_passwordStrengthRules; + + /** + * Returns default password strength rules. This is called from the rules() method. + * If no rules has been set in the module configuration, uses sane defaults + * of 8 characters containing at least one capital, lower case letter and number. + * @return array + */ + public function getPasswordStrengthRules() + { + if ($this->_passwordStrengthRules === null) { + $this->_passwordStrengthRules = array( + array('newPassword', 'length', 'min' => 8, 'message' => Yii::t('UsrModule.usr', 'New password must contain at least 8 characters.')), + array('newPassword', 'match', 'pattern' => '/^.*(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/', 'message' => Yii::t('UsrModule.usr', 'New password must contain at least one lower and upper case character and a digit.')), + ); + } + + return $this->_passwordStrengthRules; + } + + /** + * Sets rules to validate password strength. Rules should NOT contain attribute name as this method adds it. + * @param array $rules + */ + public function setPasswordStrengthRules($rules) + { + $this->_passwordStrengthRules = array(); + if (!is_array($rules)) { + return; + } + foreach ($rules as $rule) { + $this->_passwordStrengthRules[] = array_merge(array('newPassword'), $rule); + } + } + + /** + * Declares the validation rules. + * The rules state that username and password are required, + * and password needs to be authenticated. + * @return array + */ + public function rules() + { + $rules = array_merge( + array( + array('newPassword, newVerify', 'filter', 'filter' => 'trim'), + array('newPassword, newVerify', 'required'), + array('newPassword', 'unusedNewPassword'), + ), + $this->passwordStrengthRules, + array( + array('newVerify', 'compare', 'compareAttribute' => 'newPassword', 'message' => Yii::t('UsrModule.usr', 'Please type the same new password twice to verify it.')), + ) + ); + + return $rules; + } + + /** + * Adds specified scenario to the given set of rules. + * @param array $rules + * @param string $scenario + * @return array + */ + public function rulesAddScenario(array $rules, $scenario) + { + foreach ($rules as $key => $rule) { + $rules[$key]['on'] = $scenario; + } + + return $rules; + } + + /** + * Declares attribute labels. + * @return array + */ + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), array( + 'newPassword' => Yii::t('UsrModule.usr', 'New password'), + 'newVerify' => Yii::t('UsrModule.usr', 'Verify'), + )); + } + + /** + * Depending on context, could return a new or existing identity + * or the identity of currently logged in user. + * @return IdentityInterface + */ + abstract public function getIdentity(); + + /** + * @return boolean whether password reset was successful + */ + abstract public function resetPassword(); + + /** + * Checkes if current password hasn't been used before. + * This is the 'unusedNewPassword' validator as declared in rules(). + * @return boolean + */ + public function unusedNewPassword() + { + if ($this->hasErrors()) { + return; + } + + /** @var IUserIdentity */ + $identity = $this->getIdentity(); + // check if new password hasn't been used before + if ($identity instanceof IPasswordHistoryIdentity) { + if (($lastUsed = $identity->getPasswordDate($this->newPassword)) !== null) { + $this->addError('newPassword', Yii::t('UsrModule.usr', 'New password has been used before, last set on {date}.', array('{date}' => $lastUsed))); + + return false; + } + + return true; + } + // check if new password is not the same as current one if (property_exists($this, 'password')) { if ($this->password === $this->newPassword) { - $this->addError('newPassword',Yii::t('UsrModule.usr','New password must be different than the old one.')); + $this->addError('newPassword', Yii::t('UsrModule.usr', 'New password must be different than the old one.')); + return false; } } - return true; - } + + return true; + } } diff --git a/models/BaseUsrForm.php b/models/BaseUsrForm.php index 4695379..fcd0b92 100644 --- a/models/BaseUsrForm.php +++ b/models/BaseUsrForm.php @@ -11,22 +11,22 @@ abstract class BaseUsrForm extends CFormModel */ public $webUser; - private static $_names=array(); - /** - * @inheritdoc - */ - private $_behaviors=array(); - private $_userIdentityClass; - - public function getUserIdentityClass() - { - return $this->_userIdentityClass; - } - - public function setUserIdentityClass($value) - { - $this->_userIdentityClass = $value; - } + private static $_names = array(); + /** + * @inheritdoc + */ + private $_behaviors = array(); + private $_userIdentityClass; + + public function getUserIdentityClass() + { + return $this->_userIdentityClass; + } + + public function setUserIdentityClass($value) + { + $this->_userIdentityClass = $value; + } /** * Lists valid model scenarios. @@ -36,112 +36,122 @@ public function getAvailableScenarios() { $scenarios = array(); foreach ($this->_behaviors as $name) { - if (($behavior=$this->asa($name)) instanceof FormModelBehavior) { + if (($behavior = $this->asa($name)) instanceof FormModelBehavior) { $scenarios = array_merge($scenarios, $behavior->getAvailableScenarios()); } } + return $scenarios; } - /** - * @inheritdoc - * - * Additionally, tracks attached behaviors to allow iterating over them. - */ - public function attachBehavior($name, $behavior) - { - $this->_behaviors[$name] = $name; - unset(self::$_names[get_class($this)]); - return parent::attachBehavior($name, $behavior); - } - - /** - * @inheritdoc - * - * Additionally, tracks attached behaviors to allow iterating over them. - */ - public function detachBehavior($name) - { - if (isset($this->_behaviors[$name])) - unset($this->_behaviors[$name]); - unset(self::$_names[get_class($this)]); - return parent::detachBehavior($name); - } - - /** - * @inheritdoc - * - * Additionally, adds attributes defined in attached behaviors that extend FormModelBehavior. - */ - public function attributeNames() - { - $className=get_class($this); - if(!isset(self::$_names[$className])) - { - $class=new ReflectionClass(get_class($this)); - $names=array(); - foreach($class->getProperties() as $property) - { - $name=$property->getName(); - if($property->isPublic() && !$property->isStatic()) - $names[]=$name; - } - foreach($this->_behaviors as $name=>$name) { - if (($behavior=$this->asa($name)) instanceof FormModelBehavior) - $names = array_merge($names, $behavior->attributeNames()); - } - return self::$_names[$className]=$names; - } - else - return self::$_names[$className]; - } - - /** - * Returns attribute labels defined in attached behaviors that extend FormModelBehavior. - * @return array attribute labels (name => label) - * @see CModel::attributeLabels() - */ - public function getBehaviorLabels() - { - $labels = array(); - foreach($this->_behaviors as $name=>$foo) { - if (($behavior=$this->asa($name)) instanceof FormModelBehavior) - $labels = array_merge($labels, $behavior->attributeLabels()); - } - return $labels; - } - - /** + /** + * @inheritdoc + * + * Additionally, tracks attached behaviors to allow iterating over them. + */ + public function attachBehavior($name, $behavior) + { + $this->_behaviors[$name] = $name; + unset(self::$_names[get_class($this)]); + + return parent::attachBehavior($name, $behavior); + } + + /** + * @inheritdoc + * + * Additionally, tracks attached behaviors to allow iterating over them. + */ + public function detachBehavior($name) + { + if (isset($this->_behaviors[$name])) { + unset($this->_behaviors[$name]); + } + unset(self::$_names[get_class($this)]); + + return parent::detachBehavior($name); + } + + /** + * @inheritdoc + * + * Additionally, adds attributes defined in attached behaviors that extend FormModelBehavior. + */ + public function attributeNames() + { + $className = get_class($this); + if (!isset(self::$_names[$className])) { + $class = new ReflectionClass(get_class($this)); + $names = array(); + foreach ($class->getProperties() as $property) { + $name = $property->getName(); + if ($property->isPublic() && !$property->isStatic()) { + $names[] = $name; + } + } + foreach ($this->_behaviors as $name => $name) { + if (($behavior = $this->asa($name)) instanceof FormModelBehavior) { + $names = array_merge($names, $behavior->attributeNames()); + } + } + + return self::$_names[$className] = $names; + } else { + return self::$_names[$className]; + } + } + + /** + * Returns attribute labels defined in attached behaviors that extend FormModelBehavior. + * @return array attribute labels (name => label) + * @see CModel::attributeLabels() + */ + public function getBehaviorLabels() + { + $labels = array(); + foreach ($this->_behaviors as $name => $foo) { + if (($behavior = $this->asa($name)) instanceof FormModelBehavior) { + $labels = array_merge($labels, $behavior->attributeLabels()); + } + } + + return $labels; + } + + /** * Filters base rules through each attached behavior that extend FormModelBehavior, * which may add their own rules or remove existing ones. * @param array base form model rules - * @return array validation rules - * @see CModel::rules() - */ - public function filterRules($rules) - { - foreach($this->_behaviors as $name=>$foo) { - if (($behavior=$this->asa($name)) instanceof FormModelBehavior) - $rules = $behavior->filterRules($rules); - } - return $rules; - } - - /** - * A wrapper for inline validators from behaviors extending FormModelBehavior. + * @return array validation rules + * @see CModel::rules() + */ + public function filterRules($rules) + { + foreach ($this->_behaviors as $name => $foo) { + if (($behavior = $this->asa($name)) instanceof FormModelBehavior) { + $rules = $behavior->filterRules($rules); + } + } + + return $rules; + } + + /** + * A wrapper for inline validators from behaviors extending FormModelBehavior. * Set the behavior name in 'behavior' param and validator name in 'validator' param. - * @param $attribute string - * @param $params array - */ - public function behaviorValidator($attribute, $params) - { + * @param $attribute string + * @param $params array + */ + public function behaviorValidator($attribute, $params) + { $behavior = $params['behavior']; $validator = $params['validator']; unset($params['behavior']); unset($params['validator']); - if (($behavior=$this->asa($behavior)) !== null) { - return $behavior->{$validator}($attribute, $params); - } - return true; - } + if (($behavior = $this->asa($behavior)) !== null) { + return $behavior->{$validator}($attribute, $params); + } + + return true; + } } diff --git a/models/ExampleUser.php b/models/ExampleUser.php index c3430ae..4e1c1a5 100644 --- a/models/ExampleUser.php +++ b/models/ExampleUser.php @@ -30,131 +30,134 @@ */ abstract class ExampleUser extends CActiveRecord { - /** - * @inheritdoc - */ - public function tableName() - { - return '{{users}}'; - } + /** + * @inheritdoc + */ + public function tableName() + { + return '{{users}}'; + } - /** - * @inheritdoc - */ - public function rules() - { - // password is unsafe on purpose, assign it manually after hashing only if not empty - return array( - array('username, email, firstname, lastname, is_active, is_disabled', 'filter', 'filter' => 'trim'), - array('activation_key, created_on, updated_on, last_visit_on, password_set_on, email_verified', 'filter', 'filter' => 'trim', 'on' => 'search'), - array('username, email, firstname, lastname, is_active, is_disabled', 'default', 'setOnEmpty' => true, 'value' => null), - array('activation_key, created_on, updated_on, last_visit_on, password_set_on, email_verified', 'default', 'setOnEmpty' => true, 'value' => null, 'on' => 'search'), - array('username, email, is_active, is_disabled, email_verified', 'required', 'except' => 'search'), - array('created_on, updated_on, last_visit_on, password_set_on', 'date', 'format' => array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss'), 'on' => 'search'), - array('activation_key', 'length', 'max'=>128, 'on' => 'search'), - array('is_active, is_disabled, email_verified', 'boolean'), - array('username, email', 'unique', 'except' => 'search'), - ); - } + /** + * @inheritdoc + */ + public function rules() + { + // password is unsafe on purpose, assign it manually after hashing only if not empty + return array( + array('username, email, firstname, lastname, is_active, is_disabled', 'filter', 'filter' => 'trim'), + array('activation_key, created_on, updated_on, last_visit_on, password_set_on, email_verified', 'filter', 'filter' => 'trim', 'on' => 'search'), + array('username, email, firstname, lastname, is_active, is_disabled', 'default', 'setOnEmpty' => true, 'value' => null), + array('activation_key, created_on, updated_on, last_visit_on, password_set_on, email_verified', 'default', 'setOnEmpty' => true, 'value' => null, 'on' => 'search'), + array('username, email, is_active, is_disabled, email_verified', 'required', 'except' => 'search'), + array('created_on, updated_on, last_visit_on, password_set_on', 'date', 'format' => array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss'), 'on' => 'search'), + array('activation_key', 'length', 'max' => 128, 'on' => 'search'), + array('is_active, is_disabled, email_verified', 'boolean'), + array('username, email', 'unique', 'except' => 'search'), + ); + } - /** - * @inheritdoc - */ - public function relations() - { - return array( - 'userLoginAttempts' => array(self::HAS_MANY, 'UserLoginAttempt', 'user_id', 'order'=>'performed_on DESC'), - 'userProfilePictures' => array(self::HAS_MANY, 'UserProfilePicture', 'user_id'), - 'userRemoteIdentities' => array(self::HAS_MANY, 'UserRemoteIdentity', 'user_id'), - 'userUsedPasswords' => array(self::HAS_MANY, 'UserUsedPassword', 'user_id', 'order'=>'set_on DESC'), - ); - } + /** + * @inheritdoc + */ + public function relations() + { + return array( + 'userLoginAttempts' => array(self::HAS_MANY, 'UserLoginAttempt', 'user_id', 'order' => 'performed_on DESC'), + 'userProfilePictures' => array(self::HAS_MANY, 'UserProfilePicture', 'user_id'), + 'userRemoteIdentities' => array(self::HAS_MANY, 'UserRemoteIdentity', 'user_id'), + 'userUsedPasswords' => array(self::HAS_MANY, 'UserUsedPassword', 'user_id', 'order' => 'set_on DESC'), + ); + } - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('models', 'ID'), - 'username' => Yii::t('models', 'Username'), - 'password' => Yii::t('models', 'Password'), - 'email' => Yii::t('models', 'Email'), - 'firstname' => Yii::t('models', 'Firstname'), - 'lastname' => Yii::t('models', 'Lastname'), - 'activation_key' => Yii::t('models', 'Activation Key'), - 'created_on' => Yii::t('models', 'Created On'), - 'updated_on' => Yii::t('models', 'Updated On'), - 'last_visit_on' => Yii::t('models', 'Last Visit On'), - 'password_set_on' => Yii::t('models', 'Password Set On'), - 'email_verified' => Yii::t('models', 'Email Verified'), - 'is_active' => Yii::t('models', 'Is Active'), - 'is_disabled' => Yii::t('models', 'Is Disabled'), - 'one_time_password_secret' => Yii::t('models', 'One Time Password Secret'), - 'one_time_password_code' => Yii::t('models', 'One Time Password Code'), - 'one_time_password_counter' => Yii::t('models', 'One Time Password Counter'), - ); - } + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('models', 'ID'), + 'username' => Yii::t('models', 'Username'), + 'password' => Yii::t('models', 'Password'), + 'email' => Yii::t('models', 'Email'), + 'firstname' => Yii::t('models', 'Firstname'), + 'lastname' => Yii::t('models', 'Lastname'), + 'activation_key' => Yii::t('models', 'Activation Key'), + 'created_on' => Yii::t('models', 'Created On'), + 'updated_on' => Yii::t('models', 'Updated On'), + 'last_visit_on' => Yii::t('models', 'Last Visit On'), + 'password_set_on' => Yii::t('models', 'Password Set On'), + 'email_verified' => Yii::t('models', 'Email Verified'), + 'is_active' => Yii::t('models', 'Is Active'), + 'is_disabled' => Yii::t('models', 'Is Disabled'), + 'one_time_password_secret' => Yii::t('models', 'One Time Password Secret'), + 'one_time_password_code' => Yii::t('models', 'One Time Password Code'), + 'one_time_password_counter' => Yii::t('models', 'One Time Password Counter'), + ); + } - /** - * @return CActiveDataProvider the data provider that can return the models - * based on the search/filter conditions. - */ - public function search() - { - $criteria=new CDbCriteria; + /** + * @return CActiveDataProvider the data provider that can return the models + * based on the search/filter conditions. + */ + public function search() + { + $criteria = new CDbCriteria(); - $criteria->compare('id',$this->id); - $criteria->compare('username',$this->username,true); - //$criteria->compare('password',$this->password,true); - $criteria->compare('email',$this->email,true); - $criteria->compare('firstname',$this->firstname,true); - $criteria->compare('lastname',$this->lastname,true); - //$criteria->compare('activation_key',$this->activation_key,true); - $criteria->compare('created_on',$this->created_on,true); - $criteria->compare('updated_on',$this->updated_on,true); - $criteria->compare('last_visit_on',$this->last_visit_on,true); - $criteria->compare('password_set_on',$this->password_set_on,true); - $criteria->compare('email_verified',$this->email_verified); - $criteria->compare('is_active',$this->is_active); - $criteria->compare('is_disabled',$this->is_disabled); + $criteria->compare('id', $this->id); + $criteria->compare('username', $this->username, true); + //$criteria->compare('password',$this->password,true); + $criteria->compare('email', $this->email, true); + $criteria->compare('firstname', $this->firstname, true); + $criteria->compare('lastname', $this->lastname, true); + //$criteria->compare('activation_key',$this->activation_key,true); + $criteria->compare('created_on', $this->created_on, true); + $criteria->compare('updated_on', $this->updated_on, true); + $criteria->compare('last_visit_on', $this->last_visit_on, true); + $criteria->compare('password_set_on', $this->password_set_on, true); + $criteria->compare('email_verified', $this->email_verified); + $criteria->compare('is_active', $this->is_active); + $criteria->compare('is_disabled', $this->is_disabled); - return new CActiveDataProvider($this, array( - 'criteria'=>$criteria, - )); - } + return new CActiveDataProvider($this, array( + 'criteria' => $criteria, + )); + } - /** - * @param string $className active record class name. - * @return User the static model class - */ - public static function model($className=__CLASS__) - { - return parent::model($className); - } + /** + * @param string $className active record class name. + * @return User the static model class + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } - /** - * @inheritdoc - */ - protected function beforeSave() - { - if ($this->isNewRecord) { - $this->created_on = date('Y-m-d H:i:s'); - } else { - $this->updated_on = date('Y-m-d H:i:s'); - } - return parent::beforeSave(); - } + /** + * @inheritdoc + */ + protected function beforeSave() + { + if ($this->isNewRecord) { + $this->created_on = date('Y-m-d H:i:s'); + } else { + $this->updated_on = date('Y-m-d H:i:s'); + } - public static function hashPassword($password) - { - require(Yii::getPathOfAlias('usr.extensions').DIRECTORY_SEPARATOR.'password.php'); - return password_hash($password, PASSWORD_DEFAULT); - } + return parent::beforeSave(); + } - public function verifyPassword($password) - { - require(Yii::getPathOfAlias('usr.extensions').DIRECTORY_SEPARATOR.'password.php'); - return $this->password !== null && password_verify($password, $this->password); - } + public static function hashPassword($password) + { + require Yii::getPathOfAlias('usr.extensions').DIRECTORY_SEPARATOR.'password.php'; + + return password_hash($password, PASSWORD_DEFAULT); + } + + public function verifyPassword($password) + { + require Yii::getPathOfAlias('usr.extensions').DIRECTORY_SEPARATOR.'password.php'; + + return $this->password !== null && password_verify($password, $this->password); + } } diff --git a/models/ExampleUserLoginAttempt.php b/models/ExampleUserLoginAttempt.php index 49deb1e..92a7f9f 100644 --- a/models/ExampleUserLoginAttempt.php +++ b/models/ExampleUserLoginAttempt.php @@ -18,58 +18,58 @@ */ abstract class ExampleUserLoginAttempt extends CActiveRecord { - /** - * @inheritdoc - */ - public function tableName() - { - return '{{user_login_attempts}}'; - } + /** + * @inheritdoc + */ + public function tableName() + { + return '{{user_login_attempts}}'; + } - /** - * @inheritdoc - */ - public function rules() - { - return array( - ); - } + /** + * @inheritdoc + */ + public function rules() + { + return array( + ); + } - /** - * @inheritdoc - */ - public function relations() - { - return array( - 'user' => array(self::BELONGS_TO, 'User', 'user_id'), - ); - } + /** + * @inheritdoc + */ + public function relations() + { + return array( + 'user' => array(self::BELONGS_TO, 'User', 'user_id'), + ); + } - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('models', 'ID'), - 'username' => Yii::t('models', 'Username'), - 'user_id' => Yii::t('models', 'User'), - 'performed_on' => Yii::t('models', 'Performed On'), - 'is_successful' => Yii::t('models', 'Is Successful'), - 'session_id' => Yii::t('models', 'Session ID'), - 'ipv4' => Yii::t('models', 'IPv4'), - 'user_agent' => Yii::t('models', 'User Agent'), - ); - } + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('models', 'ID'), + 'username' => Yii::t('models', 'Username'), + 'user_id' => Yii::t('models', 'User'), + 'performed_on' => Yii::t('models', 'Performed On'), + 'is_successful' => Yii::t('models', 'Is Successful'), + 'session_id' => Yii::t('models', 'Session ID'), + 'ipv4' => Yii::t('models', 'IPv4'), + 'user_agent' => Yii::t('models', 'User Agent'), + ); + } - /** - * @param string $className active record class name. - * @return UserLoginAttempt the static model class - */ - public static function model($className=__CLASS__) - { - return parent::model($className); - } + /** + * @param string $className active record class name. + * @return UserLoginAttempt the static model class + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } protected function beforeSave() { @@ -80,22 +80,24 @@ protected function beforeSave() $this->session_id = Yii::app()->session->sessionID; $this->ipv4 = ip2long($request->userHostAddress); $this->user_agent = $request->userAgent; - if ($this->ipv4 > 0x7FFFFFFF) + if ($this->ipv4 > 0x7FFFFFFF) { $this->ipv4 -= (0xFFFFFFFF + 1); + } } + return parent::beforeSave(); } /** * Checks if there are not too many login attempts using specified username in the specified number of seconds until now. - * @param string $username - * @param integer $count_limit number of login attempts - * @param integer $time_limit number of seconds + * @param string $username + * @param integer $count_limit number of login attempts + * @param integer $time_limit number of seconds * @return boolean */ public static function hasTooManyFailedAttempts($username, $count_limit = 5, $time_limit = 1800) { - $since = new DateTime; + $since = new DateTime(); $since->sub(new DateInterval("PT{$time_limit}S")); $subquery = UserLoginAttempt::model()->dbConnection->createCommand() ->select('is_successful') @@ -103,9 +105,10 @@ public static function hasTooManyFailedAttempts($username, $count_limit = 5, $ti ->where('username = :username AND performed_on > :since') ->order('performed_on DESC') ->limit($count_limit)->getText(); - return $count_limit <= (int)UserLoginAttempt::model()->dbConnection->createCommand() + + return $count_limit <= (int) UserLoginAttempt::model()->dbConnection->createCommand() ->select('COUNT(NOT is_successful OR NULL)') ->from("({$subquery}) AS t") - ->queryScalar(array(':username'=>$username, ':since' => $since->format('Y-m-d H:i:s'))); + ->queryScalar(array(':username' => $username, ':since' => $since->format('Y-m-d H:i:s'))); } } diff --git a/models/ExampleUserProfilePicture.php b/models/ExampleUserProfilePicture.php index a51ba72..93a9b37 100644 --- a/models/ExampleUserProfilePicture.php +++ b/models/ExampleUserProfilePicture.php @@ -21,67 +21,68 @@ */ abstract class ExampleUserProfilePicture extends CActiveRecord { - /** - * @inheritdoc - */ - public function tableName() - { - return '{{user_profile_pictures}}'; - } + /** + * @inheritdoc + */ + public function tableName() + { + return '{{user_profile_pictures}}'; + } - /** - * @inheritdoc - */ - public function rules() - { - return array( - ); - } + /** + * @inheritdoc + */ + public function rules() + { + return array( + ); + } - /** - * @inheritdoc - */ - public function relations() - { - return array( - 'originalPicture' => array(self::BELONGS_TO, 'UserProfilePicture', 'original_picture_id'), - 'thumbnails' => array(self::HAS_MANY, 'UserProfilePicture', 'original_picture_id'), - 'user' => array(self::BELONGS_TO, 'Users', 'user_id'), - ); - } + /** + * @inheritdoc + */ + public function relations() + { + return array( + 'originalPicture' => array(self::BELONGS_TO, 'UserProfilePicture', 'original_picture_id'), + 'thumbnails' => array(self::HAS_MANY, 'UserProfilePicture', 'original_picture_id'), + 'user' => array(self::BELONGS_TO, 'Users', 'user_id'), + ); + } - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('models', 'ID'), - 'user_id' => Yii::t('models', 'User'), - 'original_picture_id' => Yii::t('models', 'Original Picture'), - 'filename' => Yii::t('models', 'Filename'), - 'width' => Yii::t('models', 'Width'), - 'height' => Yii::t('models', 'Height'), - 'mimetype' => Yii::t('models', 'Mimetype'), - 'created_on' => Yii::t('models', 'Created On'), - 'contents' => Yii::t('models', 'Contents'), - ); - } + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('models', 'ID'), + 'user_id' => Yii::t('models', 'User'), + 'original_picture_id' => Yii::t('models', 'Original Picture'), + 'filename' => Yii::t('models', 'Filename'), + 'width' => Yii::t('models', 'Width'), + 'height' => Yii::t('models', 'Height'), + 'mimetype' => Yii::t('models', 'Mimetype'), + 'created_on' => Yii::t('models', 'Created On'), + 'contents' => Yii::t('models', 'Contents'), + ); + } - /** - * @param string $className active record class name. - * @return UserProfilePicture the static model class - */ - public static function model($className=__CLASS__) - { - return parent::model($className); - } + /** + * @param string $className active record class name. + * @return UserProfilePicture the static model class + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } - protected function beforeSave() - { - if ($this->isNewRecord) { - $this->created_on = date('Y-m-d H:i:s'); - } - return parent::beforeSave(); - } + protected function beforeSave() + { + if ($this->isNewRecord) { + $this->created_on = date('Y-m-d H:i:s'); + } + + return parent::beforeSave(); + } } diff --git a/models/ExampleUserRemoteIdentity.php b/models/ExampleUserRemoteIdentity.php index 0c70f4d..109d851 100644 --- a/models/ExampleUserRemoteIdentity.php +++ b/models/ExampleUserRemoteIdentity.php @@ -16,82 +16,83 @@ */ abstract class ExampleUserRemoteIdentity extends CActiveRecord { - /** - * @inheritdoc - */ - public function tableName() - { - return '{{user_remote_identities}}'; - } + /** + * @inheritdoc + */ + public function tableName() + { + return '{{user_remote_identities}}'; + } - /** - * @return array validation rules for model attributes. - */ - public function rules() - { - return array( - array('user_id, provider, identifier', 'required'), - array('user_id', 'numerical', 'integerOnly'=>true), - array('provider, identifier', 'length', 'max'=>100), - array('user_id', 'isUnique'), - ); - } + /** + * @return array validation rules for model attributes. + */ + public function rules() + { + return array( + array('user_id, provider, identifier', 'required'), + array('user_id', 'numerical', 'integerOnly' => true), + array('provider, identifier', 'length', 'max' => 100), + array('user_id', 'isUnique'), + ); + } - /** - * An inline validator that checkes if there are no existing records - * with same provider and identifier for specified user. - * @param string $attribute - * @param array $params - * @return boolean - */ - public function isUnique($attribute, $params) - { - return 0 === $this->countByAttributes(array( - 'user_id'=>$this->user_id, - 'provider'=>$this->provider, - 'identifier'=>$this->identifier, - )); - } + /** + * An inline validator that checkes if there are no existing records + * with same provider and identifier for specified user. + * @param string $attribute + * @param array $params + * @return boolean + */ + public function isUnique($attribute, $params) + { + return 0 === $this->countByAttributes(array( + 'user_id' => $this->user_id, + 'provider' => $this->provider, + 'identifier' => $this->identifier, + )); + } - /** - * @return array relational rules. - */ - public function relations() - { - return array( - 'user' => array(self::BELONGS_TO, 'User', 'user_id'), - ); - } + /** + * @return array relational rules. + */ + public function relations() + { + return array( + 'user' => array(self::BELONGS_TO, 'User', 'user_id'), + ); + } - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('models', 'ID'), - 'user_id' => Yii::t('models', 'User'), - 'provider' => Yii::t('models', 'Provider'), - 'identifier' => Yii::t('models', 'Identifier'), - 'created_on' => Yii::t('models', 'Created On'), - 'last_used_on' => Yii::t('models', 'Last Used On'), - ); - } + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('models', 'ID'), + 'user_id' => Yii::t('models', 'User'), + 'provider' => Yii::t('models', 'Provider'), + 'identifier' => Yii::t('models', 'Identifier'), + 'created_on' => Yii::t('models', 'Created On'), + 'last_used_on' => Yii::t('models', 'Last Used On'), + ); + } - /** - * @param string $className active record class name. - * @return UserRemoteIdentity the static model class - */ - public static function model($className=__CLASS__) - { - return parent::model($className); - } + /** + * @param string $className active record class name. + * @return UserRemoteIdentity the static model class + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } - protected function beforeSave() - { - if ($this->isNewRecord) { - $this->created_on = date('Y-m-d H:i:s'); - } - return parent::beforeSave(); - } + protected function beforeSave() + { + if ($this->isNewRecord) { + $this->created_on = date('Y-m-d H:i:s'); + } + + return parent::beforeSave(); + } } diff --git a/models/ExampleUserUsedPassword.php b/models/ExampleUserUsedPassword.php index a854a9c..d3d4f32 100644 --- a/models/ExampleUserUsedPassword.php +++ b/models/ExampleUserUsedPassword.php @@ -1,6 +1,6 @@ array(self::BELONGS_TO, 'User', 'user_id'), - ); - } + /** + * @inheritdoc + */ + public function relations() + { + return array( + 'user' => array(self::BELONGS_TO, 'User', 'user_id'), + ); + } - /** - * @inheritdoc - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('models', 'ID'), - 'user_id' => Yii::t('models', 'User'), - 'password' => Yii::t('models', 'Password'), - 'set_on' => Yii::t('models', 'Password Set On'), - ); - } + /** + * @inheritdoc + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('models', 'ID'), + 'user_id' => Yii::t('models', 'User'), + 'password' => Yii::t('models', 'Password'), + 'set_on' => Yii::t('models', 'Password Set On'), + ); + } - /** - * @param string $className active record class name. - * @return UserUsedPassword the static model class - */ - public static function model($className=__CLASS__) - { - return parent::model($className); - } + /** + * @param string $className active record class name. + * @return UserUsedPassword the static model class + */ + public static function model($className = __CLASS__) + { + return parent::model($className); + } - /** - * @param string $password password to validate - * @return bool if password provided is valid for saved one - */ - public function verifyPassword($password) - { - return $this->password !== null && password_verify($password, $this->password); - } + /** + * @param string $password password to validate + * @return bool if password provided is valid for saved one + */ + public function verifyPassword($password) + { + return $this->password !== null && password_verify($password, $this->password); + } } diff --git a/models/HybridauthForm.php b/models/HybridauthForm.php index c1bf599..f183621 100644 --- a/models/HybridauthForm.php +++ b/models/HybridauthForm.php @@ -7,140 +7,149 @@ */ class HybridauthForm extends BaseUsrForm { - /** - * @var string provider name selected from the list of available providers - */ - public $provider; - /** - * @var string user identifier - */ - public $openid_identifier; - - /** - * @var array @see UsrModule::$hybridauthProviders - */ - protected $_validProviders = array(); - protected $_hybridAuth; - protected $_hybridAuthAdapter; - /** - * @var IUserIdentity cached object returned by @see getIdentity() - */ - protected $_identity; - - /** - * Declares the validation rules. - */ - public function rules() - { - return array( - array('provider, openid_identifier', 'filter', 'filter'=>'trim'), - // can't filter this because it's displayed to the user - //array('provider', 'filter', 'filter'=>'strtolower'), - array('provider', 'required'), - array('provider', 'validProvider'), - array('openid_identifier', 'required', 'on'=>'openid'), - ); - } - - public function validProvider($attribute, $params) - { - $provider = strtolower($this->$attribute); - return isset($this->_validProviders[$provider]) && $this->_validProviders[$provider]; - } - - /** - * @param array $providers list of valid providers - */ - public function setValidProviders($providers) - { - $this->_validProviders = array(); - foreach($providers as $provider=>$options) { - $this->_validProviders[strtolower($provider)] = !isset($options['enabled']) || $options['enabled']; - } - return $this; - } - - public function setHybridAuth($hybridAuth) - { - $this->_hybridAuth = $hybridAuth; - return $this; - } - - public function getHybridAuthAdapter() - { - return $this->_hybridAuthAdapter; - } - - public function getIdentity() - { - return $this->_identity; - } - - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array( - 'provider' => Yii::t('UsrModule.usr','Provider'), - 'openid_identifier' => Yii::t('UsrModule.usr','OpenID Identifier'), - ); - } - - public function requiresFilling() - { - if (strtolower($this->provider) == 'openid' && empty($this->openid_identifier)) - return true; - - return false; - } - - public function loggedInRemotely() - { - return ($adapter=$this->getHybridAuthAdapter()) !== null && $adapter->isUserConnected(); - } - - public function login() - { - $userIdentityClass = $this->userIdentityClass; - $fakeIdentity = new $userIdentityClass(null, null); - if (!($fakeIdentity instanceof IHybridauthIdentity)) - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($fakeIdentity),'{interface}'=>'IHybridauthIdentity'))); - - $params = $this->getAttributes(); - unset($params['provider']); - if (empty($params['openid_identifier'])) + /** + * @var string provider name selected from the list of available providers + */ + public $provider; + /** + * @var string user identifier + */ + public $openid_identifier; + + /** + * @var array @see UsrModule::$hybridauthProviders + */ + protected $_validProviders = array(); + protected $_hybridAuth; + protected $_hybridAuthAdapter; + /** + * @var IUserIdentity cached object returned by @see getIdentity() + */ + protected $_identity; + + /** + * Declares the validation rules. + */ + public function rules() + { + return array( + array('provider, openid_identifier', 'filter', 'filter' => 'trim'), + // can't filter this because it's displayed to the user + //array('provider', 'filter', 'filter'=>'strtolower'), + array('provider', 'required'), + array('provider', 'validProvider'), + array('openid_identifier', 'required', 'on' => 'openid'), + ); + } + + public function validProvider($attribute, $params) + { + $provider = strtolower($this->$attribute); + + return isset($this->_validProviders[$provider]) && $this->_validProviders[$provider]; + } + + /** + * @param array $providers list of valid providers + */ + public function setValidProviders($providers) + { + $this->_validProviders = array(); + foreach ($providers as $provider => $options) { + $this->_validProviders[strtolower($provider)] = !isset($options['enabled']) || $options['enabled']; + } + + return $this; + } + + public function setHybridAuth($hybridAuth) + { + $this->_hybridAuth = $hybridAuth; + + return $this; + } + + public function getHybridAuthAdapter() + { + return $this->_hybridAuthAdapter; + } + + public function getIdentity() + { + return $this->_identity; + } + + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array( + 'provider' => Yii::t('UsrModule.usr', 'Provider'), + 'openid_identifier' => Yii::t('UsrModule.usr', 'OpenID Identifier'), + ); + } + + public function requiresFilling() + { + if (strtolower($this->provider) == 'openid' && empty($this->openid_identifier)) { + return true; + } + + return false; + } + + public function loggedInRemotely() + { + return ($adapter = $this->getHybridAuthAdapter()) !== null && $adapter->isUserConnected(); + } + + public function login() + { + $userIdentityClass = $this->userIdentityClass; + $fakeIdentity = new $userIdentityClass(null, null); + if (!($fakeIdentity instanceof IHybridauthIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($fakeIdentity), '{interface}' => 'IHybridauthIdentity'))); + } + + $params = $this->getAttributes(); + unset($params['provider']); + if (empty($params['openid_identifier'])) { unset($params['openid_identifier']); - $this->_hybridAuthAdapter = $this->_hybridAuth->authenticate(strtolower($this->provider), $params); - - if ($this->_hybridAuthAdapter->isUserConnected()) { - $profile = $this->_hybridAuthAdapter->getUserProfile(); - if (($this->_identity=$userIdentityClass::findByProvider(strtolower($this->provider), $profile->identifier)) !== null) { - return $this->webUser->login($this->_identity,0); - } - } - return false; - } - - public function associate($user_id) - { - $userIdentityClass = $this->userIdentityClass; - $identity = new $userIdentityClass(null, null); - if (!($identity instanceof IHybridauthIdentity)) - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($identity),'{interface}'=>'IHybridauthIdentity'))); - $identity->setId($user_id); - $profile = $this->_hybridAuthAdapter->getUserProfile(); - if ($identity instanceof IPictureIdentity && !empty($profile->photoURL)) { - $picture = $identity->getPictureUrl(); - if ($picture['url'] != $profile->photoURL) { - $path = tempnam(sys_get_temp_dir(), 'external_profile_picture_'); - if (copy($profile->photoURL, $path)) { - $uploadedFile = new CUploadedFile(basename($path), $path, CFileHelper::getMimeType($path), filesize($path), UPLOAD_ERR_OK); - $identity->removePicture(); - $identity->savePicture($uploadedFile); - } - } - } - return $identity->addRemoteIdentity(strtolower($this->provider), $profile->identifier); - } + } + $this->_hybridAuthAdapter = $this->_hybridAuth->authenticate(strtolower($this->provider), $params); + + if ($this->_hybridAuthAdapter->isUserConnected()) { + $profile = $this->_hybridAuthAdapter->getUserProfile(); + if (($this->_identity = $userIdentityClass::findByProvider(strtolower($this->provider), $profile->identifier)) !== null) { + return $this->webUser->login($this->_identity, 0); + } + } + + return false; + } + + public function associate($user_id) + { + $userIdentityClass = $this->userIdentityClass; + $identity = new $userIdentityClass(null, null); + if (!($identity instanceof IHybridauthIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($identity), '{interface}' => 'IHybridauthIdentity'))); + } + $identity->setId($user_id); + $profile = $this->_hybridAuthAdapter->getUserProfile(); + if ($identity instanceof IPictureIdentity && !empty($profile->photoURL)) { + $picture = $identity->getPictureUrl(); + if ($picture['url'] != $profile->photoURL) { + $path = tempnam(sys_get_temp_dir(), 'external_profile_picture_'); + if (copy($profile->photoURL, $path)) { + $uploadedFile = new CUploadedFile(basename($path), $path, CFileHelper::getMimeType($path), filesize($path), UPLOAD_ERR_OK); + $identity->removePicture(); + $identity->savePicture($uploadedFile); + } + } + } + + return $identity->addRemoteIdentity(strtolower($this->provider), $profile->identifier); + } } diff --git a/models/LoginForm.php b/models/LoginForm.php index e03682a..3806417 100644 --- a/models/LoginForm.php +++ b/models/LoginForm.php @@ -7,14 +7,14 @@ */ class LoginForm extends BasePasswordForm { - public $username; - public $password; - public $rememberMe; + public $username; + public $password; + public $rememberMe; - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; /** * Retrieve list of scenarios aviable in model @@ -26,138 +26,148 @@ public function getAvailableScenarios() } /** - * Declares the validation rules. - * The rules state that username and password are required, - * and password needs to be authenticated. - */ - public function rules() - { - $rules = $this->filterRules(array_merge(array( - array('username, password', 'filter', 'filter'=>'trim'), - array('username, password', 'required'), - array('rememberMe', 'boolean'), - array('password', 'authenticate'), - ), $this->rulesAddScenario(parent::rules(), 'reset'))); - - return $rules; - } - - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array_merge(parent::attributeLabels(), array( - 'username' => Yii::t('UsrModule.usr','Username'), - 'password' => Yii::t('UsrModule.usr','Password'), - 'rememberMe' => Yii::t('UsrModule.usr','Remember me when logging in next time'), - ), $this->getBehaviorLabels()); - } - - /** - * @inheritdoc - */ - public function getIdentity() - { - if($this->_identity===null) { - $userIdentityClass = $this->userIdentityClass; - $this->_identity=new $userIdentityClass($this->username,$this->password); - $this->_identity->authenticate(); - } - return $this->_identity; - } - - /** - * Authenticates the password. - * This is the 'authenticate' validator as declared in rules(). - * @param string $attribute - * @param array $params - * @return boolean - */ - public function authenticate($attribute,$params) - { - if($this->hasErrors()) { - return; - } - $identity = $this->getIdentity(); - if (!$identity->getIsAuthenticated()) { - $this->addError('password', !empty($identity->errorMessage) ? $identity->errorMessage : Yii::t('UsrModule.usr','Invalid username or password.')); - return false; - } - return true; - } - - /** - * A wrapper for the passwordHasNotExpired method from ExpiredPasswordBehavior. - * @param $attribute string - * @param $params array - */ - public function passwordHasNotExpired($attribute, $params) - { - if (($behavior=$this->asa('expiredPasswordBehavior')) !== null) { - return $behavior->passwordHasNotExpired($attribute, $params); - } - return true; - } - - /** - * A wrapper for the validOneTimePassword method from OneTimePasswordBehavior. - * @param $attribute string - * @param $params array - */ - public function validOneTimePassword($attribute, $params) - { - if (($behavior=$this->asa('oneTimePasswordBehavior')) !== null) { - return $behavior->validOneTimePassword($attribute, $params); - } - return true; - } - - /** - * Resets user password using the new one given in the model. - * @return boolean whether password reset was successful - */ - public function resetPassword() - { - if($this->hasErrors()) { - return; - } - $identity = $this->getIdentity(); - if (($message = $identity->resetPassword($this->newPassword)) !== true) { - $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr','Failed to reset the password.')); - return false; - } - return true; - } - - /** - * Logs in the user using the given username and password in the model. - * @param integer $duration For how long the user will be logged in without any activity, in seconds. - * @return boolean whether login is successful - */ - public function login($duration = 0) - { + * Declares the validation rules. + * The rules state that username and password are required, + * and password needs to be authenticated. + */ + public function rules() + { + $rules = $this->filterRules(array_merge(array( + array('username, password', 'filter', 'filter' => 'trim'), + array('username, password', 'required'), + array('rememberMe', 'boolean'), + array('password', 'authenticate'), + ), $this->rulesAddScenario(parent::rules(), 'reset'))); + + return $rules; + } + + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), array( + 'username' => Yii::t('UsrModule.usr', 'Username'), + 'password' => Yii::t('UsrModule.usr', 'Password'), + 'rememberMe' => Yii::t('UsrModule.usr', 'Remember me when logging in next time'), + ), $this->getBehaviorLabels()); + } + + /** + * @inheritdoc + */ + public function getIdentity() + { + if ($this->_identity === null) { + $userIdentityClass = $this->userIdentityClass; + $this->_identity = new $userIdentityClass($this->username, $this->password); + $this->_identity->authenticate(); + } + + return $this->_identity; + } + + /** + * Authenticates the password. + * This is the 'authenticate' validator as declared in rules(). + * @param string $attribute + * @param array $params + * @return boolean + */ + public function authenticate($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + $identity = $this->getIdentity(); + if (!$identity->getIsAuthenticated()) { + $this->addError('password', !empty($identity->errorMessage) ? $identity->errorMessage : Yii::t('UsrModule.usr', 'Invalid username or password.')); + + return false; + } + + return true; + } + + /** + * A wrapper for the passwordHasNotExpired method from ExpiredPasswordBehavior. + * @param $attribute string + * @param $params array + */ + public function passwordHasNotExpired($attribute, $params) + { + if (($behavior = $this->asa('expiredPasswordBehavior')) !== null) { + return $behavior->passwordHasNotExpired($attribute, $params); + } + + return true; + } + + /** + * A wrapper for the validOneTimePassword method from OneTimePasswordBehavior. + * @param $attribute string + * @param $params array + */ + public function validOneTimePassword($attribute, $params) + { + if (($behavior = $this->asa('oneTimePasswordBehavior')) !== null) { + return $behavior->validOneTimePassword($attribute, $params); + } + + return true; + } + + /** + * Resets user password using the new one given in the model. + * @return boolean whether password reset was successful + */ + public function resetPassword() + { + if ($this->hasErrors()) { + return; + } + $identity = $this->getIdentity(); + if (($message = $identity->resetPassword($this->newPassword)) !== true) { + $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr', 'Failed to reset the password.')); + + return false; + } + + return true; + } + + /** + * Logs in the user using the given username and password in the model. + * @param integer $duration For how long the user will be logged in without any activity, in seconds. + * @return boolean whether login is successful + */ + public function login($duration = 0) + { if ($this->beforeLogin()) { $identity = $this->getIdentity(); if ($this->scenario === 'reset') { $identity->password = $this->newPassword; $identity->authenticate(); } - if($identity->getIsAuthenticated()) { + if ($identity->getIsAuthenticated()) { $result = $this->webUser->login($identity, $this->rememberMe ? $duration : 0); if ($result) { $this->afterLogin(); } + return $result; } } + return false; - } + } public function beforeLogin() { $event = new CModelEvent(); $this->onBeforeLogin($event); + return $event->isValid; } @@ -181,6 +191,6 @@ public function onBeforeLogin($event) */ public function onAfterLogin() { - $this->raiseEvent('onAfterLogin', new CEvent($this, array('success'=>true))); + $this->raiseEvent('onAfterLogin', new CEvent($this, array('success' => true))); } } diff --git a/models/OneTimePasswordForm.php b/models/OneTimePasswordForm.php index b727641..41746d9 100644 --- a/models/OneTimePasswordForm.php +++ b/models/OneTimePasswordForm.php @@ -7,129 +7,140 @@ */ class OneTimePasswordForm extends CFormModel { - public $oneTimePassword; - - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; - - private $_mode; - private $_authenticator; - private $_secret; - - private $_previousCounter; - private $_previousCode; - - /** - * Declares the validation rules. - */ - public function rules() - { - return array( - array('oneTimePassword', 'filter', 'filter'=>'trim'), - array('oneTimePassword', 'default', 'setOnEmpty'=>true, 'value' => null), - array('oneTimePassword', 'required'), - array('oneTimePassword', 'validOneTimePassword'), - ); - } - - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array( - 'oneTimePassword' => Yii::t('UsrModule.usr','One Time Password'), - ); - } - - public function setMode($mode) - { - $this->_mode = $mode; - return $this; - } - - public function setAuthenticator($authenticator) - { - $this->_authenticator = $authenticator; - return $this; - } - - public function setSecret($secret) - { - $this->_secret = $secret; - return $this; - } - - public function getPreviousCode() - { - if ($this->_previousCode === null) { - list($this->_previousCode, $this->_previousCounter) = $this->getIdentity()->getOneTimePassword(); - } - return $this->_previousCode; - } - - public function getPreviousCounter() - { - if ($this->_previousCounter === null) { - list($this->_previousCode, $this->_previousCounter) = $this->getIdentity()->getOneTimePassword(); - } - return $this->_previousCounter; - } - - public function getNewCode() - { - return $this->_authenticator->getCode($this->_secret, $this->_mode == OneTimePasswordFormBehavior::OTP_TIME ? null : $this->getPreviousCounter()); - } - - public function getUrl($user, $hostname, $secret) { + public $oneTimePassword; + + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; + + private $_mode; + private $_authenticator; + private $_secret; + + private $_previousCounter; + private $_previousCode; + + /** + * Declares the validation rules. + */ + public function rules() + { + return array( + array('oneTimePassword', 'filter', 'filter' => 'trim'), + array('oneTimePassword', 'default', 'setOnEmpty' => true, 'value' => null), + array('oneTimePassword', 'required'), + array('oneTimePassword', 'validOneTimePassword'), + ); + } + + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array( + 'oneTimePassword' => Yii::t('UsrModule.usr', 'One Time Password'), + ); + } + + public function setMode($mode) + { + $this->_mode = $mode; + + return $this; + } + + public function setAuthenticator($authenticator) + { + $this->_authenticator = $authenticator; + + return $this; + } + + public function setSecret($secret) + { + $this->_secret = $secret; + + return $this; + } + + public function getPreviousCode() + { + if ($this->_previousCode === null) { + list($this->_previousCode, $this->_previousCounter) = $this->getIdentity()->getOneTimePassword(); + } + + return $this->_previousCode; + } + + public function getPreviousCounter() + { + if ($this->_previousCounter === null) { + list($this->_previousCode, $this->_previousCounter) = $this->getIdentity()->getOneTimePassword(); + } + + return $this->_previousCounter; + } + + public function getNewCode() + { + return $this->_authenticator->getCode($this->_secret, $this->_mode == OneTimePasswordFormBehavior::OTP_TIME ? null : $this->getPreviousCounter()); + } + + public function getUrl($user, $hostname, $secret) + { $url = "otpauth://totp/$user@$hostname%3Fsecret%3D$secret"; $encoder = "https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl="; + return $encoder.$url; - } - - public function getIdentity() - { - if($this->_identity===null) { - $userIdentityClass = Yii::app()->controller->module->userIdentityClass; - $this->_identity = $userIdentityClass::find(array('id'=>Yii::app()->user->getId())); - if (!($this->_identity instanceof IOneTimePasswordIdentity)) { - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($this->_identity),'{interface}'=>'IOneTimePasswordIdentity'))); - } - } - return $this->_identity; - } - - /** - * Inline validator that checkes if enteres one time password is valid and hasn't been already used. - * @param string $attribute - * @param array $params - * @return boolean - */ - public function validOneTimePassword($attribute,$params) - { - if ($this->_mode === OneTimePasswordFormBehavior::OTP_TIME) { - $valid = $this->_authenticator->checkCode($this->_secret, $this->$attribute); - } elseif ($this->_mode === OneTimePasswordFormBehavior::OTP_COUNTER) { - $valid = $this->_authenticator->getCode($this->_secret, $this->getPreviousCounter()) == $this->$attribute; - } else { - $valid = false; - } - if (!$valid) { - $this->addError($attribute,Yii::t('UsrModule.usr','Entered code is invalid.')); - return false; - } - if ($this->$attribute == $this->getPreviousCode()) { - if ($this->_mode === OneTimePasswordFormBehavior::OTP_TIME) { - $message = Yii::t('UsrModule.usr','Please wait until next code will be generated.'); - } elseif ($this->_mode === OneTimePasswordFormBehavior::OTP_COUNTER) { - $message = Yii::t('UsrModule.usr','Please log in again to request a new code.'); - } - $this->addError($attribute,Yii::t('UsrModule.usr','Entered code has already been used.').' '.$message); - $this->scenario = 'verifyOTP'; - return false; - } - return true; - } + } + + public function getIdentity() + { + if ($this->_identity === null) { + $userIdentityClass = Yii::app()->controller->module->userIdentityClass; + $this->_identity = $userIdentityClass::find(array('id' => Yii::app()->user->getId())); + if (!($this->_identity instanceof IOneTimePasswordIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($this->_identity), '{interface}' => 'IOneTimePasswordIdentity'))); + } + } + + return $this->_identity; + } + + /** + * Inline validator that checkes if enteres one time password is valid and hasn't been already used. + * @param string $attribute + * @param array $params + * @return boolean + */ + public function validOneTimePassword($attribute, $params) + { + if ($this->_mode === OneTimePasswordFormBehavior::OTP_TIME) { + $valid = $this->_authenticator->checkCode($this->_secret, $this->$attribute); + } elseif ($this->_mode === OneTimePasswordFormBehavior::OTP_COUNTER) { + $valid = $this->_authenticator->getCode($this->_secret, $this->getPreviousCounter()) == $this->$attribute; + } else { + $valid = false; + } + if (!$valid) { + $this->addError($attribute, Yii::t('UsrModule.usr', 'Entered code is invalid.')); + + return false; + } + if ($this->$attribute == $this->getPreviousCode()) { + if ($this->_mode === OneTimePasswordFormBehavior::OTP_TIME) { + $message = Yii::t('UsrModule.usr', 'Please wait until next code will be generated.'); + } elseif ($this->_mode === OneTimePasswordFormBehavior::OTP_COUNTER) { + $message = Yii::t('UsrModule.usr', 'Please log in again to request a new code.'); + } + $this->addError($attribute, Yii::t('UsrModule.usr', 'Entered code has already been used.').' '.$message); + $this->scenario = 'verifyOTP'; + + return false; + } + + return true; + } } diff --git a/models/PasswordForm.php b/models/PasswordForm.php index 3d38a13..f50d5a0 100644 --- a/models/PasswordForm.php +++ b/models/PasswordForm.php @@ -6,92 +6,99 @@ */ class PasswordForm extends BasePasswordForm { - public $password; + public $password; - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; - /** - * Declares the validation rules. - */ - public function rules() - { - $rules = array_merge(array( - array('password', 'filter', 'filter'=>'trim', 'except'=>'register'), - array('password', 'required', 'except'=>'register'), - array('password', 'authenticate', 'except'=>'register'), - ), parent::rules()); + /** + * Declares the validation rules. + */ + public function rules() + { + $rules = array_merge(array( + array('password', 'filter', 'filter' => 'trim', 'except' => 'register'), + array('password', 'required', 'except' => 'register'), + array('password', 'authenticate', 'except' => 'register'), + ), parent::rules()); - return $rules; - } + return $rules; + } - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array_merge(parent::attributeLabels(), array( - 'password' => Yii::t('UsrModule.usr','Current password'), - )); - } + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), array( + 'password' => Yii::t('UsrModule.usr', 'Current password'), + )); + } - /** - * @inheritdoc - */ - public function getIdentity() - { - if($this->_identity===null) { - if ($this->scenario === 'register') - return $this->_identity; - $userIdentityClass = $this->userIdentityClass; - $this->_identity = $userIdentityClass::find(array('id'=>Yii::app()->user->getId())); - } - return $this->_identity; - } + /** + * @inheritdoc + */ + public function getIdentity() + { + if ($this->_identity === null) { + if ($this->scenario === 'register') { + return $this->_identity; + } + $userIdentityClass = $this->userIdentityClass; + $this->_identity = $userIdentityClass::find(array('id' => Yii::app()->user->getId())); + } - public function setIdentity($identity) - { - $this->_identity = $identity; - } + return $this->_identity; + } - /** - * Authenticates the password. - * This is the 'authenticate' validator as declared in rules(). - */ - public function authenticate($attribute,$params) - { - if($this->hasErrors()) { - return; - } - if (($identity=$this->getIdentity()) === null) { - throw new CException('Current user has not been found in the database.'); - } - $identity->password = $this->password; - if(!$identity->authenticate()) { - $this->addError('password',Yii::t('UsrModule.usr','Invalid password.')); - return false; - } - return true; - } + public function setIdentity($identity) + { + $this->_identity = $identity; + } - /** - * Resets user password using the new one given in the model. - * @return boolean whether password reset was successful - */ - public function resetPassword($identity=null) - { - if($this->hasErrors()) { - return; - } - if ($identity === null) - $identity = $this->getIdentity(); + /** + * Authenticates the password. + * This is the 'authenticate' validator as declared in rules(). + */ + public function authenticate($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + if (($identity = $this->getIdentity()) === null) { + throw new CException('Current user has not been found in the database.'); + } $identity->password = $this->password; - if (($message = $identity->resetPassword($this->newPassword)) !== true) { - $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr','Failed to reset the password.')); - return false; - } - return true; - } + if (!$identity->authenticate()) { + $this->addError('password', Yii::t('UsrModule.usr', 'Invalid password.')); + + return false; + } + + return true; + } + + /** + * Resets user password using the new one given in the model. + * @return boolean whether password reset was successful + */ + public function resetPassword($identity = null) + { + if ($this->hasErrors()) { + return; + } + if ($identity === null) { + $identity = $this->getIdentity(); + } + $identity->password = $this->password; + if (($message = $identity->resetPassword($this->newPassword)) !== true) { + $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr', 'Failed to reset the password.')); + + return false; + } + + return true; + } } diff --git a/models/ProfileForm.php b/models/ProfileForm.php index 5ef265d..5d9e5db 100644 --- a/models/ProfileForm.php +++ b/models/ProfileForm.php @@ -7,167 +7,176 @@ */ class ProfileForm extends BaseUsrForm { - public $username; - public $email; - public $firstName; - public $lastName; - public $picture; - public $removePicture; - public $password; - - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; - /** - * @var array Picture upload validation rules. - */ - private $_pictureUploadRules; - - /** - * Returns rules for picture upload or an empty array if they are not set. - * @return array - */ - public function getPictureUploadRules() - { - return $this->_pictureUploadRules === null ? array() : $this->_pictureUploadRules; - } - - /** - * Sets rules to validate uploaded picture. Rules should NOT contain attribute name as this method adds it. - * @param array $rules - */ - public function setPictureUploadRules($rules) - { - $this->_pictureUploadRules = array(); - if (!is_array($rules)) - return; - foreach($rules as $rule) { - $this->_pictureUploadRules[] = array_merge(array('picture'), $rule); - } - } - - /** - * Declares the validation rules. - */ - public function rules() - { - return $this->filterRules(array_merge(array( - array('username, email, firstName, lastName, removePicture', 'filter', 'filter'=>'trim'), - array('username, email, firstName, lastName, removePicture', 'default', 'setOnEmpty'=>true, 'value' => null), - - array('username, email', 'required'), - array('username, email', 'uniqueIdentity'), - array('email', 'email'), - array('removePicture', 'boolean'), - array('password', 'validCurrentPassword', 'except'=>'register'), - ), $this->pictureUploadRules)); - } - - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array_merge($this->getBehaviorLabels(), array( - 'username' => Yii::t('UsrModule.usr','Username'), - 'email' => Yii::t('UsrModule.usr','Email'), - 'firstName' => Yii::t('UsrModule.usr','First name'), - 'lastName' => Yii::t('UsrModule.usr','Last name'), - 'picture' => Yii::t('UsrModule.usr','Profile picture'), - 'removePicture' => Yii::t('UsrModule.usr','Remove picture'), - 'password' => Yii::t('UsrModule.usr','Current password'), - )); - } - - /** - * @inheritdoc - */ - public function getIdentity() - { - if($this->_identity===null) { - $userIdentityClass = $this->userIdentityClass; - if ($this->scenario == 'register') { - $this->_identity = new $userIdentityClass(null, null); - } else { - $this->_identity = $userIdentityClass::find(array('id'=>Yii::app()->user->getId())); - } - if ($this->_identity !== null && !($this->_identity instanceof IEditableIdentity)) { - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($this->_identity),'{interface}'=>'IEditableIdentity'))); - } - } - return $this->_identity; - } - - public function setIdentity($identity) - { - $this->_identity = $identity; - } - - public function uniqueIdentity($attribute,$params) - { - if($this->hasErrors()) { - return; - } - $userIdentityClass = $this->userIdentityClass; - $existingIdentity = $userIdentityClass::find(array($attribute => $this->$attribute)); - if ($existingIdentity !== null && (($identity=$this->getIdentity()) !== null && $existingIdentity->getId() != $identity->getId())) { - $this->addError($attribute,Yii::t('UsrModule.usr','{attribute} has already been used by another user.', array('{attribute}'=>$this->$attribute))); - return false; - } - return true; - } - - /** - * A valid current password is required only when changing email. - */ - public function validCurrentPassword($attribute,$params) - { - if($this->hasErrors()) { - return; - } - if (($identity=$this->getIdentity()) === null) { - throw new CException('Current user has not been found in the database.'); - } - if ($identity->getEmail() === $this->email) { - return true; - } - $identity->password = $this->$attribute; - if(!$identity->authenticate()) { - $this->addError($attribute, Yii::t('UsrModule.usr', 'Changing email address requires providing the current password.')); - return false; - } - return true; - } - - /** - * Logs in the user using the given username. - * @return boolean whether login is successful - */ - public function login() - { - $identity = $this->getIdentity(); - - return $this->webUser->login($identity,0); - } - - /** - * Updates the identity with this models attributes and saves it. - * @param boolean $requireVerifiedEmail the Usr module property - * @return boolean whether saving is successful - */ - public function save($requireVerifiedEmail = false) - { - if (($identity=$this->getIdentity()) === null) - return false; - - $identity->setAttributes($this->getAttributes()); - if ($identity->save($requireVerifiedEmail)) { - if ((!($this->picture instanceof CUploadedFile) || $identity->savePicture($this->picture)) && (!$this->removePicture || $identity->removePicture())) { - $this->_identity = $identity; - return true; - } - } - return false; - } + public $username; + public $email; + public $firstName; + public $lastName; + public $picture; + public $removePicture; + public $password; + + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; + /** + * @var array Picture upload validation rules. + */ + private $_pictureUploadRules; + + /** + * Returns rules for picture upload or an empty array if they are not set. + * @return array + */ + public function getPictureUploadRules() + { + return $this->_pictureUploadRules === null ? array() : $this->_pictureUploadRules; + } + + /** + * Sets rules to validate uploaded picture. Rules should NOT contain attribute name as this method adds it. + * @param array $rules + */ + public function setPictureUploadRules($rules) + { + $this->_pictureUploadRules = array(); + if (!is_array($rules)) { + return; + } + foreach ($rules as $rule) { + $this->_pictureUploadRules[] = array_merge(array('picture'), $rule); + } + } + + /** + * Declares the validation rules. + */ + public function rules() + { + return $this->filterRules(array_merge(array( + array('username, email, firstName, lastName, removePicture', 'filter', 'filter' => 'trim'), + array('username, email, firstName, lastName, removePicture', 'default', 'setOnEmpty' => true, 'value' => null), + + array('username, email', 'required'), + array('username, email', 'uniqueIdentity'), + array('email', 'email'), + array('removePicture', 'boolean'), + array('password', 'validCurrentPassword', 'except' => 'register'), + ), $this->pictureUploadRules)); + } + + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array_merge($this->getBehaviorLabels(), array( + 'username' => Yii::t('UsrModule.usr', 'Username'), + 'email' => Yii::t('UsrModule.usr', 'Email'), + 'firstName' => Yii::t('UsrModule.usr', 'First name'), + 'lastName' => Yii::t('UsrModule.usr', 'Last name'), + 'picture' => Yii::t('UsrModule.usr', 'Profile picture'), + 'removePicture' => Yii::t('UsrModule.usr', 'Remove picture'), + 'password' => Yii::t('UsrModule.usr', 'Current password'), + )); + } + + /** + * @inheritdoc + */ + public function getIdentity() + { + if ($this->_identity === null) { + $userIdentityClass = $this->userIdentityClass; + if ($this->scenario == 'register') { + $this->_identity = new $userIdentityClass(null, null); + } else { + $this->_identity = $userIdentityClass::find(array('id' => Yii::app()->user->getId())); + } + if ($this->_identity !== null && !($this->_identity instanceof IEditableIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($this->_identity), '{interface}' => 'IEditableIdentity'))); + } + } + + return $this->_identity; + } + + public function setIdentity($identity) + { + $this->_identity = $identity; + } + + public function uniqueIdentity($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + $userIdentityClass = $this->userIdentityClass; + $existingIdentity = $userIdentityClass::find(array($attribute => $this->$attribute)); + if ($existingIdentity !== null && (($identity = $this->getIdentity()) !== null && $existingIdentity->getId() != $identity->getId())) { + $this->addError($attribute, Yii::t('UsrModule.usr', '{attribute} has already been used by another user.', array('{attribute}' => $this->$attribute))); + + return false; + } + + return true; + } + + /** + * A valid current password is required only when changing email. + */ + public function validCurrentPassword($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + if (($identity = $this->getIdentity()) === null) { + throw new CException('Current user has not been found in the database.'); + } + if ($identity->getEmail() === $this->email) { + return true; + } + $identity->password = $this->$attribute; + if (!$identity->authenticate()) { + $this->addError($attribute, Yii::t('UsrModule.usr', 'Changing email address requires providing the current password.')); + + return false; + } + + return true; + } + + /** + * Logs in the user using the given username. + * @return boolean whether login is successful + */ + public function login() + { + $identity = $this->getIdentity(); + + return $this->webUser->login($identity, 0); + } + + /** + * Updates the identity with this models attributes and saves it. + * @param boolean $requireVerifiedEmail the Usr module property + * @return boolean whether saving is successful + */ + public function save($requireVerifiedEmail = false) + { + if (($identity = $this->getIdentity()) === null) { + return false; + } + + $identity->setAttributes($this->getAttributes()); + if ($identity->save($requireVerifiedEmail)) { + if ((!($this->picture instanceof CUploadedFile) || $identity->savePicture($this->picture)) && (!$this->removePicture || $identity->removePicture())) { + $this->_identity = $identity; + + return true; + } + } + + return false; + } } diff --git a/models/RecoveryForm.php b/models/RecoveryForm.php index 1e0c569..05f7c0a 100644 --- a/models/RecoveryForm.php +++ b/models/RecoveryForm.php @@ -7,144 +7,167 @@ */ class RecoveryForm extends BasePasswordForm { - public $username; - public $email; - public $activationKey; - - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; - - /** - * Declares the validation rules. - * The rules state that username and password are required, - * and password needs to be authenticated. - */ - public function rules() { - $rules = $this->filterRules(array_merge(array( - array('username, email', 'filter', 'filter'=>'trim'), - array('username, email', 'default', 'setOnEmpty'=>true, 'value' => null), - array('username, email', 'existingIdentity'), - array('email', 'email'), - - array('activationKey', 'filter', 'filter'=>'trim', 'on'=>'reset,verify'), - array('activationKey', 'default', 'setOnEmpty'=>true, 'value' => null, 'on'=>'reset,verify'), - array('activationKey', 'required', 'on'=>'reset,verify'), - array('activationKey', 'validActivationKey', 'on'=>'reset,verify'), - ), $this->rulesAddScenario(parent::rules(), 'reset'))); - - return $rules; - } - - /** - * Declares attribute labels. - */ - public function attributeLabels() { - return array_merge(parent::attributeLabels(), array( - 'username' => Yii::t('UsrModule.usr','Username'), - 'email' => Yii::t('UsrModule.usr','Email'), - 'activationKey' => Yii::t('UsrModule.usr','Activation Key'), - ), $this->getBehaviorLabels()); - } - - /** - * @inheritdoc - */ - public function getIdentity() { - if($this->_identity===null) { - // generate a fake object just to check if it implements a correct interface - $userIdentityClass = $this->userIdentityClass; - $fakeIdentity = new $userIdentityClass(null, null); - if (!($fakeIdentity instanceof IActivatedIdentity)) { - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>$userIdentityClass, '{interface}'=>'IActivatedIdentity'))); - } - $attributes = array(); - if ($this->username !== null) $attributes['username'] = $this->username; - if ($this->email !== null) $attributes['email'] = $this->email; - if (!empty($attributes)) - $this->_identity=$userIdentityClass::find($attributes); - } - return $this->_identity; - } - - /** - * Inline validator that checks if an identity exists matching provided username or password. - * @param string $attribute - * @param array $params - * @return boolean - */ - public function existingIdentity($attribute,$params) { - if($this->hasErrors()) { - return; - } - $identity = $this->getIdentity(); - if ($identity === null) { - if ($this->username !== null) { - $this->addError('username',Yii::t('UsrModule.usr','No user found matching this username.')); - } elseif ($this->email !== null) { - $this->addError('email',Yii::t('UsrModule.usr','No user found matching this email address.')); - } else { - $this->addError('username',Yii::t('UsrModule.usr','Please specify username or email.')); - } - return false; - } elseif ($identity->isDisabled()) { - $this->addError('username',Yii::t('UsrModule.usr','User account has been disabled.')); - return false; - } - return true; - } - - /** - * Validates the activation key. - */ - public function validActivationKey($attribute,$params) { - if($this->hasErrors()) { - return; - } - if (($identity = $this->getIdentity()) === null) - return false; - - $errorCode = $identity->verifyActivationKey($this->activationKey); - switch($errorCode) { - default: - case $identity::ERROR_AKEY_INVALID: - $this->addError('activationKey',Yii::t('UsrModule.usr','Activation key is invalid.')); - return false; - case $identity::ERROR_AKEY_TOO_OLD: - $this->addError('activationKey',Yii::t('UsrModule.usr','Activation key is too old.')); - return false; - case $identity::ERROR_AKEY_NONE: - return true; - } - return true; - } - - /** - * Resets user password using the new one given in the model. - * @return boolean whether password reset was successful - */ - public function resetPassword() { - $identity = $this->getIdentity(); - if (($message = $identity->resetPassword($this->newPassword)) !== true) { - $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr','Failed to reset the password.')); - return false; + public $username; + public $email; + public $activationKey; + + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; + + /** + * Declares the validation rules. + * The rules state that username and password are required, + * and password needs to be authenticated. + */ + public function rules() + { + $rules = $this->filterRules(array_merge(array( + array('username, email', 'filter', 'filter' => 'trim'), + array('username, email', 'default', 'setOnEmpty' => true, 'value' => null), + array('username, email', 'existingIdentity'), + array('email', 'email'), + + array('activationKey', 'filter', 'filter' => 'trim', 'on' => 'reset,verify'), + array('activationKey', 'default', 'setOnEmpty' => true, 'value' => null, 'on' => 'reset,verify'), + array('activationKey', 'required', 'on' => 'reset,verify'), + array('activationKey', 'validActivationKey', 'on' => 'reset,verify'), + ), $this->rulesAddScenario(parent::rules(), 'reset'))); + + return $rules; + } + + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), array( + 'username' => Yii::t('UsrModule.usr', 'Username'), + 'email' => Yii::t('UsrModule.usr', 'Email'), + 'activationKey' => Yii::t('UsrModule.usr', 'Activation Key'), + ), $this->getBehaviorLabels()); + } + + /** + * @inheritdoc + */ + public function getIdentity() + { + if ($this->_identity === null) { + // generate a fake object just to check if it implements a correct interface + $userIdentityClass = $this->userIdentityClass; + $fakeIdentity = new $userIdentityClass(null, null); + if (!($fakeIdentity instanceof IActivatedIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => $userIdentityClass, '{interface}' => 'IActivatedIdentity'))); + } + $attributes = array(); + if ($this->username !== null) { + $attributes['username'] = $this->username; + } + if ($this->email !== null) { + $attributes['email'] = $this->email; + } + if (!empty($attributes)) { + $this->_identity = $userIdentityClass::find($attributes); + } + } + + return $this->_identity; + } + + /** + * Inline validator that checks if an identity exists matching provided username or password. + * @param string $attribute + * @param array $params + * @return boolean + */ + public function existingIdentity($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + $identity = $this->getIdentity(); + if ($identity === null) { + if ($this->username !== null) { + $this->addError('username', Yii::t('UsrModule.usr', 'No user found matching this username.')); + } elseif ($this->email !== null) { + $this->addError('email', Yii::t('UsrModule.usr', 'No user found matching this email address.')); + } else { + $this->addError('username', Yii::t('UsrModule.usr', 'Please specify username or email.')); + } + + return false; + } elseif ($identity->isDisabled()) { + $this->addError('username', Yii::t('UsrModule.usr', 'User account has been disabled.')); + + return false; } + return true; - } - - /** - * Logs in the user using the given username and new password. - * @return boolean whether login is successful - */ - public function login() { - $identity = $this->getIdentity(); - - $identity->password = $this->newPassword; - $identity->authenticate(); - if($identity->getIsAuthenticated()) { - return $this->webUser->login($identity,0); - } - return false; - } + } + + /** + * Validates the activation key. + */ + public function validActivationKey($attribute, $params) + { + if ($this->hasErrors()) { + return; + } + if (($identity = $this->getIdentity()) === null) { + return false; + } + + $errorCode = $identity->verifyActivationKey($this->activationKey); + switch ($errorCode) { + default: + case $identity::ERROR_AKEY_INVALID: + $this->addError('activationKey', Yii::t('UsrModule.usr', 'Activation key is invalid.')); + + return false; + case $identity::ERROR_AKEY_TOO_OLD: + $this->addError('activationKey', Yii::t('UsrModule.usr', 'Activation key is too old.')); + + return false; + case $identity::ERROR_AKEY_NONE: + return true; + } + + return true; + } + + /** + * Resets user password using the new one given in the model. + * @return boolean whether password reset was successful + */ + public function resetPassword() + { + $identity = $this->getIdentity(); + if (($message = $identity->resetPassword($this->newPassword)) !== true) { + $this->addError('newPassword', is_string($message) ? $message : Yii::t('UsrModule.usr', 'Failed to reset the password.')); + + return false; + } + + return true; + } + + /** + * Logs in the user using the given username and new password. + * @return boolean whether login is successful + */ + public function login() + { + $identity = $this->getIdentity(); + + $identity->password = $this->newPassword; + $identity->authenticate(); + if ($identity->getIsAuthenticated()) { + return $this->webUser->login($identity, 0); + } + + return false; + } } diff --git a/models/SearchForm.php b/models/SearchForm.php index 557f478..69ae50c 100644 --- a/models/SearchForm.php +++ b/models/SearchForm.php @@ -6,78 +6,79 @@ */ class SearchForm extends CFormModel { - public $id; - public $username; - public $email; - public $firstName; - public $lastName; - public $createdOn; - public $updatedOn; - public $lastVisitOn; - public $emailVerified; - public $isActive; - public $isDisabled; + public $id; + public $username; + public $email; + public $firstName; + public $lastName; + public $createdOn; + public $updatedOn; + public $lastVisitOn; + public $emailVerified; + public $isActive; + public $isDisabled; - public $anyText; + public $anyText; - /** - * @var IdentityInterface cached object returned by @see getIdentity() - */ - private $_identity; + /** + * @var IdentityInterface cached object returned by @see getIdentity() + */ + private $_identity; - private $_userIdentityClass; + private $_userIdentityClass; - public function getUserIdentityClass() - { - return $this->_userIdentityClass; - } + public function getUserIdentityClass() + { + return $this->_userIdentityClass; + } - public function setUserIdentityClass($value) - { - $this->_userIdentityClass = $value; - } + public function setUserIdentityClass($value) + { + $this->_userIdentityClass = $value; + } - public function rules() - { - return array( - array('id, username, email, firstName, lastName, createdOn, updatedOn, lastVisitOn, emailVerified, isActive, isDisabled, anyText', 'filter', 'filter'=>'trim'), - array('id, username, email, firstName, lastName, createdOn, updatedOn, lastVisitOn, emailVerified, isActive, isDisabled, anyText', 'default'), - array('id', 'numerical', 'integerOnly'=>true, 'max'=>0x7FFFFFFF, 'min'=>-0x8000000), // 32-bit integers - array('createdOn, updatedOn, lastVisitOn', 'date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd hh:mm', '?yyyy-MM-dd', '?yyyy-MM-dd hh:mm', '??yyyy-MM-dd', '??yyyy-MM-dd hh:mm')), - array('emailVerified, isActive, isDisabled', 'boolean'), - ); - } + public function rules() + { + return array( + array('id, username, email, firstName, lastName, createdOn, updatedOn, lastVisitOn, emailVerified, isActive, isDisabled, anyText', 'filter', 'filter' => 'trim'), + array('id, username, email, firstName, lastName, createdOn, updatedOn, lastVisitOn, emailVerified, isActive, isDisabled, anyText', 'default'), + array('id', 'numerical', 'integerOnly' => true, 'max' => 0x7FFFFFFF, 'min' => -0x8000000), // 32-bit integers + array('createdOn, updatedOn, lastVisitOn', 'date', 'format' => array('yyyy-MM-dd', 'yyyy-MM-dd hh:mm', '?yyyy-MM-dd', '?yyyy-MM-dd hh:mm', '??yyyy-MM-dd', '??yyyy-MM-dd hh:mm')), + array('emailVerified, isActive, isDisabled', 'boolean'), + ); + } - /** - * Declares attribute labels. - */ - public function attributeLabels() - { - return array( - 'id' => Yii::t('UsrModule.manager', 'ID'), - 'username' => Yii::t('UsrModule.manager', 'Username'), - 'email' => Yii::t('UsrModule.manager', 'Email'), - 'firstName' => Yii::t('UsrModule.manager', 'Firstname'), - 'lastName' => Yii::t('UsrModule.manager', 'Lastname'), - 'createdOn' => Yii::t('UsrModule.manager', 'Created On'), - 'updatedOn' => Yii::t('UsrModule.manager', 'Updated On'), - 'lastVisitOn' => Yii::t('UsrModule.manager', 'Last Visit On'), - 'emailVerified' => Yii::t('UsrModule.manager', 'Email Verified'), - 'isActive' => Yii::t('UsrModule.manager', 'Is Active'), - 'isDisabled' => Yii::t('UsrModule.manager', 'Is Disabled'), - 'anyText' => Yii::t('UsrModule.manager', 'Search'), - ); - } + /** + * Declares attribute labels. + */ + public function attributeLabels() + { + return array( + 'id' => Yii::t('UsrModule.manager', 'ID'), + 'username' => Yii::t('UsrModule.manager', 'Username'), + 'email' => Yii::t('UsrModule.manager', 'Email'), + 'firstName' => Yii::t('UsrModule.manager', 'Firstname'), + 'lastName' => Yii::t('UsrModule.manager', 'Lastname'), + 'createdOn' => Yii::t('UsrModule.manager', 'Created On'), + 'updatedOn' => Yii::t('UsrModule.manager', 'Updated On'), + 'lastVisitOn' => Yii::t('UsrModule.manager', 'Last Visit On'), + 'emailVerified' => Yii::t('UsrModule.manager', 'Email Verified'), + 'isActive' => Yii::t('UsrModule.manager', 'Is Active'), + 'isDisabled' => Yii::t('UsrModule.manager', 'Is Disabled'), + 'anyText' => Yii::t('UsrModule.manager', 'Search'), + ); + } - public function getIdentity($id=null) - { - if($this->_identity===null) { - $userIdentityClass = $this->userIdentityClass; - $this->_identity = $userIdentityClass::find(array('id'=>$id !== null ? $id : Yii::app()->user->getId())); - if ($this->_identity !== null && !($this->_identity instanceof IManagedIdentity)) { - throw new CException(Yii::t('UsrModule.usr','The {class} class must implement the {interface} interface.',array('{class}'=>get_class($this->_identity),'{interface}'=>'IManagedIdentity'))); - } - } - return $this->_identity; - } + public function getIdentity($id = null) + { + if ($this->_identity === null) { + $userIdentityClass = $this->userIdentityClass; + $this->_identity = $userIdentityClass::find(array('id' => $id !== null ? $id : Yii::app()->user->getId())); + if ($this->_identity !== null && !($this->_identity instanceof IManagedIdentity)) { + throw new CException(Yii::t('UsrModule.usr', 'The {class} class must implement the {interface} interface.', array('{class}' => get_class($this->_identity), '{interface}' => 'IManagedIdentity'))); + } + } + + return $this->_identity; + } } diff --git a/tests/User.php b/tests/User.php index 5de161e..21688ae 100644 --- a/tests/User.php +++ b/tests/User.php @@ -4,8 +4,8 @@ class User extends ExampleUser { - public static function model($className=__CLASS__) - { - return parent::model($className); - } + public static function model($className = __CLASS__) + { + return parent::model($className); + } } diff --git a/tests/UserLoginAttempt.php b/tests/UserLoginAttempt.php index cbd0ef3..ec85c56 100644 --- a/tests/UserLoginAttempt.php +++ b/tests/UserLoginAttempt.php @@ -4,8 +4,8 @@ class UserLoginAttempt extends ExampleUserLoginAttempt { - public static function model($className=__CLASS__) - { - return parent::model($className); - } + public static function model($className = __CLASS__) + { + return parent::model($className); + } } diff --git a/tests/UserRemoteIdentity.php b/tests/UserRemoteIdentity.php index fbd9dd1..a0eec7a 100644 --- a/tests/UserRemoteIdentity.php +++ b/tests/UserRemoteIdentity.php @@ -4,8 +4,8 @@ class UserRemoteIdentity extends ExampleUserRemoteIdentity { - public static function model($className=__CLASS__) - { - return parent::model($className); - } + public static function model($className = __CLASS__) + { + return parent::model($className); + } } diff --git a/tests/UserUsedPassword.php b/tests/UserUsedPassword.php index fb54b07..9d5bc86 100644 --- a/tests/UserUsedPassword.php +++ b/tests/UserUsedPassword.php @@ -4,8 +4,8 @@ class UserUsedPassword extends ExampleUserUsedPassword { - public static function model($className=__CLASS__) - { - return parent::model($className); - } + public static function model($className = __CLASS__) + { + return parent::model($className); + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 0092f71..f6cff75 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,9 +1,9 @@ dirname(__FILE__).DIRECTORY_SEPARATOR.'..', - 'name' => 'Widgets and Extensions demo', - 'aliases' => array( - 'vendors' => dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..', - ), - 'modules'=>array( - 'usr'=>array( - 'class'=>'vendors.nineinchnick.yii-usr.UsrModule', - 'userIdentityClass' => 'UserIdentity', - 'captcha' => array('clickableImage'=>true,'showRefreshButton'=>false), + 'basePath' => dirname(__FILE__).DIRECTORY_SEPARATOR.'..', + 'name' => 'Widgets and Extensions demo', + 'aliases' => array( + 'vendors' => dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..', + ), + 'modules' => array( + 'usr' => array( + 'class' => 'vendors.nineinchnick.yii-usr.UsrModule', + 'userIdentityClass' => 'UserIdentity', + 'captcha' => array('clickableImage' => true,'showRefreshButton' => false), 'loginFormBehaviors' => array( 'expiredPasswordBehavior' => array( 'class' => 'ExpiredPasswordBehavior', @@ -23,18 +23,18 @@ 'timeout' => 123, ), ), - ), - ), - 'components'=>array( - 'db'=>array( - 'connectionString' => 'sqlite::memory:', - 'initSQLs' => array('PRAGMA foreign_keys = ON'), - //'connectionString' => 'mysql:host=localhost;dbname=test', - 'tablePrefix' => 'tbl_', - 'enableParamLogging'=>true, - ), - 'fixture'=>array( - 'class'=>'system.test.CDbFixtureManager', - ), - ), + ), + ), + 'components' => array( + 'db' => array( + 'connectionString' => 'sqlite::memory:', + 'initSQLs' => array('PRAGMA foreign_keys = ON'), + //'connectionString' => 'mysql:host=localhost;dbname=test', + 'tablePrefix' => 'tbl_', + 'enableParamLogging' => true, + ), + 'fixture' => array( + 'class' => 'system.test.CDbFixtureManager', + ), + ), ); diff --git a/tests/fixtures/init.php b/tests/fixtures/init.php index d3d2ad9..f461fd3 100644 --- a/tests/fixtures/init.php +++ b/tests/fixtures/init.php @@ -1,26 +1,26 @@ setDbConnection($this->getDbConnection()); - if($migration->up()===false) { - echo 'something went terribly wrong!'; - } - +foreach ($migrations as $class) { + $file = $migrationPath.DIRECTORY_SEPARATOR.$class.'.php'; + require_once $file; + $migration = new $class(); + $migration->setDbConnection($this->getDbConnection()); + if ($migration->up() === false) { + echo 'something went terribly wrong!'; + } } diff --git a/tests/fixtures/tbl_user_used_passwords.php b/tests/fixtures/tbl_user_used_passwords.php index 7051fb0..a61424a 100644 --- a/tests/fixtures/tbl_user_used_passwords.php +++ b/tests/fixtures/tbl_user_used_passwords.php @@ -1,9 +1,9 @@ 1, - 'password' => '$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', - 'set_on' => '2011-11-11 12:34', - ), + array( + 'user_id' => 1, + 'password' => '$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', + 'set_on' => '2011-11-11 12:34', + ), ); diff --git a/tests/fixtures/tbl_users.php b/tests/fixtures/tbl_users.php index 1398512..9661fc9 100644 --- a/tests/fixtures/tbl_users.php +++ b/tests/fixtures/tbl_users.php @@ -1,34 +1,34 @@ 'neo', - 'password'=>'$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', - 'password_set_on' => '2011-11-11 12:34', - 'email'=>'neo@matrix.com', - 'is_active'=>1, - 'is_disabled'=>0, - ), - array( - 'username'=>'tank', - 'password'=>'$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', - 'password_set_on' => '2012-12-12 10:00', - 'email'=>'tank@matrix.com', - 'is_active'=>0, - 'is_disabled'=>1, - ), - array( - 'username'=>'smith', - 'password'=>'xx', - 'email'=>'smith@matrix.com', - 'is_active'=>0, - 'is_disabled'=>1, - ), - array( - 'username'=>'cat', - 'password'=>'xx', - 'email'=>'cat@matrix.com', - 'is_active'=>1, - 'is_disabled'=>0, - ), + array( + 'username' => 'neo', + 'password' => '$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', + 'password_set_on' => '2011-11-11 12:34', + 'email' => 'neo@matrix.com', + 'is_active' => 1, + 'is_disabled' => 0, + ), + array( + 'username' => 'tank', + 'password' => '$2y$10$6q8D2lv/K73HNcDoEs01.ODNfLq7Wz/EzoAwtOJ4R8bUmCOujW4ky', + 'password_set_on' => '2012-12-12 10:00', + 'email' => 'tank@matrix.com', + 'is_active' => 0, + 'is_disabled' => 1, + ), + array( + 'username' => 'smith', + 'password' => 'xx', + 'email' => 'smith@matrix.com', + 'is_active' => 0, + 'is_disabled' => 1, + ), + array( + 'username' => 'cat', + 'password' => 'xx', + 'email' => 'cat@matrix.com', + 'is_active' => 1, + 'is_disabled' => 0, + ), ); diff --git a/tests/unit/BehaviorsTest.php b/tests/unit/BehaviorsTest.php index 16fdbcd..23ba653 100644 --- a/tests/unit/BehaviorsTest.php +++ b/tests/unit/BehaviorsTest.php @@ -6,116 +6,116 @@ class BehaviorsTest extends CTestCase { - public $identity; - public $owner; - - protected function setUp() - { - $this->identity = $this->getMock('UserIdentity', array('getPasswordDate', 'getOneTimePasswordSecret', 'getOneTimePassword'), array(null, null)); - $this->identity->expects($this->any())->method('getPasswordDate')->will($this->returnValue('2013-10-10')); - $this->identity->expects($this->any())->method('getOneTimePasswordSecret')->will($this->returnValue('ZCIDBJZMPVFXZIKA')); - $this->identity->expects($this->any())->method('getOneTimePassword')->will($this->returnValue(array(null, 1))); - - $this->owner = $this->getMock('stdClass', array('getIdentity', 'hasErrors', 'getErrors', 'addError', 'rules', 'attributeLabels', 'attributeNames')); - $this->owner->username = 'xx'; - $this->owner->expects($this->any())->method('getIdentity')->will($this->returnValue($this->identity)); - $this->owner->expects($this->any())->method('hasErrors')->will($this->returnValue(false)); - $this->owner->expects($this->any())->method('getErrors')->will($this->returnValue(array())); - $this->owner->expects($this->any())->method('addError'); - $this->owner->expects($this->any())->method('rules')->will($this->returnValue(array(array('username', 'required')))); - $this->owner->expects($this->any())->method('attributeLabels')->will($this->returnValue(array('username'=>'label'))); - $this->owner->expects($this->any())->method('attributeNames')->will($this->returnValue(array('username'))); - } - - public function testOTP() - { - Yii::import('vendors.nineinchnick.yii-usr.components.OneTimePasswordFormBehavior'); - - require dirname(__FILE__) . '/../../extensions/GoogleAuthenticator.php/lib/GoogleAuthenticator.php'; - $googleAuthenticator = new GoogleAuthenticator; - $otp = Yii::createComponent(array( - 'class' => 'OneTimePasswordFormBehavior', + public $identity; + public $owner; + + protected function setUp() + { + $this->identity = $this->getMock('UserIdentity', array('getPasswordDate', 'getOneTimePasswordSecret', 'getOneTimePassword'), array(null, null)); + $this->identity->expects($this->any())->method('getPasswordDate')->will($this->returnValue('2013-10-10')); + $this->identity->expects($this->any())->method('getOneTimePasswordSecret')->will($this->returnValue('ZCIDBJZMPVFXZIKA')); + $this->identity->expects($this->any())->method('getOneTimePassword')->will($this->returnValue(array(null, 1))); + + $this->owner = $this->getMock('stdClass', array('getIdentity', 'hasErrors', 'getErrors', 'addError', 'rules', 'attributeLabels', 'attributeNames')); + $this->owner->username = 'xx'; + $this->owner->expects($this->any())->method('getIdentity')->will($this->returnValue($this->identity)); + $this->owner->expects($this->any())->method('hasErrors')->will($this->returnValue(false)); + $this->owner->expects($this->any())->method('getErrors')->will($this->returnValue(array())); + $this->owner->expects($this->any())->method('addError'); + $this->owner->expects($this->any())->method('rules')->will($this->returnValue(array(array('username', 'required')))); + $this->owner->expects($this->any())->method('attributeLabels')->will($this->returnValue(array('username' => 'label'))); + $this->owner->expects($this->any())->method('attributeNames')->will($this->returnValue(array('username'))); + } + + public function testOTP() + { + Yii::import('vendors.nineinchnick.yii-usr.components.OneTimePasswordFormBehavior'); + + require dirname(__FILE__).'/../../extensions/GoogleAuthenticator.php/lib/GoogleAuthenticator.php'; + $googleAuthenticator = new GoogleAuthenticator(); + $otp = Yii::createComponent(array( + 'class' => 'OneTimePasswordFormBehavior', 'authenticator' => $googleAuthenticator, 'mode' => OneTimePasswordFormBehavior::OTP_COUNTER, 'required' => false, 'timeout' => 300, - )); - $otp->setEnabled(true); - $otp->attach($this->owner); - - $this->assertEquals('ZCIDBJZMPVFXZIKA', $otp->getOTP('secret')); - - $this->assertEquals(array('oneTimePassword'), $otp->attributeNames()); - $this->assertEquals(array('oneTimePassword'), $otp->attributeNames()); - $this->assertEquals(array('oneTimePassword' => Yii::t('UsrModule.usr','One Time Password')), $otp->attributeLabels()); - $rules = $otp->filterRules(); - - $ruleOptions = array('on'=>'reset'); - $otp->setRuleOptions($ruleOptions); - $this->assertEquals($ruleOptions, $otp->getRuleOptions()); - - $modifiedRules = $otp->filterRules(); - foreach($modifiedRules as $rule) { - foreach($ruleOptions as $key=>$value) { - $this->assertEquals($value, $rule[$key]); - } - } - - $code = $otp->getNewCode(); - $this->assertInternalType('string', $code); - $this->assertTrue(is_numeric($code)); - $this->assertEquals(6,strlen($code)); - - $controller = $this->getMock('stdClass', array('sendEmail')); - $controller->expects($this->once())->method('sendEmail')->with($this->equalTo($otp), $this->equalTo('oneTimePassword')); - $otp->setController($controller); - $this->assertFalse($otp->validOneTimePassword('one_time_password', array())); - $this->owner->one_time_password = '188172'; - $this->assertTrue($otp->validOneTimePassword('one_time_password', array())); - - $cookie = $otp->createOTPCookie($this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout')); - $this->assertTrue($otp->isValidOTPCookie($cookie, $this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout'))); - $cookie->value = 'xx'; - $this->assertFalse($otp->isValidOTPCookie($cookie, $this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout'))); - } - - public function testCaptcha() - { - Yii::import('vendors.nineinchnick.yii-usr.components.CaptchaFormBehavior'); - $captcha = Yii::createComponent(array( - 'class' => 'CaptchaFormBehavior', - )); - $captcha->setEnabled(true); - $captcha->attach($this->owner); - - $this->assertEquals(array('username'), $this->owner->attributeNames()); - $this->assertEquals(array('username' => 'label'), $this->owner->attributeLabels()); - $this->assertEquals(array(array('username', 'required')), $this->owner->rules()); - - $this->assertEquals(array('verifyCode'), $captcha->attributeNames()); - $this->assertEquals(array('verifyCode' => Yii::t('UsrModule.usr','Verification code')), $captcha->attributeLabels()); - $this->assertEquals(array(array('verifyCode', 'captcha', 'captchaAction' => 'usr/default/captcha')), $captcha->filterRules()); - } - - public function testExpiredPassword() - { - Yii::import('vendors.nineinchnick.yii-usr.components.ExpiredPasswordBehavior'); - $expired = Yii::createComponent(array( - 'class' => 'ExpiredPasswordBehavior', - )); - $expired->setEnabled(true); - $expired->attach($this->owner); - - $passwordSetDate = new DateTime($this->identity->getPasswordDate()); - $today = new DateTime(); - // this will force the pass to be expired - $passwordTimeout = $today->diff($passwordSetDate)->days; - $expired->setPasswordTimeout($passwordTimeout - 10); - $this->assertEquals($passwordTimeout - 10, $expired->getPasswordTimeout()); - - $this->assertFalse($expired->passwordHasNotExpired()); - - $expired->setPasswordTimeout($passwordTimeout + 10); - $this->assertTrue($expired->passwordHasNotExpired()); - } + )); + $otp->setEnabled(true); + $otp->attach($this->owner); + + $this->assertEquals('ZCIDBJZMPVFXZIKA', $otp->getOTP('secret')); + + $this->assertEquals(array('oneTimePassword'), $otp->attributeNames()); + $this->assertEquals(array('oneTimePassword'), $otp->attributeNames()); + $this->assertEquals(array('oneTimePassword' => Yii::t('UsrModule.usr', 'One Time Password')), $otp->attributeLabels()); + $rules = $otp->filterRules(); + + $ruleOptions = array('on' => 'reset'); + $otp->setRuleOptions($ruleOptions); + $this->assertEquals($ruleOptions, $otp->getRuleOptions()); + + $modifiedRules = $otp->filterRules(); + foreach ($modifiedRules as $rule) { + foreach ($ruleOptions as $key => $value) { + $this->assertEquals($value, $rule[$key]); + } + } + + $code = $otp->getNewCode(); + $this->assertInternalType('string', $code); + $this->assertTrue(is_numeric($code)); + $this->assertEquals(6, strlen($code)); + + $controller = $this->getMock('stdClass', array('sendEmail')); + $controller->expects($this->once())->method('sendEmail')->with($this->equalTo($otp), $this->equalTo('oneTimePassword')); + $otp->setController($controller); + $this->assertFalse($otp->validOneTimePassword('one_time_password', array())); + $this->owner->one_time_password = '188172'; + $this->assertTrue($otp->validOneTimePassword('one_time_password', array())); + + $cookie = $otp->createOTPCookie($this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout')); + $this->assertTrue($otp->isValidOTPCookie($cookie, $this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout'))); + $cookie->value = 'xx'; + $this->assertFalse($otp->isValidOTPCookie($cookie, $this->owner->username, $otp->getOTP('secret'), $otp->getOTP('timeout'))); + } + + public function testCaptcha() + { + Yii::import('vendors.nineinchnick.yii-usr.components.CaptchaFormBehavior'); + $captcha = Yii::createComponent(array( + 'class' => 'CaptchaFormBehavior', + )); + $captcha->setEnabled(true); + $captcha->attach($this->owner); + + $this->assertEquals(array('username'), $this->owner->attributeNames()); + $this->assertEquals(array('username' => 'label'), $this->owner->attributeLabels()); + $this->assertEquals(array(array('username', 'required')), $this->owner->rules()); + + $this->assertEquals(array('verifyCode'), $captcha->attributeNames()); + $this->assertEquals(array('verifyCode' => Yii::t('UsrModule.usr', 'Verification code')), $captcha->attributeLabels()); + $this->assertEquals(array(array('verifyCode', 'captcha', 'captchaAction' => 'usr/default/captcha')), $captcha->filterRules()); + } + + public function testExpiredPassword() + { + Yii::import('vendors.nineinchnick.yii-usr.components.ExpiredPasswordBehavior'); + $expired = Yii::createComponent(array( + 'class' => 'ExpiredPasswordBehavior', + )); + $expired->setEnabled(true); + $expired->attach($this->owner); + + $passwordSetDate = new DateTime($this->identity->getPasswordDate()); + $today = new DateTime(); + // this will force the pass to be expired + $passwordTimeout = $today->diff($passwordSetDate)->days; + $expired->setPasswordTimeout($passwordTimeout - 10); + $this->assertEquals($passwordTimeout - 10, $expired->getPasswordTimeout()); + + $this->assertFalse($expired->passwordHasNotExpired()); + + $expired->setPasswordTimeout($passwordTimeout + 10); + $this->assertTrue($expired->passwordHasNotExpired()); + } } diff --git a/tests/unit/LoginFormTest.php b/tests/unit/LoginFormTest.php index 0a6df1f..69c855d 100644 --- a/tests/unit/LoginFormTest.php +++ b/tests/unit/LoginFormTest.php @@ -8,92 +8,94 @@ class LoginFormTest extends CDbTestCase { - public $fixtures=array( - 'users'=>'User', - ); + public $fixtures = array( + 'users' => 'User', + ); - public static function validDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'neo', - 'password'=>'Test1233', - ), - ), - ); - } + public static function validDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'username' => 'neo', + 'password' => 'Test1233', + ), + ), + ); + } - public static function invalidDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'', - 'password'=>'', - ), - 'errors ' => array( - 'username'=>array('Username cannot be blank.'), - 'password'=>array('Password cannot be blank.'), - ), - ), - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'neo', - 'password'=>'xx', - ), - 'errors' => array( - 'password'=>array('Invalid username or password.'), - ), - ), - ); - } + public static function invalidDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'username' => '', + 'password' => '', + ), + 'errors ' => array( + 'username' => array('Username cannot be blank.'), + 'password' => array('Password cannot be blank.'), + ), + ), + array( + 'scenario' => '', + 'attributes' => array( + 'username' => 'neo', + 'password' => 'xx', + ), + 'errors' => array( + 'password' => array('Invalid username or password.'), + ), + ), + ); + } - public static function allDataProvider() { - return array_merge(self::validDataProvider(), self::invalidDataProvider()); - } + public static function allDataProvider() + { + return array_merge(self::validDataProvider(), self::invalidDataProvider()); + } - public function testWithBehavior() - { - $form = new LoginForm; - $formAttributes = $form->attributeNames(); - $formRules = $form->rules(); - $formLabels = $form->attributeLabels(); - $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); - $behaviorAttributes = $form->asa('captcha')->attributeNames(); - $behaviorRules = $form->asa('captcha')->filterRules(); - $behaviorLabels = $form->asa('captcha')->attributeLabels(); - $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); - $this->assertEquals(array_merge($formRules, $behaviorRules), $form->rules()); - $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); - $form->detachBehavior('captcha'); - $this->assertEquals($formAttributes, $form->attributeNames()); - $this->assertEquals($formAttributes, $form->attributeNames()); - } + public function testWithBehavior() + { + $form = new LoginForm(); + $formAttributes = $form->attributeNames(); + $formRules = $form->rules(); + $formLabels = $form->attributeLabels(); + $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); + $behaviorAttributes = $form->asa('captcha')->attributeNames(); + $behaviorRules = $form->asa('captcha')->filterRules(); + $behaviorLabels = $form->asa('captcha')->attributeLabels(); + $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); + $this->assertEquals(array_merge($formRules, $behaviorRules), $form->rules()); + $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); + $form->detachBehavior('captcha'); + $this->assertEquals($formAttributes, $form->attributeNames()); + $this->assertEquals($formAttributes, $form->attributeNames()); + } - /** - * @dataProvider validDataProvider - */ - public function testValid($scenario, $attributes) - { - $form = new LoginForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(),true)); - $this->assertEmpty($form->getErrors()); - } + /** + * @dataProvider validDataProvider + */ + public function testValid($scenario, $attributes) + { + $form = new LoginForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(), true)); + $this->assertEmpty($form->getErrors()); + } - - /** - * @dataProvider invalidDataProvider - */ - public function testInvalid($scenario, $attributes, $errors) - { - $form = new LoginForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertFalse($form->validate()); - $this->assertEquals($errors, $form->getErrors()); - } + /** + * @dataProvider invalidDataProvider + */ + public function testInvalid($scenario, $attributes, $errors) + { + $form = new LoginForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertFalse($form->validate()); + $this->assertEquals($errors, $form->getErrors()); + } } diff --git a/tests/unit/ModuleTest.php b/tests/unit/ModuleTest.php index 3b3b9e7..1f8dbf6 100644 --- a/tests/unit/ModuleTest.php +++ b/tests/unit/ModuleTest.php @@ -4,23 +4,23 @@ class ModuleTest extends CTestCase { - /*public function testModule() - { - $module = new UsrModule('usr',Yii::app()); - $composer = json_decode(file_get_contents(dirname(__FILE__).'/../../composer.json')); - $this->assertEquals($module->getVersion(), $composer->version); - }*/ + /*public function testModule() + { + $module = new UsrModule('usr',Yii::app()); + $composer = json_decode(file_get_contents(dirname(__FILE__).'/../../composer.json')); + $this->assertEquals($module->getVersion(), $composer->version); + }*/ - public function testCreateForm() - { - $module = new UsrModule('usr',Yii::app()); + public function testCreateForm() + { + $module = new UsrModule('usr', Yii::app()); $module->loginFormBehaviors = array( 'expiredPasswordBehavior' => array( 'class' => 'ExpiredPasswordBehavior', 'passwordTimeout' => 300, ), ); - $form = $module->createFormModel('LoginForm'); - $this->assertTrue($form->asa('expiredPasswordBehavior') instanceof ExpiredPasswordBehavior); - } + $form = $module->createFormModel('LoginForm'); + $this->assertTrue($form->asa('expiredPasswordBehavior') instanceof ExpiredPasswordBehavior); + } } diff --git a/tests/unit/PasswordFormTest.php b/tests/unit/PasswordFormTest.php index 96bc5ea..1b20e7d 100644 --- a/tests/unit/PasswordFormTest.php +++ b/tests/unit/PasswordFormTest.php @@ -7,69 +7,71 @@ class PasswordFormTest extends CDbTestCase { - public $fixtures=array( - 'users'=>'User', - ); + public $fixtures = array( + 'users' => 'User', + ); - public static function validDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'password'=>'Test1233', - 'newPassword'=>'Test1234', - 'newVerify'=>'Test1234', - ), - ), - ); - } + public static function validDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'password' => 'Test1233', + 'newPassword' => 'Test1234', + 'newVerify' => 'Test1234', + ), + ), + ); + } - public static function invalidDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'password'=>'xx', - 'newPassword'=>'oo', - 'newPasswordVerify'=>'oo', - ), - 'errors ' => array( - 'password' => array('Invalid password.'), - 'newVerify' => array('Verify cannot be blank.', 'Please type the same new password twice to verify it.'), - 'newPassword' => array('New password is too short (minimum is 8 characters).', 'New password must contain at least one lower and upper case character and a digit.'), - ), - ), - ); - } + public static function invalidDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'password' => 'xx', + 'newPassword' => 'oo', + 'newPasswordVerify' => 'oo', + ), + 'errors ' => array( + 'password' => array('Invalid password.'), + 'newVerify' => array('Verify cannot be blank.', 'Please type the same new password twice to verify it.'), + 'newPassword' => array('New password is too short (minimum is 8 characters).', 'New password must contain at least one lower and upper case character and a digit.'), + ), + ), + ); + } - public static function allDataProvider() { - return array_merge(self::validDataProvider(), self::invalidDataProvider()); - } + public static function allDataProvider() + { + return array_merge(self::validDataProvider(), self::invalidDataProvider()); + } - /** - * @dataProvider validDataProvider - */ - public function testValid($scenario, $attributes) - { - $form = new PasswordForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setIdentity(new UserIdentity('neo', 'Test1233')); - $form->setAttributes($attributes); - $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(),true)); - $this->assertEmpty($form->getErrors()); - } + /** + * @dataProvider validDataProvider + */ + public function testValid($scenario, $attributes) + { + $form = new PasswordForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setIdentity(new UserIdentity('neo', 'Test1233')); + $form->setAttributes($attributes); + $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(), true)); + $this->assertEmpty($form->getErrors()); + } - - /** - * @dataProvider invalidDataProvider - */ - public function testInvalid($scenario, $attributes, $errors) - { - $form = new PasswordForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setIdentity(new UserIdentity('neo', 'Test1233')); - $form->setAttributes($attributes); - $this->assertFalse($form->validate()); - $this->assertEquals($errors, $form->getErrors()); - } + /** + * @dataProvider invalidDataProvider + */ + public function testInvalid($scenario, $attributes, $errors) + { + $form = new PasswordForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setIdentity(new UserIdentity('neo', 'Test1233')); + $form->setAttributes($attributes); + $this->assertFalse($form->validate()); + $this->assertEquals($errors, $form->getErrors()); + } } diff --git a/tests/unit/ProfileFormTest.php b/tests/unit/ProfileFormTest.php index 2761b42..b63d5d1 100644 --- a/tests/unit/ProfileFormTest.php +++ b/tests/unit/ProfileFormTest.php @@ -7,85 +7,87 @@ class ProfileFormTest extends CDbTestCase { - public $fixtures=array( - 'users'=>'User', - ); + public $fixtures = array( + 'users' => 'User', + ); - public static function validDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'trin', - 'email'=>'trinity@matrix.com', - 'firstName'=>'Trinity', - 'lastName'=>'Latex', - ), - ), - ); - } + public static function validDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'username' => 'trin', + 'email' => 'trinity@matrix.com', + 'firstName' => 'Trinity', + 'lastName' => 'Latex', + ), + ), + ); + } - public static function invalidDataProvider() { - return array( - array( - 'scenario' => 'register', - 'attributes' => array( - 'username'=>'neo', - 'email'=>'neo@matrix.com', - 'firstName'=>'Neo', - 'lastName'=>'Confused', - ), - 'errors ' => array( - 'username'=>array('neo has already been used by another user.'), - ), - ), - ); - } + public static function invalidDataProvider() + { + return array( + array( + 'scenario' => 'register', + 'attributes' => array( + 'username' => 'neo', + 'email' => 'neo@matrix.com', + 'firstName' => 'Neo', + 'lastName' => 'Confused', + ), + 'errors ' => array( + 'username' => array('neo has already been used by another user.'), + ), + ), + ); + } - public static function allDataProvider() { - return array_merge(self::validDataProvider(), self::invalidDataProvider()); - } + public static function allDataProvider() + { + return array_merge(self::validDataProvider(), self::invalidDataProvider()); + } - public function testWithBehavior() - { - $form = new ProfileForm; - $formAttributes = $form->attributeNames(); - $formRules = $form->rules(); - $formLabels = $form->attributeLabels(); - $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); - $behaviorAttributes = $form->asa('captcha')->attributeNames(); - $behaviorRules = $form->asa('captcha')->filterRules(); - $behaviorLabels = $form->asa('captcha')->attributeLabels(); - $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); - $this->assertEquals(array_merge($behaviorRules, $formRules), $form->rules()); - $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); - $form->detachBehavior('captcha'); - $this->assertEquals($formAttributes, $form->attributeNames()); - $this->assertEquals($formAttributes, $form->attributeNames()); - } + public function testWithBehavior() + { + $form = new ProfileForm(); + $formAttributes = $form->attributeNames(); + $formRules = $form->rules(); + $formLabels = $form->attributeLabels(); + $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); + $behaviorAttributes = $form->asa('captcha')->attributeNames(); + $behaviorRules = $form->asa('captcha')->filterRules(); + $behaviorLabels = $form->asa('captcha')->attributeLabels(); + $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); + $this->assertEquals(array_merge($behaviorRules, $formRules), $form->rules()); + $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); + $form->detachBehavior('captcha'); + $this->assertEquals($formAttributes, $form->attributeNames()); + $this->assertEquals($formAttributes, $form->attributeNames()); + } - /** - * @dataProvider validDataProvider - */ - public function testValid($scenario, $attributes) - { - $form = new ProfileForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(),true)); - $this->assertEmpty($form->getErrors()); - } + /** + * @dataProvider validDataProvider + */ + public function testValid($scenario, $attributes) + { + $form = new ProfileForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(), true)); + $this->assertEmpty($form->getErrors()); + } - - /** - * @dataProvider invalidDataProvider - */ - public function testInvalid($scenario, $attributes, $errors) - { - $form = new ProfileForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertFalse($form->validate()); - $this->assertEquals($errors, $form->getErrors()); - } + /** + * @dataProvider invalidDataProvider + */ + public function testInvalid($scenario, $attributes, $errors) + { + $form = new ProfileForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertFalse($form->validate()); + $this->assertEquals($errors, $form->getErrors()); + } } diff --git a/tests/unit/RecoveryFormTest.php b/tests/unit/RecoveryFormTest.php index 77dea8f..27f3353 100644 --- a/tests/unit/RecoveryFormTest.php +++ b/tests/unit/RecoveryFormTest.php @@ -7,81 +7,83 @@ class RecoveryFormTest extends CDbTestCase { - public $fixtures=array( - 'users'=>'User', - ); + public $fixtures = array( + 'users' => 'User', + ); - public static function validDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'neo', - 'email'=>'neo@matrix.com', - ), - ), - ); - } + public static function validDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'username' => 'neo', + 'email' => 'neo@matrix.com', + ), + ), + ); + } - public static function invalidDataProvider() { - return array( - array( - 'scenario' => '', - 'attributes' => array( - 'username'=>'trin', - 'email'=>'trinity@matrix.com', - ), - 'errors ' => array( - 'username'=>array('No user found matching this username.'), - ), - ), - ); - } + public static function invalidDataProvider() + { + return array( + array( + 'scenario' => '', + 'attributes' => array( + 'username' => 'trin', + 'email' => 'trinity@matrix.com', + ), + 'errors ' => array( + 'username' => array('No user found matching this username.'), + ), + ), + ); + } - public static function allDataProvider() { - return array_merge(self::validDataProvider(), self::invalidDataProvider()); - } + public static function allDataProvider() + { + return array_merge(self::validDataProvider(), self::invalidDataProvider()); + } - public function testWithBehavior() - { - $form = new RecoveryForm; - $formAttributes = $form->attributeNames(); - $formRules = $form->rules(); - $formLabels = $form->attributeLabels(); - $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); - $behaviorAttributes = $form->asa('captcha')->attributeNames(); - $behaviorRules = $form->asa('captcha')->filterRules(); - $behaviorLabels = $form->asa('captcha')->attributeLabels(); - $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); - $this->assertEquals(array_merge($behaviorRules, $formRules), $form->rules()); - $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); - $form->detachBehavior('captcha'); - $this->assertEquals($formAttributes, $form->attributeNames()); - $this->assertEquals($formAttributes, $form->attributeNames()); - } + public function testWithBehavior() + { + $form = new RecoveryForm(); + $formAttributes = $form->attributeNames(); + $formRules = $form->rules(); + $formLabels = $form->attributeLabels(); + $form->attachBehavior('captcha', array('class' => 'CaptchaFormBehavior')); + $behaviorAttributes = $form->asa('captcha')->attributeNames(); + $behaviorRules = $form->asa('captcha')->filterRules(); + $behaviorLabels = $form->asa('captcha')->attributeLabels(); + $this->assertEquals(array_merge($formAttributes, $behaviorAttributes), $form->attributeNames()); + $this->assertEquals(array_merge($behaviorRules, $formRules), $form->rules()); + $this->assertEquals(array_merge($formLabels, $behaviorLabels), $form->attributeLabels()); + $form->detachBehavior('captcha'); + $this->assertEquals($formAttributes, $form->attributeNames()); + $this->assertEquals($formAttributes, $form->attributeNames()); + } - /** - * @dataProvider validDataProvider - */ - public function testValid($scenario, $attributes) - { - $form = new RecoveryForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(),true)); - $this->assertEmpty($form->getErrors()); - } + /** + * @dataProvider validDataProvider + */ + public function testValid($scenario, $attributes) + { + $form = new RecoveryForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertTrue($form->validate(), 'Failed with following validation errors: '.print_r($form->getErrors(), true)); + $this->assertEmpty($form->getErrors()); + } - - /** - * @dataProvider invalidDataProvider - */ - public function testInvalid($scenario, $attributes, $errors) - { - $form = new RecoveryForm($scenario); - $form->userIdentityClass = 'UserIdentity'; - $form->setAttributes($attributes); - $this->assertFalse($form->validate()); - $this->assertEquals($errors, $form->getErrors()); - } + /** + * @dataProvider invalidDataProvider + */ + public function testInvalid($scenario, $attributes, $errors) + { + $form = new RecoveryForm($scenario); + $form->userIdentityClass = 'UserIdentity'; + $form->setAttributes($attributes); + $this->assertFalse($form->validate()); + $this->assertEquals($errors, $form->getErrors()); + } } diff --git a/tests/unit/UserIdentityTest.php b/tests/unit/UserIdentityTest.php index c56e622..44ff1a9 100644 --- a/tests/unit/UserIdentityTest.php +++ b/tests/unit/UserIdentityTest.php @@ -7,128 +7,128 @@ class UserIdentityTest extends CDbTestCase { - public $fixtures=array( - 'users'=>'User', - 'user_used_passwords'=>'UserUsedPassword', - ); - - /** - */ - public function testGetSet() - { - $identity = new UserIdentity(null, null); - $attributes = array( - 'username' => 'u1', - 'email' => 'e1', - 'firstName' => 'f1', - 'lastName' => 'l1', - ); - $identity->setAttributes($attributes); - $this->assertEquals($attributes, $identity->getAttributes()); - $this->assertEquals($attributes['email'], $identity->getEmail()); - $identity->setId(800); - $this->assertEquals(800, $identity->getId()); - $this->assertFalse($identity->save()); - $identity->setId(null); - $this->assertTrue($identity->save()); - $this->assertEquals(5, $identity->getId()); - $this->assertEquals($attributes, $identity->getAttributes()); - - $identity = UserIdentity::find(array('username'=>'u1')); - $this->assertEquals(5, $identity->getId()); - $this->assertEquals($attributes, $identity->getAttributes()); - - $identity->setAttributes(array('username'=>null, 'password'=>null)); - $this->assertFalse($identity->save()); - } - - public function testRecord() - { - $fakeIdentity = new UserIdentity(null, null); - $fakeIdentity->setId(999); - $this->assertFalse($fakeIdentity->isDisabled()); - $this->assertFalse($fakeIdentity->isActive()); - - $identity = new UserIdentity('neo','xxx'); - $this->assertFalse($identity->authenticate()); - $this->assertFalse($identity->getIsAuthenticated()); - - $identity = new UserIdentity('tank','Test1233'); - $this->assertFalse($identity->authenticate()); - $this->assertFalse($identity->getIsAuthenticated()); - - $identity = new UserIdentity('neo','Test1233'); - $this->assertTrue($identity->authenticate()); - $this->assertTrue($identity->getIsAuthenticated()); - $this->assertTrue($identity->isActive()); - $this->assertFalse($identity->isDisabled()); - - $this->assertEquals('2011-11-11 12:34', $identity->getPasswordDate()); - $this->assertEquals('2011-11-11 12:34', $identity->getPasswordDate('Test1233')); - $this->assertNull($identity->getPasswordDate('xxx')); - - $identity2 = UserIdentity::find(array('username'=>'neo')); - $this->assertEquals($identity->getId(), $identity2->getId()); - - $identity3 = UserIdentity::find(array('username'=>'tank')); - $this->assertEquals(2, $identity3->getId()); - $this->assertFalse($identity3->isActive()); - $this->assertTrue($identity3->isDisabled()); - } - - public function testPasswordReset() - { - $fakeIdentity = new UserIdentity(null, null); - $fakeIdentity->setId(999); - $this->assertFalse($fakeIdentity->resetPassword('xx')); - - $identity = UserIdentity::find(array('username'=>'cat')); - $this->assertEquals(4, $identity->getId()); - $this->assertFalse($identity->authenticate()); - $dateBefore = date('Y-m-d H:i:s'); - $this->assertTrue($identity->resetPassword('Test1234')); - $dateAfter = date('Y-m-d H:i:s'); - $identity->password = 'Test1234'; - $this->assertTrue($identity->authenticate()); - $this->assertGreaterThanOrEqual($dateBefore, $identity->getPasswordDate()); - $this->assertLessThanOrEqual($dateAfter, $identity->getPasswordDate()); - $this->assertGreaterThanOrEqual($dateBefore, $identity->getPasswordDate('Test1234')); - $this->assertLessThanOrEqual($dateAfter, $identity->getPasswordDate('Test1234')); - $this->assertNull($identity->getPasswordDate('xx')); - } - - public function testRemoteIdentity() - { - $identity = new UserIdentity('neo','Test1233'); - $this->assertFalse($identity->addRemoteIdentity('facebook', 'one')); - $this->assertTrue($identity->authenticate()); - $this->assertTrue($identity->addRemoteIdentity('facebook', 'one')); - $identity2 = UserIdentity::findByProvider('facebook', 'one'); - $this->assertEquals($identity->getId(), $identity2->getId()); - } - - public function testActivation() - { - $fakeIdentity = new UserIdentity(null, null); - $fakeIdentity->setId(999); - $this->assertFalse($fakeIdentity->getActivationKey()); - $this->assertEquals(UserIdentity::ERROR_AKEY_INVALID, $fakeIdentity->verifyActivationKey('xx')); - - $identity = UserIdentity::find(array('username'=>'neo')); - $this->assertEquals(UserIdentity::ERROR_AKEY_INVALID, $identity->verifyActivationKey('xx')); - $key = $identity->getActivationKey(); - $this->assertInternalType('string', $key); - $this->assertEquals(UserIdentity::ERROR_AKEY_NONE, $identity->verifyActivationKey($key)); - } - - public function testVerifyEmail() - { - $fakeIdentity = new UserIdentity(null, null); - $this->assertFalse($fakeIdentity->verifyEmail()); - $fakeIdentity->setId(999); - $this->assertFalse($fakeIdentity->verifyEmail()); - - $identity = UserIdentity::find(array('username'=>'neo')); - $this->assertTrue($identity->verifyEmail()); - } + public $fixtures = array( + 'users' => 'User', + 'user_used_passwords' => 'UserUsedPassword', + ); + + /** + */ + public function testGetSet() + { + $identity = new UserIdentity(null, null); + $attributes = array( + 'username' => 'u1', + 'email' => 'e1', + 'firstName' => 'f1', + 'lastName' => 'l1', + ); + $identity->setAttributes($attributes); + $this->assertEquals($attributes, $identity->getAttributes()); + $this->assertEquals($attributes['email'], $identity->getEmail()); + $identity->setId(800); + $this->assertEquals(800, $identity->getId()); + $this->assertFalse($identity->save()); + $identity->setId(null); + $this->assertTrue($identity->save()); + $this->assertEquals(5, $identity->getId()); + $this->assertEquals($attributes, $identity->getAttributes()); + + $identity = UserIdentity::find(array('username' => 'u1')); + $this->assertEquals(5, $identity->getId()); + $this->assertEquals($attributes, $identity->getAttributes()); + + $identity->setAttributes(array('username' => null, 'password' => null)); + $this->assertFalse($identity->save()); + } + + public function testRecord() + { + $fakeIdentity = new UserIdentity(null, null); + $fakeIdentity->setId(999); + $this->assertFalse($fakeIdentity->isDisabled()); + $this->assertFalse($fakeIdentity->isActive()); + + $identity = new UserIdentity('neo', 'xxx'); + $this->assertFalse($identity->authenticate()); + $this->assertFalse($identity->getIsAuthenticated()); + + $identity = new UserIdentity('tank', 'Test1233'); + $this->assertFalse($identity->authenticate()); + $this->assertFalse($identity->getIsAuthenticated()); + + $identity = new UserIdentity('neo', 'Test1233'); + $this->assertTrue($identity->authenticate()); + $this->assertTrue($identity->getIsAuthenticated()); + $this->assertTrue($identity->isActive()); + $this->assertFalse($identity->isDisabled()); + + $this->assertEquals('2011-11-11 12:34', $identity->getPasswordDate()); + $this->assertEquals('2011-11-11 12:34', $identity->getPasswordDate('Test1233')); + $this->assertNull($identity->getPasswordDate('xxx')); + + $identity2 = UserIdentity::find(array('username' => 'neo')); + $this->assertEquals($identity->getId(), $identity2->getId()); + + $identity3 = UserIdentity::find(array('username' => 'tank')); + $this->assertEquals(2, $identity3->getId()); + $this->assertFalse($identity3->isActive()); + $this->assertTrue($identity3->isDisabled()); + } + + public function testPasswordReset() + { + $fakeIdentity = new UserIdentity(null, null); + $fakeIdentity->setId(999); + $this->assertFalse($fakeIdentity->resetPassword('xx')); + + $identity = UserIdentity::find(array('username' => 'cat')); + $this->assertEquals(4, $identity->getId()); + $this->assertFalse($identity->authenticate()); + $dateBefore = date('Y-m-d H:i:s'); + $this->assertTrue($identity->resetPassword('Test1234')); + $dateAfter = date('Y-m-d H:i:s'); + $identity->password = 'Test1234'; + $this->assertTrue($identity->authenticate()); + $this->assertGreaterThanOrEqual($dateBefore, $identity->getPasswordDate()); + $this->assertLessThanOrEqual($dateAfter, $identity->getPasswordDate()); + $this->assertGreaterThanOrEqual($dateBefore, $identity->getPasswordDate('Test1234')); + $this->assertLessThanOrEqual($dateAfter, $identity->getPasswordDate('Test1234')); + $this->assertNull($identity->getPasswordDate('xx')); + } + + public function testRemoteIdentity() + { + $identity = new UserIdentity('neo', 'Test1233'); + $this->assertFalse($identity->addRemoteIdentity('facebook', 'one')); + $this->assertTrue($identity->authenticate()); + $this->assertTrue($identity->addRemoteIdentity('facebook', 'one')); + $identity2 = UserIdentity::findByProvider('facebook', 'one'); + $this->assertEquals($identity->getId(), $identity2->getId()); + } + + public function testActivation() + { + $fakeIdentity = new UserIdentity(null, null); + $fakeIdentity->setId(999); + $this->assertFalse($fakeIdentity->getActivationKey()); + $this->assertEquals(UserIdentity::ERROR_AKEY_INVALID, $fakeIdentity->verifyActivationKey('xx')); + + $identity = UserIdentity::find(array('username' => 'neo')); + $this->assertEquals(UserIdentity::ERROR_AKEY_INVALID, $identity->verifyActivationKey('xx')); + $key = $identity->getActivationKey(); + $this->assertInternalType('string', $key); + $this->assertEquals(UserIdentity::ERROR_AKEY_NONE, $identity->verifyActivationKey($key)); + } + + public function testVerifyEmail() + { + $fakeIdentity = new UserIdentity(null, null); + $this->assertFalse($fakeIdentity->verifyEmail()); + $fakeIdentity->setId(999); + $this->assertFalse($fakeIdentity->verifyEmail()); + + $identity = UserIdentity::find(array('username' => 'neo')); + $this->assertTrue($identity->verifyEmail()); + } } diff --git a/views/default/_captcha.php b/views/default/_captcha.php index 762684d..b8c203c 100644 --- a/views/default/_captcha.php +++ b/views/default/_captcha.php @@ -1,12 +1,12 @@
- labelEx($model,'verifyCode'); ?> + labelEx($model, 'verifyCode'); ?>
widget('CCaptcha', $this->module->captcha === true ? array() : $this->module->captcha); ?>
- textField($model,'verifyCode'); ?> + textField($model, 'verifyCode'); ?>

- error($model,'verifyCode'); ?> + error($model, 'verifyCode'); ?>
diff --git a/views/default/_form.php b/views/default/_form.php index de544a7..7452125 100644 --- a/views/default/_form.php +++ b/views/default/_form.php @@ -6,56 +6,56 @@ ?>
- labelEx($model,'username'); ?> - textField($model,'username'); ?> - error($model,'username'); ?> + labelEx($model, 'username'); ?> + textField($model, 'username'); ?> + error($model, 'username'); ?>
- labelEx($model,'email'); ?> - textField($model,'email'); ?> - error($model,'email'); ?> + labelEx($model, 'email'); ?> + textField($model, 'email'); ?> + error($model, 'email'); ?>
scenario !== 'register'): ?>
- labelEx($model,'password'); ?> - passwordField($model,'password', array('autocomplete'=>'off')); ?> - error($model,'password'); ?> + labelEx($model, 'password'); ?> + passwordField($model, 'password', array('autocomplete' => 'off')); ?> + error($model, 'password'); ?>
-renderPartial('/default/_newpassword', array('form'=>$form, 'model'=>$passwordForm)); ?> +renderPartial('/default/_newpassword', array('form' => $form, 'model' => $passwordForm)); ?>
- labelEx($model,'firstName'); ?> - textField($model,'firstName'); ?> - error($model,'firstName'); ?> + labelEx($model, 'firstName'); ?> + textField($model, 'firstName'); ?> + error($model, 'firstName'); ?>
- labelEx($model,'lastName'); ?> - textField($model,'lastName'); ?> - error($model,'lastName'); ?> + labelEx($model, 'lastName'); ?> + textField($model, 'lastName'); ?> + error($model, 'lastName'); ?>
getIdentity() instanceof IPictureIdentity && !empty($model->pictureUploadRules)): - $picture = $model->getIdentity()->getPictureUrl(80,80); - if ($picture !== null) { - $url = $picture['url']; - unset($picture['url']); - } + $picture = $model->getIdentity()->getPictureUrl(80, 80); + if ($picture !== null) { + $url = $picture['url']; + unset($picture['url']); + } ?>
- labelEx($model,'picture'); ?> + labelEx($model, 'picture'); ?>
- fileField($model,'picture'); ?> - error($model,'picture'); ?> + fileField($model, 'picture'); ?> + error($model, 'picture'); ?>
- label($model,'removePicture', array('label'=>$form->checkBox($model,'removePicture').$model->getAttributeLabel('removePicture'), 'class'=>'checkbox')); ?> - error($model,'removePicture'); ?> + label($model, 'removePicture', array('label' => $form->checkBox($model, 'removePicture').$model->getAttributeLabel('removePicture'), 'class' => 'checkbox')); ?> + error($model, 'removePicture'); ?>
diff --git a/views/default/_login_remote.php b/views/default/_login_remote.php index 136e590..1e8e795 100644 --- a/views/default/_login_remote.php +++ b/views/default/_login_remote.php @@ -26,21 +26,23 @@ function PopupCenter(url, title, w, h) { Yii::app()->clientScript->registerScript(__CLASS__.'#popup', $popupScript, CClientScript::POS_END); ?>