BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
e80313f9
Commit
e80313f9
authored
Mar 02, 2017
by
Robert Schilling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Conditionally destroy a ressource
parent
998afa5f
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
71 additions
and
114 deletions
+71
-114
access_requests.rb
lib/api/access_requests.rb
+5
-6
award_emoji.rb
lib/api/award_emoji.rb
+1
-3
boards.rb
lib/api/boards.rb
+5
-6
broadcast_messages.rb
lib/api/broadcast_messages.rb
+1
-3
deploy_keys.rb
lib/api/deploy_keys.rb
+1
-4
environments.rb
lib/api/environments.rb
+1
-3
groups.rb
lib/api/groups.rb
+3
-4
helpers.rb
lib/api/helpers.rb
+14
-3
issues.rb
lib/api/issues.rb
+1
-3
labels.rb
lib/api/labels.rb
+1
-4
members.rb
lib/api/members.rb
+3
-4
merge_requests.rb
lib/api/merge_requests.rb
+1
-3
notes.rb
lib/api/notes.rb
+3
-3
project_hooks.rb
lib/api/project_hooks.rb
+1
-4
project_snippets.rb
lib/api/project_snippets.rb
+1
-3
projects.rb
lib/api/projects.rb
+3
-2
runner.rb
lib/api/runner.rb
+4
-2
runners.rb
lib/api/runners.rb
+2
-5
services.rb
lib/api/services.rb
+2
-2
snippets.rb
lib/api/snippets.rb
+1
-3
system_hooks.rb
lib/api/system_hooks.rb
+1
-4
triggers.rb
lib/api/triggers.rb
+1
-4
users.rb
lib/api/users.rb
+13
-34
tags_spec.rb
spec/requests/api/tags_spec.rb
+2
-2
No files found.
lib/api/access_requests.rb
View file @
e80313f9
...
@@ -67,13 +67,12 @@ module API
...
@@ -67,13 +67,12 @@ module API
end
end
delete
":id/access_requests/:user_id"
do
delete
":id/access_requests/:user_id"
do
source
=
find_source
(
source_type
,
params
[
:id
])
source
=
find_source
(
source_type
,
params
[
:id
])
member
=
source
.
public_send
(
:requesters
)
.
find_by!
(
user_id:
params
[
:user_id
])
member
=
source
.
requesters
.
find_by!
(
user_id:
params
[
:user_id
])
check_unmodified_since
(
member
.
updated_at
)
destroy_conditionally!
(
member
)
do
::
Members
::
DestroyService
.
new
(
source
,
current_user
,
params
)
status
204
.
execute
(
:requesters
)
::
Members
::
DestroyService
.
new
(
source
,
current_user
,
params
)
end
.
execute
(
:requesters
)
end
end
end
end
end
end
...
...
lib/api/award_emoji.rb
View file @
e80313f9
...
@@ -85,12 +85,10 @@ module API
...
@@ -85,12 +85,10 @@ module API
end
end
delete
"
#{
endpoint
}
/:award_id"
do
delete
"
#{
endpoint
}
/:award_id"
do
award
=
awardable
.
award_emoji
.
find
(
params
[
:award_id
])
award
=
awardable
.
award_emoji
.
find
(
params
[
:award_id
])
check_unmodified_since
(
award
.
updated_at
)
unauthorized!
unless
award
.
user
==
current_user
||
current_user
.
admin?
unauthorized!
unless
award
.
user
==
current_user
||
current_user
.
admin?
status
204
destroy_conditionally!
(
award
)
award
.
destroy
end
end
end
end
end
end
...
...
lib/api/boards.rb
View file @
e80313f9
...
@@ -122,14 +122,13 @@ module API
...
@@ -122,14 +122,13 @@ module API
end
end
delete
"/lists/:list_id"
do
delete
"/lists/:list_id"
do
authorize!
(
:admin_list
,
user_project
)
authorize!
(
:admin_list
,
user_project
)
list
=
board_lists
.
find
(
params
[
:list_id
])
list
=
board_lists
.
find
(
params
[
:list_id
])
check_unmodified_since
(
list
.
updated_at
)
service
=
::
Boards
::
Lists
::
DestroyService
.
new
(
user_project
,
current_user
)
unless
service
.
execute
(
list
)
destroy_conditionally!
(
list
)
do
|
list
|
render_api_error!
({
error:
'List could not be deleted!'
},
400
)
service
=
::
Boards
::
Lists
::
DestroyService
.
new
(
user_project
,
current_user
)
unless
service
.
execute
(
list
)
render_api_error!
({
error:
'List could not be deleted!'
},
400
)
end
end
end
end
end
end
end
...
...
lib/api/broadcast_messages.rb
View file @
e80313f9
...
@@ -90,10 +90,8 @@ module API
...
@@ -90,10 +90,8 @@ module API
end
end
delete
':id'
do
delete
':id'
do
message
=
find_message
message
=
find_message
check_unmodified_since
(
message
.
updated_at
)
status
204
destroy_conditionally!
(
message
)
message
.
destroy
end
end
end
end
end
end
...
...
lib/api/deploy_keys.rb
View file @
e80313f9
...
@@ -125,10 +125,7 @@ module API
...
@@ -125,10 +125,7 @@ module API
key
=
user_project
.
deploy_keys_projects
.
find_by
(
deploy_key_id:
params
[
:key_id
])
key
=
user_project
.
deploy_keys_projects
.
find_by
(
deploy_key_id:
params
[
:key_id
])
not_found!
(
'Deploy Key'
)
unless
key
not_found!
(
'Deploy Key'
)
unless
key
check_unmodified_since
(
key
.
updated_at
)
destroy_conditionally!
(
key
)
status
204
key
.
destroy
end
end
end
end
end
end
...
...
lib/api/environments.rb
View file @
e80313f9
...
@@ -78,10 +78,8 @@ module API
...
@@ -78,10 +78,8 @@ module API
authorize!
:update_environment
,
user_project
authorize!
:update_environment
,
user_project
environment
=
user_project
.
environments
.
find
(
params
[
:environment_id
])
environment
=
user_project
.
environments
.
find
(
params
[
:environment_id
])
check_unmodified_since
(
environment
.
updated_at
)
status
204
destroy_conditionally!
(
environment
)
environment
.
destroy
end
end
desc
'Stops an existing environment'
do
desc
'Stops an existing environment'
do
...
...
lib/api/groups.rb
View file @
e80313f9
...
@@ -117,11 +117,10 @@ module API
...
@@ -117,11 +117,10 @@ module API
delete
":id"
do
delete
":id"
do
group
=
find_group!
(
params
[
:id
])
group
=
find_group!
(
params
[
:id
])
authorize!
:admin_group
,
group
authorize!
:admin_group
,
group
check_unmodified_since
(
group
.
updated_at
)
status
204
destroy_conditionally!
(
group
)
do
|
group
|
::
Groups
::
DestroyService
.
new
(
group
,
current_user
).
execute
::
Groups
::
DestroyService
.
new
(
group
,
current_user
).
execute
end
end
end
desc
'Get a list of projects in this group.'
do
desc
'Get a list of projects in this group.'
do
...
...
lib/api/helpers.rb
View file @
e80313f9
...
@@ -11,14 +11,25 @@ module API
...
@@ -11,14 +11,25 @@ module API
declared
(
params
,
options
).
to_h
.
symbolize_keys
declared
(
params
,
options
).
to_h
.
symbolize_keys
end
end
def
check_unmodified_since
(
last_modified
)
def
check_unmodified_since
!
(
last_modified
)
if_unmodified_since
=
Time
.
parse
(
headers
[
'If-Unmodified-Since'
])
if
headers
.
key?
(
'If-Unmodified-Since'
)
rescue
nil
if_unmodified_since
=
Time
.
parse
(
headers
[
'If-Unmodified-Since'
])
rescue
nil
if
if_unmodified_since
&&
if_unmodified_since
<
last_modified
if
if_unmodified_since
&&
last_modified
>
if_unmodified_since
render_api_error!
(
'412 Precondition Failed'
,
412
)
render_api_error!
(
'412 Precondition Failed'
,
412
)
end
end
end
end
def
destroy_conditionally!
(
resource
,
last_update_field: :updated_at
)
check_unmodified_since!
(
resource
.
public_send
(
last_update_field
))
status
204
if
block_given?
yield
resource
else
resource
.
destroy
end
end
def
current_user
def
current_user
return
@current_user
if
defined?
(
@current_user
)
return
@current_user
if
defined?
(
@current_user
)
...
...
lib/api/issues.rb
View file @
e80313f9
...
@@ -230,10 +230,8 @@ module API
...
@@ -230,10 +230,8 @@ module API
not_found!
(
'Issue'
)
unless
issue
not_found!
(
'Issue'
)
unless
issue
authorize!
(
:destroy_issue
,
issue
)
authorize!
(
:destroy_issue
,
issue
)
check_unmodified_since
(
issue
.
updated_at
)
status
204
destroy_conditionally!
(
issue
)
issue
.
destroy
end
end
desc
'List merge requests closing issue'
do
desc
'List merge requests closing issue'
do
...
...
lib/api/labels.rb
View file @
e80313f9
...
@@ -56,10 +56,7 @@ module API
...
@@ -56,10 +56,7 @@ module API
label
=
user_project
.
labels
.
find_by
(
title:
params
[
:name
])
label
=
user_project
.
labels
.
find_by
(
title:
params
[
:name
])
not_found!
(
'Label'
)
unless
label
not_found!
(
'Label'
)
unless
label
check_unmodified_since
(
label
.
updated_at
)
destroy_conditionally!
(
label
)
status
204
label
.
destroy
end
end
desc
'Update an existing label. At least one optional parameter is required.'
do
desc
'Update an existing label. At least one optional parameter is required.'
do
...
...
lib/api/members.rb
View file @
e80313f9
...
@@ -93,12 +93,11 @@ module API
...
@@ -93,12 +93,11 @@ module API
end
end
delete
":id/members/:user_id"
do
delete
":id/members/:user_id"
do
source
=
find_source
(
source_type
,
params
[
:id
])
source
=
find_source
(
source_type
,
params
[
:id
])
# Ensure that memeber exists
member
=
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
destroy_conditionally!
(
member
)
do
::
Members
::
DestroyService
.
new
(
source
,
current_user
,
declared_params
).
execute
::
Members
::
DestroyService
.
new
(
source
,
current_user
,
declared_params
).
execute
end
end
end
end
end
end
end
...
...
lib/api/merge_requests.rb
View file @
e80313f9
...
@@ -164,10 +164,8 @@ module API
...
@@ -164,10 +164,8 @@ module API
merge_request
=
find_project_merge_request
(
params
[
:merge_request_iid
])
merge_request
=
find_project_merge_request
(
params
[
:merge_request_iid
])
authorize!
(
:destroy_merge_request
,
merge_request
)
authorize!
(
:destroy_merge_request
,
merge_request
)
check_unmodified_since
(
merge_request
.
updated_at
)
status
204
destroy_conditionally!
(
merge_request
)
merge_request
.
destroy
end
end
params
do
params
do
...
...
lib/api/notes.rb
View file @
e80313f9
...
@@ -131,10 +131,10 @@ module API
...
@@ -131,10 +131,10 @@ module API
note
=
user_project
.
notes
.
find
(
params
[
:note_id
])
note
=
user_project
.
notes
.
find
(
params
[
:note_id
])
authorize!
:admin_note
,
note
authorize!
:admin_note
,
note
check_unmodified_since
(
note
.
updated_at
)
status
204
destroy_conditionally!
(
note
)
do
|
note
|
::
Notes
::
DestroyService
.
new
(
user_project
,
current_user
).
execute
(
note
)
::
Notes
::
DestroyService
.
new
(
user_project
,
current_user
).
execute
(
note
)
end
end
end
end
end
end
end
...
...
lib/api/project_hooks.rb
View file @
e80313f9
...
@@ -96,10 +96,7 @@ module API
...
@@ -96,10 +96,7 @@ module API
delete
":id/hooks/:hook_id"
do
delete
":id/hooks/:hook_id"
do
hook
=
user_project
.
hooks
.
find
(
params
.
delete
(
:hook_id
))
hook
=
user_project
.
hooks
.
find
(
params
.
delete
(
:hook_id
))
check_unmodified_since
(
hook
.
updated_at
)
destroy_conditionally!
(
hook
)
status
204
hook
.
destroy
end
end
end
end
end
end
...
...
lib/api/project_snippets.rb
View file @
e80313f9
...
@@ -116,10 +116,8 @@ module API
...
@@ -116,10 +116,8 @@ module API
not_found!
(
'Snippet'
)
unless
snippet
not_found!
(
'Snippet'
)
unless
snippet
authorize!
:admin_project_snippet
,
snippet
authorize!
:admin_project_snippet
,
snippet
check_unmodified_since
(
snippet
.
updated_at
)
status
204
destroy_conditionally!
(
snippet
)
snippet
.
destroy
end
end
desc
'Get a raw project snippet'
desc
'Get a raw project snippet'
...
...
lib/api/projects.rb
View file @
e80313f9
...
@@ -334,9 +334,10 @@ module API
...
@@ -334,9 +334,10 @@ module API
desc
'Remove a project'
desc
'Remove a project'
delete
":id"
do
delete
":id"
do
authorize!
:remove_project
,
user_project
authorize!
:remove_project
,
user_project
check_unmodified_since
(
user_project
.
updated_at
)
::
Projects
::
DestroyService
.
new
(
user_project
,
current_user
,
{}).
async_execute
destroy_conditionally!
(
user_project
)
do
::
Projects
::
DestroyService
.
new
(
user_project
,
current_user
,
{}).
async_execute
end
accepted!
accepted!
end
end
...
...
lib/api/runner.rb
View file @
e80313f9
...
@@ -45,8 +45,10 @@ module API
...
@@ -45,8 +45,10 @@ module API
end
end
delete
'/'
do
delete
'/'
do
authenticate_runner!
authenticate_runner!
status
204
Ci
::
Runner
.
find_by_token
(
params
[
:token
]).
destroy
runner
=
Ci
::
Runner
.
find_by_token
(
params
[
:token
])
destroy_conditionally!
(
runner
)
end
end
desc
'Validates authentication credentials'
do
desc
'Validates authentication credentials'
do
...
...
lib/api/runners.rb
View file @
e80313f9
...
@@ -79,10 +79,8 @@ module API
...
@@ -79,10 +79,8 @@ module API
runner
=
get_runner
(
params
[
:id
])
runner
=
get_runner
(
params
[
:id
])
authenticate_delete_runner!
(
runner
)
authenticate_delete_runner!
(
runner
)
check_unmodified_since
(
runner
.
updated_at
)
status
204
destroy_conditionally!
(
runner
)
runner
.
destroy!
end
end
end
end
...
@@ -137,8 +135,7 @@ module API
...
@@ -137,8 +135,7 @@ module API
runner
=
runner_project
.
runner
runner
=
runner_project
.
runner
forbidden!
(
"Only one project associated with the runner. Please remove the runner instead"
)
if
runner
.
projects
.
count
==
1
forbidden!
(
"Only one project associated with the runner. Please remove the runner instead"
)
if
runner
.
projects
.
count
==
1
status
204
destroy_conditionally!
(
runner_project
)
runner_project
.
destroy
end
end
end
end
...
...
lib/api/services.rb
View file @
e80313f9
...
@@ -655,8 +655,8 @@ module API
...
@@ -655,8 +655,8 @@ module API
end
end
delete
":id/services/:service_slug"
do
delete
":id/services/:service_slug"
do
service
=
user_project
.
find_or_initialize_service
(
params
[
:service_slug
].
underscore
)
service
=
user_project
.
find_or_initialize_service
(
params
[
:service_slug
].
underscore
)
# Todo
, not sure
# Todo
: Check if this done the right way
check_unmodified_since
(
service
.
updated_at
)
check_unmodified_since
!
(
service
.
updated_at
)
attrs
=
service_attributes
(
service
).
inject
({})
do
|
hash
,
key
|
attrs
=
service_attributes
(
service
).
inject
({})
do
|
hash
,
key
|
hash
.
merge!
(
key
=>
nil
)
hash
.
merge!
(
key
=>
nil
)
...
...
lib/api/snippets.rb
View file @
e80313f9
...
@@ -122,10 +122,8 @@ module API
...
@@ -122,10 +122,8 @@ module API
return
not_found!
(
'Snippet'
)
unless
snippet
return
not_found!
(
'Snippet'
)
unless
snippet
authorize!
:destroy_personal_snippet
,
snippet
authorize!
:destroy_personal_snippet
,
snippet
check_unmodified_since
(
snippet
.
updated_at
)
status
204
destroy_conditionally!
(
snippet
)
snippet
.
destroy
end
end
desc
'Get a raw snippet'
do
desc
'Get a raw snippet'
do
...
...
lib/api/system_hooks.rb
View file @
e80313f9
...
@@ -66,10 +66,7 @@ module API
...
@@ -66,10 +66,7 @@ module API
hook
=
SystemHook
.
find_by
(
id:
params
[
:id
])
hook
=
SystemHook
.
find_by
(
id:
params
[
:id
])
not_found!
(
'System hook'
)
unless
hook
not_found!
(
'System hook'
)
unless
hook
check_unmodified_since
(
hook
.
updated_at
)
destroy_conditionally!
(
hook
)
status
204
hook
.
destroy
end
end
end
end
end
end
...
...
lib/api/triggers.rb
View file @
e80313f9
...
@@ -140,10 +140,7 @@ module API
...
@@ -140,10 +140,7 @@ module API
trigger
=
user_project
.
triggers
.
find
(
params
.
delete
(
:trigger_id
))
trigger
=
user_project
.
triggers
.
find
(
params
.
delete
(
:trigger_id
))
return
not_found!
(
'Trigger'
)
unless
trigger
return
not_found!
(
'Trigger'
)
unless
trigger
check_unmodified_since
(
trigger
.
updated_at
)
destroy_conditionally!
(
trigger
)
status
204
trigger
.
destroy
end
end
end
end
end
end
...
...
lib/api/users.rb
View file @
e80313f9
...
@@ -230,13 +230,7 @@ module API
...
@@ -230,13 +230,7 @@ module API
key
=
user
.
keys
.
find_by
(
id:
params
[
:key_id
])
key
=
user
.
keys
.
find_by
(
id:
params
[
:key_id
])
not_found!
(
'Key'
)
unless
key
not_found!
(
'Key'
)
unless
key
<<<<<<<
HEAD
destroy_conditionally!
(
key
)
status
204
=======
check_unmodified_since
(
key
.
updated_at
)
>>>>>>>
API
:
Respect
the
'If-Unmodified-Since'
for
delete
endpoints
key
.
destroy
end
end
desc
'Add an email address to a specified user. Available only for admins.'
do
desc
'Add an email address to a specified user. Available only for admins.'
do
...
@@ -292,14 +286,11 @@ module API
...
@@ -292,14 +286,11 @@ module API
email
=
user
.
emails
.
find_by
(
id:
params
[
:email_id
])
email
=
user
.
emails
.
find_by
(
id:
params
[
:email_id
])
not_found!
(
'Email'
)
unless
email
not_found!
(
'Email'
)
unless
email
<<<<<<<
HEAD
destroy_conditionally!
(
email
)
do
|
email
|
Emails
::
DestroyService
.
new
(
user
,
email:
email
.
email
).
execute
Emails
::
DestroyService
.
new
(
current_user
,
email:
email
.
email
).
execute
=======
end
check_unmodified_since
(
email
.
updated_at
)
email
.
destroy
user
.
update_secondary_emails!
user
.
update_secondary_emails!
>>>>>>>
API
:
Respect
the
'If-Unmodified-Since'
for
delete
endpoints
end
end
desc
'Delete a user. Available only for admins.'
do
desc
'Delete a user. Available only for admins.'
do
...
@@ -315,14 +306,9 @@ module API
...
@@ -315,14 +306,9 @@ module API
user
=
User
.
find_by
(
id:
params
[
:id
])
user
=
User
.
find_by
(
id:
params
[
:id
])
not_found!
(
'User'
)
unless
user
not_found!
(
'User'
)
unless
user
<<<<<<<
HEAD
destroy_conditionally!
(
user
)
do
status
204
user
.
delete_async
(
deleted_by:
current_user
,
params:
params
)
user
.
delete_async
(
deleted_by:
current_user
,
params:
params
)
end
=======
check_unmodified_since
(
user
.
updated_at
)
::
Users
::
DestroyService
.
new
(
current_user
).
execute
(
user
)
>>>>>>>
API
:
Respect
the
'If-Unmodified-Since'
for
delete
endpoints
end
end
desc
'Block a user. Available only for admins.'
desc
'Block a user. Available only for admins.'
...
@@ -500,10 +486,7 @@ module API
...
@@ -500,10 +486,7 @@ module API
key
=
current_user
.
keys
.
find_by
(
id:
params
[
:key_id
])
key
=
current_user
.
keys
.
find_by
(
id:
params
[
:key_id
])
not_found!
(
'Key'
)
unless
key
not_found!
(
'Key'
)
unless
key
check_unmodified_since
(
key
.
updated_at
)
destroy_conditionally!
(
key
)
status
204
key
.
destroy
end
end
desc
"Get the currently authenticated user's email addresses"
do
desc
"Get the currently authenticated user's email addresses"
do
...
@@ -554,9 +537,11 @@ module API
...
@@ -554,9 +537,11 @@ module API
email
=
current_user
.
emails
.
find_by
(
id:
params
[
:email_id
])
email
=
current_user
.
emails
.
find_by
(
id:
params
[
:email_id
])
not_found!
(
'Email'
)
unless
email
not_found!
(
'Email'
)
unless
email
<<<<<<<
HEAD
destroy_conditionally!
(
email
)
do
|
email
|
status
204
Emails
::
DestroyService
.
new
(
current_user
,
email:
email
.
email
).
execute
Emails
::
DestroyService
.
new
(
current_user
,
email:
email
.
email
).
execute
end
current_user
.
update_secondary_emails!
end
end
desc
'Get a list of user activities'
desc
'Get a list of user activities'
...
@@ -572,12 +557,6 @@ module API
...
@@ -572,12 +557,6 @@ module API
.
reorder
(
last_activity_on: :asc
)
.
reorder
(
last_activity_on: :asc
)
present
paginate
(
activities
),
with:
Entities
::
UserActivity
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
end
end
end
...
...
spec/requests/api/tags_spec.rb
View file @
e80313f9
...
@@ -283,7 +283,7 @@ describe API::Tags do
...
@@ -283,7 +283,7 @@ describe API::Tags do
it_behaves_like
'404 response'
do
it_behaves_like
'404 response'
do
let
(
:request
)
{
delete
api
(
route
,
current_user
)
}
let
(
:request
)
{
delete
api
(
route
,
current_user
)
}
let
(
:message
)
{
'
No such tag
'
}
let
(
:message
)
{
'
404 Tag Not Found
'
}
end
end
end
end
...
@@ -394,7 +394,7 @@ describe API::Tags do
...
@@ -394,7 +394,7 @@ describe API::Tags do
it_behaves_like
'404 response'
do
it_behaves_like
'404 response'
do
let
(
:request
)
{
put
api
(
route
,
current_user
),
description:
new_description
}
let
(
:request
)
{
put
api
(
route
,
current_user
),
description:
new_description
}
let
(
:message
)
{
'
Tag does not exist
'
}
let
(
:message
)
{
'
404 Tag Not Found
'
}
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment