} fastcgi_finish_request(); } catch (\Exception $e) { session_write_close(); header("HTTP/1.0 500 Exception"); try { /** * @mail must be here before the Lampcms\Exception::formatException * because Lampcms\Exception::formatException in case of ajax request will * send out ajax and then throw \OutOfBoundsException in order to finish request (better than exit()) */ if (defined('LAMPCMS_DEVELOPER_EMAIL') && strlen(trim(constant('LAMPCMS_DEVELOPER_EMAIL'))) > 7) { @mail(LAMPCMS_DEVELOPER_EMAIL, '500 Error in index.php', $sHtml . $extra); } $sHtml = \Lampcms\Responder::makeErrorPage('<strong>Error:</strong> ' . Lampcms\Exception::formatException($e)); $extra = isset($_SERVER) ? ' $_SERVER: ' . print_r($_SERVER, 1) : ' no server'; $extra .= 'file: ' . $e->getFile() . ' line: ' . $e->getLine() . ' trace: ' . $e->getTraceAsString(); echo $sHtml; } catch (\OutOfBoundsException $e2) { // do nothing, this was a way to exit() from Responder::sendJSON() } catch (\Exception $e2) { $sHtml = \Lampcms\Responder::makeErrorPage('<strong>Exception:</strong> ' . strip_tags($e2->getMessage()) . "\nIn file:" . $e2->getFile() . "\nLine: " . $e2->getLine()); $extra = isset($_SERVER) ? ' $_SERVER: ' . print_r($_SERVER, 1) : ' no extra'; if (defined('LAMPCMS_DEVELOPER_EMAIL') && strlen(trim(constant('LAMPCMS_DEVELOPER_EMAIL'))) > 7) { @mail(LAMPCMS_DEVELOPER_EMAIL, 'Error in index.php on line ' . __LINE__, $sHtml . $extra); } echo $sHtml; } fastcgi_finish_request(); } }
/** * Formats the exception, adding * additional exception data like backtrace * if running in debug mode * then adds the 'error' to a page * * @return * @param object $e Exception object */ public function handleException(\Lampcms\Exception $le) { try { if ($le instanceof RedirectException) { session_write_close(); header("Location: " . $le->getMessage(), true, $le->getCode()); fastcgi_finish_request(); throw new \OutOfBoundsException(); } if ($le instanceof CaptchaLimitException) { d('Captcha limit reached.'); /** * @todo add ip to CAPTCHA_HACKS collection * */ } /** * In case of LampcmsAuthException * the value of 'c' attribute in exception * element will be set to "login" * indicating to template that this * is a 'must login' type of exception * and to render the login form * */ $class = $le instanceof AuthException ? 'login' : 'excsl'; /** * Special case: * the http error code can be * passed in exception as third argument * (in case where there are no second arg, * the second arg must be passed as null) */ if (201 < ($errCode = $le->getCode())) { $this->httpCode = (int) $errCode; } if ($le instanceof Lampcms404Exception) { $this->httpCode = 404; } if (!$le instanceof Lampcms404Exception && !$le instanceof AuthException && !$le instanceof LoginException && !$le instanceof MustLoginException && !$le instanceof \OutOfBoundsException) { e('Exception caught in: ' . $le->getFile() . ' on line: ' . $le->getLine() . ' ' . $le->getMessage()); } /** * * Exception::formatException will correctly * handle sending out JSON and exiting * if the request isAjax * */ $err = Exception::formatException($le, null, $this->Registry->Tr); /** * @todo if Login exception then present a login form! * */ $this->aPageVars['layoutID'] = 1; $this->aPageVars['body'] = \tplException::parse(array('message' => $err, 'class' => $class, 'title' => $this->_('Alert'))); } catch (\OutOfBoundsException $e) { throw $e; } catch (\Exception $e) { e('Exception object ' . $e->getMessage()); $err = Responder::makeErrorPage($le->getMessage() . ' in ' . $e->getFile()); echo $err; fastcgi_finish_request(); throw new \OutOfBoundsException(); } }
/** * Add Twitter credentials to existing user * * @return $this */ protected function connect($tid) { $aUser = $this->getUserByTid($tid); d('$aUser: '******'_id'] != $this->User->getUid()) { $name = ''; if (!empty($aUser['fn'])) { $name .= $aUser['fn']; } if (!empty($aUser['ln'])) { $name .= ' ' . $aUser['fn']; } $trimmed = \trim($name); $name = !empty($trimmed) ? \trim($name) : $aUser['username']; /** * This error message will appear inside the * Small extra browser Window that Login with Twitter * opens * */ $err = '<div class="larger"><p>This Twitter account is already connected to another registered user: <strong>' . $name . '</strong><br> <br> A Twitter account cannot be associated with more than one account on this site<br> If you still want to connect Twitter account to this account you must use a different Twitter account</p>'; $err .= '<br><br> <input type="button" class="btn-m" onClick="window.close();" value=" OK "> <input type="button" class="btn-m" onClick="window.close();" value=" Close "> </div>'; $s = Responder::makeErrorPage($err); echo $s; exit; } $this->updateUser(false); }
/** * Step 2 in oAuth process * this is when Blogger redirected the user back * to our callback url, which calls this controller * @return object $this * * @throws Exception in case something goes wrong with oAuth class */ protected function step2() { try { /** * This is a callback (redirected back from Blogger page * after user authorized us) * In this case we must: create account or update account * in USER table * Re-create oViewer object * send cookie to remember user * and then send out HTML with js instruction to close the popup window */ d('Looks like we are at step 2 of authentication. Request: ' . print_r($_REQUEST, 1)); /** * @todo check first to make sure we do have oauth_token * on REQUEST, else close the window */ $this->oAuth->setToken($this->Request['oauth_token'], $_SESSION['blogger_oauth']['oauth_token_secret']); $ver = $this->Registry->Request['oauth_verifier']; d(' $ver: ' . $ver); $url = self::ACCESS_TOKEN_URL . '?oauth_verifier=' . $ver; d('url: ' . $url); $this->aAccessToken = $this->oAuth->getAccessToken(self::ACCESS_TOKEN_URL); d('$this->aAccessToken: ' . print_r($this->aAccessToken, 1)); unset($_SESSION['blogger_oauth']); $this->oAuth->setToken($this->aAccessToken['oauth_token'], $this->aAccessToken['oauth_token_secret']); /** * Now getUserBlogs * Then if user has more than one blog * display a form with "select blog" * + description about it * * Make sure to run connect() first so that oViewer['Blogger'] * element will be created and will have all user blogs * * Else - user has just one blog then close Window! * */ d('cp'); $this->getUserBlogs()->connect(); d('cp'); /** * If user has more than one blog * then show special form */ if (count($this->aBlogs) > 1) { d('User has more than one blog, generating "select blog" form'); $form = $this->makeBlogSelectionForm(); d('$form: ' . $form); echo Responder::makeErrorPage($form); throw new \OutOfBoundsException(); } else { d('User has one Blogger blog, using it now'); /** * Set flag to session indicating that user just * connected Blogger Account */ $this->Registry->Viewer['b_bg'] = true; $this->closeWindow(); } } catch (\OAuthException $e) { $aDebug = $this->oAuth->getLastResponseInfo(); /** * Always check for response code first! * it must be 201 or it's no good! * * Also check the 'url' part of it * if it does not match url you used * in request then it was redirected! */ e('OAuthException: ' . $e->getMessage() . ' in file ' . $e->getFile() . ' on line: ' . $e->getLine() . ' Debug: ' . print_r($aDebug, 1)); $err = 'Something went wrong during authorization. Please try again later. ' . $e->getMessage(); throw new \Exception($err); } return $this; }
/** * Step 2 in oAuth process * this is when tumblr redirected the user back * to our callback url, which calls this controller * * @throws \Exception in case something goes wrong with oAuth class * @return object $this */ protected function step2() { try { /** * This is a callback (redirected back from tumblr page * after user authorized us) * In this case we must: create account or update account * in USER table * Re-create oViewer object * send cookie to remember user * and then send out HTML with js instruction to close the popup window */ d('Looks like we are at step 2 of authentication. Request: ' . \json_encode($_REQUEST)); /** * @todo check first to make sure we do have oauth_token * on REQUEST, else close the window */ $this->oAuth->setToken($this->Request['oauth_token'], $_SESSION['tumblr_oauth']['oauth_token_secret']); $this->aAccessToken = $this->oAuth->getAccessToken(self::ACCESS_TOKEN_URL); d('$this->aAccessToken: ' . \json_encode($this->aAccessToken)); unset($_SESSION['tumblr_oauth']); $this->oAuth->setToken($this->aAccessToken['oauth_token'], $this->aAccessToken['oauth_token_secret']); /** * Now getUserBlogs * Then if user has more than one blog * display a form with "select blog" * + description about it * * Make sure to run connect() first so that oViewer['tumblr'] * element will be created and will have all user blogs * * * Else - user has just one blog then close Window! * */ d('cp'); $this->getUserBlogs()->connect(); d('cp'); /** * If user has more than one blog * then show special form */ if (count($this->aBlogs) > 1) { d('User has more than one blog, generating "select blog" form'); $form = $this->makeBlogSelectionForm(); d('$form: ' . $form); exit(Responder::makeErrorPage($form)); } else { d('User has one tumblr blog, using it now'); /** * Set flag to session indicating that user just * connected tumblr Account */ $this->Registry->Viewer['b_tm'] = true; $this->closeWindow(); } } catch (\OAuthException $e) { e('OAuthException: ' . $e->getMessage() . ' ' . \print_r($e, 1)); $err = '@@Something went wrong during authorization. Please try again later@@' . $e->getMessage(); throw new \Exception($err); } return $this; }
/** * Based on value of email address in the data received * from Google API * Login existing user or create a new account * and login the new user * */ protected function createOrUpdate() { $User = null; $this->email = \mb_strtolower($this->userInfo['email']); /** * @todo this can be refactored for php 5.4 * Search EMAILS collection * try to find user that has this email address */ $res = $this->Registry->Mongo->EMAILS->findOne(array(Schema::EMAIL => $this->email), array('i_uid' => true)); if (!empty($res) && !empty($res['i_uid'])) { d('found user id by email address. uid: ' . $res['i_uid']); $aUser = $this->Registry->Mongo->USERS->findOne(array(Schema::PRIMARY => $res['i_uid'])); $User = User::userFactory($this->Registry, $aUser); $this->updateUser($User); } /** * Was Not able to find user by search EMAILS collection * Search USERS collection by email address */ if (null === $User) { $a = $this->Registry->Mongo->USERS->findOne(array(Schema::EMAIL => $this->email)); if (!empty($a)) { d('found user id by email address. uid: ' . $a['_id']); $User = User::userFactory($this->Registry, $a); $this->updateUser($User); } } if (null === $User) { $User = $this->createUser(); } try { $this->processLogin($User); Cookie::sendLoginCookie($User->getUid(), $User->rs); $this->Registry->Dispatcher->post($this, 'onGoogleLogin'); $this->closeWindow(); } catch (\Lampcms\LoginException $e) { /** * re-throw as regular exception * so that it can be caught and shown in popup window */ e('Unable to process login: ' . $e->getMessage()); exit(\Lampcms\Responder::makeErrorPage($e->getMessage())); } }
try { include $lampcmsClasses . 'Controllers' . DIRECTORY_SEPARATOR . 'Logintwitter.php'; $o = new \Lampcms\Controllers\Logintwitter($Registry); header('Content-Type: text/html; charset=utf-8'); echo $o->getResult(); session_write_close(); fastcgi_finish_request(); } catch (\OutOfBoundsException $e) { session_write_close(); /** * Special case is OutOfBoundsException which * is our special way of saying exit(); but do it * gracefully - let it be caught here and then do nothing * This is better than using exit() because on some servers * exit may terminate the whole fastcgi process instead of just * stopping this one script */ $errMessage = trim($e->getMessage()); if (!empty($errMessage)) { echo '<div class="exit_error">' . $errMessage . '</div>'; d('Got exit signal from ' . $e->getTraceAsString()); } fastcgi_finish_request(); } catch (\Exception $e) { try { echo \Lampcms\Responder::makeErrorPage('<strong>Error:</strong> ' . \Lampcms\Exception::formatException($e)); } catch (Exception $e2) { echo \Lampcms\Responder::makeErrorPage('<strong>Exception:</strong> ' . $e2->getMessage() . "\nIn file:" . $e2->getFile() . "\nLine: " . $e2->getLine()); } } }
/** * Formats the exception, adding * additional exception data like backtrace * if running in debug mode * then adds the 'error' to a page * * @return void * * @param \Lampcms\Exception $le * * @throws \OutOfBoundsException * @throws \Exception|\OutOfBoundsException * @internal param object $e Exception object */ public function handleException(\Lampcms\Exception $le) { try { if ($le instanceof RedirectException) { \session_write_close(); $newUrl = $le->getMessage(); /** * If redirect url contains any URI placeholders * (like {_WEB_ROOT_} for example) * then use mapper callback function * to replace those placeholders */ if (\strstr($newUrl, '{_')) { $mapper = $this->Router->getCallback(); $newUrl = $mapper($newUrl); } /** * If a relative url then turn into * full url to comply with w3c standard that says * redirect headers must point to complete url */ if (0 !== \strncasecmp('http', $newUrl, 4)) { $newUrl = $this->Registry->Ini->SITE_URL . $newUrl; } header("Location: " . $newUrl, true, $le->getCode()); throw new \OutOfBoundsException(); } if ($le instanceof CaptchaLimitException) { d('Captcha limit reached.'); /** * @todo add ip to CAPTCHA_HACKS collection * */ } /** * In case of LampcmsAuthException * the value of 'c' attribute in exception * element will be set to "login" * indicating to template that this * is a 'must login' type of exception * and to render the login form * */ $class = $le instanceof AuthException ? 'login' : 'excsl'; /** * Special case: * the http error code can be * passed in exception as third argument * (in case where there are no second arg, * the second arg must be passed as null) */ if (201 < ($errCode = $le->getCode())) { $this->httpCode = (int) $errCode; } if ($le instanceof Lampcms404Exception) { $this->httpCode = 404; } /** * e() will also email error to developer * In case of Login and OutOfBoundsException we don't want * to email developers * We also don't want to email developers * in special types of exceptions that have * code set to -1 * which is a way to say * "This exception is not severe enough for email to be sent out" */ if ($errCode >= 0 && !$le instanceof Lampcms404Exception && !$le instanceof AuthException && !$le instanceof LoginException && !$le instanceof NoticeException && !$le instanceof MustLoginException && !$le instanceof \OutOfBoundsException) { e('Exception caught in: ' . $le->getFile() . ' on line: ' . $le->getLine() . ' ' . $le->getMessage() . ' trace: ' . $le->getTraceAsString()); } /** * * Exception::formatException will correctly * handle sending out JSON and exiting * if the request isAjax * */ $err = Exception::formatException($le, null, $this->Registry->Tr); /** * @todo if Login exception then present a login form! * */ $this->aPageVars['layoutID'] = 1; $this->aPageVars['body'] = \tplException::parse(array('message' => \nl2br($err), 'class' => $class, 'title' => '@@Alert@@')); } catch (\OutOfBoundsException $e) { throw $e; } catch (\Exception $e) { e('Exception object ' . $e->getMessage()); $err = Responder::makeErrorPage($le->getMessage() . ' in ' . $e->getFile()); echo $err; fastcgi_finish_request(); throw new \OutOfBoundsException(); } }
/** * Magic method * Must use try/catch here * because php turns uncaught exception in __toString * into a nasty error message * * @return string */ public function __toString() { try { return $this->getResult(); } catch (\Exception $e) { e('Exception in ' . __METHOD__ . ' ' . $e->getMessage()); return \Lampcms\Responder::makeErrorPage(Exception::formatException($e)); } }