From 0a081e7eff9730beebd4bea1eb40873d907b6293 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 3 Dec 2015 14:59:10 +0100 Subject: [PATCH] If a user clicks on the LFS object, it should be served if the user has access to the object. --- app/controllers/projects/blob_controller.rb | 17 +++++++++++++++++ app/models/lfs_object.rb | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 31a33bfd237..d0108c823a9 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -17,6 +17,7 @@ class Projects::BlobController < Projects::ApplicationController before_action :require_branch_head, only: [:edit, :update] before_action :editor_variables, except: [:show, :preview, :diff] before_action :after_edit_path, only: [:edit, :update] + before_action :show_lfs_object, only: :show def new commit unless @repository.empty? @@ -193,4 +194,20 @@ class Projects::BlobController < Projects::ApplicationController file_content_encoding: params[:encoding] } end + + def show_lfs_object + return unless @blob && @blob.text? && @blob.data.present? + + if @blob.data.starts_with?("version https://git-lfs.github.com/spec") + oid = @blob.data.match(/#{LfsObject::MATCH_FROM_POINTER_REGEX}/) + if oid && oid[1] + lfs_object = LfsObject.find_by_oid(oid[1]) + return nil unless lfs_object && lfs_object.file.exists? + + if lfs_object.projects.exists?(lfs_object.storage_project(@project).id) + send_file lfs_object.file.path, filename: @blob.name, disposition: 'attachment' + end + end + end + end end diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 3c1426f59d0..f087d07b5b2 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -5,4 +5,14 @@ class LfsObject < ActiveRecord::Base validates :oid, presence: true, uniqueness: true mount_uploader :file, LfsObjectUploader + + MATCH_FROM_POINTER_REGEX = "(?<=sha256:)([0-9a-f]{64})" + + def storage_project(project) + if project && project.forked? + project.forked_from_project + else + project + end + end end