Use controllers to serve uploads, with XSS prevention and access control.

This commit is contained in:
Douwe Maan 2015-02-20 13:13:48 +01:00
parent 4310431ee7
commit 00ca490259
3 changed files with 48 additions and 0 deletions

View file

@ -0,0 +1,19 @@
class Projects::UploadsController < Projects::ApplicationController
layout "project"
before_filter :project
def show
path = File.join(project.path_with_namespace, params[:secret])
uploader = FileUploader.new('uploads', path)
uploader.retrieve_from_store!(params[:filename])
if uploader.file.exists?
# Right now, these are always images, so we can safely render them inline.
send_file uploader.file.path, disposition: 'inline'
else
not_found!
end
end
end

View file

@ -0,0 +1,17 @@
class UploadsController < ApplicationController
def show
model = params[:model].camelize.constantize.find(params[:id])
uploader = model.send(params[:mounted_as])
if uploader.file_storage?
if !model.respond_to?(:project) || can?(current_user, :read_project, model.project)
disposition = uploader.image? ? 'inline' : 'attachment'
send_file uploader.file.path, disposition: disposition
else
not_found!
end
else
redirect_to uploader.url
end
end
end

View file

@ -69,7 +69,19 @@ Gitlab::Application.routes.draw do
end
end
#
# Uploads
#
scope path: :uploads do
# Note attachments and User/Group/Project avatars
get ":model/:mounted_as/:id/:filename", to: "uploads#show",
constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /.+/ }
# Project markdown uploads
get ":id/:secret/:filename", to: "projects/uploads#show",
constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/, filename: /.+/ }
end
#
# Explore area