Skip to content

Commit 998afa5

Browse files
committed
API: Respect the 'If-Unmodified-Since' for delete endpoints
1 parent 7ccef75 commit 998afa5

22 files changed

+72
-1
lines changed

lib/api/access_requests.rb

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class AccessRequests < Grape::API
6767
end
6868
delete ":id/access_requests/:user_id" do
6969
source = find_source(source_type, params[:id])
70+
member = source.public_send(:requesters).find_by!(user_id: params[:user_id])
71+
72+
check_unmodified_since(member.updated_at)
7073

7174
status 204
7275
::Members::DestroyService.new(source, current_user, params)

lib/api/award_emoji.rb

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class AwardEmoji < Grape::API
8585
end
8686
delete "#{endpoint}/:award_id" do
8787
award = awardable.award_emoji.find(params[:award_id])
88+
check_unmodified_since(award.updated_at)
8889

8990
unauthorized! unless award.user == current_user || current_user.admin?
9091

lib/api/boards.rb

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def board_lists
124124
authorize!(:admin_list, user_project)
125125

126126
list = board_lists.find(params[:list_id])
127+
check_unmodified_since(list.updated_at)
127128

128129
service = ::Boards::Lists::DestroyService.new(user_project, current_user)
129130

lib/api/broadcast_messages.rb

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def find_message
9090
end
9191
delete ':id' do
9292
message = find_message
93+
check_unmodified_since(message.updated_at)
9394

9495
status 204
9596
message.destroy

lib/api/deploy_keys.rb

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ class DeployKeys < Grape::API
125125
key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id])
126126
not_found!('Deploy Key') unless key
127127

128+
check_unmodified_since(key.updated_at)
129+
128130
status 204
129131
key.destroy
130132
end

lib/api/environments.rb

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class Environments < Grape::API
7878
authorize! :update_environment, user_project
7979

8080
environment = user_project.environments.find(params[:environment_id])
81+
check_unmodified_since(environment.updated_at)
8182

8283
status 204
8384
environment.destroy

lib/api/groups.rb

+2
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ def present_groups(groups, options = {})
117117
delete ":id" do
118118
group = find_group!(params[:id])
119119
authorize! :admin_group, group
120+
121+
check_unmodified_since(group.updated_at)
120122

121123
status 204
122124
::Groups::DestroyService.new(group, current_user).execute

lib/api/helpers.rb

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ def declared_params(options = {})
1111
declared(params, options).to_h.symbolize_keys
1212
end
1313

14+
def check_unmodified_since(last_modified)
15+
if_unmodified_since = Time.parse(headers['If-Unmodified-Since']) if headers.key?('If-Unmodified-Since') rescue nil
16+
17+
if if_unmodified_since && if_unmodified_since < last_modified
18+
render_api_error!('412 Precondition Failed', 412)
19+
end
20+
end
21+
1422
def current_user
1523
return @current_user if defined?(@current_user)
1624

lib/api/issues.rb

+2
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ def find_issues(args = {})
230230
not_found!('Issue') unless issue
231231

232232
authorize!(:destroy_issue, issue)
233+
check_unmodified_since(issue.updated_at)
234+
233235
status 204
234236
issue.destroy
235237
end

lib/api/labels.rb

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Labels < Grape::API
5656
label = user_project.labels.find_by(title: params[:name])
5757
not_found!('Label') unless label
5858

59+
check_unmodified_since(label.updated_at)
60+
5961
status 204
6062
label.destroy
6163
end

lib/api/members.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ class Members < Grape::API
9494
delete ":id/members/:user_id" do
9595
source = find_source(source_type, params[:id])
9696
# Ensure that memeber exists
97-
source.members.find_by!(user_id: params[:user_id])
97+
member = source.members.find_by!(user_id: params[:user_id])
98+
check_unmodified_since(member.updated_at)
9899

99100
status 204
100101
::Members::DestroyService.new(source, current_user, declared_params).execute

lib/api/merge_requests.rb

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def handle_merge_request_errors!(errors)
164164
merge_request = find_project_merge_request(params[:merge_request_iid])
165165

166166
authorize!(:destroy_merge_request, merge_request)
167+
check_unmodified_since(merge_request.updated_at)
168+
167169
status 204
168170
merge_request.destroy
169171
end

lib/api/notes.rb

+2
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ class Notes < Grape::API
129129
end
130130
delete ":id/#{noteables_str}/:noteable_id/notes/:note_id" do
131131
note = user_project.notes.find(params[:note_id])
132+
132133
authorize! :admin_note, note
134+
check_unmodified_since(note.updated_at)
133135

134136
status 204
135137
::Notes::DestroyService.new(user_project, current_user).execute(note)

lib/api/project_hooks.rb

+2
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class ProjectHooks < Grape::API
9696
delete ":id/hooks/:hook_id" do
9797
hook = user_project.hooks.find(params.delete(:hook_id))
9898

99+
check_unmodified_since(hook.updated_at)
100+
99101
status 204
100102
hook.destroy
101103
end

lib/api/project_snippets.rb

+2
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ def snippets_for_current_user
116116
not_found!('Snippet') unless snippet
117117

118118
authorize! :admin_project_snippet, snippet
119+
check_unmodified_since(snippet.updated_at)
120+
119121
status 204
120122
snippet.destroy
121123
end

lib/api/projects.rb

+2
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ def present_projects(options = {})
334334
desc 'Remove a project'
335335
delete ":id" do
336336
authorize! :remove_project, user_project
337+
check_unmodified_since(user_project.updated_at)
338+
337339
::Projects::DestroyService.new(user_project, current_user, {}).async_execute
338340

339341
accepted!

lib/api/runners.rb

+2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ class Runners < Grape::API
7777
end
7878
delete ':id' do
7979
runner = get_runner(params[:id])
80+
8081
authenticate_delete_runner!(runner)
82+
check_unmodified_since(runner.updated_at)
8183

8284
status 204
8385
runner.destroy!

lib/api/services.rb

+2
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,8 @@ def service_attributes(service)
655655
end
656656
delete ":id/services/:service_slug" do
657657
service = user_project.find_or_initialize_service(params[:service_slug].underscore)
658+
# Todo, not sure
659+
check_unmodified_since(service.updated_at)
658660

659661
attrs = service_attributes(service).inject({}) do |hash, key|
660662
hash.merge!(key => nil)

lib/api/snippets.rb

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def public_snippets
122122
return not_found!('Snippet') unless snippet
123123

124124
authorize! :destroy_personal_snippet, snippet
125+
check_unmodified_since(snippet.updated_at)
125126

126127
status 204
127128
snippet.destroy

lib/api/system_hooks.rb

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class SystemHooks < Grape::API
6666
hook = SystemHook.find_by(id: params[:id])
6767
not_found!('System hook') unless hook
6868

69+
check_unmodified_since(hook.updated_at)
70+
6971
status 204
7072
hook.destroy
7173
end

lib/api/triggers.rb

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class Triggers < Grape::API
140140
trigger = user_project.triggers.find(params.delete(:trigger_id))
141141
return not_found!('Trigger') unless trigger
142142

143+
check_unmodified_since(trigger.updated_at)
144+
143145
status 204
144146
trigger.destroy
145147
end

lib/api/users.rb

+28
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,12 @@ def find_user(params)
230230
key = user.keys.find_by(id: params[:key_id])
231231
not_found!('Key') unless key
232232

233+
<<<<<<< HEAD
233234
status 204
235+
=======
236+
check_unmodified_since(key.updated_at)
237+
238+
>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints
234239
key.destroy
235240
end
236241

@@ -287,7 +292,14 @@ def find_user(params)
287292
email = user.emails.find_by(id: params[:email_id])
288293
not_found!('Email') unless email
289294

295+
<<<<<<< HEAD
290296
Emails::DestroyService.new(user, email: email.email).execute
297+
=======
298+
check_unmodified_since(email.updated_at)
299+
300+
email.destroy
301+
user.update_secondary_emails!
302+
>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints
291303
end
292304

293305
desc 'Delete a user. Available only for admins.' do
@@ -299,11 +311,18 @@ def find_user(params)
299311
end
300312
delete ":id" do
301313
authenticated_as_admin!
314+
302315
user = User.find_by(id: params[:id])
303316
not_found!('User') unless user
304317

318+
<<<<<<< HEAD
305319
status 204
306320
user.delete_async(deleted_by: current_user, params: params)
321+
=======
322+
check_unmodified_since(user.updated_at)
323+
324+
::Users::DestroyService.new(current_user).execute(user)
325+
>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints
307326
end
308327

309328
desc 'Block a user. Available only for admins.'
@@ -481,6 +500,8 @@ def find_impersonation_token
481500
key = current_user.keys.find_by(id: params[:key_id])
482501
not_found!('Key') unless key
483502

503+
check_unmodified_since(key.updated_at)
504+
484505
status 204
485506
key.destroy
486507
end
@@ -533,6 +554,7 @@ def find_impersonation_token
533554
email = current_user.emails.find_by(id: params[:email_id])
534555
not_found!('Email') unless email
535556

557+
<<<<<<< HEAD
536558
status 204
537559
Emails::DestroyService.new(current_user, email: email.email).execute
538560
end
@@ -550,6 +572,12 @@ def find_impersonation_token
550572
.reorder(last_activity_on: :asc)
551573

552574
present paginate(activities), with: Entities::UserActivity
575+
=======
576+
check_unmodified_since(email.updated_at)
577+
578+
email.destroy
579+
current_user.update_secondary_emails!
580+
>>>>>>> API: Respect the 'If-Unmodified-Since' for delete endpoints
553581
end
554582
end
555583
end

0 commit comments

Comments
 (0)