/webroot/updates/concrete5.6.0.2/concrete/core/controllers/single_pages/login.php
PHP | 490 lines | 384 code | 68 blank | 38 comment | 86 complexity | 77cf281d77d74cbaf3cab5fa99f330fe MD5 | raw file
Possible License(s): MIT, LGPL-2.1, BSD-3-Clause
- <?php
- defined('C5_EXECUTE') or die("Access Denied.");
- Loader::library('authentication/open_id');
- class Concrete5_Controller_Login extends Controller {
-
- public $helpers = array('form');
- private $openIDReturnTo;
- protected $locales = array();
-
- public function on_start() {
- $this->error = Loader::helper('validation/error');
- if (USER_REGISTRATION_WITH_EMAIL_ADDRESS == true) {
- $this->set('uNameLabel', t('Email Address'));
- } else {
- $this->set('uNameLabel', t('Username'));
- }
-
- $txt = Loader::helper('text');
- if (strlen($_GET['uName'])) { // pre-populate the username if supplied, if its an email address with special characters the email needs to be urlencoded first,
- $this->set("uName",trim($txt->email($_GET['uName'])));
- }
-
- $languages = array();
- $locales = array();
- if (Config::get('LANGUAGE_CHOOSE_ON_LOGIN')) {
- Loader::library('3rdparty/Zend/Locale');
- Loader::library('3rdparty/Zend/Locale/Data');
- $languages = Localization::getAvailableInterfaceLanguages();
- if (count($languages) > 0) {
- array_unshift($languages, 'en_US');
- }
- $locales = array('' => t('** Default'));
- Zend_Locale_Data::setCache(Cache::getLibrary());
- foreach($languages as $lang) {
- $loc = new Zend_Locale($lang);
- $locales[$lang] = Zend_Locale::getTranslation($loc->getLanguage(), 'language', ACTIVE_LOCALE);
- }
- }
- $this->locales = $locales;
- $this->set('locales', $locales);
-
- $this->openIDReturnTo = BASE_URL . View::url("/login", "complete_openid");
- }
-
- /* automagically run by the controller once we're done with the current method */
- /* method is passed to this method, the method that we were just finished running */
- public function on_before_render() {
- if ($this->error->has()) {
- $this->set('error', $this->error);
- }
- }
-
- public function complete_openid_email() {
- $email = $this->post('uEmail');
- $vals = Loader::helper('validation/strings');
- $valc = Loader::helper('concrete/validation');
- if (!$vals->email($email)) {
- $this->error->add(t('Invalid email address provided.'));
- } else if (!$valc->isUniqueEmail($email)) {
- $this->error->add(t("The email address %s is already in use. Please choose another.", $_POST['uEmail']));
- }
-
- if (!$this->error->has()) {
- // complete the openid record with the provided email
- if (isset($_SESSION['uOpenIDRequested'])) {
- $oa = new OpenIDAuth();
- $ui = $oa->registerUser($_SESSION['uOpenIDRequested'], $email);
- User::loginByUserID($ui->getUserID());
- $oa->reinstatePreviousRequest();
- $this->finishLogin();
- }
- }
- }
-
- public function view() {
- $this->clearOpenIDSession();
- }
-
- private function clearOpenIDSession() {
- unset($_SESSION['uOpenIDError']);
- unset($_SESSION['uOpenIDRequested']);
- unset($_SESSION['uOpenIDExistingUser']);
- }
-
- public function complete_openid() {
- $v = Loader::helper('validation/numbers');
- $oa = new OpenIDAuth();
- $oa->setReturnURL($this->openIDReturnTo);
- $oa->complete();
- $response = $oa->getResponse();
- if ($response->code == OpenIDAuth::E_CANCEL) {
- $this->error->add(t('OpenID Verification Cancelled'));
- $this->clearOpenIDSession();
- } else if ($response->code == OpenIDAuth::E_FAILURE) {
- $this->error->add(t('OpenID Authentication Failed: %s', $response->message));
- $this->clearOpenIDSession();
- } else {
- switch($response->code) {
- case OpenIDAuth::S_USER_CREATED:
- case OpenIDAuth::S_USER_AUTHENTICATED:
- if ($v->integer($response->message)) {
- User::loginByUserID($response->message);
- $this->set('uOpenID', $response->openid);
- $oa->reinstatePreviousRequest();
- $this->finishLogin();
- }
- break;
- case OpenIDAuth::E_REGISTRATION_EMAIL_INCOMPLETE:
- // we don't have an email address, but the account is valid
- // valid display identifier comes back in message
- $_SESSION['uOpenIDRequested'] = $response->message;
- $_SESSION['uOpenIDError'] = OpenIDAuth::E_REGISTRATION_EMAIL_INCOMPLETE;
- break;
- case OpenIDAuth::E_REGISTRATION_EMAIL_EXISTS:
- // an email address came back with us from the openid server
- // but that email already exists
- $_SESSION['uOpenIDRequested'] = $response->openid;
- $_SESSION['uOpenIDExistingUser'] = $response->user;
- $_SESSION['uOpenIDError'] = OpenIDAuth::E_REGISTRATION_EMAIL_EXISTS;
- break;
- }
- }
- $this->set('oa', $oa);
- }
-
- public function account_deactivated() {
- $this->error->add(t('This user is inactive. Please contact us regarding this account.'));
- }
-
- public function do_login() {
- $ip = Loader::helper('validation/ip');
- $vs = Loader::helper('validation/strings');
-
- $loginData['success']=0;
-
- try {
- if (!$ip->check()) {
- throw new Exception($ip->getErrorMessage());
- }
- if (OpenIDAuth::isEnabled() && $vs->notempty($this->post('uOpenID'))) {
- $oa = new OpenIDAuth();
- $oa->setReturnURL($this->openIDReturnTo);
- $return = $oa->request($this->post('uOpenID'));
- $resp = $oa->getResponse();
- if ($resp->code == OpenIDAuth::E_INVALID_OPENID) {
- throw new Exception(t('Invalid OpenID.'));
- }
- }
-
- if ((!$vs->notempty($this->post('uName'))) || (!$vs->notempty($this->post('uPassword')))) {
- if (USER_REGISTRATION_WITH_EMAIL_ADDRESS) {
- throw new Exception(t('An email address and password are required.'));
- } else {
- throw new Exception(t('A username and password are required.'));
- }
- }
-
- $u = new User($this->post('uName'), $this->post('uPassword'));
- if ($u->isError()) {
- switch($u->getError()) {
- case USER_NON_VALIDATED:
- throw new Exception(t('This account has not yet been validated. Please check the email associated with this account and follow the link it contains.'));
- break;
- case USER_INVALID:
- if (USER_REGISTRATION_WITH_EMAIL_ADDRESS) {
- throw new Exception(t('Invalid email address or password.'));
- } else {
- throw new Exception(t('Invalid username or password.'));
- }
- break;
- case USER_INACTIVE:
- throw new Exception(t('This user is inactive. Please contact us regarding this account.'));
- break;
- }
- } else {
-
- if (OpenIDAuth::isEnabled() && $_SESSION['uOpenIDExistingUser'] > 0) {
- $oa = new OpenIDAuth();
- if ($_SESSION['uOpenIDExistingUser'] == $u->getUserID()) {
- // the account we logged in with is the same as the existing user from the open id. that means
- // we link the account to open id and keep the user logged in.
- $oa->linkUser($_SESSION['uOpenIDRequested'], $u);
- } else {
- // The user HAS logged in. But the account they logged into is NOT the same as the one
- // that links to their OpenID. So we log them out and tell them so.
- $u->logout();
- throw new Exception(t('This account does not match the email address provided.'));
- }
- }
-
- $loginData['success']=1;
- $loginData['msg']=t('Login Successful');
- $loginData['uID'] = intval($u->getUserID());
- }
- $loginData = $this->finishLogin($loginData);
-
- } catch(Exception $e) {
- $ip->logSignupRequest();
- if ($ip->signupRequestThreshholdReached()) {
- $ip->createIPBan();
- }
- $this->error->add($e);
- $loginData['error']=$e->getMessage();
- }
-
- if( $_REQUEST['format']=='JSON' ){
- $jsonHelper=Loader::helper('json');
- echo $jsonHelper->encode($loginData);
- die;
- }
- }
- protected function finishLogin( $loginData=array() ) {
- $u = new User();
- if ($this->post('uMaintainLogin')) {
- $u->setUserForeverCookie();
- }
-
- if (count($this->locales) > 0) {
- if (Config::get('LANGUAGE_CHOOSE_ON_LOGIN') && $this->post('USER_LOCALE') != '') {
- $u->setUserDefaultLanguage($this->post('USER_LOCALE'));
- }
- }
-
- // Verify that the user has filled out all
- // required items that are required on register
- // That means users logging in after new user attributes
- // have been created and required will be prompted here to
- // finish their profile
-
- $this->set('invalidRegistrationFields', false);
- Loader::model('attribute/categories/user');
- $ui = UserInfo::getByID($u->getUserID());
- $aks = UserAttributeKey::getRegistrationList();
- $unfilledAttributes = array();
- foreach($aks as $uak) {
- if ($uak->isAttributeKeyRequiredOnRegister()) {
- $av = $ui->getAttributeValueObject($uak);
- if (!is_object($av)) {
- $unfilledAttributes[] = $uak;
- }
- }
- }
- if ($this->post('completePartialProfile')) {
- foreach($unfilledAttributes as $uak) {
- $e1 = $uak->validateAttributeForm();
- if ($e1 == false) {
- $this->error->add(t('The field "%s" is required', $uak->getAttributeKeyName()));
- } else if ($e1 instanceof ValidationErrorHelper) {
- $this->error->add($e1);
- }
- }
-
- if (!$this->error->has()) {
- // the user has needed to complete a partial profile, and they have done so,
- // and they have no errors. So we save our profile data against the account.
- foreach($unfilledAttributes as $uak) {
- $uak->saveAttributeForm($ui);
- $unfilledAttributes = array();
- }
- }
- }
-
- if (count($unfilledAttributes) > 0) {
- $u->logout();
- $this->set('invalidRegistrationFields', true);
- $this->set('unfilledAttributes', $unfilledAttributes);
- }
- $txt = Loader::helper('text');
- $rcID = $this->post('rcID');
- $nh = Loader::helper('validation/numbers');
- //set redirect url
- if ($nh->integer($rcID)) {
- $nh = Loader::helper('navigation');
- $rc = Page::getByID($rcID);
- $url = $nh->getLinkToCollection($rc, true);
- $loginData['redirectURL'] = $url;
- }elseif( strlen($rcID) ){
- $rcID = trim($rcID, '/');
-
- $nc2 = Page::getByPath('/' . $rcID);
- if (is_object($nc2) && !$nc2->isError()) {
- $loginData['redirectURL'] = BASE_URL . DIR_REL . '/' . DISPATCHER_FILENAME . '/' . $rcID;
- }
- }
-
- /*
- //full page login redirect (non-ajax login)
- if( strlen($loginData['redirectURL']) && $_REQUEST['format']!='JSON' ){
- header('Location: ' . $loginData['redirectURL']);
- exit;
- }
- */
-
- $dash = Page::getByPath("/dashboard", "RECENT");
- $dbp = new Permissions($dash);
-
- Events::fire('on_user_login',$this);
-
- //End JSON Login
- if($_REQUEST['format']=='JSON')
- return $loginData;
-
- //should administrator be redirected to dashboard? defaults to yes if not set.
- $adminToDash=intval(Config::get('LOGIN_ADMIN_TO_DASHBOARD'));
-
- //Full page login, standard redirection
- $u = new User(); // added for the required registration attribute change above. We recalc the user and make sure they're still logged in
- if ($u->isRegistered()) {
- if ($u->config('NEWSFLOW_LAST_VIEWED') == 'FIRSTRUN') {
- $u->saveConfig('NEWSFLOW_LAST_VIEWED', 0);
- }
-
- if ($loginData['redirectURL']) {
- //make double secretly sure there's no caching going on
- header("Cache-Control: no-store, no-cache, must-revalidate");
- header("Pragma: no-cache");
- header('Expires: Fri, 30 Oct 1998 14:19:41 GMT'); //in the past
- $this->externalRedirect( $loginData['redirectURL'] );
- }else if ( $dbp->canRead() && $adminToDash ) {
- $this->redirect('/dashboard');
- } else {
- //options set in dashboard/users/registration
- $login_redirect_cid=intval(Config::get('LOGIN_REDIRECT_CID'));
- $login_redirect_mode=Config::get('LOGIN_REDIRECT');
-
- //redirect to user profile
- if( $login_redirect_mode=='PROFILE' && ENABLE_USER_PROFILES ){
- $this->redirect( '/profile/', $u->uID );
-
- //redirect to custom page
- }elseif( $login_redirect_mode=='CUSTOM' && $login_redirect_cid > 0 ){
- $redirectTarget = Page::getByID( $login_redirect_cid );
- if(intval($redirectTarget->cID)>0) $this->redirect( $redirectTarget->getCollectionPath() );
- else $this->redirect('/');
-
- //redirect home
- }else $this->redirect('/');
- }
- }
- }
- public function password_sent() {
- $this->set('intro_msg', $this->getPasswordSentMsg() );
- }
-
- public function getPasswordSentMsg(){
- return t('An email containing instructions on resetting your password has been sent to your account address.');
- }
-
- public function logout() {
- $u = new User();
- $u->logout();
- $this->redirect('/');
- }
-
- public function forward($cID = 0) {
- $nh = Loader::helper('validation/numbers');
- if ($nh->integer($cID)) {
- $this->set('rcID', $cID);
- }
- }
-
- // responsible for validating a user's email address
- public function v($hash = '') {
- $ui = UserInfo::getByValidationHash($hash);
- if (is_object($ui)) {
- $ui->markValidated();
- $this->set('uEmail', $ui->getUserEmail());
- $this->set('validated', true);
- }
- }
-
- // responsible for validating a user's email address
- public function change_password($uHash = '') {
- $db = Loader::db();
- $h = Loader::helper('validation/identifier');
- $e = Loader::helper('validation/error');
- $ui = UserInfo::getByValidationHash($uHash);
- if (is_object($ui)){
- $hashCreated = $db->GetOne("select uDateGenerated FROM UserValidationHashes where uHash=?", array($uHash));
- if($hashCreated < (time()-(USER_CHANGE_PASSWORD_URL_LIFETIME))) {
- $h->deleteKey('UserValidationHashes','uHash',$uHash);
- throw new Exception( t('Key Expired. Please visit the forgot password page again to have a new key generated.') );
- }else{
-
- if(strlen($_POST['uPassword'])){
-
- $userHelper = Loader::helper('concrete/user');
- $userHelper->validNewPassword($_POST['uPassword'],$e);
-
- if(strlen($_POST['uPassword']) && $_POST['uPasswordConfirm']!=$_POST['uPassword']){
- $e->add(t('The two passwords provided do not match.'));
- }
-
- if (!$e->has()){
- $ui->changePassword( $_POST['uPassword'] );
- $h->deleteKey('UserValidationHashes','uHash',$uHash);
- $this->set('passwordChanged', true);
-
- $u = $ui->getUserObject();
- if (USER_REGISTRATION_WITH_EMAIL_ADDRESS) {
- $_POST['uName'] = $ui->getUserEmail();
- } else {
- $_POST['uName'] = $u->getUserName();
- }
- $this->do_login();
-
- return;
- }else{
- $this->set('uHash', $uHash);
- $this->set('changePasswordForm', true);
- $this->set('errorMsg', join( '<br>', $e->getList() ) );
- }
- }else{
- $this->set('uHash', $uHash);
- $this->set('changePasswordForm', true);
- }
- }
- }else{
- throw new Exception( t('Invalid Key. Please visit the forgot password page again to have a new key generated.') );
- }
- }
-
- public function forgot_password() {
- $loginData['success']=0;
-
- $vs = Loader::helper('validation/strings');
- $em = $this->post('uEmail');
- try {
- if (!$vs->email($em)) {
- throw new Exception(t('Invalid email address.'));
- }
-
- $oUser = UserInfo::getByEmail($em);
- if (!$oUser) {
- throw new Exception(t('We have no record of that email address.'));
- }
-
- $mh = Loader::helper('mail');
- //$mh->addParameter('uPassword', $oUser->resetUserPassword());
- $mh->addParameter('uName', $oUser->getUserName());
- $mh->to($oUser->getUserEmail());
-
- //generate hash that'll be used to authenticate user, allowing them to change their password
- $h = Loader::helper('validation/identifier');
- $uHash = $h->generate('UserValidationHashes', 'uHash');
- $db = Loader::db();
- $db->Execute("DELETE FROM UserValidationHashes WHERE uID=?", array( $oUser->uID ) );
- $db->Execute("insert into UserValidationHashes (uID, uHash, uDateGenerated, type) values (?, ?, ?, ?)", array($oUser->uID, $uHash, time(),intval(UVTYPE_CHANGE_PASSWORD)));
- $changePassURL=BASE_URL . View::url('/login', 'change_password', $uHash);
- $mh->addParameter('changePassURL', $changePassURL);
-
- if (defined('EMAIL_ADDRESS_FORGOT_PASSWORD')) {
- $mh->from(EMAIL_ADDRESS_FORGOT_PASSWORD, t('Forgot Password'));
- } else {
- $adminUser = UserInfo::getByID(USER_SUPER_ID);
- if (is_object($adminUser)) {
- $mh->from($adminUser->getUserEmail(), t('Forgot Password'));
- }
- }
- $mh->load('forgot_password');
- @$mh->sendMail();
-
- $loginData['success']=1;
- $loginData['msg']=$this->getPasswordSentMsg();
- } catch(Exception $e) {
- $this->error->add($e);
- $loginData['error']=$e->getMessage();
- }
-
- if( $_REQUEST['format']=='JSON' ){
- $jsonHelper=Loader::helper('json');
- echo $jsonHelper->encode($loginData);
- die;
- }
-
- if($loginData['success']==1)
- $this->redirect('/login', 'password_sent');
- }
-
- }