git_http_controller.rb 2.07 KB
Newer Older
1 2
# This file should be identical in GitLab Community Edition and Enterprise Edition

Jacob Vosmaer's avatar
Jacob Vosmaer committed
3
class Projects::GitHttpController < Projects::GitHttpClientController
4 5 6
  # GET /foo/bar.git/info/refs?service=git-upload-pack (git pull)
  # GET /foo/bar.git/info/refs?service=git-receive-pack (git push)
  def info_refs
7
    if upload_pack? && upload_pack_allowed?
Jacob Vosmaer's avatar
Jacob Vosmaer committed
8 9 10
      render_ok
    elsif receive_pack? && receive_pack_allowed?
      render_ok
11
    elsif http_blocked?
12
      render_not_allowed
Jacob Vosmaer's avatar
Jacob Vosmaer committed
13 14
    else
      render_not_found
15 16
    end
  end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
17

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
  # POST /foo/bar.git/git-upload-pack (git pull)
  def git_upload_pack
    if upload_pack? && upload_pack_allowed?
      render_ok
    else
      render_not_found
    end
  end

  # POST /foo/bar.git/git-receive-pack" (git push)
  def git_receive_pack
    if receive_pack? && receive_pack_allowed?
      render_ok
    else
      render_not_found
    end
34 35 36 37
  end

  private

Jacob Vosmaer's avatar
Jacob Vosmaer committed
38 39
  def download_request?
    upload_pack?
40 41 42
  end

  def upload_pack?
43
    git_command == 'git-upload-pack'
Jacob Vosmaer's avatar
Jacob Vosmaer committed
44 45 46
  end

  def receive_pack?
47
    git_command == 'git-receive-pack'
Jacob Vosmaer's avatar
Jacob Vosmaer committed
48 49
  end

50
  def git_command
51
    if action_name == 'info_refs'
Jacob Vosmaer's avatar
Jacob Vosmaer committed
52
      params[:service]
53
    else
54
      action_name.dasherize
55 56
    end
  end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
57

58
  def render_ok
59
    render json: Gitlab::Workhorse.git_http_ok(repository, user)
60
  end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
61

62
  def render_not_allowed
63
    render plain: download_access.message, status: :forbidden
64 65
  end

66
  def upload_pack_allowed?
67 68 69
    return false unless Gitlab.config.gitlab_shell.upload_pack

    if user
70
      download_access.allowed?
71
    else
72
      ci? || project.public?
73 74
    end
  end
Jacob Vosmaer's avatar
Jacob Vosmaer committed
75

76 77 78 79 80 81
  def access
    return @access if defined?(@access)

    @access = Gitlab::GitAccess.new(user, project, 'http')
  end

82 83
  def download_access
    return @download_access if defined?(@download_access)
Patricio Cano's avatar
Patricio Cano committed
84

85
    @download_access = access.check('git-upload-pack')
Patricio Cano's avatar
Patricio Cano committed
86 87
  end

88
  def http_blocked?
89
    !access.protocol_allowed?
90 91
  end

Jacob Vosmaer's avatar
Jacob Vosmaer committed
92
  def receive_pack_allowed?
93 94 95 96 97
    return false unless Gitlab.config.gitlab_shell.receive_pack

    # Skip user authorization on upload request.
    # It will be done by the pre-receive hook in the repository.
    user.present?
Jacob Vosmaer's avatar
Jacob Vosmaer committed
98
  end
99
end