Search code examples
ruby-on-railsrubyopen-sourcegitlab

How does GitLab check for Grack HTTPS push permissions?


I want develop some feature for GitLab and add it to open source repo.

DESCRIPTION: When user make push, GitLab checks that all emails from commits should be present in database.

I think to add some validation method to https://github.com/gitlabhq/gitlabhq/blob/master/lib/gitlab/git_access.rb this class, but this validation doesn't call when user push some changes (e.g. git push origin master).

I've researched routing and found next: https://github.com/gitlabhq/gitlabhq/blob/master/config/routes.rb#L24

mount Grack::Bundle.new({
  git_path:     Gitlab.config.git.bin_path,
  project_root: Gitlab.config.gitlab_shell.repos_path,
  upload_pack:  Gitlab.config.gitlab_shell.upload_pack,
  receive_pack: Gitlab.config.gitlab_shell.receive_pack
}), at: '/', constraints: lambda { |request| /[-\/\w\.]+\.git\//.match(request.path_info) }, via: [:get, :post]

Grack mounted to provide access for git http protocol. And Gitlab has hook for authenticate for Grack /lib/gitlab/backend/grack_auth.rb#L79

But I debugged method authorized_request? and have got that this validation doesn't call too.

QUESTION: what class in GitLab validates pushes? Or probably this feature impossible to implement?


Solution

  • You are stumbling on the hardest point of the GitLab architecture to understand: gitlab-shell.

    This is what is meant by the comment https://github.com/gitlabhq/gitlabhq/blob/31de763e816cd5f8f80efc06cb4526ad8dc87eee/lib/gitlab/backend/grack_auth.rb#L92:

    # Skip user authorization on upload request.
    # It will be serverd by update hook in repository
    

    Rationale for this complicated system: allowing SSH pushes. SSH pushes pass through the OpenSSH server, and the only way to make that communicate with GitLab is through the .ssh/authorized_keys system, which must call an executable (GitLab shell) which needs an API to talk to GitLab (the internal API).

    If only we had an OpenSSH implementation in pure Ruby that could be called as a library like Grack does for HTTP (replacing the git built-in server), we would be able to remove that horrible part of the system. https://github.com/net-ssh/net-ssh might be usable some day.

    But seriously: first make a crystal clear feature request with motivation at: http://feedback.gitlab.com and wait for it to be accepted before implementing, or you might just waste a lot of time on something that will not get merged.