2011-01-16 13:51:39 -08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
Validate logins, and simplify email password resets
Summary:
- There are some recent reports of login issues, see T755 and T754. I'm not
really sure what's going on, but this is an attempt at getting some more
information.
- When we login a user by setting 'phusr' and 'phsid', send them to
/login/validate/ to validate that the cookies actually got set.
- Do email password resets in two steps: first, log the user in. Redirect them
through validate, then give them the option to reset their password.
- Don't CSRF logged-out users. It technically sort of works most of the time
right now, but is silly. If we need logged-out CSRF we should generate it in
some more reliable way.
Test Plan:
- Logged in with username/password.
- Logged in with OAuth.
- Logged in with email password reset.
- Sent bad values to /login/validate/, got appropriate errors.
- Reset password.
- Verified next_uri still works.
Reviewers: btrahan, jungejason
Reviewed By: btrahan
CC: aran, btrahan, j3kuntz
Maniphest Tasks: T754, T755
Differential Revision: https://secure.phabricator.com/D1353
2012-01-10 14:42:07 -08:00
|
|
|
* Copyright 2012 Facebook, Inc.
|
2011-01-16 13:51:39 -08:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @group aphront
|
|
|
|
*/
|
|
|
|
class AphrontDefaultApplicationConfiguration
|
|
|
|
extends AphrontApplicationConfiguration {
|
|
|
|
|
2011-02-24 14:52:57 -08:00
|
|
|
public function __construct() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-01-16 13:51:39 -08:00
|
|
|
public function getApplicationName() {
|
|
|
|
return 'aphront-default';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getURIMap() {
|
2011-02-24 14:52:57 -08:00
|
|
|
return $this->getResourceURIMapRules() + array(
|
Hard-code and unify "more applications" in Phabricator
Summary:
This is mostly intended to simplify D2323.
We currently allow users to edit and customize the links on the homepage, but as far as I know no one actually does this (no one complained when we redid the homepage earlier this year) and it creates a lot of mess in the database patches and quickstart dump. After D2331, this is the only data we load in the patch files. The patch files are also a mess with respect to this data and have various different versions of it.
Also the current UI is just kind of bad, it stretches stuff across too many screens and is generally ungood. Nuking this lets us nuke a lot of code in general.
(In the long term, I think we'll move toward an "application" model anyway, and this stuff will go away sooner or later.)
I'll add a drop-database patch some time later, just in case anyone does actually use this, so they can get their data out of MySQL.
Test Plan: Looked at home page, clicked "More Stuff", got a single list of other apps/things.
Reviewers: btrahan, vrana, edward, jungejason
Reviewed By: jungejason
CC: aran
Maniphest Tasks: T345
Differential Revision: https://secure.phabricator.com/D2332
2012-04-28 07:17:38 -07:00
|
|
|
'/(?:(?P<filter>(?:jump|apps))/)?' =>
|
2012-02-21 15:10:11 -08:00
|
|
|
'PhabricatorDirectoryMainController',
|
2012-02-22 08:03:15 -08:00
|
|
|
'/(?:(?P<filter>feed)/)' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'public/' => 'PhabricatorFeedPublicStreamController',
|
|
|
|
'(?:(?P<subfilter>[^/]+)/)?' =>
|
2012-02-22 08:03:15 -08:00
|
|
|
'PhabricatorDirectoryMainController',
|
|
|
|
),
|
2011-01-22 18:33:00 -08:00
|
|
|
'/file/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorFileListController',
|
|
|
|
'filter/(?P<filter>\w+)/' => 'PhabricatorFileListController',
|
|
|
|
'upload/' => 'PhabricatorFileUploadController',
|
|
|
|
'dropupload/' => 'PhabricatorFileDropUploadController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'PhabricatorFileDeleteController',
|
Move ALL files to serve from the alternate file domain, not just files without
"Content-Disposition: attachment"
Summary:
We currently serve some files off the primary domain (with "Content-Disposition:
attachment" + a CSRF check) and some files off the alternate domain (without
either).
This is not sufficient, because some UAs (like the iPad) ignore
"Content-Disposition: attachment". So there's an attack that goes like this:
- Alice uploads xss.html
- Alice says to Bob "hey download this file on your iPad"
- Bob clicks "Download" on Phabricator on his iPad, gets XSS'd.
NOTE: This removes the CSRF check for downloading files. The check is nice to
have but only raises the barrier to entry slightly. Between iPad / sniffing /
flash bytecode attacks, single-domain installs are simply insecure. We could
restore the check at some point in conjunction with a derived authentication
cookie (i.e., a mini-session-token which is only useful for downloading files),
but that's a lot of complexity to drop all at once.
(Because files are now authenticated only by knowing the PHID and secret key,
this also fixes the "no profile pictures in public feed while logged out"
issue.)
Test Plan: Viewed, info'd, and downloaded files
Reviewers: btrahan, arice, alok
Reviewed By: arice
CC: aran, epriestley
Maniphest Tasks: T843
Differential Revision: https://secure.phabricator.com/D1608
2012-02-14 14:52:27 -08:00
|
|
|
'info/(?P<phid>[^/]+)/' => 'PhabricatorFileInfoController',
|
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'data/(?P<key>[^/]+)/(?P<phid>[^/]+)/.*'
|
Move ALL files to serve from the alternate file domain, not just files without
"Content-Disposition: attachment"
Summary:
We currently serve some files off the primary domain (with "Content-Disposition:
attachment" + a CSRF check) and some files off the alternate domain (without
either).
This is not sufficient, because some UAs (like the iPad) ignore
"Content-Disposition: attachment". So there's an attack that goes like this:
- Alice uploads xss.html
- Alice says to Bob "hey download this file on your iPad"
- Bob clicks "Download" on Phabricator on his iPad, gets XSS'd.
NOTE: This removes the CSRF check for downloading files. The check is nice to
have but only raises the barrier to entry slightly. Between iPad / sniffing /
flash bytecode attacks, single-domain installs are simply insecure. We could
restore the check at some point in conjunction with a derived authentication
cookie (i.e., a mini-session-token which is only useful for downloading files),
but that's a lot of complexity to drop all at once.
(Because files are now authenticated only by knowing the PHID and secret key,
this also fixes the "no profile pictures in public feed while logged out"
issue.)
Test Plan: Viewed, info'd, and downloaded files
Reviewers: btrahan, arice, alok
Reviewed By: arice
CC: aran, epriestley
Maniphest Tasks: T843
Differential Revision: https://secure.phabricator.com/D1608
2012-02-14 14:52:27 -08:00
|
|
|
=> 'PhabricatorFileDataController',
|
|
|
|
// TODO: This is a deprecated version of /data/. Remove it after
|
|
|
|
// old links have had a chance to rot.
|
2011-08-16 14:39:01 -07:00
|
|
|
'alt/(?P<key>[^/]+)/(?P<phid>[^/]+)/'
|
Move ALL files to serve from the alternate file domain, not just files without
"Content-Disposition: attachment"
Summary:
We currently serve some files off the primary domain (with "Content-Disposition:
attachment" + a CSRF check) and some files off the alternate domain (without
either).
This is not sufficient, because some UAs (like the iPad) ignore
"Content-Disposition: attachment". So there's an attack that goes like this:
- Alice uploads xss.html
- Alice says to Bob "hey download this file on your iPad"
- Bob clicks "Download" on Phabricator on his iPad, gets XSS'd.
NOTE: This removes the CSRF check for downloading files. The check is nice to
have but only raises the barrier to entry slightly. Between iPad / sniffing /
flash bytecode attacks, single-domain installs are simply insecure. We could
restore the check at some point in conjunction with a derived authentication
cookie (i.e., a mini-session-token which is only useful for downloading files),
but that's a lot of complexity to drop all at once.
(Because files are now authenticated only by knowing the PHID and secret key,
this also fixes the "no profile pictures in public feed while logged out"
issue.)
Test Plan: Viewed, info'd, and downloaded files
Reviewers: btrahan, arice, alok
Reviewed By: arice
CC: aran, epriestley
Maniphest Tasks: T843
Differential Revision: https://secure.phabricator.com/D1608
2012-02-14 14:52:27 -08:00
|
|
|
=> 'PhabricatorFileDataController',
|
|
|
|
|
2011-05-03 10:45:45 -07:00
|
|
|
'macro/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorFileMacroListController',
|
|
|
|
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorFileMacroEditController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'PhabricatorFileMacroDeleteController',
|
2011-05-03 10:45:45 -07:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'proxy/' => 'PhabricatorFileProxyController',
|
2011-05-22 14:40:51 -07:00
|
|
|
'xform/(?P<transform>[^/]+)/(?P<phid>[^/]+)/'
|
|
|
|
=> 'PhabricatorFileTransformController',
|
2011-01-22 18:33:00 -08:00
|
|
|
),
|
2011-01-22 21:09:13 -08:00
|
|
|
'/phid/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorPHIDLookupController',
|
2011-01-16 13:51:39 -08:00
|
|
|
),
|
2011-01-23 18:09:16 -08:00
|
|
|
'/people/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorPeopleListController',
|
|
|
|
'logs/' => 'PhabricatorPeopleLogsController',
|
|
|
|
'edit/(?:(?P<id>\d+)/(?:(?P<view>\w+)/)?)?'
|
2011-07-25 20:32:02 -07:00
|
|
|
=> 'PhabricatorPeopleEditController',
|
2011-01-23 18:09:16 -08:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'/p/(?P<username>\w+)/(?:(?P<page>\w+)/)?'
|
2011-06-18 05:13:56 -03:00
|
|
|
=> 'PhabricatorPeopleProfileController',
|
2011-01-24 09:00:29 -08:00
|
|
|
'/conduit/' => array(
|
2012-04-26 22:25:05 -07:00
|
|
|
'' => 'PhabricatorConduitListController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
|
|
|
|
'log/' => 'PhabricatorConduitLogController',
|
|
|
|
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
|
|
|
|
'token/' => 'PhabricatorConduitTokenController',
|
2011-01-24 09:00:29 -08:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'/api/(?P<method>[^/]+)' => 'PhabricatorConduitAPIController',
|
2011-01-24 13:18:41 -08:00
|
|
|
|
2011-02-07 20:56:27 -08:00
|
|
|
'/D(?P<id>\d+)' => 'DifferentialRevisionViewController',
|
2011-01-24 13:18:41 -08:00
|
|
|
'/differential/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'DifferentialRevisionListController',
|
2012-03-06 13:57:31 -08:00
|
|
|
'filter/(?P<filter>\w+)/(?:(?P<username>\w+)/)?' =>
|
|
|
|
'DifferentialRevisionListController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'stats/(?P<filter>\w+)/' => 'DifferentialRevisionStatsController',
|
2011-02-05 12:20:18 -08:00
|
|
|
'diff/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'(?P<id>\d+)/' => 'DifferentialDiffViewController',
|
|
|
|
'create/' => 'DifferentialDiffCreateController',
|
2011-02-05 12:20:18 -08:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'changeset/' => 'DifferentialChangesetViewController',
|
|
|
|
'revision/edit/(?:(?P<id>\d+)/)?'
|
2011-01-25 13:26:09 -08:00
|
|
|
=> 'DifferentialRevisionEditController',
|
2011-01-30 12:08:40 -08:00
|
|
|
'comment/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'preview/(?P<id>\d+)/' => 'DifferentialCommentPreviewController',
|
|
|
|
'save/' => 'DifferentialCommentSaveController',
|
2011-01-30 12:08:40 -08:00
|
|
|
'inline/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'preview/(?P<id>\d+)/' =>
|
2011-02-02 19:38:43 -08:00
|
|
|
'DifferentialInlineCommentPreviewController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'edit/(?P<id>\d+)/' => 'DifferentialInlineCommentEditController',
|
2011-01-30 12:08:40 -08:00
|
|
|
),
|
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'subscribe/(?P<action>add|rem)/(?P<id>\d+)/'
|
2011-02-19 14:36:13 -08:00
|
|
|
=> 'DifferentialSubscribeController',
|
2011-01-24 13:18:41 -08:00
|
|
|
),
|
|
|
|
|
2011-01-25 13:48:05 -08:00
|
|
|
'/typeahead/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'common/(?P<type>\w+)/'
|
2011-01-25 13:48:05 -08:00
|
|
|
=> 'PhabricatorTypeaheadCommonDatasourceController',
|
|
|
|
),
|
2011-01-25 17:40:21 -08:00
|
|
|
|
|
|
|
'/mail/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorMetaMTAListController',
|
|
|
|
'send/' => 'PhabricatorMetaMTASendController',
|
|
|
|
'view/(?P<id>\d+)/' => 'PhabricatorMetaMTAViewController',
|
|
|
|
'lists/' => 'PhabricatorMetaMTAMailingListsController',
|
|
|
|
'lists/edit/(?:(?P<id>\d+)/)?'
|
2011-01-26 10:40:38 -08:00
|
|
|
=> 'PhabricatorMetaMTAMailingListEditController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'receive/' => 'PhabricatorMetaMTAReceiveController',
|
|
|
|
'received/' => 'PhabricatorMetaMTAReceivedListController',
|
|
|
|
'sendgrid/' => 'PhabricatorMetaMTASendGridReceiveController',
|
2011-01-26 10:40:38 -08:00
|
|
|
),
|
2011-01-26 13:21:12 -08:00
|
|
|
|
2011-01-31 11:55:26 -08:00
|
|
|
'/login/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorLoginController',
|
|
|
|
'email/' => 'PhabricatorEmailLoginController',
|
|
|
|
'etoken/(?P<token>\w+)/' => 'PhabricatorEmailTokenController',
|
|
|
|
'refresh/' => 'PhabricatorRefreshCSRFController',
|
|
|
|
'validate/' => 'PhabricatorLoginValidateController',
|
2011-01-31 11:55:26 -08:00
|
|
|
),
|
2011-02-24 14:52:57 -08:00
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'/logout/' => 'PhabricatorLogoutController',
|
2011-02-02 13:48:52 -08:00
|
|
|
|
2011-02-20 22:47:56 -08:00
|
|
|
'/oauth/' => array(
|
Add Google as an OAuth2 provider (BETA)
Summary:
This is pretty straightforward, except:
- We need to request read/write access to the address book to get the account
ID (which we MUST have) and real name, email and account name (which we'd like
to have). This is way more access than we should need, but there's apparently no
"get_loggedin_user_basic_information" type of call in the Google API suite (or,
at least, I couldn't find one).
- We can't get the profile picture or profile URI since there's no Plus API
access and Google users don't have meaningful public pages otherwise.
- Google doesn't save the fact that you've authorized the app, so every time
you want to login you need to reaffirm that you want to give us silly amounts of
access. Phabricator sessions are pretty long-duration though so this shouldn't
be a major issue.
Test Plan:
- Registered, logged out, and logged in with Google.
- Registered, logged out, and logged in with Facebook / Github to make sure I
didn't break anything.
- Linked / unlinked Google accounts.
Reviewers: Makinde, jungejason, nh, tuomaspelkonen, aran
Reviewed By: aran
CC: aran, epriestley, Makinde
Differential Revision: 916
2011-09-08 16:37:22 -07:00
|
|
|
'(?P<provider>\w+)/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'login/' => 'PhabricatorOAuthLoginController',
|
|
|
|
'diagnose/' => 'PhabricatorOAuthDiagnosticsController',
|
|
|
|
'unlink/' => 'PhabricatorOAuthUnlinkController',
|
2011-02-20 22:47:56 -08:00
|
|
|
),
|
|
|
|
),
|
|
|
|
|
OAuth - Phabricator OAuth server and Phabricator client for new Phabricator OAuth Server
Summary:
adds a Phabricator OAuth server, which has three big commands:
- auth - allows $user to authorize a given client or application. if $user has already authorized, it hands an authoization code back to $redirect_uri
- token - given a valid authorization code, this command returns an authorization token
- whoami - Conduit.whoami, all nice and purdy relative to the oauth server.
Also has a "test" handler, which I used to create some test data. T850 will
delete this as it adds the ability to create this data in the Phabricator
product.
This diff also adds the corresponding client in Phabricator for the Phabricator
OAuth Server. (Note that clients are known as "providers" in the Phabricator
codebase but client makes more sense relative to the server nomenclature)
Also, related to make this work well
- clean up the diagnostics page by variabilizing the provider-specific
information and extending the provider classes as appropriate.
- augment Conduit.whoami for more full-featured OAuth support, at least where
the Phabricator client is concerned
What's missing here... See T844, T848, T849, T850, and T852.
Test Plan:
- created a dummy client via the test handler. setup development.conf to have
have proper variables for this dummy client. went through authorization and
de-authorization flows
- viewed the diagnostics page for all known oauth providers and saw
provider-specific debugging information
Reviewers: epriestley
CC: aran, epriestley
Maniphest Tasks: T44, T797
Differential Revision: https://secure.phabricator.com/D1595
2012-02-03 16:21:40 -08:00
|
|
|
'/oauthserver/' => array(
|
2012-02-22 10:21:39 -08:00
|
|
|
'auth/' => 'PhabricatorOAuthServerAuthController',
|
|
|
|
'test/' => 'PhabricatorOAuthServerTestController',
|
|
|
|
'token/' => 'PhabricatorOAuthServerTokenController',
|
|
|
|
'clientauthorization/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorOAuthClientAuthorizationListController',
|
2012-02-22 10:21:39 -08:00
|
|
|
'delete/(?P<phid>[^/]+)/' =>
|
|
|
|
'PhabricatorOAuthClientAuthorizationDeleteController',
|
|
|
|
'edit/(?P<phid>[^/]+)/' =>
|
|
|
|
'PhabricatorOAuthClientAuthorizationEditController',
|
|
|
|
),
|
|
|
|
'client/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorOAuthClientListController',
|
|
|
|
'create/' => 'PhabricatorOAuthClientEditController',
|
|
|
|
'delete/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientDeleteController',
|
|
|
|
'edit/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientEditController',
|
|
|
|
'view/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientViewController',
|
2012-02-22 10:21:39 -08:00
|
|
|
),
|
OAuth - Phabricator OAuth server and Phabricator client for new Phabricator OAuth Server
Summary:
adds a Phabricator OAuth server, which has three big commands:
- auth - allows $user to authorize a given client or application. if $user has already authorized, it hands an authoization code back to $redirect_uri
- token - given a valid authorization code, this command returns an authorization token
- whoami - Conduit.whoami, all nice and purdy relative to the oauth server.
Also has a "test" handler, which I used to create some test data. T850 will
delete this as it adds the ability to create this data in the Phabricator
product.
This diff also adds the corresponding client in Phabricator for the Phabricator
OAuth Server. (Note that clients are known as "providers" in the Phabricator
codebase but client makes more sense relative to the server nomenclature)
Also, related to make this work well
- clean up the diagnostics page by variabilizing the provider-specific
information and extending the provider classes as appropriate.
- augment Conduit.whoami for more full-featured OAuth support, at least where
the Phabricator client is concerned
What's missing here... See T844, T848, T849, T850, and T852.
Test Plan:
- created a dummy client via the test handler. setup development.conf to have
have proper variables for this dummy client. went through authorization and
de-authorization flows
- viewed the diagnostics page for all known oauth providers and saw
provider-specific debugging information
Reviewers: epriestley
CC: aran, epriestley
Maniphest Tasks: T44, T797
Differential Revision: https://secure.phabricator.com/D1595
2012-02-03 16:21:40 -08:00
|
|
|
),
|
|
|
|
|
2011-02-02 13:48:52 -08:00
|
|
|
'/xhprof/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'profile/(?P<phid>[^/]+)/' => 'PhabricatorXHProfProfileController',
|
2011-02-02 13:48:52 -08:00
|
|
|
),
|
2011-02-02 22:38:42 -08:00
|
|
|
|
|
|
|
'/~/' => 'DarkConsoleController',
|
2011-02-05 22:36:21 -08:00
|
|
|
|
|
|
|
'/settings/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'(?:page/(?P<page>[^/]+)/)?' => 'PhabricatorUserSettingsController',
|
2011-02-05 22:36:21 -08:00
|
|
|
),
|
2011-02-08 10:53:59 -08:00
|
|
|
|
|
|
|
'/maniphest/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'ManiphestTaskListController',
|
|
|
|
'view/(?P<view>\w+)/' => 'ManiphestTaskListController',
|
|
|
|
'report/(?:(?P<view>\w+)/)?' => 'ManiphestReportController',
|
|
|
|
'batch/' => 'ManiphestBatchEditController',
|
2011-02-08 10:53:59 -08:00
|
|
|
'task/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'create/' => 'ManiphestTaskEditController',
|
|
|
|
'edit/(?P<id>\d+)/' => 'ManiphestTaskEditController',
|
2012-03-09 15:46:25 -08:00
|
|
|
'descriptionchange/(?:(?P<id>\d+)/)?' =>
|
2011-05-20 18:56:18 -07:00
|
|
|
'ManiphestTaskDescriptionChangeController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'descriptionpreview/' =>
|
2012-01-25 11:23:00 -08:00
|
|
|
'ManiphestTaskDescriptionPreviewController',
|
2011-02-08 10:53:59 -08:00
|
|
|
),
|
|
|
|
'transaction/' => array(
|
|
|
|
'save/' => 'ManiphestTransactionSaveController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'preview/(?P<id>\d+)/' => 'ManiphestTransactionPreviewController',
|
2011-02-08 10:53:59 -08:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'export/(?P<key>[^/]+)/' => 'ManiphestExportController',
|
2012-04-02 12:12:04 -07:00
|
|
|
'subpriority/' => 'ManiphestSubpriorityController',
|
2012-04-10 09:46:04 -07:00
|
|
|
'custom/' => array(
|
|
|
|
'' => 'ManiphestSavedQueryListController',
|
|
|
|
'edit/(?:(?P<id>\d+)/)?' => 'ManiphestSavedQueryEditController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'ManiphestSavedQueryDeleteController',
|
|
|
|
),
|
2011-02-08 10:53:59 -08:00
|
|
|
),
|
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'/T(?P<id>\d+)' => 'ManiphestTaskDetailController',
|
2011-02-12 18:26:15 -08:00
|
|
|
|
|
|
|
'/repository/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorRepositoryListController',
|
|
|
|
'create/' => 'PhabricatorRepositoryCreateController',
|
|
|
|
'edit/(?P<id>\d+)/(?:(?P<view>\w+)?/)?' =>
|
2011-03-06 22:29:22 -08:00
|
|
|
'PhabricatorRepositoryEditController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'delete/(?P<id>\d+)/' => 'PhabricatorRepositoryDeleteController',
|
2011-04-05 20:49:31 -07:00
|
|
|
'project/(?P<id>\d+)/' =>
|
|
|
|
'PhabricatorRepositoryArcanistProjectEditController',
|
2011-02-12 18:26:15 -08:00
|
|
|
),
|
2011-02-14 15:34:20 -08:00
|
|
|
|
|
|
|
'/search/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorSearchController',
|
|
|
|
'(?P<key>[^/]+)/' => 'PhabricatorSearchController',
|
|
|
|
'attach/(?P<phid>[^/]+)/(?P<type>\w+)/(?:(?P<action>\w+)/)?'
|
2011-05-16 11:43:39 -07:00
|
|
|
=> 'PhabricatorSearchAttachController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'select/(?P<type>\w+)/'
|
2011-05-16 11:43:39 -07:00
|
|
|
=> 'PhabricatorSearchSelectController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'index/(?P<phid>[^/]+)/' => 'PhabricatorSearchIndexController',
|
2011-02-14 15:34:20 -08:00
|
|
|
),
|
2011-02-20 18:41:23 -08:00
|
|
|
|
|
|
|
'/project/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorProjectListController',
|
|
|
|
'filter/(?P<filter>[^/]+)/' => 'PhabricatorProjectListController',
|
|
|
|
'edit/(?P<id>\d+)/' => 'PhabricatorProjectProfileEditController',
|
|
|
|
'view/(?P<id>\d+)/(?:(?P<page>\w+)/)?'
|
2011-06-18 05:13:56 -03:00
|
|
|
=> 'PhabricatorProjectProfileController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'create/' => 'PhabricatorProjectCreateController',
|
|
|
|
'update/(?P<id>\d+)/(?P<action>[^/]+)/'
|
2012-01-25 11:51:20 -08:00
|
|
|
=> 'PhabricatorProjectUpdateController',
|
2011-02-24 14:52:57 -08:00
|
|
|
),
|
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'/r(?P<callsign>[A-Z]+)(?P<commit>[a-z0-9]+)'
|
2011-03-11 09:34:22 -08:00
|
|
|
=> 'DiffusionCommitController',
|
2011-03-07 15:13:36 -08:00
|
|
|
'/diffusion/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'DiffusionHomeController',
|
2011-03-12 16:17:34 -08:00
|
|
|
'(?P<callsign>[A-Z]+)/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'DiffusionRepositoryController',
|
Fix many encoding and architecture problems in Diffusion request and URI handling
Summary:
Diffusion request/uri handling is currently a big, hastily ported mess. In particular, it has:
- Tons and tons of duplicated code.
- Bugs with handling unusual branch and file names.
- An excessively large (and yet insufficiently expressive) API on DiffusionRequest, including a nonsensical concrete base class.
- Other tools were doing hacky things like passing ":" branch names.
This diff attempts to fix these issues.
- Make the base class abstract (it was concrete ONLY for "/diffusion/").
- Move all URI generation to DiffusionRequest. Make the core static. Add unit tests.
- Delete the 300 copies of URI generation code throughout Diffusion.
- Move all URI parsing to DiffusionRequest. Make the core static. Add unit tests.
- Add an appropriate static initializer for other callers.
- Convert all code calling `newFromAphrontRequestDictionary` outside of Diffusion to the new `newFromDictionary` API.
- Refactor static initializers to be sensibly-sized.
- Refactor derived DiffusionRequest classes to remove duplicated code.
- Properly encode branch names (fixes branches with "/", see <https://github.com/facebook/phabricator/issues/100>).
- Properly encode path names (fixes issues in D1742).
- Properly escape delimiter characters ";" and "$" in path names so files like "$100" are not interpreted as "line 100".
- Fix a couple warnings.
- Fix a couple lint issues.
- Fix a bug where we would not parse filenames with spaces in them correctly in the Git browse query.
- Fix a bug where Git change queries would fail unnecessarily.
- Provide or improve some documentation.
This thing is pretty gigantic but also kind of hard to split up. If it's unreasonably difficult to review, let me know and I can take a stab at it though.
This supplants D1742.
Test Plan:
- Used home, repository, branch, browse, change, history, diff (ajax), lastmodified (ajax) views of Diffusion.
- Used Owners typeaheads and search.
- Used diffusion.getrecentcommitsbypath method.
- Pushed a change to an absurdly-named file on an absurdly-named branch, everything worked properly.
{F9185}
Reviewers: nh, vrana, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1921
2012-03-19 19:52:14 -07:00
|
|
|
|
|
|
|
'repository/(?P<dblob>.*)' => 'DiffusionRepositoryController',
|
|
|
|
'change/(?P<dblob>.*)' => 'DiffusionChangeController',
|
|
|
|
'history/(?P<dblob>.*)' => 'DiffusionHistoryController',
|
|
|
|
'browse/(?P<dblob>.*)' => 'DiffusionBrowseController',
|
|
|
|
'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController',
|
|
|
|
'diff/' => 'DiffusionDiffController',
|
2012-04-19 09:39:19 -07:00
|
|
|
'tags/(?P<dblob>.*)' => 'DiffusionTagListController',
|
2011-03-08 17:31:44 -08:00
|
|
|
),
|
Add inline comments to Diffusion/Audit
Summary:
- Add inline comments to Audits, like Differential.
- Creates new storage for the comments in the Audits database.
- Creates a new PhabricatorAuditInlineComment class, similar to DifferentialInlineComment.
- Defines an Interface which Differential and Audit comments conform to.
- Makes consumers of DifferentialInlineComments consume objects which implement that interface instead.
- Adds save
NOTE: Some features are still missing! Wanted to cut this off before it got crazy:
- Inline comments aren't shown in the main comment list.
- Inline comments aren't shown in the emails.
- Inline comments aren't previewed.
I'll followup with those but this was getting pretty big.
@vrana, does the SQL change look correct?
Test Plan:
- Created, edited, deleted, replied to, reloaded and saved inline comments in Diffusion, on the left and right side of diffs.
- Created, edited, deleted, replied to, reloaded and saved inline comments in Differentila, on the left and right side of primary and diff-versus-diff diffs.
Reviewers: btrahan, vrana
Reviewed By: btrahan
CC: aran, epriestley
Maniphest Tasks: T904
Differential Revision: https://secure.phabricator.com/D1898
2012-03-14 12:56:01 -07:00
|
|
|
'inline/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
|
2011-04-03 19:20:47 -07:00
|
|
|
'services/' => array(
|
|
|
|
'path/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'complete/' => 'DiffusionPathCompleteController',
|
|
|
|
'validate/' => 'DiffusionPathValidateController',
|
2011-04-03 19:20:47 -07:00
|
|
|
),
|
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'symbol/(?P<name>[^/]+)/' => 'DiffusionSymbolController',
|
Improve Diffusion behavior for externals
Summary:
- Feature request from Airtime that I missed in the feedback notes, came up yesterday.
- Identify git submodules as "FILE_SUBMODULE", not "FILE_NORMAL".
- Link git submodules to an external resolver endpoint, which tries to find commits in tracked repositories.
- Identify git symlinks as "FILE_SYMLINK", not "FILE_NORMAL".
- Add folder, file, symlink and externals icons.
Test Plan:
- externals/javelin is now identified as a submoudule and links to Javelin, not identified as a file and links to error.
- bin/phd is now identified as a symlink.
- Interfaces have pretty icons.
Reviewers: btrahan, cpiro, ddfisher, keebuhm, allenjohnashton
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1975
2012-03-21 14:01:20 -07:00
|
|
|
'external/' => 'DiffusionExternalController',
|
2011-03-07 15:13:36 -08:00
|
|
|
),
|
|
|
|
|
2011-03-10 13:48:29 -08:00
|
|
|
'/daemon/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'task/(?P<id>\d+)/' => 'PhabricatorWorkerTaskDetailController',
|
|
|
|
'task/(?P<id>\d+)/(?P<action>[^/]+)/'
|
2012-01-23 16:36:32 -08:00
|
|
|
=> 'PhabricatorWorkerTaskUpdateController',
|
2011-03-15 13:38:14 -07:00
|
|
|
'log/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorDaemonLogListController',
|
|
|
|
'combined/' => 'PhabricatorDaemonCombinedLogController',
|
|
|
|
'(?P<id>\d+)/' => 'PhabricatorDaemonLogViewController',
|
2011-03-15 13:38:14 -07:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'timeline/' => 'PhabricatorDaemonTimelineConsoleController',
|
|
|
|
'timeline/(?P<id>\d+)/' => 'PhabricatorDaemonTimelineEventController',
|
|
|
|
'' => 'PhabricatorDaemonConsoleController',
|
2011-03-10 13:48:29 -08:00
|
|
|
),
|
|
|
|
|
2011-03-22 13:49:46 -07:00
|
|
|
'/herald/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'HeraldHomeController',
|
General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
- Personal rules can be deleted only by their owners.
- Global rules can be deleted by any user.
- All deletes are logged.
- Logs are more detailed.
- All logged actions can be viewed in aggregate.
**Minor Cleanup**
- Merged `HomeController` and `AllController`.
- Moved most queries to Query classes.
- Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
- Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
- Reenable some transaction code (this works again now).
- Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
- Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
- Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
- Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
- Browsed, created, edited, deleted personal and gules.
- Verified generated logs.
- Did some dry runs.
- Verified transcript list and transcript details.
- Created/edited all/any rules; created/edited once/every time rules.
- Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
2012-03-30 10:49:55 -07:00
|
|
|
'view/(?P<content_type>[^/]+)/(?:(?P<rule_type>[^/]+)/)?'
|
|
|
|
=> 'HeraldHomeController',
|
|
|
|
'new/(?:(?P<type>[^/]+)/(?:(?P<rule_type>[^/]+)/)?)?'
|
|
|
|
=> 'HeraldNewController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'rule/(?:(?P<id>\d+)/)?' => 'HeraldRuleController',
|
General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
- Personal rules can be deleted only by their owners.
- Global rules can be deleted by any user.
- All deletes are logged.
- Logs are more detailed.
- All logged actions can be viewed in aggregate.
**Minor Cleanup**
- Merged `HomeController` and `AllController`.
- Moved most queries to Query classes.
- Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
- Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
- Reenable some transaction code (this works again now).
- Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
- Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
- Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
- Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
- Browsed, created, edited, deleted personal and gules.
- Verified generated logs.
- Did some dry runs.
- Verified transcript list and transcript details.
- Created/edited all/any rules; created/edited once/every time rules.
- Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
2012-03-30 10:49:55 -07:00
|
|
|
'history/(?:(?P<id>\d+)/)?' => 'HeraldRuleEditHistoryController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'delete/(?P<id>\d+)/' => 'HeraldDeleteController',
|
|
|
|
'test/' => 'HeraldTestConsoleController',
|
|
|
|
'transcript/' => 'HeraldTranscriptListController',
|
|
|
|
'transcript/(?P<id>\d+)/(?:(?P<filter>\w+)/)?'
|
2011-03-24 21:32:26 -07:00
|
|
|
=> 'HeraldTranscriptController',
|
2011-03-22 13:49:46 -07:00
|
|
|
),
|
|
|
|
|
2011-03-31 17:06:33 -07:00
|
|
|
'/uiexample/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorUIExampleRenderController',
|
|
|
|
'view/(?P<class>[^/]+)/' => 'PhabricatorUIExampleRenderController',
|
2011-03-31 17:06:33 -07:00
|
|
|
),
|
|
|
|
|
2011-04-03 14:48:36 -07:00
|
|
|
'/owners/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorOwnersListController',
|
|
|
|
'view/(?P<view>[^/]+)/' => 'PhabricatorOwnersListController',
|
|
|
|
'edit/(?P<id>\d+)/' => 'PhabricatorOwnersEditController',
|
|
|
|
'new/' => 'PhabricatorOwnersEditController',
|
|
|
|
'package/(?P<id>\d+)/' => 'PhabricatorOwnersDetailController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'PhabricatorOwnersDeleteController',
|
2011-04-03 14:48:36 -07:00
|
|
|
),
|
|
|
|
|
Add Basic Auditing Functionalities
Summary:
add basic auditing functionalities. For the related commits for a
package, we detect the following conditions which might be suspicious to the
owners of the package:
* no revision specified
* revision not found
* author not match
* reviewedby not match
* owners not involved
* commit author not recognized
The owners of the package can change the status of the audit entries by
accepting it or specify concern.
The owner can turn on/off the auditing for a package.
Test Plan:
* verified that non-owner cannot see the details of the audit and cannot modify
it
* verified that all the audit reasons can be detected
* tested dropdown filtering and package search
* verified really normal change not detected
* verified accept/concern a commit
* tested enable/disable a package for auditing
* verified one audit applies to all <commit, packages> to the packages the
auditor owns
* verified that re-parsing a commit won't have effect if there exists a
relationship for <commit, package> already
Reviewers: epriestley, nh
Reviewed By: epriestley
CC: aran, benmathews, btrahan, mpodobnik, prithvi, TomL, epriestley
Differential Revision: 1242
2011-12-17 15:52:54 -08:00
|
|
|
'/audit/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorAuditListController',
|
|
|
|
'view/(?P<filter>[^/]+)/(?:(?P<name>[^/]+)/)?'
|
2012-02-28 21:12:08 -08:00
|
|
|
=> 'PhabricatorAuditListController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'addcomment/' => 'PhabricatorAuditAddCommentController',
|
|
|
|
'preview/(?P<id>\d+)/' => 'PhabricatorAuditPreviewController',
|
Add Basic Auditing Functionalities
Summary:
add basic auditing functionalities. For the related commits for a
package, we detect the following conditions which might be suspicious to the
owners of the package:
* no revision specified
* revision not found
* author not match
* reviewedby not match
* owners not involved
* commit author not recognized
The owners of the package can change the status of the audit entries by
accepting it or specify concern.
The owner can turn on/off the auditing for a package.
Test Plan:
* verified that non-owner cannot see the details of the audit and cannot modify
it
* verified that all the audit reasons can be detected
* tested dropdown filtering and package search
* verified really normal change not detected
* verified accept/concern a commit
* tested enable/disable a package for auditing
* verified one audit applies to all <commit, packages> to the packages the
auditor owns
* verified that re-parsing a commit won't have effect if there exists a
relationship for <commit, package> already
Reviewers: epriestley, nh
Reviewed By: epriestley
CC: aran, benmathews, btrahan, mpodobnik, prithvi, TomL, epriestley
Differential Revision: 1242
2011-12-17 15:52:54 -08:00
|
|
|
),
|
|
|
|
|
2011-04-06 19:17:05 -07:00
|
|
|
'/xhpast/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorXHPASTViewRunController',
|
|
|
|
'view/(?P<id>\d+)/'
|
2011-04-06 19:17:05 -07:00
|
|
|
=> 'PhabricatorXHPASTViewFrameController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'frameset/(?P<id>\d+)/'
|
2011-04-06 19:17:05 -07:00
|
|
|
=> 'PhabricatorXHPASTViewFramesetController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'input/(?P<id>\d+)/'
|
2011-04-06 19:17:05 -07:00
|
|
|
=> 'PhabricatorXHPASTViewInputController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'tree/(?P<id>\d+)/'
|
2011-04-06 19:17:05 -07:00
|
|
|
=> 'PhabricatorXHPASTViewTreeController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'stream/(?P<id>\d+)/'
|
2011-04-06 19:17:05 -07:00
|
|
|
=> 'PhabricatorXHPASTViewStreamController',
|
|
|
|
),
|
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'/status/' => 'PhabricatorStatusController',
|
2011-04-08 11:13:29 -07:00
|
|
|
|
2011-06-10 02:53:53 -04:00
|
|
|
'/paste/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorPasteListController',
|
|
|
|
'filter/(?P<filter>\w+)/' => 'PhabricatorPasteListController',
|
2011-06-10 02:53:53 -04:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'/P(?P<id>\d+)' => 'PhabricatorPasteViewController',
|
2011-06-10 02:53:53 -04:00
|
|
|
|
2011-05-28 11:36:00 -07:00
|
|
|
'/help/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'keyboardshortcut/' => 'PhabricatorHelpKeyboardShortcutController',
|
2011-05-28 11:36:00 -07:00
|
|
|
),
|
2011-06-12 23:06:17 +00:00
|
|
|
|
|
|
|
'/countdown/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
''
|
2011-06-12 23:06:17 +00:00
|
|
|
=> 'PhabricatorCountdownListController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'(?P<id>\d+)/'
|
2011-06-12 23:06:17 +00:00
|
|
|
=> 'PhabricatorCountdownViewController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'edit/(?:(?P<id>\d+)/)?'
|
2011-06-12 23:06:17 +00:00
|
|
|
=> 'PhabricatorCountdownEditController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'delete/(?P<id>\d+)/'
|
2011-06-12 23:06:17 +00:00
|
|
|
=> 'PhabricatorCountdownDeleteController'
|
|
|
|
),
|
2011-07-05 08:35:18 -07:00
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'/V(?P<id>\d+)' => 'PhabricatorSlowvotePollController',
|
2011-07-08 11:13:11 -07:00
|
|
|
'/vote/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'(?:view/(?P<view>\w+)/)?' => 'PhabricatorSlowvoteListController',
|
|
|
|
'create/' => 'PhabricatorSlowvoteCreateController',
|
2011-07-08 11:13:11 -07:00
|
|
|
),
|
2011-07-11 08:54:22 -07:00
|
|
|
|
|
|
|
// Match "/w/" with slug "/".
|
2012-03-01 11:46:58 -08:00
|
|
|
'/w(?P<slug>/)' => 'PhrictionDocumentController',
|
2011-07-11 08:54:22 -07:00
|
|
|
// Match "/w/x/y/z/" with slug "x/y/z/".
|
2012-03-01 11:46:58 -08:00
|
|
|
'/w/(?P<slug>.+/)' => 'PhrictionDocumentController',
|
2011-07-11 12:34:53 -07:00
|
|
|
|
|
|
|
'/phriction/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhrictionListController',
|
|
|
|
'list/(?P<view>[^/]+)/' => 'PhrictionListController',
|
2011-07-11 15:42:12 -07:00
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'history(?P<slug>/)' => 'PhrictionHistoryController',
|
|
|
|
'history/(?P<slug>.+/)' => 'PhrictionHistoryController',
|
2011-07-11 15:06:19 -07:00
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'edit/(?:(?P<id>\d+)/)?' => 'PhrictionEditController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'PhrictionDeleteController',
|
2011-07-16 18:25:45 -07:00
|
|
|
|
2012-03-01 11:46:58 -08:00
|
|
|
'preview/' => 'PhrictionDocumentPreviewController',
|
|
|
|
'diff/(?P<id>\d+)/' => 'PhrictionDiffController',
|
2011-07-11 12:34:53 -07:00
|
|
|
),
|
Build a basic calendar view
Summary:
This is a very small step toward building a Status and possibly an Oncall tool.
Build a calendar view which renders months.
Much of my hesitance to bang these tools out is that dealing with
dates/calendaring is basically horrible, so I'm trying to ease into it.
This calendar is locale-aware and all that jazz.
Test Plan:
- See:
https://secure.phabricator.com/file/view/PHID-FILE-c07a9c663a7d040d2529/
- Verified that months have the right number of days, today is the right day
of the week, months begin on the day after previous months end on, etc.
Reviewed By: aran
Reviewers: jungejason, tuomaspelkonen, aran
Commenters: cwbeck, jungejason
CC: blair, aran, epriestley, cwbeck, jungejason
Differential Revision: 791
2011-08-07 18:26:31 -07:00
|
|
|
|
2012-04-12 13:09:04 -07:00
|
|
|
'/phame/' => array(
|
|
|
|
'' => 'PhamePostListController',
|
|
|
|
'post/' => array(
|
|
|
|
'' => 'PhamePostListController',
|
|
|
|
'delete/(?P<phid>[^/]+)/' => 'PhamePostDeleteController',
|
|
|
|
'edit/(?P<phid>[^/]+)/' => 'PhamePostEditController',
|
|
|
|
'new/' => 'PhamePostEditController',
|
|
|
|
'preview/' => 'PhamePostPreviewController',
|
|
|
|
'view/(?P<phid>[^/]+)/' => 'PhamePostViewController',
|
|
|
|
),
|
|
|
|
'draft/' => array(
|
|
|
|
'' => 'PhameDraftListController',
|
|
|
|
'new/' => 'PhamePostEditController',
|
|
|
|
),
|
|
|
|
'posts/' => array(
|
|
|
|
'' => 'PhamePostListController',
|
|
|
|
'(?P<bloggername>\w+)/' => 'PhamePostListController',
|
|
|
|
'(?P<bloggername>\w+)/(?P<phametitle>.+/)'
|
|
|
|
=> 'PhamePostViewController',
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|
Build a basic calendar view
Summary:
This is a very small step toward building a Status and possibly an Oncall tool.
Build a calendar view which renders months.
Much of my hesitance to bang these tools out is that dealing with
dates/calendaring is basically horrible, so I'm trying to ease into it.
This calendar is locale-aware and all that jazz.
Test Plan:
- See:
https://secure.phabricator.com/file/view/PHID-FILE-c07a9c663a7d040d2529/
- Verified that months have the right number of days, today is the right day
of the week, months begin on the day after previous months end on, etc.
Reviewed By: aran
Reviewers: jungejason, tuomaspelkonen, aran
Commenters: cwbeck, jungejason
CC: blair, aran, epriestley, cwbeck, jungejason
Differential Revision: 791
2011-08-07 18:26:31 -07:00
|
|
|
'/calendar/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'PhabricatorCalendarBrowseController',
|
Build a basic calendar view
Summary:
This is a very small step toward building a Status and possibly an Oncall tool.
Build a calendar view which renders months.
Much of my hesitance to bang these tools out is that dealing with
dates/calendaring is basically horrible, so I'm trying to ease into it.
This calendar is locale-aware and all that jazz.
Test Plan:
- See:
https://secure.phabricator.com/file/view/PHID-FILE-c07a9c663a7d040d2529/
- Verified that months have the right number of days, today is the right day
of the week, months begin on the day after previous months end on, etc.
Reviewed By: aran
Reviewers: jungejason, tuomaspelkonen, aran
Commenters: cwbeck, jungejason
CC: blair, aran, epriestley, cwbeck, jungejason
Differential Revision: 791
2011-08-07 18:26:31 -07:00
|
|
|
),
|
Drydock Rough Cut
Summary:
Rough cut of Drydock. This is very basic and doesn't do much of use yet (it
//does// allocate EC2 machines as host resources and expose interfaces to them),
but I think the overall structure is more or less reasonable.
== Interfaces
Vision: Applications interact with Drydock resources through DrydockInterfaces,
like **command**, **filesystem** and **httpd** interfaces. Each interface allows
applications to perform some kind of operation on the resource, like executing
commands, reading/writing files, or configuring a web server. Interfaces have a
concrete, specific API:
// Filesystem Interface
$fs = $lease->getInterface('filesystem'); // Constants, some day?
$fs->writeFile('index.html', 'hello world!');
// Command Interface
$cmd = $lease->getInterface('command');
echo $cmd->execx('uptime');
// HTTPD Interface
$httpd = $lease->getInterface('httpd');
$httpd->restart();
Interfaces are mostly just stock, although installs might add new interfaces if
they expose different ways to interact with resources (for instance, a resource
might want to expose a new 'MongoDB' interface or whatever).
Currently: We have like part of a command interface.
== Leases
Vision: Leases keep track of which resources are in use, and what they're being
used for. They allow us to know when we need to allocate more resources (too
many sandcastles on the existing hosts, e.g.) and when we can release resources
(because they are no longer being used). They also give applications something
to hold while resources are being allocated.
// EXAMPLE: How this should work some day.
$allocator = new DrydockAllocator();
$allocator->setResourceType('sandcastle');
$allocator->setAttributes(
array(
'diffID' => $diff->getID(),
));
$lease = $allocator->allocate();
$diff->setSandcastleLeaseID($lease->getID());
// ...
if ($lease->getStatus() == DrydockLeaseStatus::STATUS_ACTIVE) {
$sandcastle_link = $lease->getInterface('httpd')->getURI('/');
} else {
$sandcastle_link = 'Still building your sandcastle...';
}
echo "Sandcastle for this diff: ".$sandcastle_link;
// EXAMPLE: How this actually works now.
$allocator = new DrydockAllocator();
$allocator->setResourceType('host');
// NOTE: Allocation is currently synchronous but will be task-driven soon.
$lease = $allocator->allocate();
Leases are completely stock, installs will not define new lease types.
Currently: Leases exist and work but are very very basic.
== Resources
Vision: Resources represent some actual thing we've put somewhere, whether it's
a host, a block of storage, a webroot, or whatever else. Applications interact
through resources by acquiring leases to them, and then getting interfaces
through these leases. The lease acquisition process has a side effect of
allocating new resources if a lease can't be acquired on existing resources
(e.g., the application wants storage but all storage resources are full) and
things are configured to autoscale.
Resources may themselves acquire leases in order to allocate. For instance, a
storage resource might first acquire a lease to a host resource. A 'test
scaffold' resource might lease a storage resource and a mysql resource.
Not all resources are auto-allocate: the entry-level version of Drydock is that
you manually allocate a couple boxes and configure them through the web console.
Then, e.g., 'storage' / 'webroot' resources allocate on top of them, but the
host pool itself does not autoscale.
Resources are completely stock, they are abstract shells representing any
arbitrary thing.
Currently: Resource exist ('host' only) but are very very basic.
== Blueprints
Vision: Blueprints contain instructions for building interfaces to, (possibly)
allocating, updating, managing, and destroying a specific type of resource in a
specific location. One way to think of them is that they are scripts for
creating and deleting resources. For example, the LocalHost, RemoteHost and
EC2Host blueprints can all manage 'host' resources.
Eventually, we will support more types of resources (storage, webroot,
sandcastle, test scaffold, phacility deployment) and more providers for resource
types, some of which will be in the Phabricator mainline and some of which will
be custom.
Blueprints are very custom and specific to application types, so installs will
define new blueprints if they are making significant use of Drydock.
Currently: They exist but have few capabilities. The stock blueprints do nearly
nothing useful. There is a technically functional blueprint for host allocation
in EC2.
== Allocator
This is just the actual code to execute the lease acquisition process.
Test Plan: Ran "drydock_control.php" script, it allocated a machine in EC2,
acquired a lease on it, interfaced with it, and then released the lease. Ran it
again, got a fresh lease on the existing resource.
Reviewers: btrahan, jungejason
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D1454
2012-01-11 11:18:40 -08:00
|
|
|
|
|
|
|
'/drydock/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'DrydockResourceListController',
|
|
|
|
'resource/' => 'DrydockResourceListController',
|
|
|
|
'resource/allocate/' => 'DrydockResourceAllocateController',
|
Drydock Rough Cut
Summary:
Rough cut of Drydock. This is very basic and doesn't do much of use yet (it
//does// allocate EC2 machines as host resources and expose interfaces to them),
but I think the overall structure is more or less reasonable.
== Interfaces
Vision: Applications interact with Drydock resources through DrydockInterfaces,
like **command**, **filesystem** and **httpd** interfaces. Each interface allows
applications to perform some kind of operation on the resource, like executing
commands, reading/writing files, or configuring a web server. Interfaces have a
concrete, specific API:
// Filesystem Interface
$fs = $lease->getInterface('filesystem'); // Constants, some day?
$fs->writeFile('index.html', 'hello world!');
// Command Interface
$cmd = $lease->getInterface('command');
echo $cmd->execx('uptime');
// HTTPD Interface
$httpd = $lease->getInterface('httpd');
$httpd->restart();
Interfaces are mostly just stock, although installs might add new interfaces if
they expose different ways to interact with resources (for instance, a resource
might want to expose a new 'MongoDB' interface or whatever).
Currently: We have like part of a command interface.
== Leases
Vision: Leases keep track of which resources are in use, and what they're being
used for. They allow us to know when we need to allocate more resources (too
many sandcastles on the existing hosts, e.g.) and when we can release resources
(because they are no longer being used). They also give applications something
to hold while resources are being allocated.
// EXAMPLE: How this should work some day.
$allocator = new DrydockAllocator();
$allocator->setResourceType('sandcastle');
$allocator->setAttributes(
array(
'diffID' => $diff->getID(),
));
$lease = $allocator->allocate();
$diff->setSandcastleLeaseID($lease->getID());
// ...
if ($lease->getStatus() == DrydockLeaseStatus::STATUS_ACTIVE) {
$sandcastle_link = $lease->getInterface('httpd')->getURI('/');
} else {
$sandcastle_link = 'Still building your sandcastle...';
}
echo "Sandcastle for this diff: ".$sandcastle_link;
// EXAMPLE: How this actually works now.
$allocator = new DrydockAllocator();
$allocator->setResourceType('host');
// NOTE: Allocation is currently synchronous but will be task-driven soon.
$lease = $allocator->allocate();
Leases are completely stock, installs will not define new lease types.
Currently: Leases exist and work but are very very basic.
== Resources
Vision: Resources represent some actual thing we've put somewhere, whether it's
a host, a block of storage, a webroot, or whatever else. Applications interact
through resources by acquiring leases to them, and then getting interfaces
through these leases. The lease acquisition process has a side effect of
allocating new resources if a lease can't be acquired on existing resources
(e.g., the application wants storage but all storage resources are full) and
things are configured to autoscale.
Resources may themselves acquire leases in order to allocate. For instance, a
storage resource might first acquire a lease to a host resource. A 'test
scaffold' resource might lease a storage resource and a mysql resource.
Not all resources are auto-allocate: the entry-level version of Drydock is that
you manually allocate a couple boxes and configure them through the web console.
Then, e.g., 'storage' / 'webroot' resources allocate on top of them, but the
host pool itself does not autoscale.
Resources are completely stock, they are abstract shells representing any
arbitrary thing.
Currently: Resource exist ('host' only) but are very very basic.
== Blueprints
Vision: Blueprints contain instructions for building interfaces to, (possibly)
allocating, updating, managing, and destroying a specific type of resource in a
specific location. One way to think of them is that they are scripts for
creating and deleting resources. For example, the LocalHost, RemoteHost and
EC2Host blueprints can all manage 'host' resources.
Eventually, we will support more types of resources (storage, webroot,
sandcastle, test scaffold, phacility deployment) and more providers for resource
types, some of which will be in the Phabricator mainline and some of which will
be custom.
Blueprints are very custom and specific to application types, so installs will
define new blueprints if they are making significant use of Drydock.
Currently: They exist but have few capabilities. The stock blueprints do nearly
nothing useful. There is a technically functional blueprint for host allocation
in EC2.
== Allocator
This is just the actual code to execute the lease acquisition process.
Test Plan: Ran "drydock_control.php" script, it allocated a machine in EC2,
acquired a lease on it, interfaced with it, and then released the lease. Ran it
again, got a fresh lease on the existing resource.
Reviewers: btrahan, jungejason
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D1454
2012-01-11 11:18:40 -08:00
|
|
|
'host/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' => 'DrydockHostListController',
|
|
|
|
'edit/' => 'DrydockHostEditController',
|
|
|
|
'edit/(?P<id>\d+)/' => 'DrydockhostEditController',
|
Drydock Rough Cut
Summary:
Rough cut of Drydock. This is very basic and doesn't do much of use yet (it
//does// allocate EC2 machines as host resources and expose interfaces to them),
but I think the overall structure is more or less reasonable.
== Interfaces
Vision: Applications interact with Drydock resources through DrydockInterfaces,
like **command**, **filesystem** and **httpd** interfaces. Each interface allows
applications to perform some kind of operation on the resource, like executing
commands, reading/writing files, or configuring a web server. Interfaces have a
concrete, specific API:
// Filesystem Interface
$fs = $lease->getInterface('filesystem'); // Constants, some day?
$fs->writeFile('index.html', 'hello world!');
// Command Interface
$cmd = $lease->getInterface('command');
echo $cmd->execx('uptime');
// HTTPD Interface
$httpd = $lease->getInterface('httpd');
$httpd->restart();
Interfaces are mostly just stock, although installs might add new interfaces if
they expose different ways to interact with resources (for instance, a resource
might want to expose a new 'MongoDB' interface or whatever).
Currently: We have like part of a command interface.
== Leases
Vision: Leases keep track of which resources are in use, and what they're being
used for. They allow us to know when we need to allocate more resources (too
many sandcastles on the existing hosts, e.g.) and when we can release resources
(because they are no longer being used). They also give applications something
to hold while resources are being allocated.
// EXAMPLE: How this should work some day.
$allocator = new DrydockAllocator();
$allocator->setResourceType('sandcastle');
$allocator->setAttributes(
array(
'diffID' => $diff->getID(),
));
$lease = $allocator->allocate();
$diff->setSandcastleLeaseID($lease->getID());
// ...
if ($lease->getStatus() == DrydockLeaseStatus::STATUS_ACTIVE) {
$sandcastle_link = $lease->getInterface('httpd')->getURI('/');
} else {
$sandcastle_link = 'Still building your sandcastle...';
}
echo "Sandcastle for this diff: ".$sandcastle_link;
// EXAMPLE: How this actually works now.
$allocator = new DrydockAllocator();
$allocator->setResourceType('host');
// NOTE: Allocation is currently synchronous but will be task-driven soon.
$lease = $allocator->allocate();
Leases are completely stock, installs will not define new lease types.
Currently: Leases exist and work but are very very basic.
== Resources
Vision: Resources represent some actual thing we've put somewhere, whether it's
a host, a block of storage, a webroot, or whatever else. Applications interact
through resources by acquiring leases to them, and then getting interfaces
through these leases. The lease acquisition process has a side effect of
allocating new resources if a lease can't be acquired on existing resources
(e.g., the application wants storage but all storage resources are full) and
things are configured to autoscale.
Resources may themselves acquire leases in order to allocate. For instance, a
storage resource might first acquire a lease to a host resource. A 'test
scaffold' resource might lease a storage resource and a mysql resource.
Not all resources are auto-allocate: the entry-level version of Drydock is that
you manually allocate a couple boxes and configure them through the web console.
Then, e.g., 'storage' / 'webroot' resources allocate on top of them, but the
host pool itself does not autoscale.
Resources are completely stock, they are abstract shells representing any
arbitrary thing.
Currently: Resource exist ('host' only) but are very very basic.
== Blueprints
Vision: Blueprints contain instructions for building interfaces to, (possibly)
allocating, updating, managing, and destroying a specific type of resource in a
specific location. One way to think of them is that they are scripts for
creating and deleting resources. For example, the LocalHost, RemoteHost and
EC2Host blueprints can all manage 'host' resources.
Eventually, we will support more types of resources (storage, webroot,
sandcastle, test scaffold, phacility deployment) and more providers for resource
types, some of which will be in the Phabricator mainline and some of which will
be custom.
Blueprints are very custom and specific to application types, so installs will
define new blueprints if they are making significant use of Drydock.
Currently: They exist but have few capabilities. The stock blueprints do nearly
nothing useful. There is a technically functional blueprint for host allocation
in EC2.
== Allocator
This is just the actual code to execute the lease acquisition process.
Test Plan: Ran "drydock_control.php" script, it allocated a machine in EC2,
acquired a lease on it, interfaced with it, and then released the lease. Ran it
again, got a fresh lease on the existing resource.
Reviewers: btrahan, jungejason
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D1454
2012-01-11 11:18:40 -08:00
|
|
|
),
|
2012-03-01 11:46:58 -08:00
|
|
|
'lease/' => 'DrydockLeaseListController',
|
2012-03-26 20:54:26 -07:00
|
|
|
'log/' => 'DrydockLogController',
|
Drydock Rough Cut
Summary:
Rough cut of Drydock. This is very basic and doesn't do much of use yet (it
//does// allocate EC2 machines as host resources and expose interfaces to them),
but I think the overall structure is more or less reasonable.
== Interfaces
Vision: Applications interact with Drydock resources through DrydockInterfaces,
like **command**, **filesystem** and **httpd** interfaces. Each interface allows
applications to perform some kind of operation on the resource, like executing
commands, reading/writing files, or configuring a web server. Interfaces have a
concrete, specific API:
// Filesystem Interface
$fs = $lease->getInterface('filesystem'); // Constants, some day?
$fs->writeFile('index.html', 'hello world!');
// Command Interface
$cmd = $lease->getInterface('command');
echo $cmd->execx('uptime');
// HTTPD Interface
$httpd = $lease->getInterface('httpd');
$httpd->restart();
Interfaces are mostly just stock, although installs might add new interfaces if
they expose different ways to interact with resources (for instance, a resource
might want to expose a new 'MongoDB' interface or whatever).
Currently: We have like part of a command interface.
== Leases
Vision: Leases keep track of which resources are in use, and what they're being
used for. They allow us to know when we need to allocate more resources (too
many sandcastles on the existing hosts, e.g.) and when we can release resources
(because they are no longer being used). They also give applications something
to hold while resources are being allocated.
// EXAMPLE: How this should work some day.
$allocator = new DrydockAllocator();
$allocator->setResourceType('sandcastle');
$allocator->setAttributes(
array(
'diffID' => $diff->getID(),
));
$lease = $allocator->allocate();
$diff->setSandcastleLeaseID($lease->getID());
// ...
if ($lease->getStatus() == DrydockLeaseStatus::STATUS_ACTIVE) {
$sandcastle_link = $lease->getInterface('httpd')->getURI('/');
} else {
$sandcastle_link = 'Still building your sandcastle...';
}
echo "Sandcastle for this diff: ".$sandcastle_link;
// EXAMPLE: How this actually works now.
$allocator = new DrydockAllocator();
$allocator->setResourceType('host');
// NOTE: Allocation is currently synchronous but will be task-driven soon.
$lease = $allocator->allocate();
Leases are completely stock, installs will not define new lease types.
Currently: Leases exist and work but are very very basic.
== Resources
Vision: Resources represent some actual thing we've put somewhere, whether it's
a host, a block of storage, a webroot, or whatever else. Applications interact
through resources by acquiring leases to them, and then getting interfaces
through these leases. The lease acquisition process has a side effect of
allocating new resources if a lease can't be acquired on existing resources
(e.g., the application wants storage but all storage resources are full) and
things are configured to autoscale.
Resources may themselves acquire leases in order to allocate. For instance, a
storage resource might first acquire a lease to a host resource. A 'test
scaffold' resource might lease a storage resource and a mysql resource.
Not all resources are auto-allocate: the entry-level version of Drydock is that
you manually allocate a couple boxes and configure them through the web console.
Then, e.g., 'storage' / 'webroot' resources allocate on top of them, but the
host pool itself does not autoscale.
Resources are completely stock, they are abstract shells representing any
arbitrary thing.
Currently: Resource exist ('host' only) but are very very basic.
== Blueprints
Vision: Blueprints contain instructions for building interfaces to, (possibly)
allocating, updating, managing, and destroying a specific type of resource in a
specific location. One way to think of them is that they are scripts for
creating and deleting resources. For example, the LocalHost, RemoteHost and
EC2Host blueprints can all manage 'host' resources.
Eventually, we will support more types of resources (storage, webroot,
sandcastle, test scaffold, phacility deployment) and more providers for resource
types, some of which will be in the Phabricator mainline and some of which will
be custom.
Blueprints are very custom and specific to application types, so installs will
define new blueprints if they are making significant use of Drydock.
Currently: They exist but have few capabilities. The stock blueprints do nearly
nothing useful. There is a technically functional blueprint for host allocation
in EC2.
== Allocator
This is just the actual code to execute the lease acquisition process.
Test Plan: Ran "drydock_control.php" script, it allocated a machine in EC2,
acquired a lease on it, interfaced with it, and then released the lease. Ran it
again, got a fresh lease on the existing resource.
Reviewers: btrahan, jungejason
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D1454
2012-01-11 11:18:40 -08:00
|
|
|
),
|
2012-02-17 10:21:38 -08:00
|
|
|
|
|
|
|
'/chatlog/' => array(
|
2012-03-01 11:46:58 -08:00
|
|
|
'' =>
|
2012-02-17 10:21:38 -08:00
|
|
|
'PhabricatorChatLogChannelListController',
|
2012-03-01 11:46:58 -08:00
|
|
|
'channel/(?P<channel>[^/]+)/' =>
|
2012-02-17 10:21:38 -08:00
|
|
|
'PhabricatorChatLogChannelLogController',
|
|
|
|
),
|
2012-03-06 20:14:03 -08:00
|
|
|
|
|
|
|
'/aphlict/' => 'PhabricatorAphlictTestPageController',
|
2012-03-27 16:22:40 -07:00
|
|
|
|
|
|
|
'/flag/' => array(
|
|
|
|
'' => 'PhabricatorFlagListController',
|
|
|
|
'view/(?P<view>[^/]+)/' => 'PhabricatorFlagListController',
|
|
|
|
'edit/(?P<phid>[^/]+)/' => 'PhabricatorFlagEditController',
|
|
|
|
'delete/(?P<id>\d+)/' => 'PhabricatorFlagDeleteController',
|
|
|
|
),
|
2012-04-04 16:09:29 -07:00
|
|
|
|
|
|
|
'/phortune/' => array(
|
|
|
|
'stripe/' => array(
|
|
|
|
'testpaymentform/' => 'PhortuneStripeTestPaymentFormController',
|
|
|
|
),
|
|
|
|
),
|
2011-02-24 14:52:57 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getResourceURIMapRules() {
|
|
|
|
return array(
|
|
|
|
'/res/' => array(
|
Use Celerity to version all static resources
Summary:
We don't use versioned URIs for images, so when they change users may get old versions.
This was a particular issue with the recent logo change, which several users reported cache-related issues from.
Instead, use Celerity to manage image URI versions in addition to CSS/JS.
This is complicated, because we need to rewrite image URIs inside of CSS, which means the hash of a CSS file has to be derived from the current image data. Otherwise, when we updated an image the CSS wouldn't update, so we wouldn't be any better off.
So basically we:
- Find all the "raw" files, and put them into the map.
- Find all the CSS/JS, perform content-altering transformations on it (i.e., not minification) based on the partial map, and then put it into the map based on transformed hashes.
(If we wanted, we could now do CSS variables or whatever for "free", more or less.)
Test Plan:
- Regenerated celerity map, browsed site, verified images generated with versioned URIs.
- Moved "blue" flag image over "green" flag image, regenerated map, verified "green" flag image and the associated CSS changed hashes.
- Added transformation unit tests; ran unit tests.
Reviewers: btrahan, vrana, jungejason
Reviewed By: vrana
CC: aran
Maniphest Tasks: T1073
Differential Revision: https://secure.phabricator.com/D2146
2012-04-08 10:07:51 -07:00
|
|
|
'(?P<package>pkg/)?'.
|
|
|
|
'(?P<hash>[a-f0-9]{8})/'.
|
|
|
|
'(?P<path>.+\.(?:css|js|jpg|png|swf|gif))'
|
2011-02-24 14:52:57 -08:00
|
|
|
=> 'CelerityResourceController',
|
|
|
|
),
|
2011-01-16 13:51:39 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildRequest() {
|
|
|
|
$request = new AphrontRequest($this->getHost(), $this->getPath());
|
|
|
|
$request->setRequestData($_GET + $_POST);
|
2011-02-02 13:48:52 -08:00
|
|
|
$request->setApplicationConfiguration($this);
|
2011-01-16 13:51:39 -08:00
|
|
|
return $request;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function handleException(Exception $ex) {
|
|
|
|
|
Add basic per-object privacy policies
Summary:
Provides a basic start for access policies. Objects expose various capabilities, like CAN_VIEW, CAN_EDIT, etc., and set a policy for each capability. We currently implement three policies, PUBLIC (anyone, including logged-out), USERS (any logged-in) and NOONE (nobody). There's also a way to provide automatic capability grants (e.g., the owner of an object can always see it, even if some capability is set to "NOONE"), but I'm not sure how great the implementation feels and it might change.
Most of the code here is providing a primitive for efficient policy-aware list queries. The problem with doing queries naively is that you have to do crazy amounts of filtering, e.g. to show the user page 6, you need to filter at least 600 objects (and likely more) before you can figure out which ones are 500-600 for them. You can't just do "LIMIT 500, 100" because that might have only 50 results, or no results. Instead, the query looks like "WHERE id > last_visible_id", and then we fetch additional pages as necessary to satisfy the request.
The general idea is that we move all data access to Query classes and have them do object filtering. The ID paging primitive allows efficient paging in most cases, and the executeOne() method provides a concise way to do policy checks for edit/view screens.
We'll probably end up with mostly broader policy UIs or configuration-based policies, but there are at least a few cases for per-object privacy (e.g., marking tasks as "Security", and restricting things to the members of projects) so I figured we'd start with a flexible primitive and the simplify it in the UI where we can.
Test Plan: Unit tests, played around in the UI with various policy settings.
Reviewers: btrahan, vrana, jungejason
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T603
Differential Revision: https://secure.phabricator.com/D2210
2012-04-14 10:13:29 -07:00
|
|
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
2011-01-16 13:51:39 -08:00
|
|
|
|
2012-04-04 17:53:16 -07:00
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
if (!$user) {
|
|
|
|
// If we hit an exception very early, we won't have a user.
|
|
|
|
$user = new PhabricatorUser();
|
|
|
|
}
|
|
|
|
|
Add basic per-object privacy policies
Summary:
Provides a basic start for access policies. Objects expose various capabilities, like CAN_VIEW, CAN_EDIT, etc., and set a policy for each capability. We currently implement three policies, PUBLIC (anyone, including logged-out), USERS (any logged-in) and NOONE (nobody). There's also a way to provide automatic capability grants (e.g., the owner of an object can always see it, even if some capability is set to "NOONE"), but I'm not sure how great the implementation feels and it might change.
Most of the code here is providing a primitive for efficient policy-aware list queries. The problem with doing queries naively is that you have to do crazy amounts of filtering, e.g. to show the user page 6, you need to filter at least 600 objects (and likely more) before you can figure out which ones are 500-600 for them. You can't just do "LIMIT 500, 100" because that might have only 50 results, or no results. Instead, the query looks like "WHERE id > last_visible_id", and then we fetch additional pages as necessary to satisfy the request.
The general idea is that we move all data access to Query classes and have them do object filtering. The ID paging primitive allows efficient paging in most cases, and the executeOne() method provides a concise way to do policy checks for edit/view screens.
We'll probably end up with mostly broader policy UIs or configuration-based policies, but there are at least a few cases for per-object privacy (e.g., marking tasks as "Security", and restricting things to the members of projects) so I figured we'd start with a flexible primitive and the simplify it in the UI where we can.
Test Plan: Unit tests, played around in the UI with various policy settings.
Reviewers: btrahan, vrana, jungejason
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T603
Differential Revision: https://secure.phabricator.com/D2210
2012-04-14 10:13:29 -07:00
|
|
|
if ($ex instanceof PhabricatorPolicyException) {
|
|
|
|
$content =
|
|
|
|
'<div class="aphront-policy-exception">'.
|
|
|
|
phutil_escape_html($ex->getMessage()).
|
|
|
|
'</div>';
|
|
|
|
|
|
|
|
$dialog = new AphrontDialogView();
|
|
|
|
$dialog
|
|
|
|
->setTitle(
|
|
|
|
$is_serious
|
|
|
|
? 'Access Denied'
|
|
|
|
: "You Shall Not Pass")
|
|
|
|
->setClass('aphront-access-dialog')
|
|
|
|
->setUser($user)
|
|
|
|
->appendChild($content);
|
|
|
|
|
|
|
|
if ($this->getRequest()->isAjax()) {
|
|
|
|
$dialog->addCancelButton('/', 'Close');
|
|
|
|
} else {
|
|
|
|
$dialog->addCancelButton('/', $is_serious ? 'OK' : 'Away With Thee');
|
|
|
|
}
|
|
|
|
|
|
|
|
$response = new AphrontDialogResponse();
|
|
|
|
$response->setDialog($dialog);
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2012-04-23 18:36:25 -07:00
|
|
|
if ($ex instanceof AphrontUsageException) {
|
|
|
|
$error = new AphrontErrorView();
|
|
|
|
$error->setTitle(phutil_escape_html($ex->getTitle()));
|
|
|
|
$error->appendChild(phutil_escape_html($ex->getMessage()));
|
|
|
|
|
|
|
|
$view = new PhabricatorStandardPageView();
|
|
|
|
$view->setRequest($this->getRequest());
|
|
|
|
$view->appendChild($error);
|
|
|
|
|
|
|
|
$response = new AphrontWebpageResponse();
|
|
|
|
$response->setContent($view->render());
|
|
|
|
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Add basic per-object privacy policies
Summary:
Provides a basic start for access policies. Objects expose various capabilities, like CAN_VIEW, CAN_EDIT, etc., and set a policy for each capability. We currently implement three policies, PUBLIC (anyone, including logged-out), USERS (any logged-in) and NOONE (nobody). There's also a way to provide automatic capability grants (e.g., the owner of an object can always see it, even if some capability is set to "NOONE"), but I'm not sure how great the implementation feels and it might change.
Most of the code here is providing a primitive for efficient policy-aware list queries. The problem with doing queries naively is that you have to do crazy amounts of filtering, e.g. to show the user page 6, you need to filter at least 600 objects (and likely more) before you can figure out which ones are 500-600 for them. You can't just do "LIMIT 500, 100" because that might have only 50 results, or no results. Instead, the query looks like "WHERE id > last_visible_id", and then we fetch additional pages as necessary to satisfy the request.
The general idea is that we move all data access to Query classes and have them do object filtering. The ID paging primitive allows efficient paging in most cases, and the executeOne() method provides a concise way to do policy checks for edit/view screens.
We'll probably end up with mostly broader policy UIs or configuration-based policies, but there are at least a few cases for per-object privacy (e.g., marking tasks as "Security", and restricting things to the members of projects) so I figured we'd start with a flexible primitive and the simplify it in the UI where we can.
Test Plan: Unit tests, played around in the UI with various policy settings.
Reviewers: btrahan, vrana, jungejason
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T603
Differential Revision: https://secure.phabricator.com/D2210
2012-04-14 10:13:29 -07:00
|
|
|
// Always log the unhandled exception.
|
|
|
|
phlog($ex);
|
|
|
|
|
|
|
|
$class = phutil_escape_html(get_class($ex));
|
|
|
|
$message = phutil_escape_html($ex->getMessage());
|
|
|
|
|
2011-08-17 14:29:53 -07:00
|
|
|
if (PhabricatorEnv::getEnvConfig('phabricator.show-stack-traces')) {
|
2012-04-04 17:53:16 -07:00
|
|
|
$trace = $this->renderStackTrace($ex->getTrace(), $user);
|
2011-08-17 14:29:53 -07:00
|
|
|
} else {
|
|
|
|
$trace = null;
|
|
|
|
}
|
2011-07-07 12:49:59 -07:00
|
|
|
|
2011-01-16 13:51:39 -08:00
|
|
|
$content =
|
|
|
|
'<div class="aphront-unhandled-exception">'.
|
2011-08-17 14:29:53 -07:00
|
|
|
'<div class="exception-message">'.$message.'</div>'.
|
|
|
|
$trace.
|
2011-01-16 13:51:39 -08:00
|
|
|
'</div>';
|
|
|
|
|
2011-02-26 20:57:21 -08:00
|
|
|
$dialog = new AphrontDialogView();
|
|
|
|
$dialog
|
2011-08-17 14:29:53 -07:00
|
|
|
->setTitle('Unhandled Exception ("'.$class.'")')
|
2011-02-26 20:57:21 -08:00
|
|
|
->setClass('aphront-exception-dialog')
|
|
|
|
->setUser($user)
|
2011-08-17 14:29:53 -07:00
|
|
|
->appendChild($content);
|
|
|
|
|
|
|
|
if ($this->getRequest()->isAjax()) {
|
|
|
|
$dialog->addCancelButton('/', 'Close');
|
|
|
|
}
|
2011-01-16 13:51:39 -08:00
|
|
|
|
2011-02-26 20:57:21 -08:00
|
|
|
$response = new AphrontDialogResponse();
|
|
|
|
$response->setDialog($dialog);
|
2011-01-16 13:51:39 -08:00
|
|
|
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function willSendResponse(AphrontResponse $response) {
|
|
|
|
$request = $this->getRequest();
|
2011-05-16 11:43:39 -07:00
|
|
|
$response->setRequest($request);
|
2011-01-16 13:51:39 -08:00
|
|
|
if ($response instanceof AphrontDialogResponse) {
|
|
|
|
if (!$request->isAjax()) {
|
2011-01-22 17:48:55 -08:00
|
|
|
$view = new PhabricatorStandardPageView();
|
2011-02-04 17:53:14 -08:00
|
|
|
$view->setRequest($request);
|
2011-01-16 13:51:39 -08:00
|
|
|
$view->appendChild(
|
|
|
|
'<div style="padding: 2em 0;">'.
|
|
|
|
$response->buildResponseString().
|
|
|
|
'</div>');
|
|
|
|
$response = new AphrontWebpageResponse();
|
|
|
|
$response->setContent($view->render());
|
|
|
|
return $response;
|
2011-02-01 16:42:36 -08:00
|
|
|
} else {
|
|
|
|
return id(new AphrontAjaxResponse())
|
|
|
|
->setContent(array(
|
|
|
|
'dialog' => $response->buildResponseString(),
|
|
|
|
));
|
2011-01-16 13:51:39 -08:00
|
|
|
}
|
2011-02-05 11:45:13 -08:00
|
|
|
} else if ($response instanceof AphrontRedirectResponse) {
|
|
|
|
if ($request->isAjax()) {
|
|
|
|
return id(new AphrontAjaxResponse())
|
|
|
|
->setContent(
|
|
|
|
array(
|
|
|
|
'redirect' => $response->getURI(),
|
|
|
|
));
|
|
|
|
}
|
2011-01-16 13:51:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2011-01-29 16:16:09 -08:00
|
|
|
public function build404Controller() {
|
2011-01-30 08:44:28 -08:00
|
|
|
return array(new Phabricator404Controller($this->getRequest()), array());
|
2011-01-29 16:16:09 -08:00
|
|
|
}
|
|
|
|
|
2011-04-04 10:29:46 -07:00
|
|
|
public function buildRedirectController($uri) {
|
|
|
|
return array(
|
|
|
|
new PhabricatorRedirectController($this->getRequest()),
|
|
|
|
array(
|
|
|
|
'uri' => $uri,
|
|
|
|
));
|
|
|
|
}
|
2011-01-16 13:51:39 -08:00
|
|
|
|
2012-04-04 17:53:16 -07:00
|
|
|
private function renderStackTrace($trace, PhabricatorUser $user) {
|
2011-08-17 14:29:53 -07:00
|
|
|
|
|
|
|
$libraries = PhutilBootloader::getInstance()->getAllLibraries();
|
|
|
|
|
|
|
|
// TODO: Make this configurable?
|
2012-04-04 17:53:16 -07:00
|
|
|
$path = 'https://secure.phabricator.com/diffusion/%s/browse/master/src/';
|
|
|
|
|
|
|
|
$callsigns = array(
|
|
|
|
'arcanist' => 'ARC',
|
|
|
|
'phutil' => 'PHU',
|
|
|
|
'phabricator' => 'P',
|
2011-08-17 14:29:53 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
$depth = count($trace);
|
|
|
|
foreach ($trace as $part) {
|
|
|
|
$lib = null;
|
2011-08-21 13:07:09 -07:00
|
|
|
$file = idx($part, 'file');
|
2011-08-17 14:29:53 -07:00
|
|
|
$relative = $file;
|
|
|
|
foreach ($libraries as $library) {
|
|
|
|
$root = phutil_get_library_root($library);
|
|
|
|
if (Filesystem::isDescendant($file, $root)) {
|
|
|
|
$lib = $library;
|
|
|
|
$relative = Filesystem::readablePath($file, $root);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$where = '';
|
|
|
|
if (isset($part['class'])) {
|
|
|
|
$where .= $part['class'].'::';
|
|
|
|
}
|
|
|
|
if (isset($part['function'])) {
|
|
|
|
$where .= $part['function'].'()';
|
|
|
|
}
|
|
|
|
|
2011-08-21 13:07:09 -07:00
|
|
|
if ($file) {
|
2012-04-04 17:53:16 -07:00
|
|
|
if (isset($callsigns[$lib])) {
|
2012-04-07 10:09:19 -07:00
|
|
|
$attrs = array('title' => $file);
|
|
|
|
try {
|
|
|
|
$attrs['href'] = $user->loadEditorLink(
|
2012-04-04 17:53:16 -07:00
|
|
|
'/src/'.$relative,
|
|
|
|
$part['line'],
|
2012-04-07 10:09:19 -07:00
|
|
|
$callsigns[$lib]);
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
// The database can be inaccessible.
|
|
|
|
}
|
|
|
|
if (empty($attrs['href'])) {
|
2012-04-04 17:53:16 -07:00
|
|
|
$attrs['href'] = sprintf($path, $callsigns[$lib]).
|
2012-04-06 15:54:45 -07:00
|
|
|
str_replace(DIRECTORY_SEPARATOR, '/', $relative).
|
|
|
|
'$'.$part['line'];
|
2012-04-04 17:53:16 -07:00
|
|
|
$attrs['target'] = '_blank';
|
|
|
|
}
|
2011-08-21 13:07:09 -07:00
|
|
|
$file_name = phutil_render_tag(
|
|
|
|
'a',
|
2012-04-04 17:53:16 -07:00
|
|
|
$attrs,
|
2011-08-21 13:07:09 -07:00
|
|
|
phutil_escape_html($relative));
|
|
|
|
} else {
|
|
|
|
$file_name = phutil_render_tag(
|
|
|
|
'span',
|
|
|
|
array(
|
|
|
|
'title' => $file,
|
|
|
|
),
|
|
|
|
phutil_escape_html($relative));
|
|
|
|
}
|
|
|
|
$file_name = $file_name.' : '.(int)$part['line'];
|
2011-08-17 14:29:53 -07:00
|
|
|
} else {
|
2011-08-21 13:07:09 -07:00
|
|
|
$file_name = '<em>(Internal)</em>';
|
2011-08-17 14:29:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$rows[] = array(
|
|
|
|
$depth--,
|
|
|
|
phutil_escape_html($lib),
|
|
|
|
$file_name,
|
|
|
|
phutil_escape_html($where),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
$table = new AphrontTableView($rows);
|
|
|
|
$table->setHeaders(
|
|
|
|
array(
|
|
|
|
'Depth',
|
|
|
|
'Library',
|
|
|
|
'File',
|
|
|
|
'Where',
|
|
|
|
));
|
|
|
|
$table->setColumnClasses(
|
|
|
|
array(
|
|
|
|
'n',
|
|
|
|
'',
|
|
|
|
'',
|
|
|
|
'wide',
|
|
|
|
));
|
|
|
|
|
|
|
|
return
|
|
|
|
'<div class="exception-trace">'.
|
|
|
|
'<div class="exception-trace-header">Stack Trace</div>'.
|
|
|
|
$table->render().
|
|
|
|
'</div>';
|
|
|
|
}
|
|
|
|
|
2011-01-16 13:51:39 -08:00
|
|
|
}
|