class ProtocolsController < ApplicationController include RenamingUtil include ActionView::Helpers::TextHelper include ActionView::Helpers::UrlHelper include ApplicationHelper include InputSanitizeHelper include ProtocolsIoHelper include TeamsHelper include ProtocolsExporterV2 before_action :check_create_permissions, only: %i( create ) before_action :check_clone_permissions, only: [:clone] before_action :check_view_permissions, only: %i( show print versions_modal protocol_status_bar linked_children linked_children_datatable permissions ) before_action :switch_team_with_param, only: %i(index protocolsio_index) before_action :check_view_all_permissions, only: %i( index protocolsio_index datatable ) before_action :check_manage_permissions, only: %i( update_keywords update_description update_version_comment update_name update_authors unlink unlink_modal delete_steps ) before_action :check_manage_with_read_protocol_permissions, only: %i( revert revert_modal update_from_parent update_from_parent_modal ) before_action :check_restore_all_in_repository_permissions, only: :restore before_action :check_archive_all_in_repository_permissions, only: :archive before_action :check_load_from_repository_views_permissions, only: %i( load_from_repository_modal load_from_repository_datatable ) before_action :check_load_from_repository_permissions, only: [ :load_from_repository ] before_action :check_load_from_file_permissions, only: [ :load_from_file ] before_action :check_copy_to_repository_permissions, only: %i( copy_to_repository ) before_action :check_publish_permission, only: %i(publish version_comment update_version_comment) before_action :check_import_permissions, only: :import before_action :check_export_permissions, only: :export before_action :check_delete_draft_permissions, only: :destroy_draft before_action :check_save_as_draft_permissions, only: :save_as_draft before_action :check_protocolsio_import_permissions, only: %i(protocolsio_import_create protocolsio_import_save) before_action :set_importer, only: %i(load_from_file import) before_action :set_inline_name_editing, only: :show before_action :set_breadcrumbs_items, only: %i(index show) layout 'fluid' def index; end def datatable render json: ::ProtocolsDatatable.new( view_context, @current_team, @type, current_user ) end def versions_modal return render_403 unless @protocol.in_repository_published_original? || @protocol.initial_draft? @published_versions = @protocol.published_versions_with_original.order(version_number: :desc) render json: { html: render_to_string(partial: 'protocols/index/protocol_versions_modal') } end def print render layout: 'protocols/print' end def linked_children render json: { title: I18n.t('protocols.index.linked_children.title', protocol: escape_input(@protocol.name)), html: render_to_string(partial: 'protocols/index/linked_children_modal_body', locals: { protocol: @protocol }) } end def linked_children_datatable render json: ::ProtocolLinkedChildrenDatatable.new( view_context, @protocol, current_user, self ) end def publish Protocol.transaction do @protocol.update!( published_by: current_user, published_on: DateTime.now, version_comment: params[:version_comment] || @protocol.version_comment, protocol_type: (@protocol.parent_id.nil? ? :in_repository_published_original : :in_repository_published_version) ) log_activity(:protocol_template_published, nil, protocol: @protocol.id, version_number: @protocol.version_number) rescue ActiveRecord::RecordInvalid => e flash[:error] = @protocol.errors&.map(&:message)&.join(',') Rails.logger.error e.message raise ActiveRecord::Rollback rescue StandardError => e flash[:error] = I18n.t('errors.general') Rails.logger.error e.message raise ActiveRecord::Rollback end if params[:view] == 'show' redirect_to protocol_path(@protocol) else redirect_to protocols_path end end def destroy_draft Protocol.transaction do parent = @protocol.parent @protocol.destroy! @protocol = parent log_activity(:protocol_template_draft_deleted, nil, protocol: @protocol.id) flash[:success] = I18n.t('protocols.delete_draft_modal.success') redirect_to protocols_path rescue ActiveRecord::RecordNotDestroyed => e Rails.logger.error e.message render json: { message: e.message }, status: :unprocessable_entity raise ActiveRecord::Rollback rescue StandardError => e render json: { message: I18n.t('errors.general') }, status: :unprocessable_entity Rails.logger.error e.message raise ActiveRecord::Rollback end end def archive move_protocols('archive') end def restore move_protocols('restore') end def edit render :show end def show respond_to do |format| format.json { render json: @protocol, serializer: ProtocolSerializer, user: current_user } format.html end end def update_keywords if @protocol.update_keywords(params[:keywords], current_user) log_activity(:edit_keywords_in_protocol_repository, nil, protocol: @protocol.id) render json: @protocol, serializer: ProtocolSerializer, user: current_user else render json: I18n.t('errors.general'), status: :unprocessable_entity end end def update_authors if @protocol.update(authors: params.require(:protocol)[:authors], last_modified_by: current_user) log_activity(:edit_authors_in_protocol_repository, nil, protocol: @protocol.id) render json: @protocol, serializer: ProtocolSerializer, user: current_user else render json: @protocol.errors, status: :unprocessable_entity end end def update_name if @protocol.update(name: params.require(:protocol)[:name], last_modified_by: current_user) log_activity(:edit_protocol_name_in_repository, nil, protocol: @protocol.id) render json: {}, status: :ok else render json: @protocol.errors, status: :unprocessable_entity end end def update_description old_description = @protocol.description if @protocol.update(description: params.require(:protocol)[:description], last_modified_by: current_user) log_activity(:edit_description_in_protocol_repository, nil, protocol: @protocol.id) TinyMceAsset.update_images(@protocol, params[:tiny_mce_images], current_user) protocol_annotation_notification(old_description) render json: @protocol, serializer: ProtocolSerializer, user: current_user else render json: @protocol.errors, status: :unprocessable_entity end end def create @protocol = Protocol.new(create_params) ts = Time.now @protocol.team = current_team @protocol.protocol_type = :in_repository_draft @protocol.added_by = current_user @protocol.record_timestamps = false @protocol.created_at = ts @protocol.updated_at = ts @protocol.last_modified_by = current_user if @protocol.save log_activity(:create_protocol_in_repository, nil, protocol: @protocol.id) redirect_to protocol_path(@protocol) else render json: { error: @protocol.errors.messages.map { |_k, v| v }.join(', ') }, status: :unprocessable_entity end end def delete_steps @protocol.with_lock do team = @protocol.team previous_size = 0 @protocol.steps.each do |step| previous_size += step.space_taken if @protocol.in_module? log_activity(:destroy_step, @protocol.my_module.experiment.project, my_module: @protocol.my_module.id, step: step.id, step_position: { id: step.id, value_for: 'position_plus_one' }) else log_activity(:delete_step_in_protocol_repository, nil, step: step.id, step_position: { id: step.id, value_for: 'position_plus_one' }) end # skip adjusting positions after destroy as this is a bulk delete step.skip_position_adjust = true step.destroy! end team.release_space(previous_size) team.save! render json: { status: 'ok' } rescue ActiveRecord::RecordNotDestroyed render json: { status: 'error' }, status: :unprocessable_entity raise ActiveRecord::Rollback end end def clone cloned = nil Protocol.transaction do cloned = @original.deep_clone_repository(current_user) rescue StandardError raise ActiveRecord::Rollback end if cloned.present? render json: { message: t('protocols.index.clone.success_flash', original: @original.name, new: cloned.name) } else render json: { message: t('protocols.index.clone.error_flash', original: @original.name) }, status: :bad_request end end def copy_to_repository respond_to do |format| transaction_error = false Protocol.transaction do @new_protocol = @protocol.copy_to_repository(Protocol.new(create_params), current_user) log_activity(:task_protocol_save_to_template, @my_module.experiment.project, protocol: @new_protocol.id) rescue StandardError => e transaction_error = true Rails.logger.error(e.message) Rails.logger.error(e.backtrace.join("\n")) raise ActiveRecord::Rollback end format.json do if transaction_error # Bad request error render json: { message: t('my_modules.protocols.copy_to_repository_modal.error_400') }, status: :bad_request elsif @new_protocol.invalid? render json: { error: @new_protocol.errors.messages.map { |_, value| value }.join(' ') }, status: :unprocessable_entity else # Everything good, render 200 render json: { message: t('my_modules.protocols.copy_to_repository_modal.success_message') } end end format.html end end def save_as_draft Protocol.transaction do draft = @protocol.save_as_draft(current_user) if draft.invalid? flash[:error] = draft.errors.full_messages.join(', ') redirect_to protocols_path else log_activity(:protocol_template_draft_created, nil, protocol: @protocol.id) redirect_to protocol_path(draft) end rescue StandardError => e Rails.logger.error(e.message) Rails.logger.error(e.backtrace.join("\n")) flash[:error] = I18n.t('errors.general') redirect_to protocols_path raise ActiveRecord::Rollback end end def unlink transaction_error = false Protocol.transaction do @protocol.unlink rescue StandardError transaction_error = true raise ActiveRecord::Rollback end if transaction_error # Bad request error render json: { message: t('my_modules.protocols.unlink_error') }, status: :bad_request else # Everything good, display flash & render 200 flash[:success] = t( 'my_modules.protocols.unlink_flash' ) flash.keep(:success) render json: {}, status: :ok end end def revert if @protocol.can_destroy? transaction_error = false Protocol.transaction do # Revert is basically update from parent @protocol.update_from_parent(current_user, @protocol.parent) rescue StandardError transaction_error = true raise ActiveRecord::Rollback end if transaction_error # Bad request error render json: { message: t('my_modules.protocols.revert_error') }, status: :bad_request else # Everything good, display flash & render 200 log_activity(:update_protocol_in_task_from_repository, @protocol.my_module.experiment.project, my_module: @protocol.my_module.id, protocol_repository: @protocol.parent.id) flash[:success] = t( 'my_modules.protocols.revert_flash' ) flash.keep(:success) render json: {}, status: :ok end else render json: { message: t('my_modules.protocols.revert_error_locked') }, status: :bad_request end end def update_from_parent protocol_can_destroy = @protocol.can_destroy? if protocol_can_destroy transaction_error = false Protocol.transaction do # Find original published protocol template source_parent = if @protocol.parent.in_repository_published_original? @protocol.parent else @protocol.parent.parent end @protocol.update_from_parent(current_user, source_parent.latest_published_version_or_self) rescue StandardError transaction_error = true raise ActiveRecord::Rollback end end if !protocol_can_destroy render json: { message: t('my_modules.protocols.update_from_parent_error_locked') }, status: :bad_request elsif transaction_error render json: { message: t('my_modules.protocols.update_from_parent_error') }, status: :bad_request else log_activity(:update_protocol_in_task_from_repository, @protocol.my_module.experiment.project, my_module: @protocol.my_module.id, protocol_repository: @protocol.parent.id) flash[:success] = t('my_modules.protocols.update_from_parent_flash') flash.keep(:success) render json: {}, status: :ok end end def load_from_repository if @protocol.can_destroy? transaction_error = false Protocol.transaction do @protocol.load_from_repository(@source, current_user) rescue StandardError transaction_error = true raise ActiveRecord::Rollback end if transaction_error # Bad request error format.json do render json: { message: t('my_modules.protocols.load_from_repository_error') }, status: :bad_request end else # Everything good, record activity, display flash & render 200 log_activity(:load_protocol_to_task_from_repository, @protocol.my_module.experiment.project, my_module: @protocol.my_module.id, protocol_repository: @protocol.parent.id) flash[:success] = t('my_modules.protocols.load_from_repository_flash') flash.keep(:success) render json: {}, status: :ok end else render json: { message: t('my_modules.protocols.load_from_repository_error_locked') }, status: :bad_request end end def load_from_file # This is actually very similar to import if @protocol.can_destroy? transaction_error = false Protocol.transaction do @importer.import_into_existing( @protocol, @protocol_json ) rescue StandardError => e transaction_error = true Rails.logger.error(e.message) Rails.logger.error(e.backtrace.join("\n")) raise ActiveRecord::Rollback end if transaction_error format.json do render json: { status: :error }, status: :bad_request end else # Everything good, record activity, display flash & render 200 log_activity(:load_protocol_to_task_from_file, @protocol.my_module.experiment.project, my_module: @my_module.id) flash[:success] = t( 'my_modules.protocols.load_from_file_flash' ) flash.keep(:success) render json: { status: :ok }, status: :ok end else render json: { status: :locked }, status: :bad_request end end def protocolsio_index render json: { html: render_to_string({ partial: 'protocols/index/protocolsio_modal_body', formats: :html }) } end def import protocol = nil transaction_error = false Protocol.transaction do protocol = @importer.import_new_protocol(@protocol_json) rescue StandardError => e Rails.logger.error e.backtrace.join("\n") transaction_error = true raise ActiveRecord::Rollback end if transaction_error render json: { status: :bad_request }, status: :bad_request else Activities::CreateActivityService .call(activity_type: :import_protocol_in_repository, owner: current_user, subject: protocol, team: protocol.team, message_items: { protocol: protocol.id }) render json: { status: :ok }, status: :ok end end def protocolsio_import_create @protocolsio_too_big = false @protocolsio_invalid_file = false @protocolsio_no_file = false if params[:json_file].nil? @protocolsio_no_file = true respond_to do |format| format.js {} end return 0 # return 0 stops the rest of the controller code from executing end extension = File.extname(params[:json_file].path) file_size = File.size(params[:json_file].path) if extension != '.txt' && extension != '.json' @protocolsio_invalid_file = true respond_to do |format| format.js {} end return 0 # return 0 stops the rest of the controller code from executing end if file_size > Rails.configuration.x.file_max_size_mb.megabytes @protocolsio_too_big = true respond_to do |format| format.js {} # if file is too big, default to the js.erb file, # named the same as this controller # where a javascript alert is called end return 0 # return 0 stops the rest of the controller code from executing end json_file_contents = File.read(params[:json_file].path) json_file_contents.gsub! '\"', "'" # escaped double quotes too stressfull, html works with single quotes too # json double quotes dont get escaped since they dont match \" unless valid_protocol_json(json_file_contents) @protocolsio_invalid_file = true respond_to do |format| format.js {} end return 0 # return 0 stops the rest of the controller code from executing end @json_object = JSON.parse(json_file_contents) unless step_hash_null?(@json_object['steps']) @json_object['steps'] = protocols_io_guid_reorder_step_json( @json_object['steps'] ) end @protocol = Protocol.new respond_to do |format| format.js {} # go to the js.erb file named the same as this controller, # where a preview modal is rendered, # and some modals get closed and opened end rescue StandardError => e Rails.logger.error(e.backtrace.join("\n")) @protocolsio_general_error = true respond_to do |format| format.js {} end end def protocolsio_import_save @json_object = JSON.parse(params['json_object']) @db_json = {} @toolong = false @db_json['name'] = pio_eval_title_len( escape_input(not_null(params['protocol']['name'])) ) # since scinote only has description field, and protocols.io has many others # ,here i am putting everything important from protocols.io into description @db_json['authors'] = pio_eval_title_len( escape_input(not_null(params['protocol']['authors'])) ) @db_json['created_at'] = pio_eval_title_len( escape_input(not_null(params['protocol']['created_at'])) ) @db_json['updated_at'] = pio_eval_title_len( escape_input(not_null(params['protocol']['last_modified'])) ) @db_json['steps'] = {} unless step_hash_null?(@json_object['steps']) @db_json['steps'] = protocols_io_fill_step( @json_object, @db_json['steps'] ) end protocol = nil respond_to do |format| transaction_error = false @protocolsio_general_error = false Protocol.transaction do begin protocol = @importer.import_new_protocol(@db_json) rescue StandardError transaction_error = true raise ActiveRecord::Rollback end end p_name = if @db_json['name'].present? escape_input(@db_json['name']) else t('protocols.index.no_protocol_name') end if transaction_error @protocolsio_general_error = true # General something went wrong, upload to db failed error # format.json { # render json: { name: p_name, status: :bad_request }, # status: :bad_request # } else @protocolsio_general_error = false format.json do render json: { name: @db_json['name'], new_name: @db_json['name'], status: :ok }, status: :ok end end format.js {} end end def export # Make a zip output stream and send it to the client # rubocop:disable Metrics/BlockLength z_output_stream = Zip::OutputStream.write_buffer do |ostream| ostream.put_next_entry('scinote.xml') ostream.print(generate_envelope_xml(@protocols)) ostream.put_next_entry('scinote.xsd') ostream.print(generate_envelope_xsd) ostream.put_next_entry('eln.xsd') ostream.print(generate_eln_xsd) # Create folder and xml file for each protocol and populate it @protocols.each do |protocol| protocol = protocol.latest_published_version_or_self protocol_dir = get_guid(protocol.id).to_s ostream.put_next_entry("#{protocol_dir}/eln.xml") ostream.print(generate_protocol_xml(protocol)) ostream = protocol.tiny_mce_assets.save_to_eln(ostream, protocol_dir) # Add assets to protocol folder next if protocol.steps.count <= 0 protocol.steps.order(:id).each do |step| step_guid = get_guid(step.id) step_dir = "#{protocol_dir}/#{step_guid}" if step.assets.exists? step.assets.order(:id).each do |asset| next unless asset.file.attached? asset_guid = get_guid(asset.id) asset_file_name = asset_guid.to_s + File.extname(asset.file_name).to_s ostream.put_next_entry("#{step_dir}/#{asset_file_name}") ostream.print(asset.file.download) next unless asset.preview_image.attached? asset_preview_image_name = asset_guid.to_s + File.extname(asset.preview_image_file_name).to_s ostream.put_next_entry("#{step_dir}/previews/#{asset_preview_image_name}") ostream.print(asset.preview_image.download) end end ostream = step.tiny_mce_assets.save_to_eln(ostream, step_dir) step.step_texts.each do |step_text| ostream = step_text.tiny_mce_assets.save_to_eln(ostream, step_dir) end end end end # rubocop:enable Metrics/BlockLength z_output_stream.rewind file_name = export_protocol_file_name(@protocols) @protocols.each do |protocol| if params[:my_module_id] my_module = MyModule.find(params[:my_module_id]) Activities::CreateActivityService .call(activity_type: :export_protocol_from_task, owner: current_user, project: my_module.project, subject: my_module, team: my_module.team, message_items: { my_module: params[:my_module_id].to_i }) else Activities::CreateActivityService .call(activity_type: :export_protocol_in_repository, owner: current_user, subject: protocol, team: protocol.team, message_items: { protocol: protocol.id }) end end send_data(z_output_stream.read, filename: file_name) end def unlink_modal render json: { title: t('my_modules.protocols.confirm_link_update_modal.unlink_title'), message: t('my_modules.protocols.confirm_link_update_modal.unlink_message'), btn_text: t('my_modules.protocols.confirm_link_update_modal.unlink_btn_text'), url: unlink_protocol_path(@protocol) } end def revert_modal render json: { title: t('my_modules.protocols.confirm_link_update_modal.revert_title'), message: t('my_modules.protocols.confirm_link_update_modal.revert_message'), btn_text: t('my_modules.protocols.confirm_link_update_modal.revert_btn_text'), url: revert_protocol_path(@protocol) } end def update_from_parent_modal render json: { title: t('my_modules.protocols.confirm_link_update_modal.update_self_title'), message: t('my_modules.protocols.confirm_link_update_modal.update_self_message'), btn_text: t('my_modules.protocols.confirm_link_update_modal.update_self_btn_text'), url: update_from_parent_protocol_path(@protocol) } end def load_from_repository_datatable @protocol = Protocol.find_by_id(params[:id]) render json: ::LoadFromRepositoryProtocolsDatatable.new( view_context, @protocol.team, current_user ) end def load_from_repository_modal render json: { html: render_to_string(partial: 'my_modules/protocols/load_from_repository_modal_body', formats: :html) } end def protocol_status_bar render json: { html: render_to_string(partial: 'my_modules/protocols/protocol_status_bar', formats: :html) } end def version_comment render json: { version_comment: @protocol.version_comment } end def update_version_comment if @protocol.update(version_comment: params.require(:protocol)[:version_comment]) log_activity(:protocol_template_revision_notes_updated, nil, protocol: @protocol.id) render json: { version_comment: @protocol.version_comment } else render json: { errors: @protocol.errors }, status: :unprocessable_entity end end def permissions if stale?([@protocol, @protocol.team.user_assignments]) render json: { copyable: can_clone_protocol_in_repository?(@protocol), archivable: can_archive_protocol_in_repository?(@protocol), restorable: can_restore_protocol_in_repository?(@protocol), readable: can_read_protocol_in_repository?(@protocol) } end end def actions_toolbar render json: { actions: Toolbars::ProtocolsService.new( current_user, protocol_ids: params[:protocol_ids].split(',') ).actions } end def import_docx return render_403 unless Protocol.docx_parser_enabled? temp_files_ids = [] params[:files].each do |file| temp_file = TempFile.new(session_id: request.session_options[:id], file: file) if temp_file.save TempFile.destroy_obsolete(temp_file.id) temp_files_ids << temp_file.id end end @job = Protocols::DocxImportJob.perform_later(temp_files_ids, user_id: current_user.id, team_id: current_team.id) render json: { job_id: @job.job_id } end private def set_importer case params.dig('protocol', 'elnVersion') when '1.0' @importer = ProtocolsImporter.new(current_user, current_team) when '1.1' @importer = ProtocolsImporterV2.new(current_user, current_team) end end def export_protocol_file_name(protocols) protocol_name = get_protocol_name(protocols[0]) if protocols.count == 1 file_name = 'protocol.eln' unless protocol_name.nil? escaped_name = protocol_name.gsub(/[^0-9a-zA-Z\-.,_]/i, '_') .downcase[0..Constants::NAME_MAX_LENGTH] file_name = escaped_name + '.eln' unless escaped_name.blank? end elsif protocols.length > 1 file_name = 'protocols.eln' end file_name end def valid_protocol_json(json) JSON.parse(json) return true rescue JSON::ParserError => e return false end def move_protocols(action) Protocol.transaction do @protocols.find_each do |protocol| protocol = protocol.parent if protocol.parent_id unless protocol.method(action).call(current_user) raise StandardError, protocol.errors&.messages&.values&.join(' ') || I18n.t('errors.general') end end end render json: { message: t("protocols.index.#{action}_flash_html", count: @protocols.size) } rescue StandardError => e Rails.logger.error(e.message) Rails.logger.error(e.backtrace.join("\n")) render json: { message: e.message }, status: :unprocessable_entity end def set_inline_name_editing return unless @protocol.initial_draft? return unless can_manage_protocol_draft_in_repository?(@protocol) @inline_editable_title_config = { name: 'title', params_group: 'protocol', item_id: @protocol.id, field_to_udpate: 'name', path_to_update: name_protocol_path(@protocol) } end def load_team_and_type @current_team = current_team # :public, :private or :archive @type = (params[:type] || 'active').to_sym end def check_view_all_permissions load_team_and_type render_403 unless can_read_team?(@current_team) end def check_view_permissions @protocol = Protocol.find_by(id: params[:id]) current_team_switch(@protocol.team) if current_team != @protocol.team unless @protocol.present? && (can_read_protocol_in_module?(@protocol) || can_read_protocol_in_repository?(@protocol) || (@protocol.in_repository? && can_manage_team?(@protocol.team))) render_403 end end def check_create_permissions load_team_and_type if !can_create_protocols_in_repository?(@current_team) || @type == :archive render_403 end end def check_clone_permissions load_team_and_type protocol = Protocol.find_by(id: params[:protocol_ids]) @original = protocol.latest_published_version_or_self if @original.blank? || !can_clone_protocol_in_repository?(@original) || @type == :archive render_403 end end def check_manage_permissions @protocol = Protocol.find_by(id: params[:id]) render_403 unless @protocol.present? && (can_manage_protocol_in_module?(@protocol) || can_manage_protocol_draft_in_repository?(@protocol)) end def check_manage_with_read_protocol_permissions @protocol = Protocol.find_by(id: params[:id]) render_403 unless @protocol.present? && @protocol.parent.present? && (can_manage_protocol_in_module?(@protocol) && can_read_protocol_in_repository?(@protocol.parent)) end def check_save_as_draft_permissions @protocol = Protocol.find_by(id: params[:id]) render_403 unless @protocol.present? && can_save_protocol_version_as_draft?(@protocol) end def check_delete_draft_permissions @protocol = Protocol.find_by(id: params[:id]) render_403 unless @protocol.present? && can_delete_protocol_draft_in_repository?(@protocol) end def check_archive_all_in_repository_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_archive_protocol_in_repository?(protocol) respond_to { |f| f.json { render json: {}, status: :unauthorized } } break end end end def check_restore_all_in_repository_permissions @protocols = Protocol.where(id: params[:protocol_ids]) @protocols.find_each do |protocol| unless can_restore_protocol_in_repository?(protocol) respond_to { |f| f.json { render json: {}, status: :unauthorized } } break end end end def check_load_from_repository_views_permissions @protocol = Protocol.find_by_id(params[:id]) render_403 if @protocol.blank? || !can_read_protocol_in_module?(@protocol) end def check_publish_permission @protocol = Protocol.find_by(id: params[:id]) render_403 if @protocol.blank? || !can_publish_protocol_in_repository?(@protocol) end def check_load_from_repository_permissions @protocol = Protocol.find_by(id: params[:id]) @source = Protocol.find_by(id: params[:source_id])&.latest_published_version_or_self render_403 unless @protocol.present? && @source.present? && (can_manage_protocol_in_module?(@protocol) && can_read_protocol_in_repository?(@source)) end def check_load_from_file_permissions @protocol_json = params[:protocol] @protocol = Protocol.find_by_id(params[:id]) @my_module = @protocol.my_module if @protocol_json.blank? || @protocol.blank? || @my_module.blank? || !can_manage_protocol_in_module?(@protocol) render_403 end end def check_copy_to_repository_permissions @protocol = Protocol.find_by(id: params[:id]) @my_module = @protocol.my_module render_403 unless @my_module.present? && (can_read_protocol_in_module?(@protocol) || can_create_protocols_in_repository?(@protocol.team)) end def check_import_permissions @protocol_json = params[:protocol] @team = Team.find(params[:team_id]) render_403 unless @protocol_json.present? && @team.present? && can_create_protocols_in_repository?(@team) end def check_export_permissions @protocols = Protocol.where(id: params[:protocol_ids]) render_403 if @protocols.blank? @protocols.each do |p| render_403 unless can_read_protocol_in_module?(p) || can_read_protocol_in_repository?(p) end end def copy_to_repository_params params.require(:protocol).permit(:name, :protocol_type) end def create_params params.require(:protocol).permit(:name, :default_public_user_role_id, :visibility) end def check_protocolsio_import_permissions render_403 unless can_create_protocols_in_repository?(current_team) end def log_activity(type_of, project = nil, message_items = {}) message_items = { protocol: @protocol&.id }.merge(message_items) Activities::CreateActivityService .call(activity_type: type_of, owner: current_user, subject: @protocol, team: @protocol.team, project: project, message_items: message_items) end def protocol_annotation_notification(old_text) smart_annotation_notification( old_text: old_text, new_text: @protocol.description, subject: @protocol, title: t('notifications.protocol_description_annotation_title', user: current_user.full_name, protocol: @protocol.name), message: t('notifications.protocol_description_annotation_message_html', protocol: link_to(@protocol.name, protocol_url(@protocol))) ) end def set_breadcrumbs_items @breadcrumbs_items = [] archived_branch = params[:type] == 'archived' || @protocol&.archived? @breadcrumbs_items.push({ label: t('breadcrumbs.templates'), archived: archived_branch }) @breadcrumbs_items.push({ label: t('breadcrumbs.protocols'), url: archived_branch ? protocols_path(type: :archived) : protocols_path, archived: archived_branch }) if @protocol @breadcrumbs_items.push({ label: @protocol.name, url: protocol_path(@protocol), archived: archived_branch }) end @breadcrumbs_items.each do |item| item[:label] = "(A) #{item[:label]}" if item[:archived] end end end