From 998afa5f74558be215a924d95aa131a69831ca43 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 1 Mar 2017 14:35:48 +0100 Subject: [PATCH] API: Respect the 'If-Unmodified-Since' for delete endpoints --- lib/api/access_requests.rb | 3 +++ lib/api/award_emoji.rb | 1 + lib/api/boards.rb | 1 + lib/api/broadcast_messages.rb | 1 + lib/api/deploy_keys.rb | 2 ++ lib/api/environments.rb | 1 + lib/api/groups.rb | 2 ++ lib/api/helpers.rb | 8 ++++++++ lib/api/issues.rb | 2 ++ lib/api/labels.rb | 2 ++ lib/api/members.rb | 3 ++- lib/api/merge_requests.rb | 2 ++ lib/api/notes.rb | 2 ++ lib/api/project_hooks.rb | 2 ++ lib/api/project_snippets.rb | 2 ++ lib/api/projects.rb | 2 ++ lib/api/runners.rb | 2 ++ lib/api/services.rb | 2 ++ lib/api/snippets.rb | 1 + lib/api/system_hooks.rb | 2 ++ lib/api/triggers.rb | 2 ++ lib/api/users.rb | 28 ++++++++++++++++++++++++++++ 22 files changed, 72 insertions(+), 1 deletion(-) diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index cdacf9839e5..0c5b8862d79 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -67,6 +67,9 @@ module API end delete ":id/access_requests/:user_id" do source = find_source(source_type, params[:id]) + member = source.public_send(:requesters).find_by!(user_id: params[:user_id]) + + check_unmodified_since(member.updated_at) status 204 ::Members::DestroyService.new(source, current_user, params) diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 5a028fc9d0b..51a8587d26e 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -85,6 +85,7 @@ module API end delete "#{endpoint}/:award_id" do award = awardable.award_emoji.find(params[:award_id]) + check_unmodified_since(award.updated_at) unauthorized! unless award.user == current_user || current_user.admin? diff --git a/lib/api/boards.rb b/lib/api/boards.rb index 5a2d7a681e3..d36df77dc6c 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -124,6 +124,7 @@ module API authorize!(:admin_list, user_project) list = board_lists.find(params[:list_id]) + check_unmodified_since(list.updated_at) service = ::Boards::Lists::DestroyService.new(user_project, current_user) diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb index 9980aec4752..352972b584a 100644 --- a/lib/api/broadcast_messages.rb +++ b/lib/api/broadcast_messages.rb @@ -90,6 +90,7 @@ module API end delete ':id' do message = find_message + check_unmodified_since(message.updated_at) status 204 message.destroy diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 42e7c1486b0..971cc816454 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -125,6 +125,8 @@ module API key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id]) not_found!('Deploy Key') unless key + check_unmodified_since(key.updated_at) + status 204 key.destroy end diff --git a/lib/api/environments.rb b/lib/api/environments.rb index c774a5c6685..3fc423ae79a 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -78,6 +78,7 @@ module API authorize! :update_environment, user_project environment = user_project.environments.find(params[:environment_id]) + check_unmodified_since(environment.updated_at) status 204 environment.destroy diff --git a/lib/api/groups.rb b/lib/api/groups.rb index e56427304a6..c9b32a85487 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -117,6 +117,8 @@ module API delete ":id" do group = find_group!(params[:id]) authorize! :admin_group, group + + check_unmodified_since(group.updated_at) status 204 ::Groups::DestroyService.new(group, current_user).execute diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index b56fd2388b3..1c74a14d91c 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -11,6 +11,14 @@ module API declared(params, options).to_h.symbolize_keys end + def check_unmodified_since(last_modified) + if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) if headers.key?('If-Unmodified-Since') rescue nil + + if if_unmodified_since && if_unmodified_since < last_modified + render_api_error!('412 Precondition Failed', 412) + end + end + def current_user return @current_user if defined?(@current_user) diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 4cec1145f3a..cee9898d3a6 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -230,6 +230,8 @@ module API not_found!('Issue') unless issue authorize!(:destroy_issue, issue) + check_unmodified_since(issue.updated_at) + status 204 issue.destroy end diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 4520c98d951..45fa57fdf55 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -56,6 +56,8 @@ module API label = user_project.labels.find_by(title: params[:name]) not_found!('Label') unless label + check_unmodified_since(label.updated_at) + status 204 label.destroy end diff --git a/lib/api/members.rb b/lib/api/members.rb index bb970b7cd54..5634f123eca 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -94,7 +94,8 @@ module API delete ":id/members/:user_id" do source = find_source(source_type, params[:id]) # Ensure that memeber exists - source.members.find_by!(user_id: params[:user_id]) + member = source.members.find_by!(user_id: params[:user_id]) + check_unmodified_since(member.updated_at) status 204 ::Members::DestroyService.new(source, current_user, declared_params).execute diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 8810d4e441d..c6fecc1aa6c 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -164,6 +164,8 @@ module API merge_request = find_project_merge_request(params[:merge_request_iid]) authorize!(:destroy_merge_request, merge_request) + check_unmodified_since(merge_request.updated_at) + status 204 merge_request.destroy end diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 4e4e473994b..58d71787aca 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -129,7 +129,9 @@ module API end delete ":id/#{noteables_str}/:noteable_id/notes/:note_id" do note = user_project.notes.find(params[:note_id]) + authorize! :admin_note, note + check_unmodified_since(note.updated_at) status 204 ::Notes::DestroyService.new(user_project, current_user).execute(note) diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 649dd891f56..74d736fda59 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -96,6 +96,8 @@ module API delete ":id/hooks/:hook_id" do hook = user_project.hooks.find(params.delete(:hook_id)) + check_unmodified_since(hook.updated_at) + status 204 hook.destroy end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index f3d905b0068..645162d564d 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -116,6 +116,8 @@ module API not_found!('Snippet') unless snippet authorize! :admin_project_snippet, snippet + check_unmodified_since(snippet.updated_at) + status 204 snippet.destroy end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 15c3832b032..eab0ca0b3c9 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -334,6 +334,8 @@ module API desc 'Remove a project' delete ":id" do authorize! :remove_project, user_project + check_unmodified_since(user_project.updated_at) + ::Projects::DestroyService.new(user_project, current_user, {}).async_execute accepted! diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 31f940fe96b..e3b2eb904b7 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -77,7 +77,9 @@ module API end delete ':id' do runner = get_runner(params[:id]) + authenticate_delete_runner!(runner) + check_unmodified_since(runner.updated_at) status 204 runner.destroy! diff --git a/lib/api/services.rb b/lib/api/services.rb index 843c05ae32e..4fef3383e5e 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -655,6 +655,8 @@ module API end delete ":id/services/:service_slug" do service = user_project.find_or_initialize_service(params[:service_slug].underscore) + # Todo, not sure + check_unmodified_since(service.updated_at) attrs = service_attributes(service).inject({}) do |hash, key| hash.merge!(key => nil) diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb index 35ece56c65c..7107b3d669c 100644 --- a/lib/api/snippets.rb +++ b/lib/api/snippets.rb @@ -122,6 +122,7 @@ module API return not_found!('Snippet') unless snippet authorize! :destroy_personal_snippet, snippet + check_unmodified_since(snippet.updated_at) status 204 snippet.destroy diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb index c0179037440..64066a75b15 100644 --- a/lib/api/system_hooks.rb +++ b/lib/api/system_hooks.rb @@ -66,6 +66,8 @@ module API hook = SystemHook.find_by(id: params[:id]) not_found!('System hook') unless hook + check_unmodified_since(hook.updated_at) + status 204 hook.destroy end diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb index edfdb63d183..4ae70c65759 100644 --- a/lib/api/triggers.rb +++ b/lib/api/triggers.rb @@ -140,6 +140,8 @@ module API trigger = user_project.triggers.find(params.delete(:trigger_id)) return not_found!('Trigger') unless trigger + check_unmodified_since(trigger.updated_at) + status 204 trigger.destroy end diff --git a/lib/api/users.rb b/lib/api/users.rb index e2019d6d512..942bb72cf97 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -230,7 +230,12 @@ module API key = user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key +<<<<<<< HEAD status 204 +======= + check_unmodified_since(key.updated_at) + +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints key.destroy end @@ -287,7 +292,14 @@ module API email = user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email +<<<<<<< HEAD Emails::DestroyService.new(user, email: email.email).execute +======= + check_unmodified_since(email.updated_at) + + email.destroy + user.update_secondary_emails! +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end desc 'Delete a user. Available only for admins.' do @@ -299,11 +311,18 @@ module API end delete ":id" do authenticated_as_admin! + user = User.find_by(id: params[:id]) not_found!('User') unless user +<<<<<<< HEAD status 204 user.delete_async(deleted_by: current_user, params: params) +======= + check_unmodified_since(user.updated_at) + + ::Users::DestroyService.new(current_user).execute(user) +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end desc 'Block a user. Available only for admins.' @@ -481,6 +500,8 @@ module API key = current_user.keys.find_by(id: params[:key_id]) not_found!('Key') unless key + check_unmodified_since(key.updated_at) + status 204 key.destroy end @@ -533,6 +554,7 @@ module API email = current_user.emails.find_by(id: params[:email_id]) not_found!('Email') unless email +<<<<<<< HEAD status 204 Emails::DestroyService.new(current_user, email: email.email).execute end @@ -550,6 +572,12 @@ module API .reorder(last_activity_on: :asc) present paginate(activities), with: Entities::UserActivity +======= + check_unmodified_since(email.updated_at) + + email.destroy + current_user.update_secondary_emails! +>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints end end end