REST API and delete Folder/document #847

This commit is contained in:
Karel Picman 2018-04-27 09:04:02 +02:00
parent 06f325d9da
commit 49875a863d
6 changed files with 148 additions and 21 deletions

View File

@ -30,7 +30,7 @@ class DmsfController < ApplicationController
before_action :tree_view, :only => [:delete, :show] before_action :tree_view, :only => [:delete, :show]
before_action :permissions before_action :permissions
accept_api_auth :show, :create, :save accept_api_auth :show, :create, :save, :delete
skip_before_action :verify_authenticity_token, if: -> { request.headers['HTTP_X_REDMINE_API_KEY'].present? } skip_before_action :verify_authenticity_token, if: -> { request.headers['HTTP_X_REDMINE_API_KEY'].present? }
@ -251,16 +251,22 @@ class DmsfController < ApplicationController
def delete def delete
commit = params[:commit] == 'yes' commit = params[:commit] == 'yes'
if @folder.delete(commit) result = @folder.delete(commit)
if result
flash[:notice] = l(:notice_folder_deleted) flash[:notice] = l(:notice_folder_deleted)
else else
flash[:error] = @folder.errors.full_messages.to_sentence flash[:error] = @folder.errors.full_messages.to_sentence
end end
respond_to do |format|
format.html {
if commit || @tree_view if commit || @tree_view
redirect_to :back redirect_to :back
else else
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder.dmsf_folder) redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder.dmsf_folder)
end end
}
format.api { result ? render_api_ok : render_validation_errors(@folder) }
end
end end
def restore def restore

View File

@ -29,7 +29,7 @@ class DmsfFilesController < ApplicationController
before_action :tree_view, :only => [:delete] before_action :tree_view, :only => [:delete]
before_action :permissions before_action :permissions
accept_api_auth :show, :view accept_api_auth :show, :view, :delete
helper :all helper :all
helper :dmsf_workflows helper :dmsf_workflows
@ -191,7 +191,8 @@ class DmsfFilesController < ApplicationController
def delete def delete
if @file if @file
commit = params[:commit] == 'yes' commit = params[:commit] == 'yes'
if @file.delete(commit) result = @file.delete(commit)
if result
flash[:notice] = l(:notice_file_deleted) flash[:notice] = l(:notice_file_deleted)
unless commit unless commit
begin begin
@ -216,11 +217,16 @@ class DmsfFilesController < ApplicationController
Rails.logger.error msg Rails.logger.error msg
end end
end end
respond_to do |format|
format.html {
if commit || (@tree_view && params[:details].blank?) if commit || (@tree_view && params[:details].blank?)
redirect_to :back redirect_to :back
else else
redirect_to dmsf_folder_path(:id => @project, :folder_id => @file.dmsf_folder) redirect_to dmsf_folder_path(:id => @project, :folder_id => @file.dmsf_folder)
end end
}
format.api { result ? render_api_ok : render_validation_errors(@file) }
end
end end
def delete_revision def delete_revision

View File

@ -221,7 +221,7 @@
<% unless @system_folder %> <% unless @system_folder %>
<% other_formats_links do |f| %> <% other_formats_links do |f| %>
<%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '350px'); return false;" %> <%= f.link_to 'CSV', :onclick => "showModal('csv-export-options', '350px'); return false;" %>
<% end %> <% end %>
<% end %> <% end %>

View File

@ -26,9 +26,11 @@
# BOTH XML and JSON formats are supported. # BOTH XML and JSON formats are supported.
# Just replace .xml with .json # Just replace .xml with .json
#
# Uncomment a corresponding line to the case you would like to test
# 1. List of documents in a given folder or the root folder # 1. List of documents in a given folder or the root folder
curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml #curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml
#curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml?folder_id=5155 #curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:3000/projects/12/dmsf.xml?folder_id=5155
# 2. Get a document # 2. Get a document
@ -42,11 +44,11 @@ curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:
#curl --data-binary "@cat.gif" -H "Content-Type: application/octet-stream" -X POST -u ${1}:${2} http://localhost:3000/projects/12/dmsf/upload.xml?filename=cat.gif #curl --data-binary "@cat.gif" -H "Content-Type: application/octet-stream" -X POST -u ${1}:${2} http://localhost:3000/projects/12/dmsf/upload.xml?filename=cat.gif
#curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2} http://localhost:3000/projects/12/dmsf/commit.xml #curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2} http://localhost:3000/projects/12/dmsf/commit.xml
# 5. list folder contents & check folder existence (by folder title) # 5. List folder content & check folder existence (by folder title)
# curl -v -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/projects/1/dmsf.json?folder_title=Updated%20title # curl -v -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/projects/1/dmsf.json?folder_title=Updated%20title
# 6. list folder contents & check folder existence (by folder id) # 6. List folder content & check folder existence (by folder id)
# curl -v -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: USERS_API_KE" http://localhost:3000/projects/1/dmsf.json?folder_id=3 # curl -v -H "Content-Type: application/json" -X GET -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/projects/1/dmsf.json?folder_id=3
# both returns 404 not found, or json with following structure: # both returns 404 not found, or json with following structure:
# { # {
# "dmsf":{ # "dmsf":{
@ -67,7 +69,7 @@ curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:
# } # }
#} #}
# 7. update folder # 7. Update a folder
# 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?folder_id=#{folder_id} # 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?folder_id=#{folder_id}
# update-folder-payload.json # update-folder-payload.json
@ -77,3 +79,15 @@ curl -v -H "Content-Type: application/xml" -X GET -u ${1}:${2} http://localhost:
# "description": description # "description": description
# }, # },
# } # }
# 8. Delete a folder
# a) Move to trash only
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/projects/2387/dmsf/delete.xml?folder_id=#{folder_id}
# b) Delete permanently
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} "http://localhost:3000/projects/2387/dmsf/delete.xml?folder_id=#{folder_id}&commit=yes"
# 8. Delete a file
# a) Move to trash only
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml
# b) Delete permanently
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml?commit=yes"

View File

@ -21,10 +21,12 @@
require File.expand_path('../../../test_helper', __FILE__) require File.expand_path('../../../test_helper', __FILE__)
class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n
fixtures :projects, :users, :dmsf_files, :dmsf_file_revisions, :members, :roles, :member_roles fixtures :projects, :users, :dmsf_files, :dmsf_file_revisions, :members, :roles, :member_roles
def setup def setup
@admin = User.find_by_id 1
@jsmith = User.find_by_id 2 @jsmith = User.find_by_id 2
@file1 = DmsfFile.find_by_id 1 @file1 = DmsfFile.find_by_id 1
Setting.rest_api_enabled = '1' Setting.rest_api_enabled = '1'
@ -34,6 +36,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
end end
def test_truth def test_truth
assert_kind_of User, @admin
assert_kind_of User, @jsmith assert_kind_of User, @jsmith
assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file1
assert_kind_of Role, @role assert_kind_of Role, @role
@ -109,7 +112,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
</attachments> </attachments>
} }
assert_difference 'DmsfFileRevision.count', +1 do assert_difference 'DmsfFileRevision.count', +1 do
post "/projects/#{@project1.id}/dmsf/commit.xml?&key=#{token.value}", payload, {"CONTENT_TYPE" => 'application/xml'} post "/projects/#{@project1.id}/dmsf/commit.xml?key=#{token.value}", payload, {"CONTENT_TYPE" => 'application/xml'}
end end
#<?xml version="1.0" encoding="UTF-8"?> #<?xml version="1.0" encoding="UTF-8"?>
#<dmsf_files total_count="1" type="array"> #<dmsf_files total_count="1" type="array">
@ -128,4 +131,50 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
error e.message error e.message
end end
end end
def test_delete_file
@role.add_permission! :file_delete
token = Token.create!(:user => @jsmith, :action => 'api')
# 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}", {'CONTENT_TYPE' => 'application/xml'}
assert_response :success
@file1.reload
assert_equal DmsfFile::STATUS_DELETED, @file1.deleted
assert_equal User.current, @file1.deleted_by_user
end
def test_delete_file_no_permissions
token = Token.create!(:user => @jsmith, :action => 'api')
# 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}", {'CONTENT_TYPE' => 'application/xml'}
assert_response :forbidden
end
def test_delete_folder_commit_yes
@role.add_permission! :file_delete
token = Token.create!(:user => @jsmith, :action => 'api')
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml&commit=yes
delete "/dmsf/files/#{@file1.id}.xml?key=#{token.value}&commit=yes", {'CONTENT_TYPE' => 'application/xml'}
assert_response :success
assert_nil DmsfFile.find_by_id(@file1.id)
end
def test_delete_file_locked
@role.add_permission! :file_delete
User.current = @admin
@file1.lock!
User.current = @jsmith
token = Token.create!(:user => @jsmith, :action => 'api')
# 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}", {'CONTENT_TYPE' => 'application/xml'}
assert_response 422
# <?xml version="1.0" encoding="UTF-8"?>
# <errors type="array">
# <error>Locked by Admin</error>
# </errors>
assert_select 'errors > error', :text => l(:title_locked_by_user, user: @admin.name)
@file1.reload
assert_equal DmsfFile::STATUS_ACTIVE, @file1.deleted
end
end end

