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, | ||||
| ), | ), | ||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||