Commit 32c69651 authored by Steve Abrams's avatar Steve Abrams Committed by Etienne Baqué

Delete package file API

parent 8ee3d85f
---
title: Add API endpoint for deleting a package file
merge_request: 60970
author:
type: added
...@@ -352,3 +352,33 @@ Can return the following status codes: ...@@ -352,3 +352,33 @@ Can return the following status codes:
- `204 No Content`, if the package was deleted successfully. - `204 No Content`, if the package was deleted successfully.
- `404 Not Found`, if the package was not found. - `404 Not Found`, if the package was not found.
## Delete a package file
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32107) in GitLab 13.12.
WARNING:
Deleting a package file may corrupt your package making it unusable or unpullable from your package
manager client. When deleting a package file, be sure that you understand what you're doing.
Delete a package file:
```plaintext
DELETE /projects/:id/packages/:package_id/package_files/:package_file_id
```
| Attribute | Type | Required | Description |
| ----------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | ID or [URL-encoded path of the project](README.md#namespaced-path-encoding). |
| `package_id` | integer | yes | ID of a package. |
| `package_file_id` | integer | yes | ID of a package file. |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages/:package_id/package_files/:package_file_id"
```
Can return the following status codes:
- `204 No Content`: The package was deleted successfully.
- `403 Forbidden`: The user does not have permission to delete the file.
- `404 Not Found`: The package or package file was not found.
...@@ -30,6 +30,29 @@ module API ...@@ -30,6 +30,29 @@ module API
present paginate(package.package_files), with: ::API::Entities::PackageFile present paginate(package.package_files), with: ::API::Entities::PackageFile
end end
desc 'Remove a package file' do
detail 'This feature was introduced in GitLab 13.12'
end
params do
requires :package_file_id, type: Integer, desc: 'The ID of a package file'
end
delete ':id/packages/:package_id/package_files/:package_file_id' do
authorize_destroy_package!(user_project)
# We want to make sure the file belongs to the declared package
# so we look up the package before looking up the file.
package = ::Packages::PackageFinder
.new(user_project, params[:package_id]).execute
not_found! unless package
package_file = package.package_files.find_by_id(params[:package_file_id])
not_found! unless package_file
destroy_conditionally!(package_file)
end
end end
end end
end end
...@@ -7,13 +7,13 @@ RSpec.describe API::PackageFiles do ...@@ -7,13 +7,13 @@ RSpec.describe API::PackageFiles do
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let(:package) { create(:maven_package, project: project) } let(:package) { create(:maven_package, project: project) }
before do
project.add_developer(user)
end
describe 'GET /projects/:id/packages/:package_id/package_files' do describe 'GET /projects/:id/packages/:package_id/package_files' do
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files" } let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files" }
before do
project.add_developer(user)
end
context 'without the need for a license' do context 'without the need for a license' do
context 'project is public' do context 'project is public' do
it 'returns 200' do it 'returns 200' do
...@@ -78,4 +78,77 @@ RSpec.describe API::PackageFiles do ...@@ -78,4 +78,77 @@ RSpec.describe API::PackageFiles do
end end
end end
end end
describe 'DELETE /projects/:id/packages/:package_id/package_files/:package_file_id' do
let(:package_file_id) { package.package_files.first.id }
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files/#{package_file_id}" }
subject(:api_request) { delete api(url, user) }
context 'project is public' do
context 'without user' do
let(:user) { nil }
it 'returns 403 for non authenticated user', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
it 'returns 403 for a user without access to the project', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'project is private' do
let_it_be_with_refind(:project) { create(:project, :private) }
it 'returns 404 for a user without access to the project', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns 403 for a user without enough permissions', :aggregate_failures do
project.add_developer(user)
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
it 'returns 204', :aggregate_failures do
project.add_maintainer(user)
expect { api_request }.to change { package.package_files.count }.by(-1)
expect(response).to have_gitlab_http_status(:no_content)
end
context 'without user' do
let(:user) { nil }
it 'returns 404 for non authenticated user', :aggregate_failures do
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'invalid file' do
let(:url) { "/projects/#{project.id}/packages/#{package.id}/package_files/999999" }
it 'returns 404 when the package file does not exist', :aggregate_failures do
project.add_maintainer(user)
expect { api_request }.not_to change { package.package_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment