Changeset View
Changeset View
Standalone View
Standalone View
src/aphront/configuration/AphrontDefaultApplicationConfiguration.php
<?php | <?php | ||||
/** | /** | ||||
* NOTE: Do not extend this! | * NOTE: Do not extend this! | ||||
* | * | ||||
* @concrete-extensible | * @concrete-extensible | ||||
*/ | */ | ||||
class AphrontDefaultApplicationConfiguration | class AphrontDefaultApplicationConfiguration | ||||
extends AphrontApplicationConfiguration { | extends AphrontApplicationConfiguration { | ||||
public function __construct() {} | |||||
public function getApplicationName() { | |||||
return 'aphront-default'; | |||||
} | |||||
/** | /** | ||||
* @phutil-external-symbol class PhabricatorStartup | * @phutil-external-symbol class PhabricatorStartup | ||||
*/ | */ | ||||
public function buildRequest() { | public function buildRequest() { | ||||
$parser = new PhutilQueryStringParser(); | $parser = new PhutilQueryStringParser(); | ||||
$data = array(); | $data = array(); | ||||
// If the request has "multipart/form-data" content, we can't use | // If the request has "multipart/form-data" content, we can't use | ||||
Show All 20 Lines | public function buildRequest() { | ||||
$request = new AphrontRequest($this->getHost(), $this->getPath()); | $request = new AphrontRequest($this->getHost(), $this->getPath()); | ||||
$request->setRequestData($data); | $request->setRequestData($data); | ||||
$request->setApplicationConfiguration($this); | $request->setApplicationConfiguration($this); | ||||
$request->setCookiePrefix($cookie_prefix); | $request->setCookiePrefix($cookie_prefix); | ||||
return $request; | return $request; | ||||
} | } | ||||
public function handleException(Exception $ex) { | |||||
$request = $this->getRequest(); | |||||
// For Conduit requests, return a Conduit response. | |||||
if ($request->isConduit()) { | |||||
$response = new ConduitAPIResponse(); | |||||
$response->setErrorCode(get_class($ex)); | |||||
$response->setErrorInfo($ex->getMessage()); | |||||
return id(new AphrontJSONResponse()) | |||||
->setAddJSONShield(false) | |||||
->setContent($response->toDictionary()); | |||||
} | |||||
// For non-workflow requests, return a Ajax response. | |||||
if ($request->isAjax() && !$request->isWorkflow()) { | |||||
// Log these; they don't get shown on the client and can be difficult | |||||
// to debug. | |||||
phlog($ex); | |||||
$response = new AphrontAjaxResponse(); | |||||
$response->setError( | |||||
array( | |||||
'code' => get_class($ex), | |||||
'info' => $ex->getMessage(), | |||||
)); | |||||
return $response; | |||||
} | |||||
$user = $request->getUser(); | |||||
if (!$user) { | |||||
// If we hit an exception very early, we won't have a user. | |||||
$user = new PhabricatorUser(); | |||||
} | |||||
if ($ex instanceof PhabricatorSystemActionRateLimitException) { | |||||
$dialog = id(new AphrontDialogView()) | |||||
->setTitle(pht('Slow Down!')) | |||||
->setUser($user) | |||||
->setErrors(array(pht('You are being rate limited.'))) | |||||
->appendParagraph($ex->getMessage()) | |||||
->appendParagraph($ex->getRateExplanation()) | |||||
->addCancelButton('/', pht('Okaaaaaaaaaaaaaay...')); | |||||
$response = new AphrontDialogResponse(); | |||||
$response->setDialog($dialog); | |||||
return $response; | |||||
} | |||||
if ($ex instanceof PhabricatorAuthHighSecurityRequiredException) { | |||||
$form = id(new PhabricatorAuthSessionEngine())->renderHighSecurityForm( | |||||
$ex->getFactors(), | |||||
$ex->getFactorValidationResults(), | |||||
$user, | |||||
$request); | |||||
$dialog = id(new AphrontDialogView()) | |||||
->setUser($user) | |||||
->setTitle(pht('Entering High Security')) | |||||
->setShortTitle(pht('Security Checkpoint')) | |||||
->setWidth(AphrontDialogView::WIDTH_FORM) | |||||
->addHiddenInput(AphrontRequest::TYPE_HISEC, true) | |||||
->setErrors( | |||||
array( | |||||
pht( | |||||
'You are taking an action which requires you to enter '. | |||||
'high security.'), | |||||
)) | |||||
->appendParagraph( | |||||
pht( | |||||
'High security mode helps protect your account from security '. | |||||
'threats, like session theft or someone messing with your stuff '. | |||||
'while you\'re grabbing a coffee. To enter high security mode, '. | |||||
'confirm your credentials.')) | |||||
->appendChild($form->buildLayoutView()) | |||||
->appendParagraph( | |||||
pht( | |||||
'Your account will remain in high security mode for a short '. | |||||
'period of time. When you are finished taking sensitive '. | |||||
'actions, you should leave high security.')) | |||||
->setSubmitURI($request->getPath()) | |||||
->addCancelButton($ex->getCancelURI()) | |||||
->addSubmitButton(pht('Enter High Security')); | |||||
$request_parameters = $request->getPassthroughRequestParameters( | |||||
$respect_quicksand = true); | |||||
foreach ($request_parameters as $key => $value) { | |||||
$dialog->addHiddenInput($key, $value); | |||||
} | |||||
$response = new AphrontDialogResponse(); | |||||
$response->setDialog($dialog); | |||||
return $response; | |||||
} | |||||
if ($ex instanceof PhabricatorPolicyException) { | |||||
if (!$user->isLoggedIn()) { | |||||
// If the user isn't logged in, just give them a login form. This is | |||||
// probably a generally more useful response than a policy dialog that | |||||
// they have to click through to get a login form. | |||||
// | |||||
// Possibly we should add a header here like "you need to login to see | |||||
// the thing you are trying to look at". | |||||
$login_controller = new PhabricatorAuthStartController(); | |||||
$login_controller->setRequest($request); | |||||
$auth_app_class = 'PhabricatorAuthApplication'; | |||||
$auth_app = PhabricatorApplication::getByClass($auth_app_class); | |||||
$login_controller->setCurrentApplication($auth_app); | |||||
return $login_controller->handleRequest($request); | |||||
} | |||||
$content = array( | |||||
phutil_tag( | |||||
'div', | |||||
array( | |||||
'class' => 'aphront-policy-rejection', | |||||
), | |||||
$ex->getRejection()), | |||||
); | |||||
$list = null; | |||||
if ($ex->getCapabilityName()) { | |||||
$list = $ex->getMoreInfo(); | |||||
foreach ($list as $key => $item) { | |||||
$list[$key] = $item; | |||||
} | |||||
$content[] = phutil_tag( | |||||
'div', | |||||
array( | |||||
'class' => 'aphront-capability-details', | |||||
), | |||||
pht('Users with the "%s" capability:', $ex->getCapabilityName())); | |||||
} | |||||
$dialog = id(new AphrontDialogView()) | |||||
->setTitle($ex->getTitle()) | |||||
->setClass('aphront-access-dialog') | |||||
->setUser($user) | |||||
->appendChild($content); | |||||
if ($list) { | |||||
$dialog->appendList($list); | |||||
} | |||||
if ($this->getRequest()->isAjax()) { | |||||
$dialog->addCancelButton('/', pht('Close')); | |||||
} else { | |||||
$dialog->addCancelButton('/', pht('OK')); | |||||
} | |||||
$response = new AphrontDialogResponse(); | |||||
$response->setDialog($dialog); | |||||
return $response; | |||||
} | |||||
// Always log the unhandled exception. | |||||
phlog($ex); | |||||
$class = get_class($ex); | |||||
$message = $ex->getMessage(); | |||||
if ($ex instanceof AphrontSchemaQueryException) { | |||||
$message .= "\n\n".pht( | |||||
"NOTE: This usually indicates that the MySQL schema has not been ". | |||||
"properly upgraded. Run '%s' to ensure your schema is up to date.", | |||||
'bin/storage upgrade'); | |||||
} | |||||
if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) { | |||||
$trace = id(new AphrontStackTraceView()) | |||||
->setUser($user) | |||||
->setTrace($ex->getTrace()); | |||||
} else { | |||||
$trace = null; | |||||
} | |||||
$content = phutil_tag( | |||||
'div', | |||||
array('class' => 'aphront-unhandled-exception'), | |||||
array( | |||||
phutil_tag('div', array('class' => 'exception-message'), $message), | |||||
$trace, | |||||
)); | |||||
$dialog = new AphrontDialogView(); | |||||
$dialog | |||||
->setTitle(pht('Unhandled Exception ("%s")', $class)) | |||||
->setClass('aphront-exception-dialog') | |||||
->setUser($user) | |||||
->appendChild($content); | |||||
if ($this->getRequest()->isAjax()) { | |||||
$dialog->addCancelButton('/', pht('Close')); | |||||
} | |||||
$response = new AphrontDialogResponse(); | |||||
$response->setDialog($dialog); | |||||
$response->setHTTPResponseCode(500); | |||||
return $response; | |||||
} | |||||
public function build404Controller() { | public function build404Controller() { | ||||
return array(new Phabricator404Controller(), array()); | return array(new Phabricator404Controller(), array()); | ||||
} | } | ||||
public function buildRedirectController($uri, $external) { | public function buildRedirectController($uri, $external) { | ||||
return array( | return array( | ||||
new PhabricatorRedirectController(), | new PhabricatorRedirectController(), | ||||
array( | array( | ||||
'uri' => $uri, | 'uri' => $uri, | ||||
'external' => $external, | 'external' => $external, | ||||
), | ), | ||||
); | ); | ||||
} | } | ||||
} | } |