From 12a7a45e59f6c7e2cead6190042fa77b4ed5f48a Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Sun, 12 Feb 2017 19:55:15 +0100 Subject: [PATCH 1/7] Project folder names in WebDav can be the project name instead of identifier. --- lib/redmine_dmsf/webdav/base_resource.rb | 39 ++++++++++++++++++--- lib/redmine_dmsf/webdav/index_resource.rb | 4 +-- lib/redmine_dmsf/webdav/project_resource.rb | 15 ++++++-- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index ec4c59e6..d5ce211b 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -93,6 +93,22 @@ module RedmineDmsf new_path = '/' + new_path unless new_path[0,1] == '/' @__proxy.class.new("#{new_public}#{name}", "#{new_path}#{name}", request, response, options.merge(:user => @user)) end + + def child_project(p) + project_display_name = ProjectResource.create_display_name(p) + + new_public = public_path.dup + new_public = new_public + '/' unless new_public[-1,1] == '/' + new_public = '/' + new_public unless new_public[0,1] == '/' + new_public += project_display_name + + new_path = path.dup + new_path = new_path + '/' unless new_path[-1,1] == '/' + new_path = '/' + new_path unless new_path[0,1] == '/' + new_path += project_display_name + + @__proxy.class.new("#{new_public}", "#{new_path}", request, response, options.merge(:user => @user)) + end def parent p = @__proxy.parent @@ -148,12 +164,27 @@ module RedmineDmsf # Return instance of Project based on the path def project unless @project + use_project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] pinfo = @path.split('/').drop(1) if pinfo.length > 0 - begin - @project = Project.find(pinfo.first) - rescue Exception => e - Rails.logger.warn e.message + if use_project_names + unless pinfo.first.match('(\[([0-9]+)\])$').nil? + pid = $2 + begin + @project = Project.find_by_id(pid) + rescue Exception => e + Rails.logger.error e.message + end + end + if @project.nil? + Rails.logger.warn {"WebDAV ERROR: No project found on path '#{@path}'"} + end + else + begin + @project = Project.find(pinfo.first) + rescue Exception => e + Rails.logger.warn e.message + end end end end diff --git a/lib/redmine_dmsf/webdav/index_resource.rb b/lib/redmine_dmsf/webdav/index_resource.rb index 796e7914..bf09e329 100644 --- a/lib/redmine_dmsf/webdav/index_resource.rb +++ b/lib/redmine_dmsf/webdav/index_resource.rb @@ -31,10 +31,10 @@ module RedmineDmsf def children unless @projects @projects = [] - Project.select(:identifier).has_module(:dmsf).where( + Project.select(:id, :identifier, :name).has_module(:dmsf).where( Project.allowed_to_condition( User.current, :view_dmsf_folders)).order('lft').all.each do |p| - @projects << child(p.identifier) + @projects << child_project(p) end end @projects diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index 02d91627..ec495e11 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -28,7 +28,7 @@ module RedmineDmsf @children = nil end - def children + def children unless @children @children = [] if project @@ -72,7 +72,7 @@ module RedmineDmsf end def name - project.identifier unless project.nil? + ProjectResource.create_display_name(project) end def long_name @@ -108,7 +108,16 @@ module RedmineDmsf def project_id self.project.id if self.project end - + + def self.create_display_name(p) + use_project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] + if use_project_names + "#{p.name.gsub(/\W/, "_")} [#{p.id}]" unless p.nil? + else + p.identifier unless p.nil? + end + end end + end end From d58f6c23cc71146bcd7a24ace1ee0219af55f4df Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Sun, 12 Feb 2017 19:58:50 +0100 Subject: [PATCH 2/7] Added setting to enable/disable using project names instead of identifier. --- app/views/settings/_dmsf_settings.html.erb | 9 +++++++++ config/locales/cs.yml | 5 ++++- config/locales/de.yml | 5 ++++- config/locales/en.yml | 3 +++ config/locales/es.yml | 5 ++++- config/locales/fr.yml | 5 ++++- config/locales/it.yml | 5 ++++- config/locales/ja.yml | 5 ++++- config/locales/pl.yml | 5 ++++- config/locales/pt-BR.yml | 5 ++++- config/locales/ru.yml | 5 ++++- config/locales/sl.yml | 5 ++++- config/locales/zh-TW.yml | 5 ++++- config/locales/zh.yml | 5 ++++- 14 files changed, 60 insertions(+), 12 deletions(-) diff --git a/app/views/settings/_dmsf_settings.html.erb b/app/views/settings/_dmsf_settings.html.erb index ff5b56d2..62022bc8 100644 --- a/app/views/settings/_dmsf_settings.html.erb +++ b/app/views/settings/_dmsf_settings.html.erb @@ -202,6 +202,15 @@

+

+ <%= content_tag(:label, l(:label_webdav_use_project_names)) %> + <%= check_box_tag('settings[dmsf_webdav_use_project_names]', true, @settings['dmsf_webdav_use_project_names']) %> + + <%= l(:note_webdav_use_project_names) %>
+ <%= l(:label_default)%>: <%= l(:general_text_No)%> +
+

+
<%= l(:label_full_text) %> diff --git a/config/locales/cs.yml b/config/locales/cs.yml index d8d62549..dc7ddc0d 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -355,4 +355,7 @@ cs: label_dmsf_keep_documents_locked: Ponechat dokumenty zamčené note_dmsf_keep_documents_locked: Dokumenty zůstanou i po schválení zamčené. note_global: (globální) - field_dmsf_not_inheritable: Není dědičné \ No newline at end of file + field_dmsf_not_inheritable: Není dědičné + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/de.yml b/config/locales/de.yml index dcfe7a49..3d9d029f 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -352,4 +352,7 @@ de: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/en.yml b/config/locales/en.yml index 0d8f245a..4f909279 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -356,3 +356,6 @@ en: note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/es.yml b/config/locales/es.yml index 0cac72fe..3194918b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -355,4 +355,7 @@ es: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b9929766..1e48b134 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -355,4 +355,7 @@ fr: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/it.yml b/config/locales/it.yml index ae10895f..50b1e09d 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -355,4 +355,7 @@ it: # Italian strings thx 2 Matteo Arceci! label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 2b800a59..4a97a71d 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -355,4 +355,7 @@ ja: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 19e94eb7..2ee7d34d 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -355,4 +355,7 @@ pl: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index d7cd3e24..e63bf12a 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -355,4 +355,7 @@ pt-BR: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 7be56919..7fb2c19f 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -355,4 +355,7 @@ ru: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 9cbace5d..d7a10f6f 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -355,4 +355,7 @@ sl: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index f191b8cd..369c869e 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -355,4 +355,7 @@ zh-TW: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 6b3a6ec6..65aa5a9b 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -355,4 +355,7 @@ zh: label_dmsf_keep_documents_locked: Keep documents locked note_dmsf_keep_documents_locked: Documents will be kept locked when approved note_global: (global) - field_dmsf_not_inheritable: Not inheritable \ No newline at end of file + field_dmsf_not_inheritable: Not inheritable + + label_webdav_use_project_names: Use project name for project folder + note_webdav_use_project_names: Use project names instead of project identifier for project folders. From f4ca9a62730b35312276c17d804b4cbffce9c84f Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Tue, 14 Feb 2017 21:41:40 +0100 Subject: [PATCH 3/7] Updated tests for using project names. --- .../webdav/dmsf_webdav_delete_test.rb | 37 ++++++++ .../webdav/dmsf_webdav_get_test.rb | 22 ++++- .../webdav/dmsf_webdav_head_test.rb | 38 +++++++- .../webdav/dmsf_webdav_mkcol_test.rb | 20 ++-- .../webdav/dmsf_webdav_move_test.rb | 33 +++++++ .../webdav/dmsf_webdav_options_test.rb | 36 ++++--- .../webdav/dmsf_webdav_propfind_test.rb | 93 ++++++++++++++++++- .../webdav/dmsf_webdav_put_test.rb | 46 +++++---- 8 files changed, 280 insertions(+), 45 deletions(-) diff --git a/test/integration/webdav/dmsf_webdav_delete_test.rb b/test/integration/webdav/dmsf_webdav_delete_test.rb index 562533fc..c3aee556 100644 --- a/test/integration/webdav/dmsf_webdav_delete_test.rb +++ b/test/integration/webdav/dmsf_webdav_delete_test.rb @@ -40,6 +40,7 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest @file1 = DmsfFile.find_by_id 1 Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false DmsfFile.storage_path = File.expand_path '../../../fixtures/files', __FILE__ User.current = nil end @@ -169,6 +170,23 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest end end + def test_folder_delete_by_user_with_project_names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + @role.add_permission! :view_dmsf_folders + @role.add_permission! :folder_manipulation + @project1.enable_module! :dmsf # Flag module enabled + + delete "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @jsmith + assert_response 404 + + p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name_uri = URI.encode(p1name, /\W/) + delete "/dmsf/webdav/#{p1name_uri}/#{@folder6.title}", nil, @jsmith + assert_response :success + @folder6.reload + assert @folder6.deleted?, "Folder #{@folder1.title} is not expected to exist" + end + def test_file_delete_by_administrator if Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] == 'WEBDAV_READ_WRITE' @project1.enable_module! :dmsf @@ -191,6 +209,25 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest end end + def test_file_delete_by_user_with_project_names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + @project1.enable_module! :dmsf + @role.add_permission! :view_dmsf_folders + @role.add_permission! :file_delete + + delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith + assert_response 404 + + p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name_uri = URI.encode(p1name, /\W/) + + delete "/dmsf/webdav/#{p1name_uri}/#{@file1.name}", nil, @jsmith + assert_response :success + + @file1.reload + assert @file1.deleted?, "File #{@file1.name} is not expected to exist" + end + def test_locked_folder @project1.enable_module! :dmsf # Flag module enabled @role.add_permission! :view_dmsf_folders diff --git a/test/integration/webdav/dmsf_webdav_get_test.rb b/test/integration/webdav/dmsf_webdav_get_test.rb index 87b0f250..11217b17 100644 --- a/test/integration/webdav/dmsf_webdav_get_test.rb +++ b/test/integration/webdav/dmsf_webdav_get_test.rb @@ -34,6 +34,7 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest @role = Role.find_by_id 1 # Manager Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false DmsfFile.storage_path = File.expand_path '../../../fixtures/files', __FILE__ User.current = nil end @@ -62,13 +63,21 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest def test_should_list_dmsf_enabled_project get '/dmsf/webdav', nil, @admin assert_response :success - assert !response.body.match(@project1.name).nil?, "Expected to find project #{@project1.name} in return data" + assert !response.body.match(@project1.identifier).nil?, "Expected to find project #{@project1.identifier} in return data" + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + + get '/dmsf/webdav', nil, @admin + assert_response :success + assert_no_match @project1.identifier, response.body + assert_match project1_uri, response.body end def test_should_not_list_non_dmsf_enabled_project get '/dmsf/webdav', nil, @jsmith assert_response :success - assert response.body.match(@project2.name).nil?, "Unexpected find of project #{@project2.name} in return data" + assert response.body.match(@project2.identifier).nil?, "Unexpected find of project #{@project2.identifier} in return data" end def test_should_return_status_404_when_project_does_not_exist @@ -85,6 +94,15 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest def test_download_file_from_dmsf_enabled_project get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin assert_response :success + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + + get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin + assert_response 404 + + get "/dmsf/webdav/#{project1_uri}/test.txt", nil, @admin + assert_response :success end def test_should_list_dmsf_contents_within_project diff --git a/test/integration/webdav/dmsf_webdav_head_test.rb b/test/integration/webdav/dmsf_webdav_head_test.rb index 9c4e6ec9..211911af 100644 --- a/test/integration/webdav/dmsf_webdav_head_test.rb +++ b/test/integration/webdav/dmsf_webdav_head_test.rb @@ -32,7 +32,11 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest @project1 = Project.find_by_id 1 @project2 = Project.find_by_id 2 Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' - Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + # Temporarily enable project names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + @project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false DmsfFile.storage_path = File.expand_path '../../../fixtures/files', __FILE__ User.current = nil end @@ -52,12 +56,28 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest head "/dmsf/webdav/#{@project1.identifier}", nil, @admin assert_response :success check_headers_exist + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + head "/dmsf/webdav/#{@project1.identifier}", nil, @admin + assert_response 404 + + head "/dmsf/webdav/#{@project1_uri}", nil, @admin + assert_response :success end def test_head_responds_anonymous_msoffice_user_agent head "/dmsf/webdav/#{@project1.identifier}", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} assert_response :success check_headers_exist + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + head "/dmsf/webdav/#{@project1.identifier}", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} + assert_response 404 + + head "/dmsf/webdav/#{@project1_uri}", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} + assert_response :success end def test_head_responds_anonymous_other_user_agent @@ -75,12 +95,28 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest head "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin assert_response :success check_headers_exist # Note it'll allow 1 out of the 3 expected to fail + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + head "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin + assert_response 404 + + head "/dmsf/webdav/#{@project1_uri}/test.txt", nil, @admin + assert_response :success end def test_head_responds_to_file_anonymous_msoffice_user_agent head "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} assert_response :success check_headers_exist # Note it'll allow 1 out of the 3 expected to fail + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + head "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} + assert_response 404 + + head "/dmsf/webdav/#{@project1_uri}/test.txt", nil, {:HTTP_USER_AGENT => "Microsoft Office Word 2014"} + assert_response :success end def test_head_responds_to_file_anonymous_other_user_agent diff --git a/test/integration/webdav/dmsf_webdav_mkcol_test.rb b/test/integration/webdav/dmsf_webdav_mkcol_test.rb index ac571671..ebe5751d 100644 --- a/test/integration/webdav/dmsf_webdav_mkcol_test.rb +++ b/test/integration/webdav/dmsf_webdav_mkcol_test.rb @@ -35,6 +35,7 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest @folder6 = DmsfFolder.find_by_id 6 Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false DmsfFile.storage_path = File.expand_path '../../../fixtures/files', __FILE__ User.current = nil end @@ -98,12 +99,19 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest end def test_should_create_folder_for_non_admin_user_with_rights - if Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] == 'WEBDAV_READ_WRITE' - @project1.enable_module! :dmsf - @role.add_permission! :folder_manipulation - xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", nil, @jsmith - assert_response :success - end + @project1.enable_module! :dmsf + @role.add_permission! :folder_manipulation + xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", nil, @jsmith + assert_response :success + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + + xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test2", nil, @jsmith + assert_response 404 + + xml_http_request :mkcol, "/dmsf/webdav/#{project1_uri}/test3", nil, @jsmith + assert_response :success end end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_move_test.rb b/test/integration/webdav/dmsf_webdav_move_test.rb index 2aa781ae..aeaf4678 100644 --- a/test/integration/webdav/dmsf_webdav_move_test.rb +++ b/test/integration/webdav/dmsf_webdav_move_test.rb @@ -46,6 +46,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false super end @@ -130,6 +131,21 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest assert f, "Moved file '#{new_name}' not found in project." end end + + def test_move_to_new_filename_with_project_names + file = DmsfFile.find_by_id 1 + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + + new_name = "#{file.name}.moved" + assert_difference 'file.dmsf_file_revisions.count', +1 do + xml_http_request :move, "/dmsf/webdav/#{project1_uri}/#{file.name}", nil, + @jsmith.merge!({:destination => "http://www.example.com/dmsf/webdav/#{project1_uri}/#{new_name}"}) + assert_response 201 # Created + f = DmsfFile.find_file_by_name @project1, nil, "#{new_name}" + assert f, "Moved file '#{new_name}' not found in project." + end + end def test_move_zero_sized_to_new_filename file = DmsfFile.find_by_id 10 @@ -158,6 +174,23 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest assert_equal folder.id, file2.dmsf_folder_id end end + + def test_move_to_new_folder_with_project_names + file = DmsfFile.find_by_id 1 + folder = DmsfFolder.find_by_id 1 + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + assert_kind_of DmsfFile, file + assert_kind_of DmsfFolder, folder + + assert_difference 'file.dmsf_file_revisions.count', +1 do + xml_http_request :move, "/dmsf/webdav/#{project1_uri}/#{file.name}", nil, + @jsmith.merge!({:destination => "http://www.example.com/dmsf/webdav/#{project1_uri}/#{folder.title}/#{file.name}"}) + assert_response 201 # Created + file2 = DmsfFile.find_by_id 1 + assert_equal folder.id, file2.dmsf_folder_id + end + end def test_move_zero_sized_to_new_folder file = DmsfFile.find_by_id 10 diff --git a/test/integration/webdav/dmsf_webdav_options_test.rb b/test/integration/webdav/dmsf_webdav_options_test.rb index 069b2ed4..ae732d97 100644 --- a/test/integration/webdav/dmsf_webdav_options_test.rb +++ b/test/integration/webdav/dmsf_webdav_options_test.rb @@ -33,6 +33,7 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest @project2 = Project.find_by_id 2 Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false end def test_truth @@ -60,8 +61,7 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest assert_response :success assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert response.headers['Allow'] , 'Allow header is empty or does not exist' - # TODO: Unable to set the 'WEBDAV_READ_WRITE' mode - #assert_equal response.headers['Allow'], 'OPTIONS,HEAD,GET,PROPFIND,PUT,POST,DELETE,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK' + assert_equal response.headers['Allow'], 'OPTIONS,HEAD,GET,PROPFIND,PUT,POST,DELETE,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK' end def test_options_returns_expected_dav_header @@ -111,8 +111,7 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest assert_response :success assert !(response.headers.nil? || response.headers.empty?), "Response headers are empty" assert response.headers['Allow'], 'Allow header is empty or does not exist' - # TODO: Unable to set the 'WEBDAV_READ_WRITE' mode - #assert_equal response.headers['Allow'], 'OPTIONS,HEAD,GET,PROPFIND,PUT,POST,DELETE,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK' + assert_equal response.headers['Allow'], 'OPTIONS,HEAD,GET,PROPFIND,PUT,POST,DELETE,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK' end def test_authenticated_options_returns_expected_dav_header @@ -148,18 +147,25 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest def test_authenticated_options_for_other_user_agent xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin.merge!({:HTTP_USER_AGENT => "Other"}) assert_response :success + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + + xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin.merge!({:HTTP_USER_AGENT => "Other"}) + assert_response 404 + xml_http_request :options, "/dmsf/webdav/#{project1_uri}", nil, @admin.merge!({:HTTP_USER_AGENT => "Other"}) + assert_response :success end - # TODO: It doesn't work - # def test_authenticated_options_returns_401_for_non_dmsf_enabled_items - # @project2.disable_module! :dmsf - # xml_http_request :options, "/dmsf/webdav/#{@project2.identifier}", nil, @jsmith - # assert_response 401 # refused - # end - # - # def test_authenticated_options_returns_401_for_not_found - # xml_http_request :options, '/dmsf/webdav/does-not-exist', nil, @jsmith - # assert_response 401 # refused - # end + def test_authenticated_options_returns_404_for_non_dmsf_enabled_items + @project2.disable_module! :dmsf + xml_http_request :options, "/dmsf/webdav/#{@project2.identifier}", nil, @jsmith + assert_response 404 + end + + def test_authenticated_options_returns_404_for_not_found + xml_http_request :options, '/dmsf/webdav/does-not-exist', nil, @jsmith + assert_response 404 + end end diff --git a/test/integration/webdav/dmsf_webdav_propfind_test.rb b/test/integration/webdav/dmsf_webdav_propfind_test.rb index ef997ada..54f51779 100644 --- a/test/integration/webdav/dmsf_webdav_propfind_test.rb +++ b/test/integration/webdav/dmsf_webdav_propfind_test.rb @@ -20,6 +20,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../test_helper', __FILE__) +require 'uri' class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest @@ -42,6 +43,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false + RedmineDmsf::Webdav::Cache.init_nullcache end def test_truth @@ -108,6 +111,26 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_no_match "#{@project2.identifier}", response.body end + def test_propfind_depth1_on_root_for_admin_with_project_names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + xml_http_request :propfind, "/dmsf/webdav/", nil, + @admin.merge!({:HTTP_DEPTH => "1"}) + + assert_response 207 # MultiStatus + assert_match "http://www.example.com:80/dmsf/webdav/", response.body + assert_match "/", response.body + + # project.identifier should not match when using project names + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body + assert_no_match "#{@project1.identifier}", response.body + + # but the project name should match + p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name_uri = URI.encode(p1name, /\W/) + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body + assert_match "#{p1name}", response.body + end + def test_propfind_depth0_on_project1_for_non_member xml_http_request :propfind, "/dmsf/webdav/#{@project1.identifier}", nil, @jsmith.merge!({:HTTP_DEPTH => "0"}) @@ -136,6 +159,28 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file10.name}", response.body assert_no_match "#{@file10.name}", response.body end + + def test_propfind_depth0_on_project1_for_admin_with_project_names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + xml_http_request :propfind, "/dmsf/webdav/#{@project1.identifier}", nil, + @admin.merge!({:HTTP_DEPTH => "0"}) + assert_response 404 + + p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name_uri = URI.encode(p1name, /\W/) + + xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, + @admin.merge!({:HTTP_DEPTH => "0"}) + assert_response 207 # MultiStatus + assert_no_match "http://www.example.com:80/dmsf/webdav/", response.body + assert_no_match "/", response.body + # Project + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body + assert_no_match "#{@project1.identifier}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body + assert_match "#{p1name}", response.body + end def test_propfind_depth1_on_project1_for_admin xml_http_request :propfind, "/dmsf/webdav/#{@project1.identifier}", nil, @@ -160,6 +205,50 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_match "#{@file10.name}", response.body end + def test_propfind_depth1_on_project1_for_admin_with_project_names + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + xml_http_request :propfind, "/dmsf/webdav/#{@project1.identifier}", nil, + @admin.merge!({:HTTP_DEPTH => "1"}) + assert_response 404 + + p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name_uri = URI.encode(p1name, /\W/) + + xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, + @admin.merge!({:HTTP_DEPTH => "1"}) + assert_response 207 # MultiStatus + + assert_no_match "http://www.example.com:80/dmsf/webdav/", response.body + assert_no_match "/", response.body + + # Project + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body + assert_no_match "#{@project1.identifier}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body + assert_match "#{p1name}", response.body + + # Folders + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}/", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@folder1.title}/", response.body + assert_match "#{@folder1.title}", response.body + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}/", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@folder6.title}/", response.body + assert_match "#{@folder6.title}", response.body + + # Files + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file1.name}", response.body + assert_match "#{@file1.name}", response.body + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file9.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file9.name}", response.body + assert_match "#{@file9.name}", response.body + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file10.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file10.name}", response.body + assert_match "#{@file10.name}", response.body + end + + def test_propfind_depth0_on_project1_for_admin_with_cache RedmineDmsf::Webdav::Cache.init_testcache @@ -184,8 +273,6 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_response 207 # MultiStatus end assert_match "Cached PROPSTATS/#{@project1.identifier}", response.body - - RedmineDmsf::Webdav::Cache.init_nullcache end def test_propfind_depth1_on_project1_for_admin_with_cache @@ -237,8 +324,6 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_match "Cached PROPSTATS/#{@project1.identifier}", response.body assert_match "Cached PROPSTATS/#{@project1.identifier}", RedmineDmsf::Webdav::Cache.read("PROPFIND/#{@project1.id}") assert !RedmineDmsf::Webdav::Cache.exist?("PROPFIND/#{@project1.id}.invalid") - - RedmineDmsf::Webdav::Cache.init_nullcache end end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_put_test.rb b/test/integration/webdav/dmsf_webdav_put_test.rb index 38a11fbf..b111debb 100644 --- a/test/integration/webdav/dmsf_webdav_put_test.rb +++ b/test/integration/webdav/dmsf_webdav_put_test.rb @@ -39,6 +39,7 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest @role = Role.find 1 # Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false super end @@ -93,13 +94,19 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest end def test_put_as_admin_granted_on_dmsf_enabled_project - if Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] == 'WEBDAV_READ_WRITE' - put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) - assert_response :success # 201 Created - # Lets check for our file - file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' - assert file, 'Check for files existance' - end + put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) + assert_response :success # 201 Created + # Lets check for our file + file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' + assert file, 'Check for files existance' + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + + put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) + assert_response 409 + put "/dmsf/webdav/#{project1_uri}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) + assert_response :success # 201 Created end def test_put_failed_as_jsmith_on_non_dmsf_enabled_project @@ -137,16 +144,21 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest end def test_put_succeeds_for_non_admin_with_correct_permissions - if Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] == 'WEBDAV_READ_WRITE' - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :view_dmsf_folders - @role.add_permission! :file_manipulation - put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) - assert_response :success # 201 - Now we have permissions - # Lets check for our file - file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' - assert file, 'File test-1234 was not found in projects dmsf folder.' - end + @project1.enable_module! :dmsf # Flag module enabled + @role.add_permission! :view_dmsf_folders + @role.add_permission! :file_manipulation + put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) + assert_response :success # 201 - Now we have permissions + # Lets check for our file + file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' + assert file, 'File test-1234 was not found in projects dmsf folder.' + + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) + assert_response 409 + put "/dmsf/webdav/#{project1_uri}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) + assert_response :success # 201 - Now we have permissions end def test_put_writes_revision_successfully_for_unlocked_file From 75f644970b62dd4aeea08c3153c2a1fd5f8e7924 Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Wed, 15 Feb 2017 22:42:10 +0100 Subject: [PATCH 4/7] Renamed create_display_name to create_project_name, added PROJECT_NAME_FILTER. --- lib/redmine_dmsf/webdav/base_resource.rb | 2 +- lib/redmine_dmsf/webdav/project_resource.rb | 10 ++++++---- test/integration/webdav/dmsf_webdav_delete_test.rb | 4 ++-- test/integration/webdav/dmsf_webdav_get_test.rb | 4 ++-- test/integration/webdav/dmsf_webdav_head_test.rb | 2 +- test/integration/webdav/dmsf_webdav_mkcol_test.rb | 2 +- test/integration/webdav/dmsf_webdav_move_test.rb | 4 ++-- test/integration/webdav/dmsf_webdav_options_test.rb | 2 +- .../integration/webdav/dmsf_webdav_propfind_test.rb | 13 ++++++------- test/integration/webdav/dmsf_webdav_put_test.rb | 4 ++-- 10 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index d5ce211b..fbd67438 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -95,7 +95,7 @@ module RedmineDmsf end def child_project(p) - project_display_name = ProjectResource.create_display_name(p) + project_display_name = ProjectResource.create_project_name(p) new_public = public_path.dup new_public = new_public + '/' unless new_public[-1,1] == '/' diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index ec495e11..d1b7875c 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -72,7 +72,7 @@ module RedmineDmsf end def name - ProjectResource.create_display_name(project) + ProjectResource.create_project_name(project) end def long_name @@ -109,15 +109,17 @@ module RedmineDmsf self.project.id if self.project end - def self.create_display_name(p) + # Characters that MATCH this regex will be replaced by '_' + PROJECT_NAME_FILTER = /\W/ + + def self.create_project_name(p) use_project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] if use_project_names - "#{p.name.gsub(/\W/, "_")} [#{p.id}]" unless p.nil? + "#{p.name.gsub(PROJECT_NAME_FILTER, "_")} [#{p.id}]" unless p.nil? else p.identifier unless p.nil? end end end - end end diff --git a/test/integration/webdav/dmsf_webdav_delete_test.rb b/test/integration/webdav/dmsf_webdav_delete_test.rb index c3aee556..e4274d90 100644 --- a/test/integration/webdav/dmsf_webdav_delete_test.rb +++ b/test/integration/webdav/dmsf_webdav_delete_test.rb @@ -179,7 +179,7 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest delete "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @jsmith assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) p1name_uri = URI.encode(p1name, /\W/) delete "/dmsf/webdav/#{p1name_uri}/#{@folder6.title}", nil, @jsmith assert_response :success @@ -218,7 +218,7 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) p1name_uri = URI.encode(p1name, /\W/) delete "/dmsf/webdav/#{p1name_uri}/#{@file1.name}", nil, @jsmith diff --git a/test/integration/webdav/dmsf_webdav_get_test.rb b/test/integration/webdav/dmsf_webdav_get_test.rb index 11217b17..a06b3195 100644 --- a/test/integration/webdav/dmsf_webdav_get_test.rb +++ b/test/integration/webdav/dmsf_webdav_get_test.rb @@ -66,7 +66,7 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest assert !response.body.match(@project1.identifier).nil?, "Expected to find project #{@project1.identifier} in return data" Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) + project1_uri = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) get '/dmsf/webdav', nil, @admin assert_response :success @@ -96,7 +96,7 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest assert_response :success Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin assert_response 404 diff --git a/test/integration/webdav/dmsf_webdav_head_test.rb b/test/integration/webdav/dmsf_webdav_head_test.rb index 211911af..5f38370b 100644 --- a/test/integration/webdav/dmsf_webdav_head_test.rb +++ b/test/integration/webdav/dmsf_webdav_head_test.rb @@ -35,7 +35,7 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' # Temporarily enable project names Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - @project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + @project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false DmsfFile.storage_path = File.expand_path '../../../fixtures/files', __FILE__ User.current = nil diff --git a/test/integration/webdav/dmsf_webdav_mkcol_test.rb b/test/integration/webdav/dmsf_webdav_mkcol_test.rb index ebe5751d..bdaf4a67 100644 --- a/test/integration/webdav/dmsf_webdav_mkcol_test.rb +++ b/test/integration/webdav/dmsf_webdav_mkcol_test.rb @@ -105,7 +105,7 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest assert_response :success Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test2", nil, @jsmith assert_response 404 diff --git a/test/integration/webdav/dmsf_webdav_move_test.rb b/test/integration/webdav/dmsf_webdav_move_test.rb index aeaf4678..96105fd7 100644 --- a/test/integration/webdav/dmsf_webdav_move_test.rb +++ b/test/integration/webdav/dmsf_webdav_move_test.rb @@ -135,7 +135,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest def test_move_to_new_filename_with_project_names file = DmsfFile.find_by_id 1 Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) new_name = "#{file.name}.moved" assert_difference 'file.dmsf_file_revisions.count', +1 do @@ -179,7 +179,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest file = DmsfFile.find_by_id 1 folder = DmsfFolder.find_by_id 1 Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) assert_kind_of DmsfFile, file assert_kind_of DmsfFolder, folder diff --git a/test/integration/webdav/dmsf_webdav_options_test.rb b/test/integration/webdav/dmsf_webdav_options_test.rb index ae732d97..f213b495 100644 --- a/test/integration/webdav/dmsf_webdav_options_test.rb +++ b/test/integration/webdav/dmsf_webdav_options_test.rb @@ -149,7 +149,7 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest assert_response :success Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin.merge!({:HTTP_USER_AGENT => "Other"}) assert_response 404 diff --git a/test/integration/webdav/dmsf_webdav_propfind_test.rb b/test/integration/webdav/dmsf_webdav_propfind_test.rb index 54f51779..9eb86771 100644 --- a/test/integration/webdav/dmsf_webdav_propfind_test.rb +++ b/test/integration/webdav/dmsf_webdav_propfind_test.rb @@ -125,8 +125,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_no_match "#{@project1.identifier}", response.body # but the project name should match - p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) - p1name_uri = URI.encode(p1name, /\W/) + p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) + p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body assert_match "#{p1name}", response.body end @@ -167,8 +167,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest @admin.merge!({:HTTP_DEPTH => "0"}) assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) - p1name_uri = URI.encode(p1name, /\W/) + p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) + p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, @admin.merge!({:HTTP_DEPTH => "0"}) @@ -212,8 +212,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest @admin.merge!({:HTTP_DEPTH => "1"}) assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1) - p1name_uri = URI.encode(p1name, /\W/) + p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) + p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, @admin.merge!({:HTTP_DEPTH => "1"}) @@ -248,7 +248,6 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_match "#{@file10.name}", response.body end - def test_propfind_depth0_on_project1_for_admin_with_cache RedmineDmsf::Webdav::Cache.init_testcache diff --git a/test/integration/webdav/dmsf_webdav_put_test.rb b/test/integration/webdav/dmsf_webdav_put_test.rb index b111debb..eb5b28fe 100644 --- a/test/integration/webdav/dmsf_webdav_put_test.rb +++ b/test/integration/webdav/dmsf_webdav_put_test.rb @@ -101,7 +101,7 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest assert file, 'Check for files existance' Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) assert_response 409 @@ -154,7 +154,7 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest assert file, 'File test-1234 was not found in projects dmsf folder.' Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_display_name(@project1), /\W/) + project1_uri = URI.encode(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1), /\W/) put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) assert_response 409 put "/dmsf/webdav/#{project1_uri}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) From fd02c66fec26711f8178ba0272d9801ec1fed23d Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Wed, 15 Feb 2017 23:02:27 +0100 Subject: [PATCH 5/7] Added test for cache when using project names. --- .../webdav/dmsf_webdav_propfind_test.rb | 90 ++++++++++++++----- 1 file changed, 69 insertions(+), 21 deletions(-) diff --git a/test/integration/webdav/dmsf_webdav_propfind_test.rb b/test/integration/webdav/dmsf_webdav_propfind_test.rb index 9eb86771..68c5d2ff 100644 --- a/test/integration/webdav/dmsf_webdav_propfind_test.rb +++ b/test/integration/webdav/dmsf_webdav_propfind_test.rb @@ -43,6 +43,11 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + + # Temporarily enable project names to generate names for project1 + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + @project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) + @project1_uri = URI.encode(@project1_name, /\W/) Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false RedmineDmsf::Webdav::Cache.init_nullcache end @@ -125,10 +130,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert_no_match "#{@project1.identifier}", response.body # but the project name should match - p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) - p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body - assert_match "#{p1name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/", response.body + assert_match "#{@project1_name}", response.body end def test_propfind_depth0_on_project1_for_non_member @@ -167,10 +170,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest @admin.merge!({:HTTP_DEPTH => "0"}) assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) - p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) - - xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, + xml_http_request :propfind, "/dmsf/webdav/#{@project1_uri}", nil, @admin.merge!({:HTTP_DEPTH => "0"}) assert_response 207 # MultiStatus assert_no_match "http://www.example.com:80/dmsf/webdav/", response.body @@ -178,8 +178,8 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest # Project assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body assert_no_match "#{@project1.identifier}", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body - assert_match "#{p1name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/", response.body + assert_match "#{@project1_name}", response.body end def test_propfind_depth1_on_project1_for_admin @@ -212,10 +212,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest @admin.merge!({:HTTP_DEPTH => "1"}) assert_response 404 - p1name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) - p1name_uri = URI.encode(p1name, RedmineDmsf::Webdav::ProjectResource::PROJECT_NAME_FILTER) - - xml_http_request :propfind, "/dmsf/webdav/#{p1name_uri}", nil, + xml_http_request :propfind, "/dmsf/webdav/#{@project1_uri}", nil, @admin.merge!({:HTTP_DEPTH => "1"}) assert_response 207 # MultiStatus @@ -225,29 +222,80 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest # Project assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body assert_no_match "#{@project1.identifier}", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/", response.body - assert_match "#{p1name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/", response.body + assert_match "#{@project1_name}", response.body # Folders assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}/", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@folder1.title}/", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/#{@folder1.title}/", response.body assert_match "#{@folder1.title}", response.body assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}/", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@folder6.title}/", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/#{@folder6.title}/", response.body assert_match "#{@folder6.title}", response.body # Files assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file1.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/#{@file1.name}", response.body assert_match "#{@file1.name}", response.body assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file9.name}", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file9.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/#{@file9.name}", response.body assert_match "#{@file9.name}", response.body assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file10.name}", response.body - assert_match "http://www.example.com:80/dmsf/webdav/#{p1name_uri}/#{@file10.name}", response.body + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/#{@file10.name}", response.body assert_match "#{@file10.name}", response.body end + def test_propfind_depth1_on_root_for_admin_with_project_names_and_cache + RedmineDmsf::Webdav::Cache.init_testcache + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + + # PROPSTATS for / and project1 should be cached. + assert_difference 'RedmineDmsf::Webdav::Cache.cache.instance_variable_get(:@data).count', +2 do + xml_http_request :propfind, "/dmsf/webdav/", nil, + @admin.merge!({:HTTP_DEPTH => "1"}) + end + + assert_response 207 # MultiStatus + assert_match "http://www.example.com:80/dmsf/webdav/", response.body + assert_match "/", response.body + + # project.identifier should not match when using project names + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body + assert_no_match "#{@project1.identifier}", response.body + + # but the project name should match + assert_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/", response.body + assert_match "#{@project1_name}", response.body + + # Rename project1 + @project1.name = "Online Cookbook" + @project1.save! + project1_new_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) + project1_new_uri = URI.encode(project1_new_name, /\W/) + + # PROPSTATS for / is already cached, but a new PROPSTATS should be cached for project1 + assert_difference 'RedmineDmsf::Webdav::Cache.cache.instance_variable_get(:@data).count', +1 do + xml_http_request :propfind, "/dmsf/webdav/", nil, + @admin.merge!({:HTTP_DEPTH => "1"}) + end + + assert_response 207 # MultiStatus + assert_match "http://www.example.com:80/dmsf/webdav/", response.body + assert_match "/", response.body + + # project.identifier should not match when using project names + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/", response.body + assert_no_match "#{@project1.identifier}", response.body + + # old project name should not match + assert_no_match "http://www.example.com:80/dmsf/webdav/#{@project1_uri}/", response.body + assert_no_match "#{@project1_name}", response.body + + # but new project name should match + assert_match "http://www.example.com:80/dmsf/webdav/#{project1_new_uri}/", response.body + assert_match "#{project1_new_name}", response.body + end + def test_propfind_depth0_on_project1_for_admin_with_cache RedmineDmsf::Webdav::Cache.init_testcache From 49fa536fb8b178e59197035586e4502ec3b3da6e Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Thu, 16 Feb 2017 21:40:22 +0100 Subject: [PATCH 6/7] Fixed filter for invalid characters in project name. --- lib/redmine_dmsf/webdav/project_resource.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index d1b7875c..aa6dc3f6 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -109,13 +109,16 @@ module RedmineDmsf self.project.id if self.project end - # Characters that MATCH this regex will be replaced by '_' - PROJECT_NAME_FILTER = /\W/ + # Characters that MATCH this regex will be replaced with dots, no more than one dot in a row. + INVALID_CHARACTERS = /[\/\\\?":<>#%\*]/.freeze # = / \ ? " : < > # % * def self.create_project_name(p) use_project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] if use_project_names - "#{p.name.gsub(PROJECT_NAME_FILTER, "_")} [#{p.id}]" unless p.nil? + # 1. Invalid characters are replaced with a dot. + # 2. Two or more dots in a row are replaced with a single dot. + # (3. Windows WebClient does not like a dot at the end, but since the project id tag is appended this is not a problem.) + "#{p.name.gsub(INVALID_CHARACTERS, ".").gsub(/\.{2,}/, ".")} [#{p.id}]" unless p.nil? else p.identifier unless p.nil? end From 8e8f142792a05f41a639600bfb01d2c11297e4a4 Mon Sep 17 00:00:00 2001 From: "COLA@Redmine.local" Date: Mon, 20 Feb 2017 09:59:09 +0100 Subject: [PATCH 7/7] Added #, % and * to invalid characters in folder/file names. --- app/models/dmsf_folder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/dmsf_folder.rb b/app/models/dmsf_folder.rb index b1284836..f2342a1a 100644 --- a/app/models/dmsf_folder.rb +++ b/app/models/dmsf_folder.rb @@ -43,7 +43,7 @@ class DmsfFolder < ActiveRecord::Base has_many :locks, -> { where(entity_type: 1).order("#{DmsfLock.table_name}.updated_at DESC") }, :class_name => 'DmsfLock', :foreign_key => 'entity_id', :dependent => :destroy - INVALID_CHARACTERS = /\A[^\/\\\?":<>]*\z/.freeze + INVALID_CHARACTERS = /\A[^\/\\\?":<>#%\*]*\z/.freeze STATUS_DELETED = 1.freeze STATUS_ACTIVE = 0.freeze AVAILABLE_COLUMNS = %w(id title extension size modified version workflow author).freeze