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?
You are stumbling on the hardest point of the GitLab architecture to understand: gitlab-shell.
GitLab automatically symlinks your repository hooks repositories/user/project.git/hooks
to: https://github.com/gitlabhq/gitlab-shell/tree/master/hooks
Whenever there would be a Git push to the repo, hooks are called. This includes HTTP, SSH and web editing, and it is the pre-receive hook https://github.com/gitlabhq/gitlab-shell/blob/master/hooks/pre-receive that checks the permission (man githooks
) and aborts the push if you don't have it.
the pre receive hooks makes an API call to https://github.com/gitlabhq/gitlabhq/blob/ab2db486b8014e509455b624dfd1719f77e27ede/lib/api/internal.rb, which just calls on the usual Abilities system and returns an HTTP request with either true
or false
which determines if the hook succeeds.
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.