Add error handling and secutiry checks

This commit is contained in:
Anton Ignatov 2019-05-02 16:12:25 +02:00
parent f73dd38780
commit fef691d30f
7 changed files with 144 additions and 101 deletions

View file

@ -200,7 +200,6 @@ var MarvinJsEditor = (function() {
type: 'PUT',
success: function(json) {
config.image[0].src = json.url;
config.saveButton.removeClass('hidden');
$(marvinJsModal).modal('hide');
}
});

View file

@ -561,31 +561,32 @@ var FilePreviewModal = (function() {
MarvinJsEditor().create_preview(src, target);
MarvinJsEditor().create_download_link(src, link, name);
modal.find('.file-name').text(name);
if (!readOnly) {
modal.find('.file-edit-link').css('display', '');
modal.find('.file-edit-link').off().click(function(ev) {
ev.preventDefault();
ev.stopPropagation();
modal.modal('hide');
MarvinJsEditor().open({
mode: 'edit',
data: src.val(),
name: name,
marvinUrl: sketch.dataset.updateUrl,
reloadImage: {
src: src,
sketch: sketch
}
$.get(sketch.dataset.updateUrl, function(result) {
if (!readOnly && result.editable) {
modal.find('.file-edit-link').css('display', '');
modal.find('.file-edit-link').off().click(function(ev) {
ev.preventDefault();
ev.stopPropagation();
modal.modal('hide');
MarvinJsEditor().open({
mode: 'edit',
data: src.val(),
name: name,
marvinUrl: sketch.dataset.updateUrl,
reloadImage: {
src: src,
sketch: sketch
}
});
});
});
} else {
modal.find('.file-edit-link').css('display', 'none');
}
} else {
modal.find('.file-edit-link').css('display', 'none');
}
});
}
return Object.freeze({
init: initPreviewModal,
imageEditor: initImageEditor,
imageEditor: initImageEditor
});
}(window));

View file

@ -37,6 +37,78 @@ var TinyMCE = (function() {
}
}
function initImageToolBar(editor) {
var editorForm = $(editor.getContainer()).closest('form');
var editorContainer = $(editor.getContainer());
var menuBar = editorForm.find('.mce-menubar.mce-toolbar.mce-first .mce-flow-layout');
var editorToolbar = editorForm.find('.mce-top-part');
var editorIframe = $('#' + editor.id).prev().find('.mce-edit-area iframe');
$('<div class="tinymce-active-object-handler" style="display:none">'
+ '<a class="file-download-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-donwload"></i></a>'
+ '<span class="file-edit-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-pencil"></i></span>'
+ '<span class="file-image-editor-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-image"></i></span>'
+ '</div>').appendTo(editorToolbar.find('.mce-stack-layout'));
editorIframe.contents().click(function() {
var marvinJsEdit;
setTimeout(() => {
var image = editorIframe.contents().find('img[data-mce-selected="1"]');
var editLink;
var imageEditorLink;
if (image.length > 0) {
image.on('load', function() {
editorContainer.find('.tinymce-save-button').removeClass('hidden');
});
editorContainer.find('.tinymce-active-object-handler').css('display', 'block');
editorContainer.find('.tinymce-active-object-handler .file-download-link')
.attr('href', image[0].src)
.attr('download', 'tinymce-image');
// Edit link
editLink = editorContainer.find('.tinymce-active-object-handler .file-edit-link');
if (image[0].dataset.sourceId) {
editLink.css('display', 'inline-block');
marvinJsEdit = (image[0].dataset.sourceType === 'MarvinJsAsset' && typeof (MarvinJsEditor) !== 'undefined');
if (!marvinJsEdit) editLink.css('display', 'none');
editLink.on('click', function() {
if (marvinJsEdit) {
MarvinJsEditor().open({
mode: 'edit-tinymce',
marvinUrl: '/marvin_js_assets/' + image[0].dataset.sourceId,
image: image
});
}
});
} else {
editLink.css('display', 'none');
editLink.off('click');
}
// imaged editor Link
imageEditorLink = editorContainer.find('.tinymce-active-object-handler .file-image-editor-link');
if (image[0].dataset.mceToken && image[0].dataset.sourceId) {
imageEditorLink.css('display', 'inline-block');
imageEditorLink.on('click', function() {
FilePreviewModal.imageEditor({
'download-url': image[0].src,
filename: 'tinymce-image.jpg',
mode: 'tinymce',
url: '/tiny_mce_assets/' + image[0].dataset.mceToken,
quality: 100,
'mime-type': 'image/jpeg',
image: image[0]
});
});
} else {
imageEditorLink.css('display', 'none');
imageEditorLink.off('click');
}
} else {
editorContainer.find('.tinymce-active-object-handler').css('display', 'none');
}
}, 100);
});
}
// returns a public API for TinyMCE editor
return Object.freeze({
init: function(selector, mceConfig = {}) {
@ -153,6 +225,9 @@ var TinyMCE = (function() {
moveToolbar(editor, editorToolbar, editorToolbaroffset);
});
// Init image toolbar
initImageToolBar(editor);
// Init Save button
editorForm
.find('.tinymce-save-button')
@ -166,70 +241,6 @@ var TinyMCE = (function() {
editorForm.submit();
});
// Init image helpers
$('<div class="tinymce-active-object-handler" style="display:none">'
+ '<a class="file-download-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-donwload"></i></a>'
+ '<span class="file-edit-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-pencil"></i></span>'
+ '<span class="file-image-editor-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-image"></i></span>'
+ '</div>').appendTo(editorToolbar.find('.mce-stack-layout'));
editorIframe.contents().click(function() {
var marvinJsEdit;
setTimeout(() => {
var image = editorIframe.contents().find('img[data-mce-selected="1"]');
var editLink;
var imageEditorLink;
if (image.length > 0) {
editorContainer.find('.tinymce-active-object-handler').css('display', 'block');
editorContainer.find('.tinymce-active-object-handler .file-download-link')
.attr('href', image[0].src)
.attr('download', 'tinymce-image');
// Edit link
editLink = editorContainer.find('.tinymce-active-object-handler .file-edit-link');
if (image[0].dataset.sourceId) {
editLink.css('display', 'inline-block');
marvinJsEdit = (image[0].dataset.sourceType === 'MarvinJsAsset' && typeof (MarvinJsEditor) !== 'undefined');
if (!marvinJsEdit) editLink.css('display', 'none');
editLink.on('click', function() {
if (marvinJsEdit) {
MarvinJsEditor().open({
mode: 'edit-tinymce',
marvinUrl: '/marvin_js_assets/' + image[0].dataset.sourceId,
image: image,
saveButton: editorContainer.find('.tinymce-save-button')
});
}
});
} else {
editLink.css('display', 'none');
editLink.off('click');
}
// imaged editor Link
imageEditorLink = editorContainer.find('.tinymce-active-object-handler .file-image-editor-link');
if (image[0].dataset.mceToken && image[0].dataset.sourceId) {
imageEditorLink.css('display', 'inline-block');
imageEditorLink.on('click', function() {
FilePreviewModal.imageEditor({
'download-url': image[0].src,
filename: 'tinymce-image.jpg',
mode: 'tinymce',
url: '/tiny_mce_assets/' + image[0].dataset.mceToken,
quality: 100,
'mime-type': 'image/jpeg',
image: image[0]
});
});
} else {
imageEditorLink.css('display', 'none');
imageEditorLink.off('click');
}
} else {
editorContainer.find('.tinymce-active-object-handler').css('display', 'none');
}
}, 100);
});
// After save action
editorForm
.on('ajax:success', function(ev, data) {

View file

@ -20,23 +20,47 @@ class MarvinJsAssetsController < ApplicationController
source_type: new_asset.class.name
}
}, content_type: 'text/html'
else
elsif new_asset
render json: new_asset
else
render json: new_asset.errors, status: :unprocessable_entity
end
end
def show
render json: (MarvinJsAsset.find_by_id(params[:id]) || {})
sketch = current_team.marvin_js_assets.find_by_id(params[:id])
if sketch
if sketch.object_type == 'Step'
editable = can_manage_protocol_in_module?(sketch.object.protocol) ||
can_manage_protocol_in_repository?(sketch.object.protocol)
render json: {
sketch: sketch,
editable: editable
}
else
render json: sketch
end
else
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
end
end
def destroy
sketch = MarvinJsAsset.find(params[:id])
sketch.destroy
render json: sketch
sketch = current_team.marvin_js_assets.find_by_id(params[:id])
if sketch.destroy
render json: sketch
else
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
end
end
def update
render json: MarvinJsAsset.update_sketch(marvin_params)
sketch = MarvinJsAsset.update_sketch(marvin_params, current_team)
if sketch
render json: sketch
else
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
end
end
def team_sketches

View file

@ -1,6 +1,11 @@
# frozen_string_literal: true
class MarvinJsAsset < ApplicationRecord
validates :name, presence: true
validates :description, presence: true
validates :object_id, presence: true
validates :object_type, presence: true
belongs_to :object, polymorphic: true,
optional: true,
inverse_of: :marvin_js_assets
@ -17,28 +22,30 @@ class MarvinJsAsset < ApplicationRecord
def self.add_sketch(values, team)
if values[:object_type] == 'TinyMceAsset'
tiny_mce_img = TinyMceAsset.new(
tiny_mce_img = TinyMceAsset.create(
object: nil,
team_id: team.id,
saved: false,
image: values[:image],
image_file_name: "#{name}.jpg"
)
tiny_mce_img.save!
values[:object_id] = tiny_mce_img.id
end
values[:name] = I18n.t('marvinjs.new_sketch') if values[:name].empty?
create(values.merge(team_id: team.id).except(:image))
end
def self.update_sketch(values)
sketch = MarvinJsAsset.find(values[:id])
sketch.update(values.except(:image, :object_type, :id))
def self.update_sketch(values, team)
sketch = team.marvin_js_assets.find(values[:id])
return false unless sketch
if values[:object_type] == 'TinyMceAsset'
image = TinyMceAsset.find(sketch.object_id)
image.update(image: values[:image])
return { url: image.url(:large) }
end
values[:name] = I18n.t('marvinjs.new_sketch') if values[:name].empty?
sketch.update(values.except(:image, :object_type, :id))
sketch
end
end

View file

@ -10,7 +10,7 @@
</div>
<div class="col-xl-8 col-md-12">
<div class="attachemnts-header pull-right">
<% if MarvinJsAsset.enabled? %>
<% if MarvinJsAsset.enabled? && (can_manage_protocol_in_module?(step.protocol) || can_manage_protocol_in_repository?(step.protocol)) %>
<%= render partial: '/assets/marvinjs/create_marvin_sketch_button.html.erb',
locals: { element_id: step.id, element_type: 'Step', sketch_container: ".attacments#att-#{step.id}" } %>
<% end %>

View file

@ -2146,5 +2146,6 @@ en:
new_sketch: "New sketch"
new_button: "New chemical drawing"
checmical_drawing: "Chemical drawings"
team_drawings: Team drawings
task: Task
team_drawings: "Team drawings"
task: "Task"
no_sketches_found: "No sketches found"