View File

@ -21,12 +21,14 @@
require File.expand_path('../../../test_helper', __FILE__) require File.expand_path('../../../test_helper', __FILE__)
class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :projects, :users, :members, :roles, fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :projects, :users, :members, :roles,
:member_roles :member_roles
def setup def setup
Setting.plugin_redmine_dmsf['dmsf_storage_directory'] = File.expand_path '../../../fixtures/files', __FILE__ Setting.plugin_redmine_dmsf['dmsf_storage_directory'] = File.expand_path '../../../fixtures/files', __FILE__
@admin = User.find_by_id 1
@jsmith = User.find_by_id 2 @jsmith = User.find_by_id 2
@file1 = DmsfFile.find_by_id 1 @file1 = DmsfFile.find_by_id 1
@folder1 = DmsfFolder.find_by_id 1 @folder1 = DmsfFolder.find_by_id 1
@ -37,6 +39,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
end end
def test_truth def test_truth
assert_kind_of User, @admin
assert_kind_of User, @jsmith assert_kind_of User, @jsmith
assert_kind_of DmsfFolder, @folder1 assert_kind_of DmsfFolder, @folder1
assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file1
@ -91,7 +94,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
<dmsf_folder_id/> <dmsf_folder_id/>
</dmsf_folder> </dmsf_folder>
} }
post "/projects/#{@project1.id}/dmsf/create.xml?&key=#{token.value}", payload, {'CONTENT_TYPE' => 'application/xml'} post "/projects/#{@project1.id}/dmsf/create.xml?key=#{token.value}", payload, {'CONTENT_TYPE' => 'application/xml'}
assert_response :success assert_response :success
# <?xml version="1.0" encoding="UTF-8"?> # <?xml version="1.0" encoding="UTF-8"?>
# <dmsf_folder> # <dmsf_folder>
@ -195,4 +198,53 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
assert_select 'dmsf_folder > title', :text => 'rest_api' assert_select 'dmsf_folder > title', :text => 'rest_api'
end end
def test_delete_folder
@role.add_permission! :folder_manipulation
token = Token.create!(:user => @jsmith, :action => 'api')
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
delete "/projects/#{@project1.id}/dmsf/delete.xml?key=#{token.value}&folder_id=#{@folder1.id}",
{'CONTENT_TYPE' => 'application/xml'}
assert_response :success
@folder1.reload
assert_equal DmsfFolder::STATUS_DELETED, @folder1.deleted
assert_equal User.current, @folder1.deleted_by_user
end
def test_delete_folder_no_permission
token = Token.create!(:user => @jsmith, :action => 'api')
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
delete "/projects/#{@project1.id}/dmsf/delete.xml?key=#{token.value}&folder_id=#{@folder1.id}",
{'CONTENT_TYPE' => 'application/xml'}
assert_response :forbidden
end
def test_delete_folder_commit_yes
@role.add_permission! :folder_manipulation
token = Token.create!(:user => @jsmith, :action => 'api')
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
delete "/projects/#{@project1.id}/dmsf/delete.xml?key=#{token.value}&folder_id=#{@folder1.id}&commit=yes",
{'CONTENT_TYPE' => 'application/xml'}
assert_response :success
assert_nil DmsfFolder.find_by_id(@folder1.id)
end
def test_delete_folder_locked
@role.add_permission! :folder_manipulation
User.current = @admin
@folder1.lock!
User.current = @jsmith
token = Token.create!(:user => @jsmith, :action => 'api')
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
delete "/projects/#{@project1.id}/dmsf/delete.xml?key=#{token.value}&folder_id=#{@folder1.id}",
{'CONTENT_TYPE' => 'application/xml'}
assert_response 422
# <?xml version="1.0" encoding="UTF-8"?>
# <errors type="array">
# <error>Folder is locked</error>
# </errors>
assert_select 'errors > error', :text => l(:error_folder_is_locked)
@folder1.reload
assert_equal DmsfFolder::STATUS_ACTIVE, @folder1.deleted
end
end end