BigW Consortium Gitlab

lfs_api_controller.rb 2.09 KB
Newer Older
Jacob Vosmaer committed
1 2 3
class Projects::LfsApiController < Projects::GitHttpClientController
  include LfsHelper

4
  before_action :require_lfs_enabled!
Jacob Vosmaer committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
  before_action :lfs_check_access!, except: [:deprecated]

  def batch
    unless objects.present?
      render_lfs_not_found
      return
    end

    if download_request?
      render json: { objects: download_objects! }
    elsif upload_request?
      render json: { objects: upload_objects! }
    else
      raise "Never reached"
    end
  end

  def deprecated
    render(
      json: {
        message: 'Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.',
        documentation_url: "#{Gitlab.config.gitlab.url}/help",
      },
      status: 501
    )
  end

  private

  def objects
35
    @objects ||= (params[:objects] || []).to_a
Jacob Vosmaer committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
  end

  def existing_oids
    @existing_oids ||= begin
      storage_project.lfs_objects.where(oid: objects.map { |o| o['oid'].to_s }).pluck(:oid)
    end
  end

  def download_objects!
    objects.each do |object|
      if existing_oids.include?(object[:oid])
        object[:actions] = download_actions(object)
      else
        object[:error] = {
          code: 404,
          message: "Object does not exist on the server or you don't have permissions to access it",
        }
      end
    end
    objects
  end

  def upload_objects!
    objects.each do |object|
      object[:actions] = upload_actions(object) unless existing_oids.include?(object[:oid])
    end
    objects
  end

  def download_actions(object)
    {
      download: {
        href: "#{project.http_url_to_repo}/gitlab-lfs/objects/#{object[:oid]}",
        header: {
          Authorization: request.headers['Authorization']
        }.compact
      }
    }
  end

  def upload_actions(object)
    {
      upload: {
        href: "#{project.http_url_to_repo}/gitlab-lfs/objects/#{object[:oid]}/#{object[:size]}",
        header: {
          Authorization: request.headers['Authorization']
        }.compact
      }
    }
  end

  def download_request?
    params[:operation] == 'download'
  end

  def upload_request?
    params[:operation] == 'upload'
  end
end