Search code examples
apacheubuntugitolitegitweb

Only show repos in gitweb that user has access to via Gitolite


I have gitolite setup and working with SSH key based auth. I can control access to repos via the gitolite-admin.git repo and the conf file. All of this works great over SSH but I would like to use GitWeb as a quick way to view the repos.

GitWeb is working great now but shows all repositories via the web interface. So my goal here is to:

  • Authenticate users in apache2 via PAM, I already have the Ubuntu server authenticating aginst AD and all the users are available. This should not be an issue.
  • Use the user name logged in with the check gitolite permissions
  • Display apropriate REPOS in the web interface.

Does anyone have a starting point for this? The Apache part shouldn't be difficult, and I'll set it to auth all fo the /gitweb/ url. I dont know how to pass that username around and authorize it against gitolite. Any ideas?

Thanks,

Nathan


Solution

  • Yes, it is possible, but you need to complete the gitweb config scripts in order to call gitolite.

    The key is in the gitweb_config.perl: if that file exists, gitweb will include and call it.
    See my gitweb/gitweb_config.perl file:

    our $home_link_str = "ITSVC projects";
    our $site_name = "ITSVC Gitweb";
    use lib (".");
    require "gitweb.conf.pl";
    

    In gitweb/gitweb.conf.pl (custom script), I define the official callback function called by gitweb: export_auth_hook: that function will call gitolite.

    use Gitolite::Common;
    use Gitolite::Conf::Load;
    #$ENV{GL_USER} = $cgi->remote_user || "gitweb";
    
    $export_auth_hook = sub {
      my $repo = shift;
      my $user = $ENV{GL_USER};
      # gitweb passes us the full repo path; so we strip the beginning
      # and the end, to get the repo name as it is specified in gitolite conf
      return unless $repo =~ s/^\Q$projectroot\E\/?(.+)\.git$/$1/;
    
      # check for (at least) "R" permission
      my $ret = &access( $repo, $user, 'R', 'any' );
      my $res = $ret !~ /DENIED/;
    
      return ($ret !~ /DENIED/);
    };
    

    From the comments:

    GL_USER is set because of the line:

    $ENV{GL_USER} = $cgi->remote_user || "gitweb";
    

    $cgi->remote_user will pick the environment REMOTE_USER set by any Apache Auth module which has completed the authentication (like in this Apache configuration file).
    You can print it with a 'die' line.

    "Could not find Gitolite/Rc.pm" means the INC variable used by perl doesn't contain $ENV{GL_LIBDIR}; (set to ~/gitolite/lib or <any_place_where_gitolite_was_installed>/lib).
    That is why there is a line in the same gitweb/gitweb.conf.pl file which adds that to INC:

    unshift @INC, $ENV{GL_LIBDIR};
    use lib $ENV{GL_LIBDIR};
    use Gitolite::Rc;
    

    Edit from Nat45928: in my case I needed to insert my home path into all the '@H@' entries. That solved all of my issues right away.