How does GitLab check for Grack HTTPS push permissions?

这一生的挚爱 提交于 2020-01-01 18:20:10

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/26467731/how-does-gitlab-check-for-grack-https-push-permissions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!