2018-09-14 01:42:05 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-05-01 09:14:35 -04:00
|
|
|
module UploadsActions
|
2017-12-06 06:36:11 -05:00
|
|
|
include Gitlab::Utils::StrongMemoize
|
2018-03-09 09:16:06 -05:00
|
|
|
include SendFileUpload
|
2017-12-06 06:36:11 -05:00
|
|
|
|
2017-09-26 03:54:32 -04:00
|
|
|
UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze
|
2018-01-29 12:57:34 -05:00
|
|
|
|
2017-05-01 09:14:35 -04:00
|
|
|
def create
|
2019-01-03 00:17:07 -05:00
|
|
|
uploader = UploadService.new(model, params[:file], uploader_class).execute
|
2017-05-01 09:14:35 -04:00
|
|
|
|
|
|
|
respond_to do |format|
|
2019-01-03 00:17:07 -05:00
|
|
|
if uploader
|
2017-05-01 09:14:35 -04:00
|
|
|
format.json do
|
2019-01-03 00:17:07 -05:00
|
|
|
render json: { link: uploader.to_h }
|
2017-05-01 09:14:35 -04:00
|
|
|
end
|
|
|
|
else
|
|
|
|
format.json do
|
|
|
|
render json: 'Invalid file.', status: :unprocessable_entity
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-01-29 12:57:34 -05:00
|
|
|
# This should either
|
|
|
|
# - send the file directly
|
|
|
|
# - or redirect to its URL
|
|
|
|
#
|
2017-05-01 09:14:35 -04:00
|
|
|
def show
|
2018-02-21 11:09:30 -05:00
|
|
|
return render_404 unless uploader&.exists?
|
2017-05-01 09:14:35 -04:00
|
|
|
|
2019-01-22 05:09:04 -05:00
|
|
|
if cache_publicly?
|
2019-01-21 16:25:54 -05:00
|
|
|
# We need to reset caching from the applications controller to get rid of the no-store value
|
|
|
|
headers['Cache-Control'] = ''
|
|
|
|
expires_in 5.minutes, public: true, must_revalidate: false
|
2019-01-22 05:09:04 -05:00
|
|
|
else
|
|
|
|
expires_in 0.seconds, must_revalidate: true, private: true
|
2019-01-21 16:25:54 -05:00
|
|
|
end
|
2017-05-01 09:14:35 -04:00
|
|
|
|
2018-03-09 09:16:06 -05:00
|
|
|
disposition = uploader.image_or_video? ? 'inline' : 'attachment'
|
|
|
|
|
2018-04-13 15:29:01 -04:00
|
|
|
uploaders = [uploader, *uploader.versions.values]
|
|
|
|
uploader = uploaders.find { |version| version.filename == params[:filename] }
|
2018-04-12 08:11:21 -04:00
|
|
|
|
2018-04-13 15:29:01 -04:00
|
|
|
return render_404 unless uploader
|
2018-04-12 08:11:21 -04:00
|
|
|
|
2018-12-06 16:22:39 -05:00
|
|
|
workhorse_set_content_type!
|
2018-04-13 15:29:01 -04:00
|
|
|
send_upload(uploader, attachment: uploader.filename, disposition: disposition)
|
2017-05-01 09:14:35 -04:00
|
|
|
end
|
2017-12-06 06:36:11 -05:00
|
|
|
|
2018-06-12 11:54:37 -04:00
|
|
|
def authorize
|
|
|
|
set_workhorse_internal_api_content_type
|
|
|
|
|
|
|
|
authorized = uploader_class.workhorse_authorize(
|
|
|
|
has_length: false,
|
|
|
|
maximum_size: Gitlab::CurrentSettings.max_attachment_size.megabytes.to_i)
|
|
|
|
|
|
|
|
render json: authorized
|
2018-09-05 09:24:06 -04:00
|
|
|
rescue SocketError
|
|
|
|
render json: "Error uploading file", status: :internal_server_error
|
2018-06-12 11:54:37 -04:00
|
|
|
end
|
|
|
|
|
2017-12-06 06:36:11 -05:00
|
|
|
private
|
|
|
|
|
2018-01-29 12:57:34 -05:00
|
|
|
def uploader_class
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
|
|
|
|
def upload_mount
|
|
|
|
mounted_as = params[:mounted_as]
|
|
|
|
mounted_as if UPLOAD_MOUNTS.include?(mounted_as)
|
|
|
|
end
|
|
|
|
|
|
|
|
def uploader_mounted?
|
|
|
|
upload_model_class < CarrierWave::Mount::Extension && !upload_mount.nil?
|
|
|
|
end
|
|
|
|
|
2017-12-06 06:36:11 -05:00
|
|
|
def uploader
|
|
|
|
strong_memoize(:uploader) do
|
2018-01-29 12:57:34 -05:00
|
|
|
if uploader_mounted?
|
|
|
|
model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
|
|
|
|
else
|
|
|
|
build_uploader_from_upload || build_uploader_from_params
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-12-06 06:36:11 -05:00
|
|
|
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2018-01-29 12:57:34 -05:00
|
|
|
def build_uploader_from_upload
|
2018-03-02 10:41:40 -05:00
|
|
|
return unless uploader = build_uploader
|
2017-12-06 06:36:11 -05:00
|
|
|
|
2018-03-02 10:41:40 -05:00
|
|
|
upload_paths = uploader.upload_paths(params[:filename])
|
|
|
|
upload = Upload.find_by(uploader: uploader_class.to_s, path: upload_paths)
|
2018-01-29 12:57:34 -05:00
|
|
|
upload&.build_uploader
|
|
|
|
end
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2018-01-29 12:57:34 -05:00
|
|
|
|
|
|
|
def build_uploader_from_params
|
2018-03-02 10:41:40 -05:00
|
|
|
return unless uploader = build_uploader
|
|
|
|
|
|
|
|
uploader.retrieve_from_store!(params[:filename])
|
|
|
|
uploader
|
|
|
|
end
|
|
|
|
|
|
|
|
def build_uploader
|
|
|
|
return unless params[:secret] && params[:filename]
|
|
|
|
|
2018-01-29 16:06:17 -05:00
|
|
|
uploader = uploader_class.new(model, secret: params[:secret])
|
2018-02-21 11:09:30 -05:00
|
|
|
|
2018-03-02 10:41:40 -05:00
|
|
|
return unless uploader.model_valid?
|
2018-02-21 11:09:30 -05:00
|
|
|
|
2018-01-29 12:57:34 -05:00
|
|
|
uploader
|
2017-12-06 06:36:11 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def image_or_video?
|
|
|
|
uploader && uploader.exists? && uploader.image_or_video?
|
|
|
|
end
|
|
|
|
|
2018-01-29 12:57:34 -05:00
|
|
|
def find_model
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2019-01-22 05:09:04 -05:00
|
|
|
def cache_publicly?
|
|
|
|
false
|
2019-01-21 16:25:54 -05:00
|
|
|
end
|
|
|
|
|
2018-01-29 12:57:34 -05:00
|
|
|
def model
|
|
|
|
strong_memoize(:model) { find_model }
|
2017-12-06 06:36:11 -05:00
|
|
|
end
|
2017-05-01 09:14:35 -04:00
|
|
|
end
|