2011-03-08 00:13:36 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class DiffusionController extends PhabricatorController {
|
|
|
|
|
2011-03-09 02:31:44 +01:00
|
|
|
protected $diffusionRequest;
|
|
|
|
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
public function willBeginExecution() {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$uri = $request->getRequestURI();
|
|
|
|
|
|
|
|
// Check if this is a VCS request, e.g. from "git clone", "hg clone", or
|
|
|
|
// "svn checkout". If it is, we jump off into repository serving code to
|
|
|
|
// process the request.
|
|
|
|
|
|
|
|
$regex = '@^/diffusion/(?P<callsign>[A-Z]+)(/|$)@';
|
|
|
|
$matches = null;
|
|
|
|
if (preg_match($regex, (string)$uri, $matches)) {
|
|
|
|
$vcs = null;
|
|
|
|
|
2013-10-26 21:10:52 +02:00
|
|
|
$content_type = $request->getHTTPHeader('Content-Type');
|
|
|
|
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
if ($request->getExists('__vcs__')) {
|
|
|
|
// This is magic to make it easier for us to debug stuff by telling
|
|
|
|
// users to run:
|
|
|
|
//
|
|
|
|
// curl http://example.phabricator.com/diffusion/X/?__vcs__=1
|
|
|
|
//
|
|
|
|
// ...to get a human-readable error.
|
|
|
|
$vcs = $request->getExists('__vcs__');
|
|
|
|
} else if ($request->getExists('service')) {
|
2013-10-26 21:10:52 +02:00
|
|
|
$service = $request->getStr('service');
|
|
|
|
// We get this initially for `info/refs`.
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
// Git also gives us a User-Agent like "git/1.8.2.3".
|
|
|
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
2013-10-26 21:10:52 +02:00
|
|
|
} else if ($content_type == 'application/x-git-upload-pack-request') {
|
|
|
|
// We get this for `git-upload-pack`.
|
|
|
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
2013-11-01 16:44:37 +01:00
|
|
|
} else if ($content_type == 'application/x-git-receive-pack-request') {
|
|
|
|
// We get this for `git-receive-pack`.
|
|
|
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
} else if ($request->getExists('cmd')) {
|
|
|
|
// Mercurial also sends an Accept header like
|
|
|
|
// "application/mercurial-0.1", and a User-Agent like
|
|
|
|
// "mercurial/proto-1.0".
|
|
|
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
|
|
|
|
} else {
|
|
|
|
// Subversion also sends an initial OPTIONS request (vs GET/POST), and
|
|
|
|
// has a User-Agent like "SVN/1.8.3 (x86_64-apple-darwin11.4.2)
|
|
|
|
// serf/1.3.2".
|
|
|
|
$dav = $request->getHTTPHeader('DAV');
|
|
|
|
$dav = new PhutilURI($dav);
|
|
|
|
if ($dav->getDomain() === 'subversion.tigris.org') {
|
|
|
|
$vcs = PhabricatorRepositoryType::REPOSITORY_TYPE_SVN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($vcs) {
|
|
|
|
return $this->processVCSRequest($matches['callsign']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
parent::willBeginExecution();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function processVCSRequest($callsign) {
|
|
|
|
|
2013-11-01 16:44:37 +01:00
|
|
|
// If authentication credentials have been provided, try to find a user
|
|
|
|
// that actually matches those credentials.
|
|
|
|
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
|
|
|
|
$username = $_SERVER['PHP_AUTH_USER'];
|
|
|
|
$password = new PhutilOpaqueEnvelope($_SERVER['PHP_AUTH_PW']);
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
|
2013-11-01 16:44:37 +01:00
|
|
|
$viewer = $this->authenticateHTTPRepositoryUser($username, $password);
|
|
|
|
if (!$viewer) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('Invalid credentials.'));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// User hasn't provided credentials, which means we count them as
|
|
|
|
// being "not logged in".
|
|
|
|
$viewer = new PhabricatorUser();
|
|
|
|
}
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
|
|
|
|
$allow_public = PhabricatorEnv::getEnvConfig('policy.allow-public');
|
2013-11-01 16:44:37 +01:00
|
|
|
$allow_auth = PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth');
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
if (!$allow_public) {
|
|
|
|
if (!$viewer->isLoggedIn()) {
|
2013-11-01 16:44:37 +01:00
|
|
|
if ($allow_auth) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
401,
|
|
|
|
pht('You must log in to access repositories.'));
|
|
|
|
} else {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('Public and authenticated HTTP access are both forbidden.'));
|
|
|
|
}
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$repository = id(new PhabricatorRepositoryQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withCallsigns(array($callsign))
|
|
|
|
->executeOne();
|
|
|
|
if (!$repository) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
404,
|
|
|
|
pht('No such repository exists.'));
|
|
|
|
}
|
|
|
|
} catch (PhabricatorPolicyException $ex) {
|
|
|
|
if ($viewer->isLoggedIn()) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('You do not have permission to access this repository.'));
|
|
|
|
} else {
|
2013-11-01 16:44:37 +01:00
|
|
|
if ($allow_auth) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
401,
|
|
|
|
pht('You must log in to access this repository.'));
|
|
|
|
} else {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht(
|
|
|
|
'This repository requires authentication, which is forbidden '.
|
|
|
|
'over HTTP.'));
|
|
|
|
}
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-30 21:15:32 +01:00
|
|
|
if (!$repository->isTracked()) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('This repository is inactive.'));
|
|
|
|
}
|
|
|
|
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
$is_push = !$this->isReadOnlyRequest($repository);
|
|
|
|
|
|
|
|
switch ($repository->getServeOverHTTP()) {
|
|
|
|
case PhabricatorRepository::SERVE_READONLY:
|
|
|
|
if ($is_push) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('This repository is read-only over HTTP.'));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PhabricatorRepository::SERVE_READWRITE:
|
|
|
|
if ($is_push) {
|
|
|
|
$can_push = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$repository,
|
|
|
|
DiffusionCapabilityPush::CAPABILITY);
|
|
|
|
if (!$can_push) {
|
|
|
|
if ($viewer->isLoggedIn()) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('You do not have permission to push to this repository.'));
|
|
|
|
} else {
|
2013-11-01 16:44:37 +01:00
|
|
|
if ($allow_auth) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
401,
|
|
|
|
pht('You must log in to push to this repository.'));
|
|
|
|
} else {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht(
|
|
|
|
'Pushing to this repository requires authentication, '.
|
|
|
|
'which is forbidden over HTTP.'));
|
|
|
|
}
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PhabricatorRepository::SERVE_OFF:
|
|
|
|
default:
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
403,
|
|
|
|
pht('This repository is not available over HTTP.'));
|
|
|
|
}
|
|
|
|
|
2013-10-26 21:10:52 +02:00
|
|
|
switch ($repository->getVersionControlSystem()) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
2013-10-31 23:46:57 +01:00
|
|
|
$result = $this->serveGitRequest($repository);
|
2013-11-03 02:18:12 +01:00
|
|
|
break;
|
2013-10-26 21:10:52 +02:00
|
|
|
default:
|
2013-10-31 23:46:57 +01:00
|
|
|
$result = new PhabricatorVCSResponse(
|
|
|
|
999,
|
|
|
|
pht('TODO: Implement meaningful responses.'));
|
2013-10-26 21:10:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-10-31 23:46:57 +01:00
|
|
|
$code = $result->getHTTPResponseCode();
|
|
|
|
|
|
|
|
if ($is_push && ($code == 200)) {
|
|
|
|
$repository->writeStatusMessage(
|
|
|
|
PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE,
|
|
|
|
PhabricatorRepositoryStatusMessage::CODE_OKAY);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function isReadOnlyRequest(
|
|
|
|
PhabricatorRepository $repository) {
|
|
|
|
$request = $this->getRequest();
|
2013-10-26 21:10:52 +02:00
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
|
|
|
|
// TODO: This implementation is safe by default, but very incomplete.
|
|
|
|
|
|
|
|
switch ($repository->getVersionControlSystem()) {
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
|
|
|
$service = $request->getStr('service');
|
2013-10-26 21:10:52 +02:00
|
|
|
$path = $this->getRequestDirectoryPath();
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
// NOTE: Service names are the reverse of what you might expect, as they
|
|
|
|
// are from the point of view of the server. The main read service is
|
|
|
|
// "git-upload-pack", and the main write service is "git-receive-pack".
|
2013-10-26 21:10:52 +02:00
|
|
|
|
|
|
|
if ($method == 'GET' &&
|
|
|
|
$path == '/info/refs' &&
|
|
|
|
$service == 'git-upload-pack') {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($path == '/git-upload-pack') {
|
|
|
|
return true;
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
}
|
2013-10-26 21:10:52 +02:00
|
|
|
|
Accept and route VCS HTTP requests
Summary:
Mostly ripped from D7391, with some changes:
- Serve repositories at `/diffusion/X/`, with no special `/git/` or `/serve/` URI component.
- This requires a little bit of magic, but I got the magic working for Git, Mercurial and SVN, and it seems reasonable.
- I think having one URI for everything will make it easier for users to understand.
- One downside is that git will clone into `X` by default, but I think that's not a big deal, and we can work around that in the future easily enough.
- Accept HTTP requests for Git, SVN and Mercurial repositories.
- Auth logic is a little different in order to be more consistent with how other things work.
- Instead of AphrontBasicAuthResponse, added "VCSResponse". Mercurial can print strings we send it on the CLI if we're careful, so support that. I did a fair amount of digging and didn't have any luck with git or svn.
- Commands we don't know about are assumed to require "Push" capability by default.
No actual VCS data going over the wire yet.
Test Plan:
Ran a bunch of stuff like this:
$ hg clone http://local.aphront.com:8080/diffusion/P/
abort: HTTP Error 403: This repository is not available over HTTP.
...and got pretty reasonable-seeming errors in all cases. All this can do is produce errors for now.
Reviewers: hach-que, btrahan
Reviewed By: hach-que
CC: aran
Maniphest Tasks: T2230
Differential Revision: https://secure.phabricator.com/D7417
2013-10-26 16:56:17 +02:00
|
|
|
break;
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
|
|
|
$cmd = $request->getStr('cmd');
|
|
|
|
switch ($cmd) {
|
|
|
|
case 'capabilities':
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PhabricatorRepositoryType::REPOSITORY_TYPE_SUBVERSION:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-09 02:31:44 +01:00
|
|
|
public function willProcessRequest(array $data) {
|
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-20 03:52:14 +01:00
|
|
|
if (isset($data['callsign'])) {
|
2012-11-09 00:14:44 +01:00
|
|
|
$drequest = DiffusionRequest::newFromAphrontRequestDictionary(
|
|
|
|
$data,
|
|
|
|
$this->getRequest());
|
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-20 03:52:14 +01:00
|
|
|
$this->diffusionRequest = $drequest;
|
|
|
|
}
|
2011-03-09 02:31:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setDiffusionRequest(DiffusionRequest $request) {
|
|
|
|
$this->diffusionRequest = $request;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2011-03-13 01:17:34 +01:00
|
|
|
protected function getDiffusionRequest() {
|
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-20 03:52:14 +01:00
|
|
|
if (!$this->diffusionRequest) {
|
|
|
|
throw new Exception("No Diffusion request object!");
|
|
|
|
}
|
2011-03-13 01:17:34 +01:00
|
|
|
return $this->diffusionRequest;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildCrumbs(array $spec = array()) {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
2011-03-31 07:08:41 +02:00
|
|
|
$crumb_list = $this->buildCrumbList($spec);
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
foreach ($crumb_list as $crumb) {
|
|
|
|
$crumbs->addCrumb($crumb);
|
|
|
|
}
|
2011-03-31 07:08:41 +02:00
|
|
|
return $crumbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildCrumbList(array $spec = array()) {
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2012-04-19 18:39:19 +02:00
|
|
|
$spec = $spec + array(
|
|
|
|
'commit' => null,
|
|
|
|
'tags' => null,
|
2012-05-10 09:28:19 +02:00
|
|
|
'branches' => null,
|
2012-04-19 18:39:19 +02:00
|
|
|
'view' => null,
|
|
|
|
);
|
|
|
|
|
2011-03-13 01:17:34 +01:00
|
|
|
$crumb_list = array();
|
|
|
|
|
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-20 03:52:14 +01:00
|
|
|
// On the home page, we don't have a DiffusionRequest.
|
|
|
|
if ($this->diffusionRequest) {
|
|
|
|
$drequest = $this->getDiffusionRequest();
|
|
|
|
$repository = $drequest->getRepository();
|
|
|
|
} else {
|
|
|
|
$drequest = null;
|
|
|
|
$repository = null;
|
|
|
|
}
|
|
|
|
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
if (!$repository) {
|
2011-03-31 07:08:41 +02:00
|
|
|
return $crumb_list;
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$callsign = $repository->getCallsign();
|
2012-12-13 03:40:18 +01:00
|
|
|
$repository_name = 'r'.$callsign;
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2012-05-10 09:28:19 +02:00
|
|
|
if (!$spec['commit'] && !$spec['tags'] && !$spec['branches']) {
|
2012-01-19 20:49:51 +01:00
|
|
|
$branch_name = $drequest->getBranch();
|
|
|
|
if ($branch_name) {
|
2012-12-13 03:40:18 +01:00
|
|
|
$repository_name .= ' ('.$branch_name.')';
|
2012-01-19 20:49:51 +01:00
|
|
|
}
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = id(new PhabricatorCrumbView())
|
|
|
|
->setName($repository_name);
|
|
|
|
if (!$spec['view'] && !$spec['commit'] &&
|
|
|
|
!$spec['tags'] && !$spec['branches']) {
|
|
|
|
$crumb_list[] = $crumb;
|
|
|
|
return $crumb_list;
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
2013-09-23 21:54:12 +02:00
|
|
|
$crumb->setHref(
|
|
|
|
$drequest->generateURI(
|
|
|
|
array(
|
|
|
|
'action' => 'branch',
|
|
|
|
'path' => '/',
|
|
|
|
)));
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb_list[] = $crumb;
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2011-03-14 00:19:39 +01:00
|
|
|
$raw_commit = $drequest->getRawCommit();
|
2012-04-24 03:36:25 +02:00
|
|
|
|
|
|
|
if ($spec['tags']) {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = new PhabricatorCrumbView();
|
2012-04-24 03:36:25 +02:00
|
|
|
if ($spec['commit']) {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb->setName(
|
2013-05-11 17:23:19 +02:00
|
|
|
pht("Tags for %s", 'r'.$callsign.$raw_commit));
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb->setHref($drequest->generateURI(
|
2012-04-24 03:36:25 +02:00
|
|
|
array(
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
'action' => 'commit',
|
|
|
|
'commit' => $raw_commit,
|
2013-02-19 22:33:10 +01:00
|
|
|
)));
|
2012-04-24 03:36:25 +02:00
|
|
|
} else {
|
2013-05-11 17:23:19 +02:00
|
|
|
$crumb->setName(pht('Tags'));
|
2012-04-24 03:36:25 +02:00
|
|
|
}
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb_list[] = $crumb;
|
2011-03-31 07:08:41 +02:00
|
|
|
return $crumb_list;
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
2012-05-10 09:28:19 +02:00
|
|
|
if ($spec['branches']) {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = id(new PhabricatorCrumbView())
|
2013-05-11 17:23:19 +02:00
|
|
|
->setName(pht('Branches'));
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb_list[] = $crumb;
|
2012-05-10 09:28:19 +02:00
|
|
|
return $crumb_list;
|
|
|
|
}
|
|
|
|
|
2012-04-24 03:36:25 +02:00
|
|
|
if ($spec['commit']) {
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = id(new PhabricatorCrumbView())
|
|
|
|
->setName("r{$callsign}{$raw_commit}")
|
|
|
|
->setHref("r{$callsign}{$raw_commit}");
|
|
|
|
$crumb_list[] = $crumb;
|
2012-04-19 18:39:19 +02:00
|
|
|
return $crumb_list;
|
|
|
|
}
|
|
|
|
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = new PhabricatorCrumbView();
|
2011-03-13 01:17:34 +01:00
|
|
|
$view = $spec['view'];
|
|
|
|
|
|
|
|
switch ($view) {
|
|
|
|
case 'history':
|
2013-05-11 17:23:19 +02:00
|
|
|
$view_name = pht('History');
|
2011-03-13 01:17:34 +01:00
|
|
|
break;
|
|
|
|
case 'browse':
|
2013-05-11 17:23:19 +02:00
|
|
|
$view_name = pht('Browse');
|
2011-03-13 01:17:34 +01:00
|
|
|
break;
|
2012-11-08 20:11:44 +01:00
|
|
|
case 'lint':
|
2013-05-11 17:23:19 +02:00
|
|
|
$view_name = pht('Lint');
|
2012-11-08 20:11:44 +01:00
|
|
|
break;
|
2011-03-14 06:03:30 +01:00
|
|
|
case 'change':
|
2013-05-11 17:23:19 +02:00
|
|
|
$view_name = pht('Change');
|
2013-09-23 21:54:12 +02:00
|
|
|
break;
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
upgrade diffusion to use modern header UI and fix a few quirks
Summary:
upgrades are CrumbsView, HeaderView, PropertyListView, and ActionListView. I had to modify CrumbsView stuff a bit to handle the "advanced" diffusion crumbs.
Quirks fixed include making file tree view show up in diffusion, the page not have extra space when the file tree is hidden, links no longer breaking once you visit files (since without the change the files always got "/" appended and thus 404'd), and a differential quirk where it read "next step:" and that colon is a no no,
Test Plan: played around in diffusion and differential
Reviewers: epriestley
Reviewed By: epriestley
CC: aran, Korvin, chad
Maniphest Tasks: T2048, T2178
Differential Revision: https://secure.phabricator.com/D4169
2012-12-13 02:50:42 +01:00
|
|
|
$crumb = id(new PhabricatorCrumbView())
|
|
|
|
->setName($view_name);
|
2011-03-13 01:17:34 +01:00
|
|
|
|
2013-09-19 20:57:33 +02:00
|
|
|
$crumb_list[] = $crumb;
|
2011-03-31 07:08:41 +02:00
|
|
|
return $crumb_list;
|
2011-03-13 01:17:34 +01:00
|
|
|
}
|
|
|
|
|
2013-05-01 23:44:28 +02:00
|
|
|
protected function callConduitWithDiffusionRequest(
|
|
|
|
$method,
|
|
|
|
array $params = array()) {
|
|
|
|
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
$drequest = $this->getDiffusionRequest();
|
|
|
|
|
|
|
|
return DiffusionQuery::callConduitWithDiffusionRequest(
|
|
|
|
$user,
|
|
|
|
$drequest,
|
|
|
|
$method,
|
|
|
|
$params);
|
|
|
|
}
|
2013-05-24 21:37:42 +02:00
|
|
|
|
|
|
|
protected function getRepositoryControllerURI(
|
|
|
|
PhabricatorRepository $repository,
|
|
|
|
$path) {
|
|
|
|
return $this->getApplicationURI($repository->getCallsign().'/'.$path);
|
|
|
|
}
|
|
|
|
|
2013-09-23 21:55:23 +02:00
|
|
|
protected function renderPathLinks(DiffusionRequest $drequest, $action) {
|
2013-09-20 01:01:04 +02:00
|
|
|
$path = $drequest->getPath();
|
|
|
|
$path_parts = array_filter(explode('/', trim($path, '/')));
|
|
|
|
|
2013-10-14 18:40:05 +02:00
|
|
|
$divider = phutil_tag(
|
|
|
|
'span',
|
|
|
|
array(
|
|
|
|
'class' => 'phui-header-divider'),
|
|
|
|
'/');
|
|
|
|
|
2013-09-20 01:01:04 +02:00
|
|
|
$links = array();
|
|
|
|
if ($path_parts) {
|
|
|
|
$links[] = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $drequest->generateURI(
|
|
|
|
array(
|
2013-09-23 21:55:23 +02:00
|
|
|
'action' => $action,
|
2013-09-20 01:01:04 +02:00
|
|
|
'path' => '',
|
|
|
|
)),
|
|
|
|
),
|
2013-10-14 18:40:05 +02:00
|
|
|
'r'.$drequest->getRepository()->getCallsign());
|
|
|
|
$links[] = $divider;
|
2013-09-20 01:01:04 +02:00
|
|
|
$accum = '';
|
|
|
|
$last_key = last_key($path_parts);
|
|
|
|
foreach ($path_parts as $key => $part) {
|
|
|
|
$accum .= '/'.$part;
|
|
|
|
if ($key === $last_key) {
|
|
|
|
$links[] = $part;
|
|
|
|
} else {
|
|
|
|
$links[] = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $drequest->generateURI(
|
|
|
|
array(
|
2013-09-23 21:55:23 +02:00
|
|
|
'action' => $action,
|
2013-10-04 00:51:47 +02:00
|
|
|
'path' => $accum.'/',
|
2013-09-20 01:01:04 +02:00
|
|
|
)),
|
|
|
|
),
|
2013-10-14 18:40:05 +02:00
|
|
|
$part);
|
|
|
|
$links[] = $divider;
|
2013-09-20 01:01:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2013-10-14 18:40:05 +02:00
|
|
|
$links[] = 'r'.$drequest->getRepository()->getCallsign();
|
|
|
|
$links[] = $divider;
|
2013-09-20 01:01:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return $links;
|
|
|
|
}
|
|
|
|
|
2013-10-26 21:10:52 +02:00
|
|
|
/**
|
|
|
|
* @phutil-external-symbol class PhabricatorStartup
|
|
|
|
*/
|
|
|
|
private function serveGitRequest(PhabricatorRepository $repository) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
|
|
|
|
$request_path = $this->getRequestDirectoryPath();
|
|
|
|
$repository_root = $repository->getLocalPath();
|
|
|
|
|
|
|
|
// Rebuild the query string to strip `__magic__` parameters and prevent
|
|
|
|
// issues where we might interpret inputs like "service=read&service=write"
|
|
|
|
// differently than the server does and pass it an unsafe command.
|
2013-11-01 16:44:37 +01:00
|
|
|
|
|
|
|
// NOTE: This does not use getPassthroughRequestParameters() because
|
|
|
|
// that code is HTTP-method agnostic and will encode POST data.
|
|
|
|
|
|
|
|
$query_data = $_GET;
|
|
|
|
foreach ($query_data as $key => $value) {
|
|
|
|
if (!strncmp($key, '__', 2)) {
|
|
|
|
unset($query_data[$key]);
|
|
|
|
}
|
|
|
|
}
|
2013-10-26 21:10:52 +02:00
|
|
|
$query_string = http_build_query($query_data, '', '&');
|
|
|
|
|
|
|
|
// We're about to wipe out PATH with the rest of the environment, so
|
|
|
|
// resolve the binary first.
|
|
|
|
$bin = Filesystem::resolveBinary('git-http-backend');
|
|
|
|
if (!$bin) {
|
|
|
|
throw new Exception("Unable to find `git-http-backend` in PATH!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$env = array(
|
|
|
|
'REQUEST_METHOD' => $_SERVER['REQUEST_METHOD'],
|
|
|
|
'QUERY_STRING' => $query_string,
|
2013-11-01 16:44:37 +01:00
|
|
|
'CONTENT_TYPE' => $request->getHTTPHeader('Content-Type'),
|
|
|
|
'HTTP_CONTENT_ENCODING' => $request->getHTTPHeader('Content-Encoding'),
|
2013-10-26 21:10:52 +02:00
|
|
|
'REMOTE_ADDR' => $_SERVER['REMOTE_ADDR'],
|
|
|
|
'GIT_PROJECT_ROOT' => $repository_root,
|
|
|
|
'GIT_HTTP_EXPORT_ALL' => '1',
|
|
|
|
'PATH_INFO' => $request_path,
|
2013-11-01 16:44:37 +01:00
|
|
|
|
|
|
|
// TODO: Set these correctly.
|
|
|
|
'REMOTE_USER' => '',
|
|
|
|
// GIT_COMMITTER_NAME
|
|
|
|
// GIT_COMMITTER_EMAIL
|
2013-10-26 21:10:52 +02:00
|
|
|
);
|
|
|
|
|
2013-11-01 16:44:37 +01:00
|
|
|
$input = PhabricatorStartup::getRawInput();
|
|
|
|
|
|
|
|
list($err, $stdout, $stderr) = id(new ExecFuture('%s', $bin))
|
2013-10-26 21:10:52 +02:00
|
|
|
->setEnv($env, true)
|
2013-11-01 16:44:37 +01:00
|
|
|
->write($input)
|
|
|
|
->resolve();
|
|
|
|
|
|
|
|
if ($err) {
|
|
|
|
return new PhabricatorVCSResponse(
|
|
|
|
500,
|
|
|
|
pht('Error %d: %s', $err, $stderr));
|
|
|
|
}
|
2013-10-26 21:10:52 +02:00
|
|
|
|
|
|
|
return id(new DiffusionGitResponse())->setGitData($stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getRequestDirectoryPath() {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$request_path = $request->getRequestURI()->getPath();
|
|
|
|
return preg_replace('@^/diffusion/[A-Z]+@', '', $request_path);
|
|
|
|
}
|
|
|
|
|
Add an "importing" state to repositories and clean up the UI
Summary:
Fixes T3217. Ref T776. Ref T1493. Broadly, this introduces a mechanism which works like this:
- When a repository is created, we set an "importing" flag.
- After discovery completes, we check if a repository has no importing commits. Basically, this is the first time we catch up to HEAD.
- If we're caught up, clear the "importing" flag.
This flag lets us fix some issues:
- T3217. Currently, when you import a new repository and users have rules like "Email me on every commit ever" or "trigger an audit on every commit", we take a bunch of publish actions. Instead, implicitly disable publishing during import.
- An imported but un-pulled repository currently has an incomprehensible error on `/diffusion/X/`. Fix that.
- Show more cues in the UI about importing.
- Made some exceptions more specific.
Test Plan:
This is the new screen for a completely new repo, replacing a giant exception:
{F75443}
- Created a repository, saw it "importing".
- Pulled and discovered it.
- Processed its commits.
- Ran discovery again, saw import flag clear.
- Also this repository was empty, which hit some of the other code.
This is the new "parsed empty repository" UI, which isn't good, but is less broken:
{F75446}
Reviewers: btrahan
Reviewed By: btrahan
CC: aran, hach-que
Maniphest Tasks: T3607, T1493, T776, T3217
Differential Revision: https://secure.phabricator.com/D7429
2013-10-27 03:59:57 +01:00
|
|
|
protected function renderStatusMessage($title, $body) {
|
|
|
|
return id(new AphrontErrorView())
|
|
|
|
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
|
|
|
|
->setTitle($title)
|
|
|
|
->appendChild($body);
|
|
|
|
}
|
2013-11-01 16:44:37 +01:00
|
|
|
|
|
|
|
private function authenticateHTTPRepositoryUser(
|
|
|
|
$username,
|
|
|
|
PhutilOpaqueEnvelope $password) {
|
|
|
|
|
|
|
|
if (!PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) {
|
|
|
|
// No HTTP auth permitted.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$user = id(new PhabricatorPeopleQuery())
|
|
|
|
->setViewer(new PhabricatorUser())
|
|
|
|
->withUsernames(array($username))
|
|
|
|
->executeOne();
|
|
|
|
if (!$user) {
|
|
|
|
// Username doesn't match anything.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
$password_entry = id(new PhabricatorRepositoryVCSPassword())
|
|
|
|
->loadOneWhere('userPHID = %s', $user->getPHID());
|
|
|
|
if (!$password_entry) {
|
|
|
|
// User doesn't have a password set.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$password_entry->comparePassword($password, $user)) {
|
|
|
|
// Password doesn't match.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($user->getIsDisabled()) {
|
|
|
|
// User is disabled.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
2011-03-08 00:13:36 +01:00
|
|
|
}
|
2013-09-20 01:01:04 +02:00
|
|
|
|