Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ijin/456981 to your computer and use it in GitHub Desktop.
Save ijin/456981 to your computer and use it in GitHub Desktop.
--- Redmine.pm 2010-06-29 14:35:18.567980004 +0900
+++ Redmine.pm.new 2010-06-29 15:32:11.528961555 +0900
@@ -93,6 +93,68 @@
And you need to upgrade at least reposman.rb (after r860).
+=head1 GIT SMART HTTP SUPPORT
+
+support for Redmine v0.8.1 based off of http://www.redmine.org/issues/4905
+
+Git's smart HTTP protocol will not work with the above settings. Redmine.pm
+normally does access control depending on the HTTP method used: read-only
+methods are OK for everyone in public projects and members with read rights
+in private projects. The rest require membership with commit rights in the
+project.
+
+However, this scheme doesn't work for Git's smart HTTP protocol, as it will use
+POST even for a simple clone. Instead, read-only requests must be detected
+using the full URL (including the query string): anything that doesn't belong
+to the git-receive-pack service is read-only.
+
+To activate this mode of operation, add this line inside your <Location /git>
+block:
+
+ RedmineGitSmartHttp yes
+
+Here's a sample Apache configuration which integrates git-http-backend with
+a MySQL database and this new option:
+
+ SetEnv GIT_PROJECT_ROOT /var/www/git/
+ SetEnv GIT_HTTP_EXPORT_ALL
+ ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
+ <Location /git>
+ Order allow,deny
+ Allow from all
+
+ AuthType Basic
+ AuthName Git
+ Require valid-user
+
+ PerlAccessHandler Apache::Authn::Redmine::access_handler
+ PerlAuthenHandler Apache::Authn::Redmine::authen_handler
+ # for mysql
+ RedmineDSN "DBI:mysql:database=redmine;host=127.0.0.1"
+ RedmineDbUser "redmine"
+ RedmineDbPass "xxx"
+ RedmineGitSmartHttp yes
+ </Location>
+
+Make sure that all the names of the repositories under /var/www/git/ match
+exactly the identifier for some project: /var/www/git/myproject.git won't work,
+due to the way this module extracts the identifier from the URL.
+/var/www/git/myproject will work, though. You can put both bare and non-bare
+repositories in /var/www/git.
+
+Once you have activated this option, you have two options when cloning a
+repository. Cloning using "http://user@host/git/repo" works, but will ask for
+the password all the time. To avoid being pestered by password requests, it's
+best to create a ~/.netrc file with your username and password, and clone using
+"http://host/git/repo" instead.
+
+IMPORTANT NOTE: It is *very important* that the file cannot be read by other
+users, as it will contain your password in cleartext. To create the file, you
+can use the following commands, replacing yourhost, youruser and yourpassword
+with the right values:
+
+ touch ~/.netrc
+ chmod 600 .netrc
+ echo -e "machine yourhost\nlogin youruser\npassword yourpassword" > ~/.netrc
+
=cut
use strict;
@@ -142,6 +204,11 @@
args_how => TAKE1,
errmsg => 'RedmineCacheCredsMax must be decimal number',
},
+ {
+ name => 'RedmineGitSmartHttp',
+ req_override => OR_AUTHCFG,
+ args_how => TAKE1,
+ },
);
sub RedmineDSN {
@@ -176,6 +243,17 @@
}
}
+sub RedmineGitSmartHttp {
+ my ($self, $parms, $arg) = @_;
+ $arg = lc $arg;
+
+ if ($arg eq "yes" || $arg eq "true") {
+ $self->{RedmineGitSmartHttp} = 1;
+ } else {
+ $self->{RedmineGitSmartHttp} = 0;
+ }
+}
+
sub trim {
my $string = shift;
$string =~ s/\s{2,}/ /g;
@@ -192,6 +270,23 @@
my %read_only_methods = map { $_ => 1 } qw/GET PROPFIND REPORT OPTIONS/;
+sub request_is_read_only {
+ my ($r) = @_;
+ my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+
+ # Do we use Git's smart HTTP protocol, or not?
+ if (defined $cfg->{RedmineGitSmartHttp} and $cfg->{RedmineGitSmartHttp}) {
+ my $uri = $r->unparsed_uri;
+ my $is_read_only = $uri !~ /^\/git\/.*\/[^\/]*git\-receive\-pack$/o;
+ return $is_read_only;
+ } else {
+ # Old behaviour: check the HTTP method
+ my $method = $r->method;
+ return defined $read_only_methods{$method};
+ }
+}
+
+
sub access_handler {
my $r = shift;
@@ -200,8 +295,7 @@
return FORBIDDEN;
}
- my $method = $r->method;
- return OK unless defined $read_only_methods{$method};
+ return OK unless request_is_read_only($r);
my $project_id = get_project_identifier($r);
@@ -282,7 +376,9 @@
unless ($auth_source_id) {
my $method = $r->method;
- if ($hashed_password eq $pass_digest && (defined $read_only_methods{$method} || $permissions =~ /:commit_access/) ) {
+ if ($hashed_password eq $pass_digest && ((request_is_read_only($r) && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
$ret = 1;
last;
}
@ijin
Copy link
Author

ijin commented Jun 29, 2010

Patch to Redmine.pm to integrate with git's smart HTTP support for Redmine v0.8.1 because I can't upgrade to v0.9.x at the moment.

Based off of Antonio García-Domínguez's patch#4905 (http://www.redmine.org/issues/4905)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment