diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index 0149ce92..70789fd2 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -59,7 +59,7 @@ module RedmineDmsf elsif subproject # Projects load_projects subproject.children - if project && project.module_enabled?('dmsf') + if subproject.module_enabled?(:dmsf) # Folders if User.current.allowed_to?(:view_dmsf_folders, project) subproject.dmsf_folders.visible.pluck(:title).each do |title| diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index a3daf0ac..782768b2 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -35,13 +35,19 @@ module RedmineDmsf if project # Sub-projects load_projects project.children - # Folders - project.dmsf_folders.visible.pluck(:title).each do |title| - @children.push child(title) - end - # Files - project.dmsf_files.visible.pluck(:name).each do |name| - @children.push child(name) + if project.module_enabled?(:dmsf) + # Folders + if User.current.allowed_to?(:view_dmsf_folders, project) + project.dmsf_folders.visible.pluck(:title).each do |title| + @children.push child(title) + end + end + # Files + if User.current.allowed_to?(:view_dmsf_files, project) + project.dmsf_files.visible.pluck(:name).each do |name| + @children.push child(name) + end + end end end end diff --git a/test/integration/webdav/dmsf_webdav_get_test.rb b/test/integration/webdav/dmsf_webdav_get_test.rb index 3f89fd7e..dfe3f3a5 100644 --- a/test/integration/webdav/dmsf_webdav_get_test.rb +++ b/test/integration/webdav/dmsf_webdav_get_test.rb @@ -25,7 +25,7 @@ require File.expand_path('../../../test_helper', __FILE__) class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, - :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions + :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions def setup @admin = credentials 'admin' @@ -34,6 +34,9 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest @project2 = Project.find 2 @project3 = Project.find 3 @file1 = DmsfFile.find 1 + @file2 = DmsfFile.find 2 + @folder1 = DmsfFolder.find 1 + @folder3 = DmsfFolder.find 3 @folder10 = DmsfFolder.find 10 @file12 = DmsfFile.find 12 @role = Role.find_by(name: 'Manager') @@ -67,66 +70,104 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest assert_kind_of Project, @project2 assert_kind_of Project, @project3 assert_kind_of DmsfFile, @file1 + assert_kind_of DmsfFile, @file2 assert_kind_of DmsfFile, @file12 + assert_kind_of DmsfFolder, @folder1 + assert_kind_of DmsfFolder, @folder3 assert_kind_of DmsfFolder, @folder10 assert_kind_of Role, @role end def test_should_deny_anonymous - get '/dmsf/webdav' - assert_response :unauthorized + get '/dmsf/webdav' + assert_response :unauthorized end def test_should_deny_failed_authentication - get '/dmsf/webdav', params: nil, headers: credentials('admin', 'badpassword') - assert_response :unauthorized + get '/dmsf/webdav', params: nil, headers: credentials('admin', 'badpassword') + assert_response :unauthorized end def test_should_permit_authenticated_user - get '/dmsf/webdav', params: nil, headers: @admin - assert_response :success + get '/dmsf/webdav', params: nil, headers: @admin + assert_response :success end def test_should_list_dmsf_enabled_project - get '/dmsf/webdav', params: nil, headers: @admin - assert_response :success - 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_project_name(@project1) - get '/dmsf/webdav', params: nil, headers: @admin - assert_response :success - assert_no_match @project1.identifier, response.body - assert_match project1_uri, response.body + get '/dmsf/webdav', params: nil, headers: @admin + assert_response :success + 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_project_name(@project1) + get '/dmsf/webdav', params: nil, headers: @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', params: nil, headers: @jsmith - assert_response :success - assert response.body.match(@project2.identifier).nil?, - "Unexpected find of project #{@project2.identifier} in return data" + def test_should_list_non_dmsf_enabled_project + @project2.disable_module! :dmsf + get '/dmsf/webdav', params: nil, headers: @jsmith + assert_response :success + assert response.body.match(@project2.identifier) end def test_should_return_status_404_when_project_does_not_exist - @project1.enable_module! :dmsf # Flag module enabled - get '/dmsf/webdav/project_does_not_exist', params: nil, headers: @jsmith - assert_response :not_found + get '/dmsf/webdav/project_does_not_exist', params: nil, headers: @jsmith + assert_response :not_found end - def test_should_return_status_404_when_dmsf_not_enabled - get "/dmsf/webdav/#{@project2.identifier}", params: nil, headers: @jsmith - assert_response :not_found + def test_should_return_status_404_when_dmsf_not_enabled_for_file + get "/dmsf/webdav/#{@project2.identifier}/#{@file2.name}", params: nil, headers: @jsmith + assert_response :not_found + end + + def test_should_return_status_404_when_dmsf_not_enabled_for_folder + get "/dmsf/webdav/#{@project2.identifier}/#{@folder3.title}", params: nil, headers: @jsmith + assert_response :not_found + end + + def test_should_return_status_200_when_dmsf_not_enabled_for_project + assert !@project2.module_enabled?('dmsf') + get "/dmsf/webdav/#{@project2.identifier}", params: nil, headers: @jsmith + assert_response :success + # Folders and files are not listed + assert response.body.match(@file2.name).nil? + assert response.body.match(@folder3.title).nil? + end + + def test_should_not_list_files_without_permissions + assert @project1.module_enabled?('dmsf') + @role.add_permission! :view_dmsf_folders + @role.remove_permission! :view_dmsf_files + get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith + assert_response :success + # Files are not listed + assert response.body.match(@file1.name).nil? + assert response.body.match(@folder1.title) + end + + def test_should_not_list_folders_without_permissions + assert @project1.module_enabled?('dmsf') + @role.remove_permission! :view_dmsf_folders + @role.add_permission! :view_dmsf_files + get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith + assert_response :success + # Folders are not listed + assert response.body.match(@file1.name) + assert response.body.match(@folder1.title).nil? end def test_download_file_from_dmsf_enabled_project - get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin - assert_response :success - Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) - get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin - assert_response :not_found - get "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin - assert_response :success + get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin + assert_response :success + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) + get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin + assert_response :not_found + get "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin + assert_response :success end def test_should_list_dmsf_contents_within_project @@ -135,55 +176,56 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest folder = DmsfFolder.find_by(id: 1) assert_not_nil folder assert response.body.match(folder.title), - "Expected to find #{folder.title} in return data" + "Expected to find #{folder.title} in return data" file = DmsfFile.find_by(id: 1) assert_not_nil file assert response.body.match(file.name), - "Expected to find #{file.name} in return data" + "Expected to find #{file.name} in return data" end def test_user_assigned_to_project_dmsf_module_not_enabled - get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith - assert_response :not_found + get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith + assert_response :success end - def test_user_assigned_to_project_folder_forbidden - @project2.enable_module! :dmsf # Flag module enabled - get "/dmsf/webdav/#{@project2.identifier}", params: nil, headers: @jsmith - assert_response :not_found + def test_user_assigned_to_archived_project + @project1.enable_module! :dmsf + @project1.archive + get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith + assert_response :not_found end def test_user_assigned_to_project_folder_ok - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :view_dmsf_folders - @role.add_permission! :view_dmsf_files - get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith - assert_response :success + @project1.enable_module! :dmsf + @role.add_permission! :view_dmsf_folders + @role.add_permission! :view_dmsf_files + get "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith + assert_response :success end def test_user_assigned_to_project_file_forbidden - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :view_dmsf_folders - get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @jsmith - assert_response :forbidden + @project1.enable_module! :dmsf + @role.add_permission! :view_dmsf_folders + get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @jsmith + assert_response :forbidden end def test_user_assigned_to_project_file_ok - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :view_dmsf_folders - @role.add_permission! :view_dmsf_files - get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @jsmith - assert_response :success + @project1.enable_module! :dmsf + @role.add_permission! :view_dmsf_folders + @role.add_permission! :view_dmsf_files + get "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @jsmith + assert_response :success end def test_get_file_in_subproject - @project3.enable_module! :dmsf # Flag module enabled - get "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, headers: @admin - assert_response :success + @project3.enable_module! :dmsf + get "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, headers: @admin + assert_response :success end def test_get_folder_in_subproject - @project3.enable_module! :dmsf # Flag module enabled + @project3.enable_module! :dmsf get "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, headers: @admin assert_response :success end diff --git a/test/integration/webdav/dmsf_webdav_options_test.rb b/test/integration/webdav/dmsf_webdav_options_test.rb index 140c9109..4d0c6b04 100644 --- a/test/integration/webdav/dmsf_webdav_options_test.rb +++ b/test/integration/webdav/dmsf_webdav_options_test.rb @@ -161,25 +161,12 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest def test_authenticated_options_for_other_user_agent process :options, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_USER_AGENT: 'Other' }) assert_response :success - Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true + project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) - process :options, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_USER_AGENT: 'Other' }) - assert_response :not_found process :options, "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin.merge!({ HTTP_USER_AGENT: 'Other' }) assert_response :success end - def test_authenticated_options_returns_404_for_non_dmsf_enabled_items - @project2.disable_module! :dmsf - process :options, "/dmsf/webdav/#{@project2.identifier}", params: nil, headers: @jsmith - assert_response :not_found - end - - def test_authenticated_options_returns_404_for_not_found - process :options, '/dmsf/webdav/does-not-exist', params: nil, headers: @jsmith - assert_response :not_found - end - def test_options_for_subproject process :options, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: nil, headers: @admin assert_response :success diff --git a/test/integration/webdav/dmsf_webdav_propfind_test.rb b/test/integration/webdav/dmsf_webdav_propfind_test.rb index 426ebcd2..1f8c7c5f 100644 --- a/test/integration/webdav/dmsf_webdav_propfind_test.rb +++ b/test/integration/webdav/dmsf_webdav_propfind_test.rb @@ -117,6 +117,18 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest def test_propfind_depth0_on_project1_for_non_member process :propfind, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @jsmith.merge!({ HTTP_DEPTH: '0' }) + assert_response :success + end + + def test_propfind_depth0_on_folder1_for_non_member + process :propfind, "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: '0' }) + assert_response :not_found + end + + def test_propfind_depth0_on_file1_for_non_member + process :propfind, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: '0' }) assert_response :not_found end diff --git a/test/integration/webdav/dmsf_webdav_put_test.rb b/test/integration/webdav/dmsf_webdav_put_test.rb index 6e43cdd4..fc943b06 100644 --- a/test/integration/webdav/dmsf_webdav_put_test.rb +++ b/test/integration/webdav/dmsf_webdav_put_test.rb @@ -91,7 +91,7 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest def test_put_denied_at_root_level put '/dmsf/webdav/test.txt', params: '1234', headers: @admin.merge!({ content_type: :text }) - assert_response :not_implemented + assert_response :forbidden end def test_put_denied_on_folder @@ -121,46 +121,25 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest end def test_put_failed_as_jsmith_on_non_dmsf_enabled_project + @project2.disable_module! :dmsf put "/dmsf/webdav/#{@project2.identifier}/test-1234.txt", params: '1234', headers: @jsmith.merge!({ content_type: :text }) - assert_response :conflict # Should report conflict, as project 2 technically doesn't exist if not enabled + assert_response :forbidden # Lets check for our file file = DmsfFile.find_file_by_name @project2, nil, 'test-1234.txt' assert_nil file, 'Check for files existance' end def test_put_failed_when_no_permission - @project2.enable_module! :dmsf # Flag module enabled + @project1.enable_module! :dmsf + @role.remove_permission! :file_manipulation put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", params: '1234', headers: @jsmith.merge!({ content_type: :text }) - assert_response :conflict # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist - # to us. - end - - def test_put_failed_when_no_file_manipulation_permission - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :view_dmsf_folders - put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", params: '1234', - headers: @jsmith.merge!({ content_type: :text }) - assert_response :forbidden # We don't hold the permission file_manipulation - so we're unable to do anything - # with files - end - - def test_put_failed_when_no_view_dmsf_folders_permission - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :file_manipulation - # Check we don't have write access even if we do have the file_manipulation permission - put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", params: '1234', - headers: @jsmith.merge!({ content_type: :text }) - assert_response :conflict # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist - # to us. - # Lets check for our file - file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' - assert_nil file, 'File test-1234 was found in projects dmsf folder.' + assert_response :forbidden end def test_put_succeeds_for_non_admin_with_correct_permissions - @project1.enable_module! :dmsf # Flag module enabled + @project1.enable_module! :dmsf @role.add_permission! :view_dmsf_folders @role.add_permission! :file_manipulation put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", params: '1234', @@ -171,11 +150,13 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest assert file, 'File test-1234 was not found in projects dmsf folder.' assert file.last_revision assert_equal file.last_revision.digest_type, 'SHA256' + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true - project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", params: '1234', headers: @jsmith.merge!({ content_type: :text }) assert_response :conflict + + project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) put "/dmsf/webdav/#{project1_uri}/test-1234.txt", params: '1234', headers: @jsmith.merge!({ content_type: :text }) assert_response :created # Now we have permissions end