diff --git a/conf/default.conf.php b/conf/default.conf.php index bbdfae0187..5caf71509c 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -200,15 +200,6 @@ return array( 'github.application-secret' => null, - // Github Authorize URI. You don't need to change this unless Github changes - // its API in the future (this is unlikely). - 'github.authorize-uri' => 'https://github.com/login/oauth/authorize', - - // Github Access Token URI. You don't need to change this unless Github - // changes its API in the future (this is unlikely). - 'github.access-token-uri' => 'https://github.com/login/oauth/access_token', - - // -- Recaptcha ------------------------------------------------------------- // // Is Recaptcha enabled? If disabled, captchas will not appear. @@ -247,11 +238,18 @@ return array( // // The keys in this array are viewable mime types; the values are the mime // types they will be delivered as when they are viewed in the browser. - 'files.viewable-mime-types' => array( + 'files.viewable-mime-types' => array( 'image/jpeg' => 'image/jpeg', 'image/jpg' => 'image/jpg', 'image/png' => 'image/png', 'text/plain' => 'text/plain; charset=utf-8', ), +// -- Customization --------------------------------------------------------- // + + // Paths to additional phutil libraries to load. + 'load-libraries' => array(), + + 'aphront.default-application-configuration-class' => + 'AphrontDefaultApplicationConfiguration', ); diff --git a/src/aphront/console/plugin/config/DarkConsoleConfigPlugin.php b/src/aphront/console/plugin/config/DarkConsoleConfigPlugin.php index 853e0c4ef1..bd67c45f2b 100755 --- a/src/aphront/console/plugin/config/DarkConsoleConfigPlugin.php +++ b/src/aphront/console/plugin/config/DarkConsoleConfigPlugin.php @@ -27,19 +27,50 @@ class DarkConsoleConfigPlugin extends DarkConsolePlugin { } public function generateData() { - return PhabricatorEnv::getAllConfigKeys(); + $lib_data = array(); + foreach (PhutilBootloader::getInstance()->getAllLibraries() as $lib) { + $lib_data[$lib] = phutil_get_library_root($lib); + } + return array( + 'config' => PhabricatorEnv::getAllConfigKeys(), + 'libraries' => $lib_data, + ); } public function render() { $data = $this->getData(); - ksort($data); - + + $lib_data = $data['libraries']; + + $lib_rows = array(); + foreach ($lib_data as $key => $value) { + $lib_rows[] = array( + phutil_escape_html($key), + phutil_escape_html($value), + ); + } + + $lib_table = new AphrontTableView($lib_rows); + $lib_table->setHeaders( + array( + 'Library', + 'Loaded From', + )); + $lib_table->setColumnClasses( + array( + 'header', + 'wide wrap', + )); + + $config_data = $data['config']; + ksort($config_data); + $mask = PhabricatorEnv::getEnvConfig('darkconsole.config-mask'); $mask = array_fill_keys($mask, true); - + $rows = array(); - foreach ($data as $key => $value) { + foreach ($config_data as $key => $value) { if (empty($mask[$key])) { $display_value = is_array($value) ? json_encode($value) : $value; $display_value = phutil_escape_html($display_value); @@ -64,6 +95,6 @@ class DarkConsoleConfigPlugin extends DarkConsolePlugin { 'wide wrap', )); - return $table->render(); + return $lib_table->render().$table->render(); } } diff --git a/src/aphront/console/plugin/config/__init__.php b/src/aphront/console/plugin/config/__init__.php index 3d244d156e..3a5d4625ac 100644 --- a/src/aphront/console/plugin/config/__init__.php +++ b/src/aphront/console/plugin/config/__init__.php @@ -11,6 +11,7 @@ phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'view/control/table'); phutil_require_module('phutil', 'markup'); +phutil_require_module('phutil', 'moduleutils'); phutil_require_source('DarkConsoleConfigPlugin.php'); diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 4047a6c7c0..0ef8fd2786 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -22,12 +22,16 @@ class AphrontDefaultApplicationConfiguration extends AphrontApplicationConfiguration { + public function __construct() { + + } + public function getApplicationName() { return 'aphront-default'; } public function getURIMap() { - return array( + return $this->getResourceURIMapRules() + array( '/' => array( '$' => 'PhabricatorDirectoryMainController', ), @@ -100,11 +104,6 @@ class AphrontDefaultApplicationConfiguration => 'DifferentialSubscribeController', ), - '/res/' => array( - '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?:css|js))$' - => 'CelerityResourceController', - ), - '/typeahead/' => array( 'common/(?P\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', @@ -124,11 +123,8 @@ class AphrontDefaultApplicationConfiguration 'email/$' => 'PhabricatorEmailLoginController', 'etoken/(?P\w+)/$' => 'PhabricatorEmailTokenController', ), + '/logout/$' => 'PhabricatorLogoutController', - '/facebook-auth/' => array( - '$' => 'PhabricatorFacebookAuthController', - 'diagnose/$' => 'PhabricatorFacebookAuthDiagnosticsController', - ), '/oauth/' => array( '(?Pgithub|facebook)/' => array( @@ -184,7 +180,17 @@ class AphrontDefaultApplicationConfiguration 'view/(?P\d+)/$' => 'PhabricatorProjectProfileController', 'affiliation/(?P\d+)/$' => 'PhabricatorProjectAffiliationEditController', - ) + ), + + ); + } + + protected function getResourceURIMapRules() { + return array( + '/res/' => array( + '(?Ppkg/)?(?P[a-f0-9]{8})/(?P.+\.(?:css|js))$' + => 'CelerityResourceController', + ), ); } diff --git a/webroot/index.php b/webroot/index.php index e9a74d221c..4bb283b4c1 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -18,21 +18,28 @@ error_reporting(E_ALL | E_STRICT); -$env = getenv('PHABRICATOR_ENV'); +$env = getenv('PHABRICATOR_ENV'); // Apache if (!$env) { - header('Content-Type: text/plain'); - die( - "CONFIG ERROR: ". + if (isset($_SERVER['PHABRICATOR_ENV'])) { + $env = $_SERVER['PHABRICATOR_ENV']; // HipHop + } +} + +if (!$env) { + phabricator_fatal_config_error( "The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ". "your httpd.conf to include 'SetEnv PHABRICATOR_ENV ', where '' ". "is one of 'development', 'production', or a custom environment."); } if (!function_exists('mysql_connect')) { - header('Content-Type: text/plain'); - die( - "CONFIG ERROR: ". - "the PHP MySQL extension is not installed. This extension is required."); + phabricator_fatal_config_error( + "The PHP MySQL extension is not installed. This extension is required."); +} + +if (!isset($_REQUEST['__path__'])) { + phabricator_fatal_config_error( + "__path__ is not set. Your rewrite rules are not configured correctly."); } require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; @@ -52,18 +59,20 @@ phutil_require_module('phabricator', 'aphront/console/plugin/errorlog/api'); set_error_handler(array('DarkConsoleErrorLogPluginAPI', 'handleError')); set_exception_handler(array('DarkConsoleErrorLogPluginAPI', 'handleException')); +foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) { + phutil_load_library($library); +} + + $host = $_SERVER['HTTP_HOST']; $path = $_REQUEST['__path__']; -// Based on the host and path, choose which application should serve the -// request. The default is the Aphront demo, but you'll want to replace this -// with whichever other applications you're running. - switch ($host) { default: - phutil_require_module('phutil', 'autoload'); - phutil_autoload_class('AphrontDefaultApplicationConfiguration'); - $application = new AphrontDefaultApplicationConfiguration(); + $config_key = 'aphront.default-application-configuration-class'; + $config_class = PhabricatorEnv::getEnvConfig($config_key); + PhutilSymbolLoader::loadClass($config_class); + $application = newv($config_class, array()); break; } @@ -103,6 +112,7 @@ foreach ($headers as $header) { header("{$header}: {$value}"); } +// TODO: This shouldn't be possible in a production-configured environment. if (isset($_REQUEST['__profile__']) && ($_REQUEST['__profile__'] == 'all')) { $profile = DarkConsoleXHProfPluginAPI::stopProfiler(); @@ -133,7 +143,7 @@ function setup_aphront_basics() { $aphront_root = dirname(dirname(__FILE__)); $libraries_root = dirname($aphront_root); - ini_set('include_path', ini_get('include_path').':'.$libraries_root.'/'); + ini_set('include_path', $libraries_root.':'.ini_get('include_path')); @include_once 'libphutil/src/__phutil_library_init__.php'; if (!@constant('__LIBPHUTIL__')) { echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ". @@ -141,14 +151,24 @@ function setup_aphront_basics() { exit(1); } - if (!ini_get('date.timezone')) { - date_default_timezone_set('America/Los_Angeles'); - } - - phutil_load_library($libraries_root.'/arcanist/src'); + // Load Phabricator itself using the absolute path, so we never end up doing + // anything surprising (loading index.php and libraries from different + // directories). phutil_load_library($aphront_root.'/src'); + phutil_load_library('arcanist/src'); } function __autoload($class_name) { PhutilSymbolLoader::loadClass($class_name); } + +function phabricator_fatal_config_error($msg) { + header('Content-Type: text/plain', $replace = true, $http_error = 500); + $error = "CONFIG ERROR: ".$msg."\n"; + + error_log($error); + echo $error; + + die(); +} +