summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorHannes Rosenögger <123haynes@gmail.com>2015-02-14 16:04:45 +0100
committerDouwe Maan <douwe@gitlab.com>2015-02-17 22:20:44 +0100
commit9bf8480b4a0d3ea6e284c4bd8bf26243f3f3f6f5 (patch)
tree2365d68b1905ddce4d20f226f9e888c29bc0dcf4 /app
parent0da0d800f2a0db9d9c16cf5e2feb0dd80b528223 (diff)
downloadgitlab-ce-9bf8480b4a0d3ea6e284c4bd8bf26243f3f3f6f5.tar.gz
Generalize the image upload in markdown
This commit generalizes the image upload via drag and drop so it supports all files. It also adds access control for these files.
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/dropzone_input.js.coffee21
-rw-r--r--app/controllers/files_controller.rb29
-rw-r--r--app/controllers/projects_controller.rb18
-rw-r--r--app/services/projects/file_service.rb55
-rw-r--r--app/services/projects/image_service.rb39
-rw-r--r--app/uploaders/file_uploader.rb19
-rw-r--r--app/views/projects/_issuable_form.html.haml2
-rw-r--r--app/views/projects/issues/_form.html.haml2
-rw-r--r--app/views/projects/merge_requests/_form.html.haml2
-rw-r--r--app/views/projects/merge_requests/_new_submit.html.haml5
-rw-r--r--app/views/projects/milestones/_form.html.haml4
-rw-r--r--app/views/projects/notes/_edit_form.html.haml2
-rw-r--r--app/views/projects/notes/_form.html.haml6
-rw-r--r--app/views/projects/wikis/_form.html.haml5
14 files changed, 135 insertions, 74 deletions
diff --git a/app/assets/javascripts/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee
index d98d5482937..bed8471b39a 100644
--- a/app/assets/javascripts/dropzone_input.js.coffee
+++ b/app/assets/javascripts/dropzone_input.js.coffee
@@ -9,7 +9,7 @@ class @DropzoneInput
iconPicture = "<i class=\"fa fa-picture-o div-dropzone-icon\"></i>"
iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>"
btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>"
- project_image_path_upload = window.project_image_path_upload or null
+ project_file_path_upload = window.project_file_path_upload or null
form_textarea = $(form).find("textarea.markdown-area")
form_textarea.wrap "<div class=\"div-dropzone\"></div>"
@@ -72,13 +72,12 @@ class @DropzoneInput
form.find(".md-preview-holder").hide()
dropzone = form_dropzone.dropzone(
- url: project_image_path_upload
+ url: project_file_path_upload
dictDefaultMessage: ""
clickable: true
- paramName: "markdown_img"
+ paramName: "markdown_file"
maxFilesize: 10
uploadMultiple: false
- acceptedFiles: "image/jpg,image/jpeg,image/gif,image/png"
headers:
"X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")
@@ -133,7 +132,10 @@ class @DropzoneInput
child = $(dropzone[0]).children("textarea")
formatLink = (str) ->
- "![" + str.alt + "](" + str.url + ")"
+ text = "[" + str.alt + "](" + str.url + ")"
+ if str.is_image is true
+ text = "!" + text
+ text
handlePaste = (event) ->
pasteEvent = event.originalEvent
@@ -177,9 +179,9 @@ class @DropzoneInput
uploadFile = (item, filename) ->
formData = new FormData()
- formData.append "markdown_img", item, filename
+ formData.append "markdown_file", item, filename
$.ajax
- url: project_image_path_upload
+ url: project_file_path_upload
type: "POST"
data: formData
dataType: "json"
@@ -234,4 +236,7 @@ class @DropzoneInput
return
formatLink: (str) ->
- "![" + str.alt + "](" + str.url + ")"
+ text = "[" + str.alt + "](" + str.url + ")"
+ if str.is_image is true
+ text = "!" + text
+ text
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index 15523cbc2e7..a86340dd9bb 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -1,5 +1,5 @@
class FilesController < ApplicationController
- def download
+ def download_notes
note = Note.find(params[:id])
uploader = note.attachment
@@ -14,7 +14,32 @@ class FilesController < ApplicationController
not_found!
end
else
- redirect_to uploader.url
+ not_found!
end
end
+
+ def download_files
+ namespace_id = params[:namespace]
+ project_id = params[:project]
+ folder_id = params[:folder_id]
+ filename = params[:filename]
+ project_with_namespace="#{namespace_id}/#{project_id}"
+ filename_with_id="#{folder_id}/#{filename}"
+
+ project = Project.find_with_namespace(project_with_namespace)
+
+ uploader = FileUploader.new("#{Rails.root}/uploads","#{project_with_namespace}/#{folder_id}")
+ uploader.retrieve_from_store!(filename)
+
+ if can?(current_user, :read_project, project)
+ download(uploader)
+ else
+ not_found!
+ end
+ end
+
+ def download(uploader)
+ disposition = uploader.image? ? 'inline' : 'attachment'
+ send_file uploader.file.path, disposition: disposition
+ end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 462ab3d4749..b430278903a 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -134,12 +134,13 @@ class ProjectsController < ApplicationController
end
end
- def upload_image
- link_to_image = ::Projects::ImageService.new(repository, params, root_url).execute
+ def upload_file
+ link_to_file = ::Projects::FileService.new(repository, params, root_url).
+ execute
respond_to do |format|
- if link_to_image
- format.json { render json: { link: link_to_image } }
+ if link_to_file
+ format.json { render json: { link: link_to_file } }
else
format.json { render json: 'Invalid file.', status: :unprocessable_entity }
end
@@ -158,13 +159,8 @@ class ProjectsController < ApplicationController
private
- def upload_path
- base_dir = FileUploader.generate_dir
- File.join(repository.path_with_namespace, base_dir)
- end
-
- def accepted_images
- %w(png jpg jpeg gif)
+ def invalid_file(error)
+ render json: { message: error.message }, status: :internal_server_error
end
def set_title
diff --git a/app/services/projects/file_service.rb b/app/services/projects/file_service.rb
new file mode 100644
index 00000000000..8c149bf53a1
--- /dev/null
+++ b/app/services/projects/file_service.rb
@@ -0,0 +1,55 @@
+module Projects
+ class FileService < BaseService
+ include Rails.application.routes.url_helpers
+ def initialize(repository, params, root_url)
+ @repository, @params, @root_url = repository, params.dup, root_url
+ end
+
+ def execute
+ uploader = FileUploader.new("#{Rails.root}/uploads", upload_path, accepted_files)
+ file = @params['markdown_file']
+
+ if file
+ alt = file.original_filename
+ uploader.store!(file)
+ filename = nil
+ if image?(file)
+ filename=File.basename(alt, '.*')
+ else
+ filename=File.basename(alt)
+ end
+ link = {
+ 'alt' => filename,
+ 'url' => uploader.secure_url,
+ 'is_image' => image?(file)
+ }
+ else
+ link = nil
+ end
+ end
+
+ protected
+
+ def accepted_files
+ # insert accepted mime types here (e.g %w(jpg jpeg gif png))
+ nil
+ end
+
+ def accepted_images
+ %w(jpg jpeg gif png)
+ end
+
+ def image?(file)
+ accepted_images.map { |format| file.content_type.include? format }.any?
+ end
+
+ def upload_path
+ base_dir = FileUploader.generate_dir
+ File.join(@repository.path_with_namespace, base_dir)
+ end
+
+ def correct_mime_type?(file)
+ accepted_files.map { |format| image.content_type.include? format }.any?
+ end
+ end
+end
diff --git a/app/services/projects/image_service.rb b/app/services/projects/image_service.rb
deleted file mode 100644
index 7ca7e82c4a3..00000000000
--- a/app/services/projects/image_service.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module Projects
- class ImageService < BaseService
- include Rails.application.routes.url_helpers
- def initialize(repository, params, root_url)
- @repository, @params, @root_url = repository, params.dup, root_url
- end
-
- def execute
- uploader = FileUploader.new('uploads', upload_path, accepted_images)
- image = @params['markdown_img']
-
- if image && correct_mime_type?(image)
- alt = image.original_filename
- uploader.store!(image)
- link = {
- 'alt' => File.basename(alt, '.*'),
- 'url' => File.join(@root_url, uploader.url)
- }
- else
- link = nil
- end
- end
-
- protected
-
- def upload_path
- base_dir = FileUploader.generate_dir
- File.join(@repository.path_with_namespace, base_dir)
- end
-
- def accepted_images
- %w(png jpg jpeg gif)
- end
-
- def correct_mime_type?(image)
- accepted_images.map{ |format| image.content_type.include? format }.any?
- end
- end
-end
diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb
index 0fa987c93f6..ac7bd5b27ec 100644
--- a/app/uploaders/file_uploader.rb
+++ b/app/uploaders/file_uploader.rb
@@ -21,7 +21,7 @@ class FileUploader < CarrierWave::Uploader::Base
end
def extension_white_list
- @allowed_extensions
+ @allowed_extensions || super
end
def store!(file)
@@ -38,4 +38,21 @@ class FileUploader < CarrierWave::Uploader::Base
def self.generate_dir
SecureRandom.hex(5)
end
+
+ def secure_url
+ Gitlab.config.gitlab.relative_url_root + "/files/#{@path}/#{@filename}"
+ end
+
+ def image?
+ img_ext = %w(png jpg jpeg gif bmp tiff)
+ if file.respond_to?(:extension)
+ img_ext.include?(file.extension.downcase)
+ else
+ # Not all CarrierWave storages respond to :extension
+ ext = file.path.split('.').last.downcase
+ img_ext.include?(ext)
+ end
+ rescue
+ false
+ end
end
diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml
index 5a57673b584..18897b055aa 100644
--- a/app/views/projects/_issuable_form.html.haml
+++ b/app/views/projects/_issuable_form.html.haml
@@ -23,7 +23,7 @@
Parsed with
#{link_to 'GitLab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}.
.pull-right
- Attach images (JPG, PNG, GIF) by dragging &amp; dropping
+ Attach files by dragging &amp; dropping
or #{link_to 'selecting them', '#', class: 'markdown-selector' }.
.clearfix
diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml
index 2a7b44955cd..975980bd6bd 100644
--- a/app/views/projects/issues/_form.html.haml
+++ b/app/views/projects/issues/_form.html.haml
@@ -11,4 +11,4 @@
e.preventDefault();
});
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index d52e64666a0..28c4734e14f 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -9,4 +9,4 @@
e.preventDefault();
});
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index bca3e45bf19..0653b30fcca 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -27,7 +27,7 @@
Parsed with
#{link_to 'Gitlab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}.
.pull-right
- Attach images (JPG, PNG, GIF) by dragging &amp; dropping
+ Attach files by dragging &amp; dropping
or #{link_to 'selecting them', '#', class: 'markdown-selector'}.
.clearfix
@@ -113,10 +113,11 @@
e.preventDefault();
});
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
:javascript
var merge_request
merge_request = new MergeRequest({
action: 'commits'
});
+
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index b3b170d7114..5fbb668570c 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -25,7 +25,7 @@
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.hint
.pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}.
- .pull-left Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
+ .pull-left Attach files by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
.clearfix
.error-alert
.col-md-6
@@ -51,4 +51,4 @@
onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
}).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val()));
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml
index cdc76f5d96f..4ba59078318 100644
--- a/app/views/projects/notes/_edit_form.html.haml
+++ b/app/views/projects/notes/_edit_form.html.haml
@@ -6,7 +6,7 @@
.comment-hints.clearfix
.pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }}
- .pull-right Attach images (JPG, PNG, GIF) by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }.
+ .pull-right Attach files by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }.
.note-form-actions
.buttons
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index 1a4e06289f8..fe3dab569f4 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project, @note], remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new_note js-new-note-form common-note-form gfm-form" }, authenticity_token: true do |f|
+= form_for [@project, @note], remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new_note js-new-note-form common-note-form" }, authenticity_token: true do |f|
= note_target_fields
= f.hidden_field :commit_id
= f.hidden_field :line_code
@@ -11,7 +11,7 @@
.comment-hints.clearfix
.pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }}
- .pull-right Attach images (JPG, PNG, GIF) by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }.
+ .pull-right Attach files by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }.
.note-form-actions
@@ -29,4 +29,4 @@
= f.file_field :attachment, class: "js-note-attachment-input hidden"
:javascript
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml
index 84731e43e95..0afee138c8b 100644
--- a/app/views/projects/wikis/_form.html.haml
+++ b/app/views/projects/wikis/_form.html.haml
@@ -26,7 +26,7 @@
= render 'projects/zen', f: f, attr: :content, classes: 'description form-control'
.col-sm-12.hint
.pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}
- .pull-right Attach images (JPG, PNG, GIF) by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
+ .pull-right Attach files by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
.clearfix
.error-alert
@@ -43,5 +43,6 @@
= link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel"
:javascript
- window.project_image_path_upload = "#{upload_image_project_path @project}";
+ window.project_file_path_upload = "#{upload_file_project_path @project}";
+