From 6d2301988fdc0118c5583f48ba6da4a3b8247ba4 Mon Sep 17 00:00:00 2001 From: Rakib Hasan Date: Wed, 1 Feb 2017 21:07:38 -0500 Subject: [PATCH 1/4] Fix for issue #462 Modified uploadCompose action to send media ids of attached media when sending a request. Modified create method in MediaController to check if when posting a video, there are no other media attached to the status by looking at the media ids sent from the uploadCompose action. --- app/assets/javascripts/components/actions/compose.jsx | 5 ++++- app/controllers/api/v1/media_controller.rb | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/components/actions/compose.jsx b/app/assets/javascripts/components/actions/compose.jsx index 03aae885e..84fbc7fc5 100644 --- a/app/assets/javascripts/components/actions/compose.jsx +++ b/app/assets/javascripts/components/actions/compose.jsx @@ -119,7 +119,10 @@ export function uploadCompose(files) { let data = new FormData(); data.append('file', files[0]); - + data.append('media_ids', getState().getIn( + ['compose', 'media_attachments'] + ).map(item => item.get('id'))); + api(getState).post('/api/v1/media', data, { onUploadProgress: function (e) { dispatch(uploadComposeProgress(e.loaded, e.total)); diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index f8139ade7..582d04daf 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -11,6 +11,10 @@ class Api::V1::MediaController < ApiController def create @media = MediaAttachment.create!(account: current_user.account, file: params[:file]) + if @media.video? and params[:media_ids] != "List []" + @media.destroy + render json: {error: 'Cannot attach a video to a toot that already contains images'}, status: 422 + end rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: { error: 'File type of uploaded media could not be verified' }, status: 422 rescue Paperclip::Error From 6f9ecd899e9e7cb335940465c23dd53acc37269c Mon Sep 17 00:00:00 2001 From: Rakib Hasan Date: Thu, 2 Feb 2017 23:10:17 -0500 Subject: [PATCH 2/4] revisted fix for #462 Moved validation to services/post_status_service.rb --- .../javascripts/components/actions/compose.jsx | 5 +---- app/controllers/api/v1/media_controller.rb | 4 ---- app/controllers/api/v1/statuses_controller.rb | 16 ++++++++++------ app/services/post_status_service.rb | 8 +++++++- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/components/actions/compose.jsx b/app/assets/javascripts/components/actions/compose.jsx index 84fbc7fc5..03aae885e 100644 --- a/app/assets/javascripts/components/actions/compose.jsx +++ b/app/assets/javascripts/components/actions/compose.jsx @@ -119,10 +119,7 @@ export function uploadCompose(files) { let data = new FormData(); data.append('file', files[0]); - data.append('media_ids', getState().getIn( - ['compose', 'media_attachments'] - ).map(item => item.get('id'))); - + api(getState).post('/api/v1/media', data, { onUploadProgress: function (e) { dispatch(uploadComposeProgress(e.loaded, e.total)); diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index 582d04daf..f8139ade7 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -11,10 +11,6 @@ class Api::V1::MediaController < ApiController def create @media = MediaAttachment.create!(account: current_user.account, file: params[:file]) - if @media.video? and params[:media_ids] != "List []" - @media.destroy - render json: {error: 'Cannot attach a video to a toot that already contains images'}, status: 422 - end rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: { error: 'File type of uploaded media could not be verified' }, status: 422 rescue Paperclip::Error diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 69cbdce5d..036383d1e 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -62,12 +62,16 @@ class Api::V1::StatusesController < ApiController end def create - @status = PostStatusService.new.call(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]), media_ids: params[:media_ids], - sensitive: params[:sensitive], - spoiler_text: params[:spoiler_text], - visibility: params[:visibility], - application: doorkeeper_token.application) - + begin + @status = PostStatusService.new.call(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]), media_ids: params[:media_ids], + sensitive: params[:sensitive], + spoiler_text: params[:spoiler_text], + visibility: params[:visibility], + application: doorkeeper_token.application) + rescue Mastodon::NotPermitted => e + render json: {error: e.message}, status: 422 + return + end render action: :show end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 979941c84..d70103547 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -35,8 +35,14 @@ class PostStatusService < BaseService def attach_media(status, media_ids) return if media_ids.nil? || !media_ids.is_a?(Enumerable) - media = MediaAttachment.where(status_id: nil).where(id: media_ids.take(4).map(&:to_i)) + if media.length > 1 + media.each do |m| + if m.video? + raise Mastodon::NotPermitted, 'Cannot attach a video to a toot that already contains images' + end + end + end media.update(status_id: status.id) end From 87a6bed9e947aaad62466f072d1a27cd0f782a7d Mon Sep 17 00:00:00 2001 From: Rakib Hasan Date: Sat, 4 Feb 2017 22:03:24 -0500 Subject: [PATCH 3/4] previous commit was creating the status regardless of mix of video and images in status, just wasn't rendering the show action. I moved the validation before the status creation --- app/services/post_status_service.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index d70103547..7ead80430 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -13,6 +13,7 @@ class PostStatusService < BaseService # @option [Doorkeeper::Application] :application # @return [Status] def call(account, text, in_reply_to = nil, options = {}) + media = validate_media options[:media_ids] status = account.statuses.create!(text: text, thread: in_reply_to, sensitive: options[:sensitive], @@ -20,7 +21,7 @@ class PostStatusService < BaseService visibility: options[:visibility], application: options[:application]) - attach_media(status, options[:media_ids]) + attach_media(status, media) process_mentions_service.call(status) process_hashtags_service.call(status) @@ -33,7 +34,7 @@ class PostStatusService < BaseService private - def attach_media(status, media_ids) + def validate_media(media_ids) return if media_ids.nil? || !media_ids.is_a?(Enumerable) media = MediaAttachment.where(status_id: nil).where(id: media_ids.take(4).map(&:to_i)) if media.length > 1 @@ -43,6 +44,11 @@ class PostStatusService < BaseService end end end + return media + end + + def attach_media(status, media) + return if media.nil? media.update(status_id: status.id) end From 9433d03705d3aa86a059d82ffc549c699092912d Mon Sep 17 00:00:00 2001 From: Rakib Hasan Date: Fri, 17 Feb 2017 02:58:16 +0000 Subject: [PATCH 4/4] Removed try clause from create action in status controller Using catch statement in api_controller.rb to catch NotPermitted Exception, and render error message --- app/controllers/api/v1/statuses_controller.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 036383d1e..2ffd4a018 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -62,16 +62,11 @@ class Api::V1::StatusesController < ApiController end def create - begin @status = PostStatusService.new.call(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]), media_ids: params[:media_ids], sensitive: params[:sensitive], spoiler_text: params[:spoiler_text], visibility: params[:visibility], application: doorkeeper_token.application) - rescue Mastodon::NotPermitted => e - render json: {error: e.message}, status: 422 - return - end render action: :show end