Compare commits
9 Commits
release-1.
...
feature.we
Author | SHA1 | Date | |
---|---|---|---|
|
cdb8dbafe2 | ||
|
33b22f95ab | ||
|
39f77886db | ||
|
f7470e4a7a | ||
|
c10c002ee3 | ||
|
a47ec0df0a | ||
|
be95050a4b | ||
|
5043c4e845 | ||
|
dacbf0707b |
@@ -13,6 +13,7 @@ or newer to properly run this version of Indefero!
|
|||||||
- Display monotone file and directory attributes in the tree and file view
|
- Display monotone file and directory attributes in the tree and file view
|
||||||
(needs a monotone with an interface version of 13.1 or newer)
|
(needs a monotone with an interface version of 13.1 or newer)
|
||||||
- The context area is now kept in view when a page scrolls down several pages
|
- The context area is now kept in view when a page scrolls down several pages
|
||||||
|
- git repositories are now available under /r/projectname/
|
||||||
|
|
||||||
## Bugfixes
|
## Bugfixes
|
||||||
|
|
||||||
|
57
doc/httprepos-git.mdtext
Normal file
57
doc/httprepos-git.mdtext
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Accessing git repositories over HTTP
|
||||||
|
|
||||||
|
Starting with indefero 1.2, git repositories are provided via http,
|
||||||
|
featuring read-only and read-write access with full integration with
|
||||||
|
indefero's access control mechanisms.
|
||||||
|
|
||||||
|
## Access git repositories
|
||||||
|
|
||||||
|
The repositories are available under http://YOURHOST/BASEPATH/r/PROJECT.
|
||||||
|
|
||||||
|
For authentication, use the "extra password" which you can find on your
|
||||||
|
profile page.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
The main thing to setup is git_repositories and git_remote_url in
|
||||||
|
src/IDF/conf/idf.php
|
||||||
|
|
||||||
|
git_remote_url should match http://YOURHOST/BASEPATH/r/%s, while
|
||||||
|
git_repositories points to the local directory supposed to contain the
|
||||||
|
repositories like /PATH/TO/REPOSITORIES/%s.git.
|
||||||
|
|
||||||
|
## Setup requirements when using PHP over FastCGI
|
||||||
|
|
||||||
|
There are a couple of things to setup when using PHP over FastCGI, as compared
|
||||||
|
to mod_php or similar integrated mechanisms:
|
||||||
|
|
||||||
|
- You will need to setup a RewriteRule for mod_rewrite (in case of Apache,
|
||||||
|
analogous mechanisms might need to be setup for other http daemons), which
|
||||||
|
passes through the Authorization HTTP Header of a request.
|
||||||
|
|
||||||
|
In case of mod_rewrite, the necessary line is
|
||||||
|
one of (depending on server configuration):
|
||||||
|
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
|
||||||
|
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
|
||||||
|
|
||||||
|
- The FastCGI adaptor must allow large requests to be handled by PHP,
|
||||||
|
otherwise push might fail.
|
||||||
|
|
||||||
|
For mod_fcgid, this is the FcgidMaxRequestLen option, or MaxRequestLen in
|
||||||
|
older versions. Set this option to some large enough value - there is no
|
||||||
|
issue with RAM use, as another option defines the limit after which the
|
||||||
|
request is backed on disk, which can remain small.
|
||||||
|
|
||||||
|
## When migrating from syncgit
|
||||||
|
|
||||||
|
HTTP access can be used in parallel to syncgit.
|
||||||
|
|
||||||
|
If you want to disable syncgit, just undo the changes detailled
|
||||||
|
in doc/syncgit.mdtext:
|
||||||
|
- In src/IDF/conf/idf.php keep git_repositories
|
||||||
|
- In src/IDF/conf/idf.php adapt git_remote_url to http://host/basepath/r/%s
|
||||||
|
- In src/IDF/conf/idf.php remove idf_plugin_syncgit*
|
||||||
|
- Remove the cronjob that called gitcron.php
|
||||||
|
- Disable the git daemon (eg. /etc/event.d/local-git-daemon)
|
||||||
|
- You can remove the git user and group, if you also adapt the git repositories
|
||||||
|
to be owned by the www user.
|
@@ -44,7 +44,7 @@ class IDF_Middleware
|
|||||||
function process_request(&$request)
|
function process_request(&$request)
|
||||||
{
|
{
|
||||||
$match = array();
|
$match = array();
|
||||||
if (preg_match('#^/(?:api/p|p)/([\-\w]+)/?#', $request->query, $match)) {
|
if (preg_match('#^/(?:api/p|p|r)/([\-\w]+)/?#', $request->query, $match)) {
|
||||||
try {
|
try {
|
||||||
$request->project = IDF_Project::getOr404($match[1]);
|
$request->project = IDF_Project::getOr404($match[1]);
|
||||||
} catch (Pluf_HTTP_Error404 $e) {
|
} catch (Pluf_HTTP_Error404 $e) {
|
||||||
|
@@ -927,14 +927,19 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
|
|
||||||
public function repository($request, $match)
|
public function repository($request, $match)
|
||||||
{
|
{
|
||||||
// authenticate: authenticate connection through "extra" password
|
// handle a couple of workarounds for authenticating with FastCGI/PHP
|
||||||
if (isset($_SERVER['HTTP_AUTHORIZATION']) && $_SERVER['HTTP_AUTHORIZATION'] != '')
|
if (!empty($_SERVER['HTTP_AUTHORIZATION']))
|
||||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
||||||
|
elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
|
||||||
|
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)));
|
||||||
|
elseif (!empty($_SERVER['REDIRECT_REMOTE_USER']))
|
||||||
|
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)));
|
||||||
|
|
||||||
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
// authenticate: authenticate connection through "extra" password
|
||||||
|
if (!empty($_SERVER['PHP_AUTH_USER'])) {
|
||||||
$sql = new Pluf_SQL('login=%s', array($_SERVER['PHP_AUTH_USER']));
|
$sql = new Pluf_SQL('login=%s', array($_SERVER['PHP_AUTH_USER']));
|
||||||
$users = Pluf::factory('Pluf_User')->getList(array('filter'=>$sql->gen()));
|
$users = Pluf::factory('Pluf_User')->getList(array('filter'=>$sql->gen()));
|
||||||
if ((count($users) == 1) && ($users[0]->active)) {
|
if (count($users) == 1 && $users[0]->active) {
|
||||||
$user = $users[0];
|
$user = $users[0];
|
||||||
$realkey = substr(sha1($user->password.Pluf::f('secret_key')), 0, 8);
|
$realkey = substr(sha1($user->password.Pluf::f('secret_key')), 0, 8);
|
||||||
if ($_SERVER['PHP_AUTH_PW'] == $realkey) {
|
if ($_SERVER['PHP_AUTH_PW'] == $realkey) {
|
||||||
@@ -952,6 +957,19 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
|
|
||||||
$path = $match[2];
|
$path = $match[2];
|
||||||
|
|
||||||
|
if (!file_exists($this->repo)) {
|
||||||
|
mkdir($this->repo, 0750, true);
|
||||||
|
$out = array();
|
||||||
|
$res = 0;
|
||||||
|
exec(sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||||
|
Pluf::f('git_path', 'git').' --git-dir=%s init', escapeshellarg($this->repo)),
|
||||||
|
$out, $res);
|
||||||
|
if ($res != 0) {
|
||||||
|
Pluf_Log::error(array('IDF_Scm_Git::repository', $res, $this->repo));
|
||||||
|
throw new Exception(sprintf('Init repository error, exit status %d.', $res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update files before delivering them
|
// update files before delivering them
|
||||||
if (($path == 'objects/info/pack') || ($path == 'info/refs')) {
|
if (($path == 'objects/info/pack') || ($path == 'info/refs')) {
|
||||||
$cmd = sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
$cmd = sprintf(Pluf::f('idf_exec_cmd_prefix', '').
|
||||||
@@ -961,15 +979,21 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// smart HTTP discovery
|
// smart HTTP discovery
|
||||||
if (($path == 'info/refs') &&
|
if ($path == 'info/refs' && !empty($request->GET['service'])){
|
||||||
(array_key_exists('service', $request->GET))){
|
$service = $request->GET['service'];
|
||||||
$service = $request->GET["service"];
|
|
||||||
switch ($service) {
|
switch ($service) {
|
||||||
case 'git-upload-pack':
|
|
||||||
case 'git-receive-pack':
|
case 'git-receive-pack':
|
||||||
|
if (IDF_Precondition::projectMemberOrOwner($request) !== true) {
|
||||||
|
$response = new Pluf_HTTP_Response("");
|
||||||
|
$response->status_code = 401;
|
||||||
|
$response->headers['WWW-Authenticate']='Basic realm="git for '.$this->project.'"';
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
case 'git-upload-pack':
|
||||||
$content = sprintf('%04x',strlen($service)+15).
|
$content = sprintf('%04x',strlen($service)+15).
|
||||||
'# service='.$service."\n0000";
|
'# service='.$service."\n0000";
|
||||||
$content .= self::shell_exec('IDF_Scm_Git::repository',
|
$content .= self::shell_exec('IDF_Scm_Git::repository',
|
||||||
|
Pluf::f('idf_exec_cmd_prefix', '').
|
||||||
$service.' --stateless-rpc --advertise-refs '.
|
$service.' --stateless-rpc --advertise-refs '.
|
||||||
$this->repo);
|
$this->repo);
|
||||||
$response = new Pluf_HTTP_Response($content,
|
$response = new Pluf_HTTP_Response($content,
|
||||||
@@ -982,12 +1006,19 @@ class IDF_Scm_Git extends IDF_Scm
|
|||||||
|
|
||||||
switch($path) {
|
switch($path) {
|
||||||
// smart HTTP RPC
|
// smart HTTP RPC
|
||||||
case 'git-upload-pack':
|
|
||||||
case 'git-receive-pack':
|
case 'git-receive-pack':
|
||||||
$response = new Pluf_HTTP_Response_CommandPassThru($path.
|
if (IDF_Precondition::projectMemberOrOwner($request) !== true) {
|
||||||
|
$response = new Pluf_HTTP_Response("");
|
||||||
|
$response->status_code = 401;
|
||||||
|
$response->headers['WWW-Authenticate']='Basic realm="git for '.$this->project.'"';
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
case 'git-upload-pack':
|
||||||
|
$response = new Pluf_HTTP_Response_CommandPassThru(
|
||||||
|
Pluf::f('idf_exec_cmd_prefix', '').$path.
|
||||||
' --stateless-rpc '.$this->repo,
|
' --stateless-rpc '.$this->repo,
|
||||||
'application/x-'.$path.'-result');
|
'application/x-'.$path.'-result');
|
||||||
$response->addStdin('php://input');
|
$response->setStdin(fopen('php://input', 'rb'));
|
||||||
return $response;
|
return $response;
|
||||||
|
|
||||||
// regular file
|
// regular file
|
||||||
|
@@ -245,7 +245,7 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#',
|
|||||||
'model' => 'IDF_Views_Source_Svn',
|
'model' => 'IDF_Views_Source_Svn',
|
||||||
'method' => 'changelogRev');
|
'method' => 'changelogRev');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/repo/(.*)$#',
|
$ctl[] = array('regex' => '#^/r/([\-\w]+)/(.*)$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'repository');
|
'method' => 'repository');
|
||||||
|
Reference in New Issue
Block a user