lfs_request.rb 2.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# This concern assumes:
# - a `#project` accessor
# - a `#user` accessor
# - a `#authentication_result` accessor
# - a `#can?(object, action, subject)` method
# - a `#ci?` method
# - a `#download_request?` method
# - a `#upload_request?` method
# - a `#has_authentication_ability?(ability)` method
module LfsRequest
  extend ActiveSupport::Concern

  included do
    before_action :require_lfs_enabled!
    before_action :lfs_check_access!
  end

  private
19

J
Jacob Vosmaer 已提交
20
  def require_lfs_enabled!
J
Jacob Vosmaer 已提交
21 22 23 24 25
    return if Gitlab.config.lfs.enabled

    render(
      json: {
        message: 'Git LFS is not enabled on this GitLab server, contact your admin.',
26
        documentation_url: help_url
J
Jacob Vosmaer 已提交
27 28 29 30 31 32 33 34 35
      },
      status: 501
    )
  end

  def lfs_check_access!
    return if download_request? && lfs_download_access?
    return if upload_request? && lfs_upload_access?

36 37
    if project.public? || can?(user, :read_project, project)
      lfs_forbidden!
J
Jacob Vosmaer 已提交
38 39 40 41 42
    else
      render_lfs_not_found
    end
  end

43 44
  def lfs_forbidden!
    render_lfs_forbidden
J
Jacob Vosmaer 已提交
45 46 47 48 49 50
  end

  def render_lfs_forbidden
    render(
      json: {
        message: 'Access forbidden. Check your access level.',
51
        documentation_url: help_url
J
Jacob Vosmaer 已提交
52 53 54 55 56 57 58 59 60 61
      },
      content_type: "application/vnd.git-lfs+json",
      status: 403
    )
  end

  def render_lfs_not_found
    render(
      json: {
        message: 'Not found.',
62
        documentation_url: help_url
J
Jacob Vosmaer 已提交
63 64 65 66 67 68
      },
      content_type: "application/vnd.git-lfs+json",
      status: 404
    )
  end

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
  def lfs_download_access?
    return false unless project.lfs_enabled?

    ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code?
  end

  def lfs_upload_access?
    return false unless project.lfs_enabled?

    has_authentication_ability?(:push_code) && can?(user, :push_code, project)
  end

  def lfs_deploy_token?
    authentication_result.lfs_deploy_token?(project)
  end

  def user_can_download_code?
    has_authentication_ability?(:download_code) && can?(user, :download_code, project)
  end

  def build_can_download_code?
    has_authentication_ability?(:build_download_code) && can?(user, :build_download_code, project)
  end

J
Jacob Vosmaer 已提交
93 94 95 96
  def storage_project
    @storage_project ||= begin
      result = project

J
Rubocop  
Jacob Vosmaer 已提交
97 98
      loop do
        break unless result.forked?
J
Jacob Vosmaer 已提交
99 100 101 102 103 104
        result = result.forked_from_project
      end

      result
    end
  end
105 106 107 108

  def objects
    @objects ||= (params[:objects] || []).to_a
  end
109 110 111 112

  def has_authentication_ability?(capability)
    (authentication_abilities || []).include?(capability)
  end
J
Jacob Vosmaer 已提交
113
end