diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f30a40224d..7647a8ef85 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,277 +1,284 @@ array( 'Aphront404Response' => 'aphront/response/404', 'AphrontAjaxResponse' => 'aphront/response/ajax', 'AphrontApplicationConfiguration' => 'aphront/applicationconfiguration', 'AphrontController' => 'aphront/controller', 'AphrontDatabaseConnection' => 'storage/connection/base', 'AphrontDefaultApplicationConfiguration' => 'aphront/default/configuration', 'AphrontDefaultApplicationController' => 'aphront/default/controller', 'AphrontDialogResponse' => 'aphront/response/dialog', 'AphrontDialogView' => 'view/dialog', 'AphrontErrorView' => 'view/form/error', + 'AphrontException' => 'aphront/exception/base', 'AphrontFileResponse' => 'aphront/response/file', 'AphrontFormCheckboxControl' => 'view/form/control/checkbox', 'AphrontFormControl' => 'view/form/control/base', 'AphrontFormFileControl' => 'view/form/control/file', 'AphrontFormMarkupControl' => 'view/form/control/markup', 'AphrontFormSelectControl' => 'view/form/control/select', 'AphrontFormStaticControl' => 'view/form/control/static', 'AphrontFormSubmitControl' => 'view/form/control/submit', 'AphrontFormTextAreaControl' => 'view/form/control/textarea', 'AphrontFormTextControl' => 'view/form/control/text', 'AphrontFormTokenizerControl' => 'view/form/control/tokenizer', 'AphrontFormView' => 'view/form/base', 'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql', 'AphrontNullView' => 'view/null', 'AphrontPageView' => 'view/page/base', 'AphrontPanelView' => 'view/layout/panel', 'AphrontQueryConnectionException' => 'storage/exception/connection', 'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost', 'AphrontQueryCountException' => 'storage/exception/count', 'AphrontQueryException' => 'storage/exception/base', 'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing', 'AphrontQueryParameterException' => 'storage/exception/parameter', 'AphrontQueryRecoverableException' => 'storage/exception/recoverable', + 'AphrontRedirectException' => 'aphront/exception/redirect', 'AphrontRedirectResponse' => 'aphront/response/redirect', 'AphrontRequest' => 'aphront/request', 'AphrontResponse' => 'aphront/response/base', 'AphrontSideNavView' => 'view/layout/sidenav', 'AphrontTableView' => 'view/control/table', 'AphrontURIMapper' => 'aphront/mapper', 'AphrontView' => 'view/base', 'AphrontWebpageResponse' => 'aphront/response/webpage', 'CelerityAPI' => 'infratructure/celerity/api', 'CelerityResourceController' => 'infratructure/celerity/controller', 'CelerityResourceMap' => 'infratructure/celerity/map', 'CelerityStaticResourceResponse' => 'infratructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', 'ConduitAPIRequest' => 'applications/conduit/protocol/request', 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', 'ConduitAPI_differential_creatediff_Method' => 'applications/conduit/method/differential/creatediff', 'ConduitAPI_differential_setdiffproperty_Method' => 'applications/conduit/method/differential/setdiffproperty', 'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload', 'ConduitAPI_user_find_Method' => 'applications/conduit/method/user/find', 'ConduitException' => 'applications/conduit/protocol/exception', 'DifferentialAction' => 'applications/differential/constants/action', 'DifferentialChangeType' => 'applications/differential/constants/changetype', 'DifferentialChangeset' => 'applications/differential/storage/changeset', 'DifferentialChangesetDetailView' => 'applications/differential/view/changesetdetailview', 'DifferentialChangesetListView' => 'applications/differential/view/changesetlistview', 'DifferentialChangesetParser' => 'applications/differential/parser/changeset', 'DifferentialChangesetViewController' => 'applications/differential/controller/changesetview', 'DifferentialController' => 'applications/differential/controller/base', 'DifferentialDAO' => 'applications/differential/storage/base', 'DifferentialDiff' => 'applications/differential/storage/diff', 'DifferentialDiffProperty' => 'applications/differential/storage/diffproperty', 'DifferentialDiffTableOfContentsView' => 'applications/differential/view/difftableofcontents', 'DifferentialDiffViewController' => 'applications/differential/controller/diffview', 'DifferentialHunk' => 'applications/differential/storage/hunk', 'DifferentialLintStatus' => 'applications/differential/constants/lintstatus', 'DifferentialRevision' => 'applications/differential/storage/revision', 'DifferentialRevisionControlSystem' => 'applications/differential/constants/revisioncontrolsystem', 'DifferentialRevisionEditController' => 'applications/differential/controller/revisionedit', 'DifferentialRevisionListController' => 'applications/differential/controller/revisionlist', 'DifferentialRevisionStatus' => 'applications/differential/constants/revisionstatus', 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 'Javelin' => 'infratructure/javelin/api', 'LiskDAO' => 'storage/lisk/dao', + 'PhabricatorAuthController' => 'applications/auth/controlller/base', 'PhabricatorConduitAPIController' => 'applications/conduit/controller/api', 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog', 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console', 'PhabricatorConduitController' => 'applications/conduit/controller/base', 'PhabricatorConduitDAO' => 'applications/conduit/storage/base', 'PhabricatorConduitLogController' => 'applications/conduit/controller/log', 'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog', 'PhabricatorController' => 'applications/base/controller/base', 'PhabricatorDirectoryCategory' => 'applications/directory/storage/category', 'PhabricatorDirectoryCategoryDeleteController' => 'applications/directory/controller/categorydelete', 'PhabricatorDirectoryCategoryEditController' => 'applications/directory/controller/categoryedit', 'PhabricatorDirectoryCategoryListController' => 'applications/directory/controller/categorylist', 'PhabricatorDirectoryController' => 'applications/directory/controller/base', 'PhabricatorDirectoryDAO' => 'applications/directory/storage/base', 'PhabricatorDirectoryItem' => 'applications/directory/storage/item', 'PhabricatorDirectoryItemDeleteController' => 'applications/directory/controller/itemdelete', 'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit', 'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist', 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 'PhabricatorFile' => 'applications/files/storage/file', 'PhabricatorFileController' => 'applications/files/controller/base', 'PhabricatorFileDAO' => 'applications/files/storage/base', 'PhabricatorFileListController' => 'applications/files/controller/list', 'PhabricatorFileStorageBlob' => 'applications/files/storage/storageblob', 'PhabricatorFileURI' => 'applications/files/uri', 'PhabricatorFileUploadController' => 'applications/files/controller/upload', 'PhabricatorFileViewController' => 'applications/files/controller/view', 'PhabricatorLiskDAO' => 'applications/base/storage/lisk', + 'PhabricatorLoginController' => 'applications/auth/controlller/login', 'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/base', 'PhabricatorMetaMTADAO' => 'applications/metamta/storage/base', 'PhabricatorMetaMTAListController' => 'applications/metamta/controller/list', 'PhabricatorMetaMTAMail' => 'applications/metamta/storage/mail', 'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/mailinglist', 'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/mailinglistedit', 'PhabricatorMetaMTAMailingListsController' => 'applications/metamta/controller/mailinglists', 'PhabricatorMetaMTASendController' => 'applications/metamta/controller/send', 'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view', 'PhabricatorObjectHandle' => 'applications/phid/handle', 'PhabricatorObjectHandleData' => 'applications/phid/handle/data', 'PhabricatorPHID' => 'applications/phid/storage/phid', 'PhabricatorPHIDAllocateController' => 'applications/phid/controller/allocate', 'PhabricatorPHIDController' => 'applications/phid/controller/base', 'PhabricatorPHIDDAO' => 'applications/phid/storage/base', 'PhabricatorPHIDListController' => 'applications/phid/controller/list', 'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup', 'PhabricatorPHIDType' => 'applications/phid/storage/type', 'PhabricatorPHIDTypeEditController' => 'applications/phid/controller/typeedit', 'PhabricatorPHIDTypeListController' => 'applications/phid/controller/typelist', 'PhabricatorPeopleController' => 'applications/people/controller/base', 'PhabricatorPeopleEditController' => 'applications/people/controller/edit', 'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleProfileController' => 'applications/people/controller/profile', 'PhabricatorStandardPageView' => 'view/page/standard', 'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common', 'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base', 'PhabricatorUser' => 'applications/people/storage/user', 'PhabricatorUserDAO' => 'applications/people/storage/base', ), 'function' => array( '_qsprintf_check_scalar_type' => 'storage/qsprintf', '_qsprintf_check_type' => 'storage/qsprintf', 'celerity_generate_unique_node_id' => 'infratructure/celerity/api', 'celerity_register_resource_map' => 'infratructure/celerity/map', 'javelin_render_tag' => 'infratructure/javelin/markup', 'qsprintf' => 'storage/qsprintf', 'queryfx' => 'storage/queryfx', 'queryfx_all' => 'storage/queryfx', 'queryfx_one' => 'storage/queryfx', 'require_celerity_resource' => 'infratructure/celerity/api', 'vqsprintf' => 'storage/qsprintf', 'vqueryfx' => 'storage/queryfx', 'xsprintf_query' => 'storage/qsprintf', ), 'requires_class' => array( 'Aphront404Response' => 'AphrontResponse', 'AphrontAjaxResponse' => 'AphrontResponse', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDefaultApplicationController' => 'AphrontController', 'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogView' => 'AphrontView', 'AphrontErrorView' => 'AphrontView', 'AphrontFileResponse' => 'AphrontResponse', 'AphrontFormCheckboxControl' => 'AphrontFormControl', 'AphrontFormControl' => 'AphrontView', 'AphrontFormFileControl' => 'AphrontFormControl', 'AphrontFormMarkupControl' => 'AphrontFormControl', 'AphrontFormSelectControl' => 'AphrontFormControl', 'AphrontFormStaticControl' => 'AphrontFormControl', 'AphrontFormSubmitControl' => 'AphrontFormControl', 'AphrontFormTextAreaControl' => 'AphrontFormControl', 'AphrontFormTextControl' => 'AphrontFormControl', 'AphrontFormTokenizerControl' => 'AphrontFormControl', 'AphrontFormView' => 'AphrontView', 'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection', 'AphrontNullView' => 'AphrontView', 'AphrontPageView' => 'AphrontView', 'AphrontPanelView' => 'AphrontView', 'AphrontQueryConnectionException' => 'AphrontQueryException', 'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException', 'AphrontQueryCountException' => 'AphrontQueryException', 'AphrontQueryObjectMissingException' => 'AphrontQueryException', 'AphrontQueryParameterException' => 'AphrontQueryException', 'AphrontQueryRecoverableException' => 'AphrontQueryException', + 'AphrontRedirectException' => 'AphrontException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontSideNavView' => 'AphrontView', 'AphrontTableView' => 'AphrontView', 'AphrontWebpageResponse' => 'AphrontResponse', 'CelerityResourceController' => 'AphrontController', 'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod', 'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod', 'ConduitAPI_user_find_Method' => 'ConduitAPIMethod', 'DifferentialChangeset' => 'DifferentialDAO', 'DifferentialChangesetDetailView' => 'AphrontView', 'DifferentialChangesetListView' => 'AphrontView', 'DifferentialChangesetViewController' => 'DifferentialController', 'DifferentialController' => 'PhabricatorController', 'DifferentialDAO' => 'PhabricatorLiskDAO', 'DifferentialDiff' => 'DifferentialDAO', 'DifferentialDiffProperty' => 'DifferentialDAO', 'DifferentialDiffTableOfContentsView' => 'AphrontView', 'DifferentialDiffViewController' => 'DifferentialController', 'DifferentialHunk' => 'DifferentialDAO', 'DifferentialRevision' => 'DifferentialDAO', 'DifferentialRevisionEditController' => 'DifferentialController', 'DifferentialRevisionListController' => 'DifferentialController', + 'PhabricatorAuthController' => 'PhabricatorController', 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 'PhabricatorConduitController' => 'PhabricatorController', 'PhabricatorConduitDAO' => 'PhabricatorLiskDAO', 'PhabricatorConduitLogController' => 'PhabricatorConduitController', 'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO', 'PhabricatorController' => 'AphrontController', 'PhabricatorDirectoryCategory' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryCategoryDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryCategoryListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryController' => 'PhabricatorController', 'PhabricatorDirectoryDAO' => 'PhabricatorLiskDAO', 'PhabricatorDirectoryItem' => 'PhabricatorDirectoryDAO', 'PhabricatorDirectoryItemDeleteController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController', 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 'PhabricatorFile' => 'PhabricatorFileDAO', 'PhabricatorFileController' => 'PhabricatorController', 'PhabricatorFileDAO' => 'PhabricatorLiskDAO', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileUploadController' => 'PhabricatorFileController', 'PhabricatorFileViewController' => 'PhabricatorFileController', 'PhabricatorLiskDAO' => 'LiskDAO', + 'PhabricatorLoginController' => 'PhabricatorAuthController', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO', 'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAMailingListsController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController', 'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController', 'PhabricatorPHID' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDAllocateController' => 'PhabricatorPHIDController', 'PhabricatorPHIDController' => 'PhabricatorController', 'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO', 'PhabricatorPHIDListController' => 'PhabricatorPHIDController', 'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController', 'PhabricatorPHIDType' => 'PhabricatorPHIDDAO', 'PhabricatorPHIDTypeEditController' => 'PhabricatorPHIDController', 'PhabricatorPHIDTypeListController' => 'PhabricatorPHIDController', 'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController', 'PhabricatorStandardPageView' => 'AphrontPageView', 'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController', 'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController', 'PhabricatorUser' => 'PhabricatorUserDAO', 'PhabricatorUserDAO' => 'PhabricatorLiskDAO', ), 'requires_interface' => array( ), )); diff --git a/src/aphront/controller/AphrontController.php b/src/aphront/controller/AphrontController.php index ea55eda1f8..0ba389fd05 100644 --- a/src/aphront/controller/AphrontController.php +++ b/src/aphront/controller/AphrontController.php @@ -1,40 +1,44 @@ request = $request; } final public function getRequest() { return $this->request; } } diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 977aa14cea..2cbc9e30f8 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -1,154 +1,156 @@ array( '$' => 'RepositoryListController', 'new/$' => 'RepositoryEditController', 'edit/(?\d+)/$' => 'RepositoryEditController', 'delete/(?\d+)/$' => 'RepositoryDeleteController', ), '/' => array( '$' => 'PhabricatorDirectoryMainController', ), '/directory/' => array( 'item/$' => 'PhabricatorDirectoryItemListController', 'item/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryItemEditController', 'item/delete/(?\d+)/' => 'PhabricatorDirectoryItemDeleteController', 'category/$' => 'PhabricatorDirectoryCategoryListController', 'category/edit/(?:(?\d+)/)?$' => 'PhabricatorDirectoryCategoryEditController', 'category/delete/(?\d+)/' => 'PhabricatorDirectoryCategoryDeleteController', ), '/file/' => array( '$' => 'PhabricatorFileListController', 'upload/$' => 'PhabricatorFileUploadController', '(?info)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?view)/(?[^/]+)/' => 'PhabricatorFileViewController', '(?download)/(?[^/]+)/' => 'PhabricatorFileViewController', ), '/phid/' => array( '$' => 'PhabricatorPHIDLookupController', 'list/$' => 'PhabricatorPHIDListController', 'type/$' => 'PhabricatorPHIDTypeListController', 'type/edit/(?:(?\d+)/)?$' => 'PhabricatorPHIDTypeEditController', 'new/$' => 'PhabricatorPHIDAllocateController', ), '/people/' => array( '$' => 'PhabricatorPeopleListController', 'edit/(?:(?\w+)/)?$' => 'PhabricatorPeopleEditController', ), '/p/(?\w+)/$' => 'PhabricatorPeopleProfileController', '/conduit/' => array( '$' => 'PhabricatorConduitConsoleController', 'method/(?[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', ), '/api/(?[^/]+)$' => 'PhabricatorConduitAPIController', '/differential/' => array( '$' => 'DifferentialRevisionListController', 'diff/(?\d+)/$' => 'DifferentialDiffViewController', 'changeset/(?\d+)/$' => 'DifferentialChangesetViewController', 'revision/edit/(?:(?\d+)/)?$' => 'DifferentialRevisionEditController', ), '/res/' => array( '(?[a-f0-9]{8})/(?.+\.(?:css|js))$' => 'CelerityResourceController', ), '/typeahead/' => array( 'common/(?\w+)/$' => 'PhabricatorTypeaheadCommonDatasourceController', ), '/mail/' => array( '$' => 'PhabricatorMetaMTAListController', 'send/$' => 'PhabricatorMetaMTASendController', 'view/(?\d+)/$' => 'PhabricatorMetaMTAViewController', 'lists/$' => 'PhabricatorMetaMTAMailingListsController', 'lists/edit/(?:(?\d+)/)?$' => 'PhabricatorMetaMTAMailingListEditController', ), + + '/login/' => 'PhabricatorLoginController', ); } public function buildRequest() { $request = new AphrontRequest($this->getHost(), $this->getPath()); $request->setRequestData($_GET + $_POST); return $request; } public function handleException(Exception $ex) { $class = phutil_escape_html(get_class($ex)); $message = phutil_escape_html($ex->getMessage()); $content = '
'. '

Unhandled Exception "'.$class.'": '.$message.'

'. ''.phutil_escape_html((string)$ex).''. '
'; $view = new PhabricatorStandardPageView(); $view->appendChild($content); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } public function willSendResponse(AphrontResponse $response) { $request = $this->getRequest(); if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $view = new PhabricatorStandardPageView(); $view->appendChild( '
'. $response->buildResponseString(). '
'); $response = new AphrontWebpageResponse(); $response->setContent($view->render()); return $response; } } return $response; } } diff --git a/src/applications/base/controller/base/PhabricatorController.php b/src/aphront/exception/base/AphrontException.php similarity index 65% copy from src/applications/base/controller/base/PhabricatorController.php copy to src/aphront/exception/base/AphrontException.php index 320c99788d..cfe38e6cf6 100644 --- a/src/applications/base/controller/base/PhabricatorController.php +++ b/src/aphront/exception/base/AphrontException.php @@ -1,29 +1,21 @@ appendChild($view); - $response = new AphrontWebpageResponse(); - $response->setContent($page->render()); - return $response; - } +class AphrontException extends Exception { } diff --git a/src/aphront/request/__init__.php b/src/aphront/exception/base/__init__.php similarity index 69% copy from src/aphront/request/__init__.php copy to src/aphront/exception/base/__init__.php index 3b8c8f9a1d..79f57e73ca 100644 --- a/src/aphront/request/__init__.php +++ b/src/aphront/exception/base/__init__.php @@ -1,10 +1,10 @@ appendChild($view); - $response = new AphrontWebpageResponse(); - $response->setContent($page->render()); - return $response; + private $uri; + + public function __construct($uri) { + $this->uri = $uri; + } + + public function getURI() { + return $this->uri; } } diff --git a/src/aphront/exception/redirect/__init__.php b/src/aphront/exception/redirect/__init__.php new file mode 100644 index 0000000000..0b69311903 --- /dev/null +++ b/src/aphront/exception/redirect/__init__.php @@ -0,0 +1,12 @@ +host = $host; $this->path = $path; } final public function setRequestData(array $request_data) { $this->requestData = $request_data; return $this; } final public function getPath() { return $this->path; } final public function getHost() { return $this->host; } final public function getInt($name, $default = null) { if (isset($this->requestData[$name])) { return (int)$this->requestData[$name]; } else { return $default; } } final public function getStr($name, $default = null) { if (isset($this->requestData[$name])) { return (string)$this->requestData[$name]; } else { return $default; } } final public function getArr($name, $default = array()) { if (isset($this->requestData[$name]) && is_array($this->requestData[$name])) { return $this->requestData[$name]; } else { return $default; } } final public function getExists($name) { return array_key_exists($name, $this->requestData); } final public function isHTTPPost() { return ($_SERVER['REQUEST_METHOD'] == 'POST'); } final public function isAjax() { return $this->getExists(self::TYPE_AJAX); } final public function isFormPost() { return $this->getExists(self::TYPE_FORM) && $this->isHTTPPost(); } + final public function getCookie($name, $default = null) { + return idx($_COOKIE, $name, $default); + } + + final public function clearCookie($name) { + $this->setCookie($name, '', time() - (60 * 60 * 24 * 30)); + } + + final public function setCookie($name, $value, $expire = null) { + if ($expire === null) { + $expire = time() + (60 * 60 * 24 * 365 * 5); + } + setcookie( + $name, + $value, + $expire, + $path = '/', + $domain = '', + $secure = false, + $http_only = true); + } + + final public function setUser($user) { + $this->user = $user; + return $this; + } + + final public function getUser() { + return $this->user; + } + + + } diff --git a/src/aphront/request/__init__.php b/src/aphront/request/__init__.php index 3b8c8f9a1d..a1f61c228e 100644 --- a/src/aphront/request/__init__.php +++ b/src/aphront/request/__init__.php @@ -1,10 +1,12 @@ buildStandardPageView(); - $page->setApplicationName('Files'); - $page->setBaseURI('/file/'); + $page->setApplicationName('Login'); + $page->setBaseURI('/login/'); $page->setTitle(idx($data, 'title')); - $page->setGlyph("\xE2\x87\xAA"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/files/controller/base/__init__.php b/src/applications/auth/controlller/base/__init__.php similarity index 71% copy from src/applications/files/controller/base/__init__.php copy to src/applications/auth/controlller/base/__init__.php index 16685a0b26..a0563c0c9a 100644 --- a/src/applications/files/controller/base/__init__.php +++ b/src/applications/auth/controlller/base/__init__.php @@ -1,16 +1,15 @@ getRequest(); + + $error = false; + $login_name = $request->getCookie('phu'); + if ($request->isFormPost()) { + $login_name = $request->getStr('login'); + + $user = id(new PhabricatorUser())->loadOneWhere( + 'username = %s', + $login_name); + + $user->setPassword('asdf'); + $user->save(); + + $okay = false; + if ($user) { + if ($user->comparePassword($request->getStr('password'))) { + $conn_w = $user->establishConnection('w'); + + $urandom = fopen('/dev/urandom', 'r'); + if (!$urandom) { + throw new Exception("Failed to open /dev/urandom!"); + } + $entropy = fread($urandom, 20); + if (strlen($entropy) != 20) { + throw new Exception("Failed to read /dev/urandom!"); + } + + $session_key = sha1($entropy); + queryfx( + $conn_w, + 'INSERT INTO phabricator_session '. + '(userPHID, type, sessionKey, sessionStart)'. + ' VALUES '. + '(%s, %s, %s, UNIX_TIMESTAMP()) '. + 'ON DUPLICATE KEY UPDATE '. + 'sessionKey = VALUES(sessionKey), '. + 'sessionStart = VALUES(sessionStart)', + $user->getPHID(), + 'web', + $session_key); + + $request->setCookie('phusr', $user->getUsername()); + $request->setCookie('phsid', $session_key); + + return id(new AphrontRedirectResponse()) + ->setURI('/'); + } + } + + if (!$okay) { + $request->clearCookie('phusr'); + $request->clearCookie('phsid'); + } + + $error = true; + } + + $error_view = null; + if ($error) { + $error_view = new AphrontErrorView(); + $error_view->setTitle('Bad username/password.'); + } + + $form = new AphrontFormView(); + $form + ->setAction('/login/') + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel('Login') + ->setName('login') + ->setValue($login_name)) + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel('Password') + ->setName('password')) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Login')); + + + $panel = new AphrontPanelView(); + $panel->setHeader('Phabricator Login'); + $panel->setWidth(AphrontPanelView::WIDTH_FORM); + $panel->appendChild($form); + + return $this->buildStandardPageResponse( + array( + $error_view, + $panel, + ), + array( + 'title' => 'Login', + )); + } + +} diff --git a/src/applications/auth/controlller/login/__init__.php b/src/applications/auth/controlller/login/__init__.php new file mode 100644 index 0000000000..9909a8d0d4 --- /dev/null +++ b/src/applications/auth/controlller/login/__init__.php @@ -0,0 +1,21 @@ +getRequest(); + + $user = new PhabricatorUser(); + + $phusr = $request->getCookie('phusr'); + $phsid = $request->getCookie('phsid'); + + if ($phusr && $phsid) { + $info = queryfx_one( + $user->establishConnection('r'), + 'SELECT u.* FROM %T u JOIN %T s ON u.phid = s.userPHID + AND s.type = %s AND s.sessionKey = %s', + $user->getTableName(), + 'phabricator_session', + 'web', + $phsid); + if ($info) { + $user->loadFromArray($info); + } + } + + $request->setUser($user); + + if ($this->shouldRequireLogin() && !$user->getPHID()) { + throw new AphrontRedirectException('/login/'); + } + } + + public function buildStandardPageView() { + $view = new PhabricatorStandardPageView(); + $view->setRequest($this->getRequest()); + return $view; + } + public function buildStandardPageResponse($view) { - $page = new PhabricatorStandardPageView(); + $page = $this->buildStandardPageView(); $page->appendChild($view); $response = new AphrontWebpageResponse(); $response->setContent($page->render()); return $response; } } diff --git a/src/applications/base/controller/base/__init__.php b/src/applications/base/controller/base/__init__.php index 03cfc02dba..038d5108a6 100644 --- a/src/applications/base/controller/base/__init__.php +++ b/src/applications/base/controller/base/__init__.php @@ -1,14 +1,17 @@ buildStandardPageView(); $page->setApplicationName('Conduit'); $page->setBaseURI('/conduit/'); $page->setTitle(idx($data, 'title')); $page->setTabs( array( 'console' => array( 'href' => '/conduit/', 'name' => 'Console', ), 'logs' => array( 'href' => '/conduit/log/', 'name' => 'Logs', ), ), idx($data, 'tab')); $page->setGlyph("\xE2\x87\xB5"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/conduit/controller/base/__init__.php b/src/applications/conduit/controller/base/__init__.php index 6dd4aa3801..a2fb05dbbf 100644 --- a/src/applications/conduit/controller/base/__init__.php +++ b/src/applications/conduit/controller/base/__init__.php @@ -1,16 +1,15 @@ buildStandardPageView(); $page->setApplicationName('Differential'); $page->setBaseURI('/differential/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x9A\x99"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/differential/controller/base/__init__.php b/src/applications/differential/controller/base/__init__.php index e2a4f7a73b..5e0ce69e00 100644 --- a/src/applications/differential/controller/base/__init__.php +++ b/src/applications/differential/controller/base/__init__.php @@ -1,17 +1,16 @@ buildStandardPageView(); $page->setApplicationName('Directory'); $page->setBaseURI('/'); $page->setTitle(idx($data, 'title')); $page->setTabs( array( 'directory' => array( 'href' => '/', 'name' => 'Directory', ), 'categories' => array( 'href' => '/directory/category/', 'name' => 'Categories', ), 'items' => array( 'href' => '/directory/item/', 'name' => 'Items', ), ), idx($data, 'tab')); $page->setGlyph("\xE2\x9A\x92"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/directory/controller/base/__init__.php b/src/applications/directory/controller/base/__init__.php index bab124638d..e30b96d052 100644 --- a/src/applications/directory/controller/base/__init__.php +++ b/src/applications/directory/controller/base/__init__.php @@ -1,16 +1,15 @@ buildStandardPageView(); $page->setApplicationName('Files'); $page->setBaseURI('/file/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x87\xAA"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/files/controller/base/__init__.php b/src/applications/files/controller/base/__init__.php index 16685a0b26..97ee9ef525 100644 --- a/src/applications/files/controller/base/__init__.php +++ b/src/applications/files/controller/base/__init__.php @@ -1,16 +1,15 @@ buildStandardPageView(); $page->setApplicationName('MetaMTA'); $page->setBaseURI('/mail/'); $page->setTitle(idx($data, 'title')); $page->setTabs( array( 'queue' => array( 'name' => 'Mail Queue', 'href' => '/mail/', ), 'lists' => array( 'name' => 'Mailing Lists', 'href' => '/mail/lists/', ), ), idx($data, 'tab')); $page->setGlyph("@"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/metamta/controller/base/__init__.php b/src/applications/metamta/controller/base/__init__.php index 23abc13fab..d961d62e8e 100644 --- a/src/applications/metamta/controller/base/__init__.php +++ b/src/applications/metamta/controller/base/__init__.php @@ -1,16 +1,15 @@ buildStandardPageView(); $page->setApplicationName('People'); $page->setBaseURI('/people/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x99\xA5"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/people/controller/base/__init__.php b/src/applications/people/controller/base/__init__.php index 9544894bc6..792184c7d0 100644 --- a/src/applications/people/controller/base/__init__.php +++ b/src/applications/people/controller/base/__init__.php @@ -1,16 +1,15 @@ true, ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID(self::PHID_TYPE); } + public function setPassword($password) { + $this->setPasswordSalt(md5(mt_rand())); + $hash = $this->hashPassword($password); + $this->setPasswordHash($hash); + return $this; + } + + public function comparePassword($password) { + $password = $this->hashPassword($password); + return ($password === $this->getPasswordHash()); + } + + private function hashPassword($password) { + $password = $this->getUsername(). + $password. + $this->getPHID(). + $this->getPasswordSalt(); + for ($ii = 0; $ii < 1000; $ii++) { + $password = md5($password); + } + return $password; + } + } diff --git a/src/applications/phid/controller/base/PhabricatorPHIDController.php b/src/applications/phid/controller/base/PhabricatorPHIDController.php index 0b5b089234..1bb234fb5f 100644 --- a/src/applications/phid/controller/base/PhabricatorPHIDController.php +++ b/src/applications/phid/controller/base/PhabricatorPHIDController.php @@ -1,50 +1,50 @@ buildStandardPageView(); $page->setApplicationName('PHID'); $page->setBaseURI('/phid/'); $page->setTitle(idx($data, 'title')); $page->setTabs( array( 'lookup' => array( 'href' => '/phid/', 'name' => 'PHID Lookup', ), 'phids' => array( 'href' => '/phid/list/', 'name' => 'PHID List', ), 'types' => array( 'href' => '/phid/type/', 'name' => 'PHID Types', ), ), idx($data, 'tab')); $page->setGlyph('#'); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/phid/controller/base/__init__.php b/src/applications/phid/controller/base/__init__.php index 44f0f1b94d..17a9f28a12 100644 --- a/src/applications/phid/controller/base/__init__.php +++ b/src/applications/phid/controller/base/__init__.php @@ -1,16 +1,15 @@ request = $request; + return $this; + } + + public function getRequest() { + return $this->request; + } public function setApplicationName($application_name) { $this->applicationName = $application_name; return $this; } public function getApplicationName() { return $this->applicationName; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setTabs(array $tabs, $selected_tab) { $this->tabs = $tabs; $this->selectedTab = $selected_tab; return $this; } public function getTitle() { return $this->getGlyph().' '.parent::getTitle(); } protected function willRenderPage() { require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-core-buttons-css'); require_celerity_resource('phabricator-standard-page-view'); require_celerity_resource('javelin-lib-dev'); $this->bodyContent = $this->renderChildren(); } protected function getHead() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('css'). ''. ''; } public function setGlyph($glyph) { $this->glyph = $glyph; return $this; } public function getGlyph() { return $this->glyph; } protected function getBody() { $tabs = array(); foreach ($this->tabs as $name => $tab) { $tabs[] = phutil_render_tag( 'a', array( 'href' => idx($tab, 'href'), 'class' => ($name == $this->selectedTab) ? 'phabricator-selected-tab' : null, ), phutil_escape_html(idx($tab, 'name'))); } $tabs = implode('', $tabs); if ($tabs) { $tabs = ''.$tabs.''; } + $login_stuff = null; + $request = $this->getRequest(); + $user = $request->getUser(); + + if ($user->getPHID()) { + $login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername()); + } + return '
'. '
'. + ''. 'Phabricator '. phutil_render_tag( 'a', array( 'href' => $this->getBaseURI(), 'class' => 'phabricator-head-appname', ), phutil_escape_html($this->getApplicationName())). $tabs. '
'. $this->bodyContent. '
'. '
'; } protected function getTail() { $response = CelerityAPI::getStaticResourceResponse(); return $response->renderResourcesOfType('js'). $response->renderHTMLFooter(); } } diff --git a/webroot/index.php b/webroot/index.php index 0a98a88566..ca2a0ab82d 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -1,87 +1,92 @@ setHost($host); $application->setPath($path); $request = $application->buildRequest(); $application->setRequest($request); list($controller, $uri_data) = $application->buildController(); -$controller->willProcessRequest($uri_data); try { + $controller->willBeginExecution(); + + $controller->willProcessRequest($uri_data); $response = $controller->processRequest(); +} catch (AphrontRedirectException $ex) { + $response = id(new AphrontRedirectResponse()) + ->setURI($ex->getURI()); } catch (Exception $ex) { $response = $application->handleException($ex); } $response = $application->willSendResponse($response); $response->setRequest($request); $response_string = $response->buildResponseString(); $headers = $response->getCacheHeaders(); $headers = array_merge($headers, $response->getHeaders()); foreach ($headers as $header) { list($header, $value) = $header; header("{$header}: {$value}"); } echo $response_string; /** * @group aphront */ function setup_aphront_basics() { $aphront_root = dirname(dirname(__FILE__)); $libraries_root = dirname($aphront_root); ini_set('include_path', ini_get('include_path').':'.$libraries_root.'/'); @include_once 'libphutil/src/__phutil_library_init__.php'; if (!@constant('__LIBPHUTIL__')) { echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ". "include the parent directory of libphutil/.\n"; exit(1); } if (!ini_get('date.timezone')) { date_default_timezone_set('America/Los_Angeles'); } phutil_load_library($libraries_root.'/arcanist/src'); phutil_load_library($aphront_root.'/src'); } function __autoload($class_name) { PhutilSymbolLoader::loadClass($class_name); } diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index cdc97ace79..164b6da120 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -1,48 +1,52 @@ /** * @provides phabricator-standard-page-view */ .phabricator-standard-page { background: #ffffff; border-bottom: 1px solid #888888; font-size: 14px; -webkit-box-shadow: 0 0 6px #000; -mox-box-shadow: 0 0 6px #000; box-shadow: 0 0 6px #000; } .phabricator-standard-header { background: #003366; color: white; padding: 1em 1em 0.5em 1em; overflow: hidden; position: relative; } .phabricator-standard-header a { color: white; } .phabricator-standard-header .phabricator-head-tabs { padding: 0 1em; font-size: 13px; font-weight: bold; } .phabricator-standard-header .phabricator-head-tabs a { border-bottom: 3px solid transparent; padding: 0.5em 0.75em; position: relative; bottom: 2px; } .phabricator-standard-header .phabricator-head-tabs a.phabricator-selected-tab { border-bottom-color: #cccccc; } .phabricator-standard-header .phabricator-head-appname { padding: 0 1em; text-transform: uppercase; } + +.phabricator-login-details { + float: right; +}