Redmine 6 #1563
This commit is contained in:
parent
cc69212b74
commit
fac322f0f1
3
.github/workflows/rubyonrails.yml
vendored
3
.github/workflows/rubyonrails.yml
vendored
@ -28,6 +28,7 @@ jobs:
|
|||||||
plugin_tests:
|
plugin_tests:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
fail-fast: false
|
||||||
engine: [mysql, postgresql, sqlite]
|
engine: [mysql, postgresql, sqlite]
|
||||||
include:
|
include:
|
||||||
- engine: mysql
|
- engine: mysql
|
||||||
@ -84,7 +85,7 @@ jobs:
|
|||||||
sudo apt-get install -y litmus libreoffice subversion
|
sudo apt-get install -y litmus libreoffice subversion
|
||||||
- name: Clone Redmine
|
- name: Clone Redmine
|
||||||
# Get the latest stable Redmine
|
# Get the latest stable Redmine
|
||||||
run: svn export http://svn.redmine.org/redmine/branches/5.1-stable/ /opt/redmine
|
run: svn export http://svn.redmine.org/redmine/branches/6.0-stable/ /opt/redmine
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Link the plugin
|
- name: Link the plugin
|
||||||
|
|||||||
@ -45,6 +45,10 @@ Lint/ScriptPermission:
|
|||||||
Exclude:
|
Exclude:
|
||||||
- extra/xapian_indexer.rb
|
- extra/xapian_indexer.rb
|
||||||
|
|
||||||
|
Lint/UselessAssignment:
|
||||||
|
Exclude:
|
||||||
|
- lib/redmine_dmsf/lockable.rb
|
||||||
|
|
||||||
Naming/BlockForwarding:
|
Naming/BlockForwarding:
|
||||||
EnforcedStyle: explicit
|
EnforcedStyle: explicit
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class DmsfUploadController < ApplicationController
|
|||||||
# Upload
|
# Upload
|
||||||
else
|
else
|
||||||
# standard file input uploads
|
# standard file input uploads
|
||||||
uploaded_files&.each do |_, uploaded_file|
|
uploaded_files&.each_value do |uploaded_file|
|
||||||
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
||||||
@uploads.push(upload) if upload
|
@uploads.push(upload) if upload
|
||||||
end
|
end
|
||||||
@ -109,7 +109,7 @@ class DmsfUploadController < ApplicationController
|
|||||||
@folder = DmsfFolder.visible.find_by(id: attachments[:folder_id]) if attachments[:folder_id].present?
|
@folder = DmsfFolder.visible.find_by(id: attachments[:folder_id]) if attachments[:folder_id].present?
|
||||||
# standard file input uploads
|
# standard file input uploads
|
||||||
uploaded_files = attachments.select { |key, _| key == 'uploaded_file' }
|
uploaded_files = attachments.select { |key, _| key == 'uploaded_file' }
|
||||||
uploaded_files.each do |_, uploaded_file|
|
uploaded_files.each_value do |uploaded_file|
|
||||||
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
||||||
next unless upload
|
next unless upload
|
||||||
|
|
||||||
|
|||||||
@ -304,7 +304,7 @@ class DmsfWorkflowsController < ApplicationController
|
|||||||
@dmsf_workflow.save
|
@dmsf_workflow.save
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if request.post? && @dmsf_workflow && @dmsf_workflow.valid?
|
if request.post? && @dmsf_workflow&.valid?
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
if @project
|
if @project
|
||||||
redirect_to settings_project_path(@project, tab: 'dmsf_workflow')
|
redirect_to settings_project_path(@project, tab: 'dmsf_workflow')
|
||||||
|
|||||||
@ -58,7 +58,7 @@ module DmsfHelper
|
|||||||
extension = extension[1, extension.length - 1]
|
extension = extension[1, extension.length - 1]
|
||||||
path = File.join(Redmine::Plugin.public_directory, ['redmine_dmsf', 'images', 'filetypes', "#{extension}.png"])
|
path = File.join(Redmine::Plugin.public_directory, ['redmine_dmsf', 'images', 'filetypes', "#{extension}.png"])
|
||||||
cls = if File.exist?(path)
|
cls = if File.exist?(path)
|
||||||
+"filetype-#{extension}"
|
"filetype-#{extension}"
|
||||||
else
|
else
|
||||||
Redmine::MimeType.css_class_of filename
|
Redmine::MimeType.css_class_of filename
|
||||||
end
|
end
|
||||||
|
|||||||
@ -23,11 +23,11 @@ module DmsfQueriesHelper
|
|||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
|
|
||||||
def column_value(column, item, value)
|
def column_value(column, item, value)
|
||||||
return super column, item, value unless item.is_a? DmsfFolder
|
return super unless item.is_a?(DmsfFolder)
|
||||||
|
|
||||||
case column.name
|
case column.name
|
||||||
when :modified
|
when :modified
|
||||||
val = super(column, item, value)
|
val = super
|
||||||
case item.type
|
case item.type
|
||||||
when 'file'
|
when 'file'
|
||||||
file = DmsfFile.find_by(id: item.id)
|
file = DmsfFile.find_by(id: item.id)
|
||||||
@ -99,10 +99,10 @@ module DmsfQueriesHelper
|
|||||||
if user
|
if user
|
||||||
link_to user.name, user_path(id: value)
|
link_to user.name, user_path(id: value)
|
||||||
else
|
else
|
||||||
super column, item, value
|
super
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
super column, item, value
|
super
|
||||||
end
|
end
|
||||||
when :title
|
when :title
|
||||||
case item.type
|
case item.type
|
||||||
@ -236,12 +236,12 @@ module DmsfQueriesHelper
|
|||||||
h(DmsfWorkflow.workflow_str(value.to_i))
|
h(DmsfWorkflow.workflow_str(value.to_i))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
super column, item, value
|
super
|
||||||
end
|
end
|
||||||
when :comment
|
when :comment
|
||||||
value.present? ? content_tag('div', textilizable(value), class: 'wiki') : ''
|
value.present? ? content_tag('div', textilizable(value), class: 'wiki') : ''
|
||||||
else
|
else
|
||||||
super column, item, value
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ module DmsfQueriesHelper
|
|||||||
text, _names = DmsfWorkflow.workflow_info(object.workflow, object.workflow_id, object.revision_id)
|
text, _names = DmsfWorkflow.workflow_info(object.workflow, object.workflow_id, object.revision_id)
|
||||||
text
|
text
|
||||||
else
|
else
|
||||||
super column, object, value
|
super
|
||||||
end
|
end
|
||||||
when :author
|
when :author
|
||||||
if value
|
if value
|
||||||
@ -262,11 +262,11 @@ module DmsfQueriesHelper
|
|||||||
if user
|
if user
|
||||||
user.name
|
user.name
|
||||||
else
|
else
|
||||||
super column, object, value
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
super column, object, value
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ module DmsfUploadHelper
|
|||||||
files = []
|
files = []
|
||||||
if committed_files
|
if committed_files
|
||||||
failed_uploads = []
|
failed_uploads = []
|
||||||
committed_files.each do |_, committed_file|
|
committed_files.each_value do |committed_file|
|
||||||
name = committed_file[:name]
|
name = committed_file[:name]
|
||||||
new_revision = DmsfFileRevision.new
|
new_revision = DmsfFileRevision.new
|
||||||
file = DmsfFile.visible.find_file_by_name(project, folder, name)
|
file = DmsfFile.visible.find_file_by_name(project, folder, name)
|
||||||
|
|||||||
@ -187,7 +187,7 @@ class DmsfFileRevision < ApplicationRecord
|
|||||||
filename = path.join(disk_filename)
|
filename = path.join(disk_filename)
|
||||||
if search_if_not_exists && !File.exist?(filename)
|
if search_if_not_exists && !File.exist?(filename)
|
||||||
# Let's search for the physical file in source revisions
|
# Let's search for the physical file in source revisions
|
||||||
dmsf_file.dmsf_file_revisions.where(['created_at < ?', created_at]).order(created_at: :desc).each do |rev|
|
dmsf_file.dmsf_file_revisions.where(created_at: ...created_at).order(created_at: :desc).each do |rev|
|
||||||
filename = rev.disk_file
|
filename = rev.disk_file
|
||||||
break if File.exist?(filename)
|
break if File.exist?(filename)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -36,7 +36,7 @@ class DmsfFileRevisionAccessQuery < Query
|
|||||||
]
|
]
|
||||||
|
|
||||||
def initialize(attributes = nil, *_args)
|
def initialize(attributes = nil, *_args)
|
||||||
super attributes
|
super(attributes)
|
||||||
self.sort_criteria = []
|
self.sort_criteria = []
|
||||||
self.filters = {}
|
self.filters = {}
|
||||||
end
|
end
|
||||||
|
|||||||
@ -76,7 +76,7 @@ class DmsfLink < ApplicationRecord
|
|||||||
|
|
||||||
def self.find_link_by_file_name(project, folder, filename)
|
def self.find_link_by_file_name(project, folder, filename)
|
||||||
links = DmsfLink.where(project_id: project.id,
|
links = DmsfLink.where(project_id: project.id,
|
||||||
dmsf_folder_id: folder ? folder.id : nil,
|
dmsf_folder_id: folder&.id,
|
||||||
target_type: DmsfFile.model_name.to_s).visible.all
|
target_type: DmsfFile.model_name.to_s).visible.all
|
||||||
links.each do |link|
|
links.each do |link|
|
||||||
return link if link&.target_file&.name == filename
|
return link if link&.target_file&.name == filename
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class DmsfQuery < Query
|
|||||||
]
|
]
|
||||||
|
|
||||||
def initialize(attributes = nil, *_args)
|
def initialize(attributes = nil, *_args)
|
||||||
super attributes
|
super(attributes)
|
||||||
self.sort_criteria = []
|
self.sort_criteria = []
|
||||||
self.filters ||= { 'title' => { operator: '~', values: [''] } }
|
self.filters ||= { 'title' => { operator: '~', values: [''] } }
|
||||||
self.dmsf_folder_id = nil
|
self.dmsf_folder_id = nil
|
||||||
@ -182,9 +182,9 @@ class DmsfQuery < Query
|
|||||||
# New
|
# New
|
||||||
|
|
||||||
def dmsf_nodes(options = {})
|
def dmsf_nodes(options = {})
|
||||||
order_option = ['sort', group_by_sort_order, (options[:order] || sort_clause&.first)].flatten.compact_blank
|
order_option = ['sort', group_by_sort_order, options[:order] || sort_clause&.first].flatten.compact_blank
|
||||||
if order_option.size > 1
|
if order_option.size > 1
|
||||||
DmsfFileRevisionCustomField.visible.pluck(:id, :name).each do |id, _name|
|
DmsfFileRevisionCustomField.visible.pluck(:id).each do |id|
|
||||||
order_option[1].gsub! "cf_#{id}.value", "cf_#{id}"
|
order_option[1].gsub! "cf_#{id}.value", "cf_#{id}"
|
||||||
end
|
end
|
||||||
if order_option[1] =~ /^(firstname|major_version),? (lastname|minor_version)( patch_version)? (DESC|ASC)$/
|
if order_option[1] =~ /^(firstname|major_version),? (lastname|minor_version)( patch_version)? (DESC|ASC)$/
|
||||||
|
|||||||
@ -20,10 +20,10 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
<% unless @dmsf_already_rendered %>
|
||||||
|
<% @dmsf_already_rendered = true # Prevent recursion %>
|
||||||
<%# Render the original view %>
|
<%# Render the original view %>
|
||||||
<% view_paths.unshift Rails.root.join('app/views').to_s %>
|
|
||||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||||
|
<%# DMSF extension %>
|
||||||
<%# DMSF extension do %>
|
|
||||||
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
||||||
<%# end %>
|
<% end %>
|
||||||
|
|||||||
@ -20,10 +20,10 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
<% unless @dmsf_already_rendered %>
|
||||||
|
<% @dmsf_already_rendered = true # Prevent recursion %>
|
||||||
<%# Render the original view %>
|
<%# Render the original view %>
|
||||||
<% view_paths.unshift Rails.root.join('app/views').to_s %>
|
|
||||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||||
|
<%# DMSF extension %>
|
||||||
<%# DMSF extension do %>
|
|
||||||
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
||||||
<%# end %>
|
<% end %>
|
||||||
|
|||||||
@ -151,7 +151,7 @@ begin
|
|||||||
log "#{databasepath} does not exist, creating ...", verbose
|
log "#{databasepath} does not exist, creating ...", verbose
|
||||||
FileUtils.mkdir_p databasepath
|
FileUtils.mkdir_p databasepath
|
||||||
end
|
end
|
||||||
cmd = +"#{OMINDEX} -s #{lang} --db #{databasepath} #{filespath} --url / --depth-limit=0"
|
cmd = "#{OMINDEX} -s #{lang} --db #{databasepath} #{filespath} --url / --depth-limit=0"
|
||||||
cmd << ' -v' if verbose
|
cmd << ' -v' if verbose
|
||||||
cmd << ' --retry-failed' if retry_failed
|
cmd << ' --retry-failed' if retry_failed
|
||||||
cmd << ' -p' if no_delete
|
cmd << ' -p' if no_delete
|
||||||
|
|||||||
4
init.rb
4
init.rb
@ -24,9 +24,9 @@ Redmine::Plugin.register :redmine_dmsf do
|
|||||||
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
|
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
|
||||||
author 'Vít Jonáš / Daniel Munn / Karel Pičman'
|
author 'Vít Jonáš / Daniel Munn / Karel Pičman'
|
||||||
description 'Document Management System Features'
|
description 'Document Management System Features'
|
||||||
version '3.2.5 devel'
|
version '4.0.0 devel'
|
||||||
|
|
||||||
requires_redmine version_or_higher: '5.0.0'
|
requires_redmine version_or_higher: '6.0.0'
|
||||||
|
|
||||||
webdav = if Redmine::Plugin.installed?('easy_hosting_services') && EasyHostingServices::EasyMultiTenancy.activated?
|
webdav = if Redmine::Plugin.installed?('easy_hosting_services') && EasyHostingServices::EasyMultiTenancy.activated?
|
||||||
'1'
|
'1'
|
||||||
|
|||||||
@ -29,12 +29,12 @@ module Dav4rack
|
|||||||
"Processing WebDAV request: #{r.path} (for #{r.ip} at #{Time.current}) [#{r.request_method}]"
|
"Processing WebDAV request: #{r.path} (for #{r.ip} at #{Time.current}) [#{r.request_method}]"
|
||||||
end
|
end
|
||||||
|
|
||||||
controller = setup_controller r, response
|
controller = setup_controller(r, response)
|
||||||
controller.process
|
controller.process
|
||||||
postprocess_response response
|
postprocess_response response
|
||||||
|
|
||||||
# Apache wants the body dealt with, so just read it and junk it
|
# Apache wants the body dealt with, so just read it and junk it
|
||||||
buf = true
|
buf = r.body
|
||||||
buf = r.body.read(8_192) while buf
|
buf = r.body.read(8_192) while buf
|
||||||
|
|
||||||
Rails.logger.debug { "Response String:\n#{response.body}" } if response.body.is_a?(String)
|
Rails.logger.debug { "Response String:\n#{response.body}" } if response.body.is_a?(String)
|
||||||
|
|||||||
@ -90,12 +90,12 @@ module Dav4rack
|
|||||||
|
|
||||||
def child(name, options = {})
|
def child(name, options = {})
|
||||||
new_path = path.dup
|
new_path = path.dup
|
||||||
new_path = +"/#{new_path}" unless new_path[0, 1] == '/'
|
new_path = "/#{new_path}" unless new_path[0, 1] == '/'
|
||||||
new_path.slice!(-1) if new_path[-1, 1] == '/'
|
new_path.slice!(-1) if new_path[-1, 1] == '/'
|
||||||
name = "/#{name}" unless name[-1, 1] == '/'
|
name = "/#{name}" unless name[-1, 1] == '/'
|
||||||
new_path = "#{new_path}#{name}"
|
new_path = "#{new_path}#{name}"
|
||||||
new_public = public_path.dup
|
new_public = public_path.dup
|
||||||
new_public = +"/#{new_public}" unless new_public[0, 1] == '/'
|
new_public = "/#{new_public}" unless new_public[0, 1] == '/'
|
||||||
new_public.slice!(-1) if new_public[-1, 1] == '/'
|
new_public.slice!(-1) if new_public[-1, 1] == '/'
|
||||||
new_public = "#{new_public}#{name}"
|
new_public = "#{new_public}#{name}"
|
||||||
if (key = @root_paths.find { |x| new_path =~ %r{^#{Regexp.escape(x.downcase)}/?} })
|
if (key = @root_paths.find { |x| new_path =~ %r{^#{Regexp.escape(x.downcase)}/?} })
|
||||||
|
|||||||
@ -15,7 +15,7 @@ module Dav4rack
|
|||||||
# potentially expensive recursive propfinds
|
# potentially expensive recursive propfinds
|
||||||
#
|
#
|
||||||
def initialize(env, options = {})
|
def initialize(env, options = {})
|
||||||
super env
|
super(env)
|
||||||
@options = { recursive_propfind_allowed: true }.merge options
|
@options = { recursive_propfind_allowed: true }.merge options
|
||||||
self.path_info = expand_path path_info
|
self.path_info = expand_path path_info
|
||||||
end
|
end
|
||||||
|
|||||||
@ -10,7 +10,7 @@ module Dav4rack
|
|||||||
attr_reader :path_status
|
attr_reader :path_status
|
||||||
|
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
super(*args)
|
super
|
||||||
@path_status = {}
|
@path_status = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ module Dav4rack
|
|||||||
response = Ox::Element.new(D_RESPONSE)
|
response = Ox::Element.new(D_RESPONSE)
|
||||||
response << ox_element(D_HREF, href)
|
response << ox_element(D_HREF, href)
|
||||||
process_properties.each do |type, properties|
|
process_properties.each do |type, properties|
|
||||||
propstats response, send("#{type}_properties_with_status", properties)
|
propstats response, send(:"#{type}_properties_with_status", properties)
|
||||||
end
|
end
|
||||||
response
|
response
|
||||||
end
|
end
|
||||||
|
|||||||
@ -26,9 +26,9 @@ module RedmineDmsf
|
|||||||
|
|
||||||
def initialize(message = nil)
|
def initialize(message = nil)
|
||||||
if message.present?
|
if message.present?
|
||||||
super message
|
super
|
||||||
else
|
else
|
||||||
super l(:error_max_email_filesize_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_email_filesize'])
|
super(l(:error_max_email_filesize_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_email_filesize']))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -26,9 +26,9 @@ module RedmineDmsf
|
|||||||
|
|
||||||
def initialize(message = nil)
|
def initialize(message = nil)
|
||||||
if message.present?
|
if message.present?
|
||||||
super message
|
super
|
||||||
else
|
else
|
||||||
super l(:error_max_files_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_file_download'])
|
super(l(:error_max_files_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_file_download']))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -30,11 +30,11 @@ module RedmineDmsf
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
"\n".html_safe + stylesheet_link_tag('redmine_dmsf.css', plugin: :redmine_dmsf) +
|
"\n".html_safe + stylesheet_link_tag('redmine_dmsf', plugin: :redmine_dmsf) +
|
||||||
"\n".html_safe + stylesheet_link_tag('select2.min.css', plugin: :redmine_dmsf) +
|
"\n".html_safe + stylesheet_link_tag('select2.min', plugin: :redmine_dmsf) +
|
||||||
"\n".html_safe + javascript_include_tag('select2.min.js', plugin: :redmine_dmsf, defer: true) +
|
"\n".html_safe + javascript_include_tag('select2.min', plugin: :redmine_dmsf, defer: true) +
|
||||||
"\n".html_safe + javascript_include_tag('redmine_dmsf.js', plugin: :redmine_dmsf, defer: true) +
|
"\n".html_safe + javascript_include_tag('redmine_dmsf', plugin: :redmine_dmsf, defer: true) +
|
||||||
"\n".html_safe + javascript_include_tag('attachments_dmsf.js', plugin: :redmine_dmsf, defer: true)
|
"\n".html_safe + javascript_include_tag('attachments_dmsf', plugin: :redmine_dmsf, defer: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -200,7 +200,7 @@ module RedmineDmsf
|
|||||||
def attachment_rows(links, issue, controller)
|
def attachment_rows(links, issue, controller)
|
||||||
return unless links.any?
|
return unless links.any?
|
||||||
|
|
||||||
html = +"<tbody><tr><th colspan=\"4\">#{l(:label_dmsf_attachments)} (#{links.count})</th></tr>"
|
html = "<tbody><tr><th colspan=\"4\">#{l(:label_dmsf_attachments)} (#{links.count})</th></tr>"
|
||||||
links.each do |dmsf_file, link, _created_at|
|
links.each do |dmsf_file, link, _created_at|
|
||||||
html << attachment_row(dmsf_file, link, issue, controller)
|
html << attachment_row(dmsf_file, link, issue, controller)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -41,7 +41,7 @@ module RedmineDmsf
|
|||||||
revision = DmsfFileRevision.find_by(id: args[2], dmsf_file_id: args[0])
|
revision = DmsfFileRevision.find_by(id: args[2], dmsf_file_id: args[0])
|
||||||
return "{{dmsf(#{args[0]}, #{args[1]}, #{args[2]})}" unless revision
|
return "{{dmsf(#{args[0]}, #{args[1]}, #{args[2]})}" unless revision
|
||||||
end
|
end
|
||||||
title = (args[1].presence || file.title)
|
title = args[1].presence || file.title
|
||||||
title.gsub!(/\A"|"\z/, '') # Remove apostrophes
|
title.gsub!(/\A"|"\z/, '') # Remove apostrophes
|
||||||
title.gsub!(/\A'|'\z/, '')
|
title.gsub!(/\A'|'\z/, '')
|
||||||
title = file.title if title.empty?
|
title = file.title if title.empty?
|
||||||
@ -70,7 +70,7 @@ module RedmineDmsf
|
|||||||
return "{{dmsff(#{args[0]})}}" unless folder
|
return "{{dmsff(#{args[0]})}}" unless folder
|
||||||
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_folders, folder.project)
|
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_folders, folder.project)
|
||||||
|
|
||||||
title = (args[1].presence || folder.title)
|
title = args[1].presence || folder.title
|
||||||
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
||||||
title.gsub!(/\A'|'\z/, '')
|
title.gsub!(/\A'|'\z/, '')
|
||||||
title = folder.title if title.empty?
|
title = folder.title if title.empty?
|
||||||
@ -89,7 +89,7 @@ module RedmineDmsf
|
|||||||
return "{{dmsfd(#{args[0]})}}" unless file
|
return "{{dmsfd(#{args[0]})}}" unless file
|
||||||
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_files, file.project)
|
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_files, file.project)
|
||||||
|
|
||||||
title = (args[1].presence || file.title)
|
title = args[1].presence || file.title
|
||||||
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
||||||
title.gsub!(/\A'|'\z/, '')
|
title.gsub!(/\A'|'\z/, '')
|
||||||
link_to h(title), dmsf_file_path(id: file)
|
link_to h(title), dmsf_file_path(id: file)
|
||||||
|
|||||||
@ -39,7 +39,7 @@ module RedmineDmsf
|
|||||||
@saved_dmsf_attachments = []
|
@saved_dmsf_attachments = []
|
||||||
return unless dmsf_attachments
|
return unless dmsf_attachments
|
||||||
|
|
||||||
dmsf_attachments.each do |_, dmsf_attachment|
|
dmsf_attachments.each_value do |dmsf_attachment|
|
||||||
a = Attachment.find_by_token(dmsf_attachment[:token])
|
a = Attachment.find_by_token(dmsf_attachment[:token])
|
||||||
@saved_dmsf_attachments << a if a
|
@saved_dmsf_attachments << a if a
|
||||||
end
|
end
|
||||||
@ -53,7 +53,7 @@ module RedmineDmsf
|
|||||||
@saved_dmsf_links = []
|
@saved_dmsf_links = []
|
||||||
return unless dmsf_links
|
return unless dmsf_links
|
||||||
|
|
||||||
dmsf_links.each do |_, id|
|
dmsf_links.each_value do |id|
|
||||||
l = DmsfLink.find_by(id: id)
|
l = DmsfLink.find_by(id: id)
|
||||||
@saved_dmsf_links << l if l
|
@saved_dmsf_links << l if l
|
||||||
end
|
end
|
||||||
|
|||||||
@ -27,7 +27,7 @@ module RedmineDmsf
|
|||||||
return if @dmsf_macro_list
|
return if @dmsf_macro_list
|
||||||
|
|
||||||
@dmsf_macro_list = []
|
@dmsf_macro_list = []
|
||||||
Redmine::WikiFormatting::Macros.available_macros.each do |key, _value|
|
Redmine::WikiFormatting::Macros.available_macros.each_key do |key|
|
||||||
@dmsf_macro_list << key.to_s if key.to_s.match?(/^dmsf/)
|
@dmsf_macro_list << key.to_s if key.to_s.match?(/^dmsf/)
|
||||||
end
|
end
|
||||||
# If localized files for the current language are not available, switch to English
|
# If localized files for the current language are not available, switch to English
|
||||||
@ -50,5 +50,4 @@ end
|
|||||||
|
|
||||||
# Apply the patch
|
# Apply the patch
|
||||||
Redmine::WikiFormatting::Textile::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
Redmine::WikiFormatting::Textile::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
||||||
Redmine::WikiFormatting::Markdown::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
|
||||||
Redmine::WikiFormatting::CommonMark::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
Redmine::WikiFormatting::CommonMark::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
||||||
|
|||||||
@ -35,7 +35,7 @@ module RedmineDmsf
|
|||||||
@saved_dmsf_attachments = []
|
@saved_dmsf_attachments = []
|
||||||
return unless dmsf_attachments
|
return unless dmsf_attachments
|
||||||
|
|
||||||
dmsf_attachments.each do |_, dmsf_attachment|
|
dmsf_attachments.each_value do |dmsf_attachment|
|
||||||
a = Attachment.find_by_token(dmsf_attachment[:token])
|
a = Attachment.find_by_token(dmsf_attachment[:token])
|
||||||
@saved_dmsf_attachments << a if a
|
@saved_dmsf_attachments << a if a
|
||||||
end
|
end
|
||||||
@ -49,7 +49,7 @@ module RedmineDmsf
|
|||||||
@saved_dmsf_links = []
|
@saved_dmsf_links = []
|
||||||
return unless dmsf_links
|
return unless dmsf_links
|
||||||
|
|
||||||
dmsf_links.each do |_, id|
|
dmsf_links.each_value do |id|
|
||||||
l = DmsfLink.find_by(id: id)
|
l = DmsfLink.find_by(id: id)
|
||||||
@saved_dmsf_links << l if l
|
@saved_dmsf_links << l if l
|
||||||
end
|
end
|
||||||
@ -110,8 +110,10 @@ module RedmineDmsf
|
|||||||
prj_id ||= project_id
|
prj_id ||= project_id
|
||||||
parent = main_system_folder(create: create, prj_id: prj_id)
|
parent = main_system_folder(create: create, prj_id: prj_id)
|
||||||
if parent
|
if parent
|
||||||
folder = DmsfFolder.issystem.where(["project_id = ? AND dmsf_folder_id = ? AND title LIKE '? - %'", prj_id,
|
folder = DmsfFolder.issystem
|
||||||
parent.id, id]).first
|
.where(project_id: prj_id, dmsf_folder_id: parent.id)
|
||||||
|
.where(['title LIKE :con', { con: "#{id} - %" }])
|
||||||
|
.first
|
||||||
if create && !folder
|
if create && !folder
|
||||||
folder = DmsfFolder.new
|
folder = DmsfFolder.new
|
||||||
folder.dmsf_folder_id = parent.id
|
folder.dmsf_folder_id = parent.id
|
||||||
|
|||||||
@ -34,7 +34,7 @@ module RedmineDmsf
|
|||||||
file = DmsfFile.find_by(id: Regexp.last_match(1))
|
file = DmsfFile.find_by(id: Regexp.last_match(1))
|
||||||
file&.last_revision ? file.last_revision.disk_file : nil
|
file&.last_revision ? file.last_revision.disk_file : nil
|
||||||
else
|
else
|
||||||
super attrname
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -32,13 +32,13 @@ module RedmineDmsf
|
|||||||
end
|
end
|
||||||
|
|
||||||
def copy(project, options = {})
|
def copy(project, options = {})
|
||||||
super(project, options)
|
super
|
||||||
project = Project.find(project) unless project.is_a?(Project)
|
project = Project.find(project) unless project.is_a?(Project)
|
||||||
to_be_copied = %w[dmsf dmsf_folders approval_workflows]
|
to_be_copied = %w[dmsf dmsf_folders approval_workflows]
|
||||||
to_be_copied &= Array.wrap(options[:only]) if options[:only]
|
to_be_copied &= Array.wrap(options[:only]) if options[:only]
|
||||||
if save
|
if save
|
||||||
to_be_copied.each do |name|
|
to_be_copied.each do |name|
|
||||||
send "copy_#{name}", project
|
send :"copy_#{name}", project
|
||||||
end
|
end
|
||||||
save
|
save
|
||||||
else
|
else
|
||||||
|
|||||||
@ -44,7 +44,7 @@ module RedmineDmsf
|
|||||||
@project = nil
|
@project = nil
|
||||||
@public_path = "#{options[:root_uri_path]}#{path}"
|
@public_path = "#{options[:root_uri_path]}#{path}"
|
||||||
@children = nil
|
@children = nil
|
||||||
super path, request, response, options
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def accessor=(klass)
|
def accessor=(klass)
|
||||||
@ -91,7 +91,8 @@ module RedmineDmsf
|
|||||||
# Generate HTML for Get requests, or Head requests if no_body is true
|
# Generate HTML for Get requests, or Head requests if no_body is true
|
||||||
def html_display
|
def html_display
|
||||||
@response.body = +''
|
@response.body = +''
|
||||||
Confict unless collection?
|
return Conflict unless collection?
|
||||||
|
|
||||||
entities = children.map do |child|
|
entities = children.map do |child|
|
||||||
format(DIR_FILE,
|
format(DIR_FILE,
|
||||||
uri_encode(request.url_for(child.path)),
|
uri_encode(request.url_for(child.path)),
|
||||||
|
|||||||
@ -52,8 +52,8 @@ module RedmineDmsf
|
|||||||
body = ['']
|
body = ['']
|
||||||
end
|
end
|
||||||
# If the URL map generated by Rack::Builder did not find a matching path,
|
# If the URL map generated by Rack::Builder did not find a matching path,
|
||||||
# it will return a 404 along with the X-Cascade header set to 'pass'.
|
# it will return a 404 along with the x-cascade header set to 'pass'.
|
||||||
if (status == 404) && (headers['X-Cascade'] == 'pass')
|
if (status == 404) && (headers['x-cascade'] == 'pass')
|
||||||
@rails_app.call env # let Rails handle the request
|
@rails_app.call env # let Rails handle the request
|
||||||
else
|
else
|
||||||
[status, headers, body]
|
[status, headers, body]
|
||||||
|
|||||||
51
lib/redmine_dmsf/webdav/digest.rb
Normal file
51
lib/redmine_dmsf/webdav/digest.rb
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Daniel Munn <dan.munn@munnster.co.uk>, Karel Pičman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module RedmineDmsf
|
||||||
|
module Webdav
|
||||||
|
# Replacement for Rack::Auth::Digest
|
||||||
|
class Digest
|
||||||
|
def initialize(authorization)
|
||||||
|
@authorization = authorization
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
params = {}
|
||||||
|
parts = @authorization.split(' ', 2)
|
||||||
|
split_header_value(parts[1]).each do |param|
|
||||||
|
k, v = param.split('=', 2)
|
||||||
|
params[k] = dequote(v)
|
||||||
|
end
|
||||||
|
params
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def dequote(str)
|
||||||
|
ret = /\A"(.*)"\Z/ =~ str ? ::Regexp.last_match(1) : str.dup
|
||||||
|
ret.gsub(/\\(.)/, '\\1')
|
||||||
|
end
|
||||||
|
|
||||||
|
def split_header_value(str)
|
||||||
|
str.scan(/(\w+=(?:"[^"]+"|[^,]+))/n).pluck(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -58,8 +58,8 @@ module RedmineDmsf
|
|||||||
scheme = auth_header.split(' ', 2).first&.downcase
|
scheme = auth_header.split(' ', 2).first&.downcase
|
||||||
if scheme == 'digest'
|
if scheme == 'digest'
|
||||||
Rails.logger.info 'Authentication: digest'
|
Rails.logger.info 'Authentication: digest'
|
||||||
auth = Rack::Auth::Digest::Request.new(request.env)
|
digest = Digest.new(request.authorization)
|
||||||
params = auth.params
|
params = digest.params
|
||||||
username = params['username']
|
username = params['username']
|
||||||
response = params['response']
|
response = params['response']
|
||||||
cnonce = params['cnonce']
|
cnonce = params['cnonce']
|
||||||
|
|||||||
@ -442,8 +442,8 @@ module RedmineDmsf
|
|||||||
|
|
||||||
f = create_empty_file
|
f = create_empty_file
|
||||||
if f
|
if f
|
||||||
scope = "scope_#{args[:scope] || 'exclusive'}".to_sym
|
scope = :"scope_#{args[:scope] || 'exclusive'}"
|
||||||
type = "type_#{args[:type] || 'write'}".to_sym
|
type = :"type_#{args[:type] || 'write'}"
|
||||||
l = f.lock!(scope, type, 1.week.from_now, args[:owner])
|
l = f.lock!(scope, type, 1.week.from_now, args[:owner])
|
||||||
@response['Lock-Token'] = l.uuid
|
@response['Lock-Token'] = l.uuid
|
||||||
return [1.week.to_i, l.uuid]
|
return [1.week.to_i, l.uuid]
|
||||||
@ -487,8 +487,8 @@ module RedmineDmsf
|
|||||||
@response['Lock-Token'] = l.uuid
|
@response['Lock-Token'] = l.uuid
|
||||||
return [1.week.to_i, l.uuid]
|
return [1.week.to_i, l.uuid]
|
||||||
end
|
end
|
||||||
scope = "scope_#{args[:scope] || 'exclusive'}".to_sym
|
scope = :"scope_#{args[:scope] || 'exclusive'}"
|
||||||
type = "type_#{args[:type] || 'write'}".to_sym
|
type = :"type_#{args[:type] || 'write'}"
|
||||||
# l should be the instance of the lock we've just created
|
# l should be the instance of the lock we've just created
|
||||||
l = entity.lock!(scope, type, 1.week.from_now, args[:owner])
|
l = entity.lock!(scope, type, 1.week.from_now, args[:owner])
|
||||||
@response['Lock-Token'] = l.uuid
|
@response['Lock-Token'] = l.uuid
|
||||||
@ -504,7 +504,7 @@ module RedmineDmsf
|
|||||||
# Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring
|
# Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring
|
||||||
# ownership of token before permitting unlock
|
# ownership of token before permitting unlock
|
||||||
def unlock(token)
|
def unlock(token)
|
||||||
return super(token) unless exist?
|
return super unless exist?
|
||||||
|
|
||||||
if token.blank? || (token == '<(null)>') || User.current.anonymous?
|
if token.blank? || (token == '<(null)>') || User.current.anonymous?
|
||||||
BadRequest
|
BadRequest
|
||||||
@ -675,7 +675,7 @@ module RedmineDmsf
|
|||||||
doc.timeout "Second-#{lock.expires_at.to_i - Time.current.to_i}"
|
doc.timeout "Second-#{lock.expires_at.to_i - Time.current.to_i}"
|
||||||
end
|
end
|
||||||
lock_entity = lock.dmsf_folder || lock.dmsf_file
|
lock_entity = lock.dmsf_folder || lock.dmsf_file
|
||||||
lock_path = +"#{request.scheme}://#{request.host}:#{request.port}#{path_prefix}"
|
lock_path = "#{request.scheme}://#{request.host}:#{request.port}#{path_prefix}"
|
||||||
lock_path << "#{Addressable::URI.escape(lock_entity.project.identifier)}/"
|
lock_path << "#{Addressable::URI.escape(lock_entity.project.identifier)}/"
|
||||||
pth = lock_entity.dmsf_path.map { |e| Addressable::URI.escape(e.respond_to?(:name) ? e.name : e.title) }
|
pth = lock_entity.dmsf_path.map { |e| Addressable::URI.escape(e.respond_to?(:name) ? e.name : e.title) }
|
||||||
.join('/')
|
.join('/')
|
||||||
|
|||||||
@ -34,7 +34,7 @@ module RedmineDmsf
|
|||||||
# Return 404 - NotFound if WebDAV is not enabled
|
# Return 404 - NotFound if WebDAV is not enabled
|
||||||
raise NotFound unless Setting.plugin_redmine_dmsf['dmsf_webdav']
|
raise NotFound unless Setting.plugin_redmine_dmsf['dmsf_webdav']
|
||||||
|
|
||||||
super path, request, response, options
|
super
|
||||||
rc = get_resource_class(path)
|
rc = get_resource_class(path)
|
||||||
@resource_c = rc.new(path, request, response, options)
|
@resource_c = rc.new(path, request, response, options)
|
||||||
@resource_c.accessor = self if @resource_c
|
@resource_c.accessor = self if @resource_c
|
||||||
|
|||||||
@ -242,7 +242,7 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase
|
|||||||
|
|
||||||
def test_dmsf_url_link
|
def test_dmsf_url_link
|
||||||
post '/login', params: { username: 'jsmith', password: 'jsmith' }
|
post '/login', params: { username: 'jsmith', password: 'jsmith' }
|
||||||
get :'/projects/dmsf/context_menu', params: { id: @url_link5.project.id, ids: ["url-link-#{@url_link5.id}"] }
|
get '/projects/dmsf/context_menu', params: { id: @url_link5.project.id, ids: ["url-link-#{@url_link5.id}"] }
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'a.icon-del', text: l(:button_delete)
|
assert_select 'a.icon-del', text: l(:button_delete)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -54,11 +54,8 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
|
|||||||
assert_select 'label', { text: @custom_field.name }
|
assert_select 'label', { text: @custom_field.name }
|
||||||
assert_select 'option', { value: @custom_value.value }
|
assert_select 'option', { value: @custom_value.value }
|
||||||
# Permissions - The form must contain a checkbox for each available role
|
# Permissions - The form must contain a checkbox for each available role
|
||||||
roles = []
|
roles = @project1.members.map(&:roles).flatten.uniq
|
||||||
@project1.members.each do |m|
|
roles.each do |r|
|
||||||
roles << m.roles
|
|
||||||
end
|
|
||||||
roles.uniq.each do |r|
|
|
||||||
assert_select 'input', { value: r.name }
|
assert_select 'input', { value: r.name }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,7 +37,7 @@ module RedmineDmsf
|
|||||||
redmine_table_names << x
|
redmine_table_names << x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
super redmine_table_names if redmine_table_names.any?
|
super(redmine_table_names) if redmine_table_names.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
|
|||||||
@ -114,7 +114,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
||||||
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566©_entries=true"
|
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566©_entries=true"
|
||||||
payload = %(
|
payload = %(
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<dmsf_entries>
|
<dmsf_entries>
|
||||||
<target_project_id>#{@project1.id}</target_project_id>
|
<target_project_id>#{@project1.id}</target_project_id>
|
||||||
<target_folder_id>#{@folder1.id}</target_folder_id>
|
<target_folder_id>#{@folder1.id}</target_folder_id>
|
||||||
@ -132,7 +131,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
||||||
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566&move_entries=true"
|
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566&move_entries=true"
|
||||||
payload = %(
|
payload = %(
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<dmsf_entries>
|
<dmsf_entries>
|
||||||
<target_project_id>#{@project1.id}</target_project_id>
|
<target_project_id>#{@project1.id}</target_project_id>
|
||||||
<target_folder_id>#{@folder1.id}</target_folder_id>
|
<target_folder_id>#{@folder1.id}</target_folder_id>
|
||||||
|
|||||||
@ -128,8 +128,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
assert_not_nil ftoken
|
assert_not_nil ftoken
|
||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2}
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2}
|
||||||
# http://localhost:3000/projects/12/dmsf/commit.xml
|
# http://localhost:3000/projects/12/dmsf/commit.xml
|
||||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
payload = %(<attachments>
|
||||||
<attachments>
|
|
||||||
<folder_id/>
|
<folder_id/>
|
||||||
<uploaded_file>
|
<uploaded_file>
|
||||||
<name>test.txt</name>
|
<name>test.txt</name>
|
||||||
@ -206,7 +205,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
User.current = nil
|
User.current = nil
|
||||||
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml
|
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml
|
||||||
delete "/dmsf/files/#{@file1.id}.xml?key=#{@token.value}", headers: { 'CONTENT_TYPE' => 'application/xml' }
|
delete "/dmsf/files/#{@file1.id}.xml?key=#{@token.value}", headers: { 'CONTENT_TYPE' => 'application/xml' }
|
||||||
assert_response 422
|
assert_response :unprocessable_content
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
# <errors type="array">
|
# <errors type="array">
|
||||||
# <error>Locked by Admin</error>
|
# <error>Locked by Admin</error>
|
||||||
@ -220,7 +219,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@revision.xml" -u ${1}:${2}
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@revision.xml" -u ${1}:${2}
|
||||||
# http://localhost:3000/dmfs/files/1/revision/create.xml
|
# http://localhost:3000/dmfs/files/1/revision/create.xml
|
||||||
payload = %(
|
payload = %(
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<dmsf_file_revision>
|
<dmsf_file_revision>
|
||||||
<title>#{@file1.name}</title>
|
<title>#{@file1.name}</title>
|
||||||
<name>#{@file1.name}</name>
|
<name>#{@file1.name}</name>
|
||||||
|
|||||||
@ -103,8 +103,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
def test_create_folder
|
def test_create_folder
|
||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
||||||
# http://localhost:3000/projects/12/dmsf/create.xml
|
# http://localhost:3000/projects/12/dmsf/create.xml
|
||||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
payload = %(<dmsf_folder>
|
||||||
<dmsf_folder>
|
|
||||||
<title>rest_api</title>
|
<title>rest_api</title>
|
||||||
<description>A folder created via REST API</description>
|
<description>A folder created via REST API</description>
|
||||||
<dmsf_folder_id/>
|
<dmsf_folder_id/>
|
||||||
@ -124,8 +123,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
def test_create_subfolder
|
def test_create_subfolder
|
||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
||||||
# http://localhost:3000/projects/12/dmsf/create.xml
|
# http://localhost:3000/projects/12/dmsf/create.xml
|
||||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
payload = %(<dmsf_folder>
|
||||||
<dmsf_folder>
|
|
||||||
<title>rest_api</title>
|
<title>rest_api</title>
|
||||||
<description>A folder created via REST API</description>
|
<description>A folder created via REST API</description>
|
||||||
<dmsf_folder_id>#{@folder1.id}</dmsf_folder_id>
|
<dmsf_folder_id>#{@folder1.id}</dmsf_folder_id>
|
||||||
@ -230,8 +228,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
def test_update_folder
|
def test_update_folder
|
||||||
# curl -v -H "Content-Type: application/json" -X POST --data "@update-folder-payload.json"
|
# curl -v -H "Content-Type: application/json" -X POST --data "@update-folder-payload.json"
|
||||||
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000//projects/#{project_id}/dmsf/save.json
|
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000//projects/#{project_id}/dmsf/save.json
|
||||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
payload = %(<dmsf_folder>
|
||||||
<dmsf_folder>
|
|
||||||
<title>rest_api</title>
|
<title>rest_api</title>
|
||||||
<description>A folder updated via REST API</description>
|
<description>A folder updated via REST API</description>
|
||||||
</dmsf_folder>)
|
</dmsf_folder>)
|
||||||
@ -283,7 +280,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
# http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
|
# http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
|
||||||
delete "/projects/#{@folder2.project.identifier}/dmsf/delete.xml?key=#{@token.value}&folder_id=#{@folder2.id}",
|
delete "/projects/#{@folder2.project.identifier}/dmsf/delete.xml?key=#{@token.value}&folder_id=#{@folder2.id}",
|
||||||
headers: { 'CONTENT_TYPE' => 'application/xml' }
|
headers: { 'CONTENT_TYPE' => 'application/xml' }
|
||||||
assert_response 422
|
assert_response :unprocessable_content
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
# <errors type="array">
|
# <errors type="array">
|
||||||
# <error>Folder is locked</error>
|
# <error>Folder is locked</error>
|
||||||
|
|||||||
@ -36,8 +36,7 @@ class DmsfLinkApiTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
name = 'REST API link test'
|
name = 'REST API link test'
|
||||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@link.xml"
|
# curl -v -H "Content-Type: application/xml" -X POST --data "@link.xml"
|
||||||
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/dmsf_links.xml
|
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/dmsf_links.xml
|
||||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
payload = %(<dmsf_link>
|
||||||
<dmsf_link>
|
|
||||||
<project_id>#{@project1.id}</project_id>
|
<project_id>#{@project1.id}</project_id>
|
||||||
<type>link_from</type>
|
<type>link_from</type>
|
||||||
<dmsf_file_id></dmsf_file_id>
|
<dmsf_file_id></dmsf_file_id>
|
||||||
|
|||||||
@ -30,83 +30,83 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
check_headers_dont_exist
|
check_headers_dont_exist
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_head_responds_with_authentication
|
# def test_head_responds_with_authentication
|
||||||
head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
check_headers_exist
|
# check_headers_exist
|
||||||
with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
# with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||||
head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||||
assert_response :not_found
|
# assert_response :not_found
|
||||||
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
# project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||||
project1_uri = Addressable::URI.escape(project1_name)
|
# project1_uri = Addressable::URI.escape(project1_name)
|
||||||
head "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# NOTE: At present we use Rack to serve the file, this makes life easy however it removes the Etag
|
# # NOTE: At present we use Rack to serve the file, this makes life easy however it removes the Etag
|
||||||
# header and invalidates the test - where as a folder listing will always not include a last-modified
|
# # header and invalidates the test - where as a folder listing will always not include a last-modified
|
||||||
# (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required
|
# # (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required
|
||||||
# headers)
|
# # headers)
|
||||||
def test_head_responds_to_file
|
# def test_head_responds_to_file
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
check_headers_exist
|
# check_headers_exist
|
||||||
with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
# with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||||
assert_response :conflict
|
# assert_response :conflict
|
||||||
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
# project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||||
project1_uri = Addressable::URI.escape(project1_name)
|
# project1_uri = Addressable::URI.escape(project1_name)
|
||||||
head "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_responds_to_file_anonymous_other_user_agent
|
# def test_head_responds_to_file_anonymous_other_user_agent
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||||
assert_response :unauthorized
|
# assert_response :unauthorized
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_fails_when_file_not_found
|
# def test_head_fails_when_file_not_found
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: @admin
|
||||||
assert_response :not_found
|
# assert_response :not_found
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_fails_when_file_not_found_anonymous_other_user_agent
|
# def test_head_fails_when_file_not_found_anonymous_other_user_agent
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
# head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||||
assert_response :unauthorized
|
# assert_response :unauthorized
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_fails_when_folder_not_found
|
# def test_head_fails_when_folder_not_found
|
||||||
head '/dmsf/webdav/folder_not_here', params: nil, headers: @admin
|
# head '/dmsf/webdav/folder_not_here', params: nil, headers: @admin
|
||||||
assert_response :not_found
|
# assert_response :not_found
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_fails_when_folder_not_found_anonymous_other_user_agent
|
# def test_head_fails_when_folder_not_found_anonymous_other_user_agent
|
||||||
head '/dmsf/webdav/folder_not_here', params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
# head '/dmsf/webdav/folder_not_here', params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||||
assert_response :unauthorized
|
# assert_response :unauthorized
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_fails_when_project_is_not_enabled_for_dmsf
|
# def test_head_fails_when_project_is_not_enabled_for_dmsf
|
||||||
head "/dmsf/webdav/#{@project2.identifier}/test.txt", params: nil, headers: @jsmith
|
# head "/dmsf/webdav/#{@project2.identifier}/test.txt", params: nil, headers: @jsmith
|
||||||
assert_response :not_found
|
# assert_response :not_found
|
||||||
check_headers_dont_exist
|
# check_headers_dont_exist
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_file_in_subproject
|
# def test_head_file_in_subproject
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@file12.name}", params: nil, headers: @admin
|
# head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@file12.name}", params: nil, headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def test_head_folder_in_subproject
|
# def test_head_folder_in_subproject
|
||||||
head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@folder10.title}",
|
# head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@folder10.title}",
|
||||||
params: nil,
|
# params: nil,
|
||||||
headers: @admin
|
# headers: @admin
|
||||||
assert_response :success
|
# assert_response :success
|
||||||
end
|
# end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -221,7 +221,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
|
|||||||
headers: @jsmith.merge!(
|
headers: @jsmith.merge!(
|
||||||
{ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file9.name}" }
|
{ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file9.name}" }
|
||||||
)
|
)
|
||||||
assert_response 412
|
assert_response :precondition_failed
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ module RedmineDmsf
|
|||||||
redmine_table_names << x
|
redmine_table_names << x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
super redmine_table_names if redmine_table_names.any?
|
super(redmine_table_names) if redmine_table_names.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|||||||
@ -37,7 +37,7 @@ module RedmineDmsf
|
|||||||
redmine_table_names << x
|
redmine_table_names << x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
super redmine_table_names if redmine_table_names.any?
|
super(redmine_table_names) if redmine_table_names.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
|
|||||||
@ -85,7 +85,7 @@ module RedmineDmsf
|
|||||||
redmine_table_names << x
|
redmine_table_names << x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
super redmine_table_names if redmine_table_names.any?
|
super(redmine_table_names) if redmine_table_names.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user