From 3c299df27d7472397125d88a3624dc4846e910b5 Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 14:18:32 +0000 Subject: [PATCH 1/7] Add docs for list api for file uploads Changelog: added --- doc/api/projects.md | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/doc/api/projects.md b/doc/api/projects.md index d53c515bfbe1a9..d20b359582b65a 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -2215,7 +2215,9 @@ POST /projects/:id/restore |-----------|----------------|------------------------|-------------| | `id` | integer or string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). | -## Upload a file +## File uploads + +### Upload a file Uploads a file to the specified project to be used in an issue or merge request description, or a comment. GitLab versions 14.0 and later @@ -2255,7 +2257,7 @@ The returned `url` is relative to the project path. The returned `full_path` is the absolute path to the file. In Markdown contexts, the link is expanded when the format in `markdown` is used. -### Max attachment size enforcement +#### Max attachment size enforcement > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57250) in GitLab 13.11. @@ -2291,6 +2293,43 @@ To disable this enforcement: Feature.disable(:enforce_max_attachment_size_upload_api) ``` +### List uploaded files + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/111444) in GitLab 15.9 + +Lists files in the specified project that may be used in an issue or merge request description, or a comment. + +```plaintext +GET /projects/:id/uploads +``` + +| Attribute | Type | Required | Description | +|-----------|----------------|------------------------|-------------| +| `id` | integer or string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). | + +Example using curl: + +```shell +curl --request GET --header "PRIVATE-TOKEN: " \ + "https://gitlab.example.com/api/v4/projects/5/uploads" +``` + +Returned object: + +```json +[ + { + "alt": "dk", + "url": "/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png", + "full_path": "/namespace1/project1/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png", + "markdown": "![dk](/uploads/66dbcd21ec5d24ed6ea225176098d52b/dk.png)" + } +] +``` + +The returned `url` is relative to the project path. The returned `full_path` is the absolute path to the file. +In Markdown contexts, the link is expanded when the format in `markdown` is used. + ## Upload a project avatar Uploads an avatar to the specified project. -- GitLab From b646755b36a45d5dc0c2da00a193d907732b2226 Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 16:18:36 +0000 Subject: [PATCH 2/7] Add skeleton testcases --- spec/requests/api/projects_spec.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 1c8aec878eaa9c..dd4e1d6b2927a0 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -2227,6 +2227,32 @@ end end + describe "GET /projects/:id/uploads" do + # let!(:file) { fixture_file_upload("spec/fixtures/dk.png", "image/png") } + + context 'when unauthenticated' do + it 'does not return uploads for private projects' do + private_project = create(:project, :private) + get api("/projects/#{private_project.id}/uploads") + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'for public projects' do + it 'successful upload list response' do + public_project = create(:project) + get api("/projects/#{public_project.id}/uploads") + + binding.pry + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + end + end + end + end + describe 'GET /project/:id/share_locations' do let_it_be(:root_group) { create(:group, :public, name: 'root group') } let_it_be(:project_group1) { create(:group, :public, parent: root_group, name: 'group1') } -- GitLab From 4189b0ce213e6a78c7484b1973828ef963eacdab Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 16:19:23 +0000 Subject: [PATCH 3/7] Add naive implementation --- lib/api/projects.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index e1e756d8e8c249..a0ad746f78fe4e 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -808,6 +808,19 @@ def add_import_params(params) present upload, with: Entities::ProjectUpload end + desc 'List uploaded files' do + success code: 200, model: Entities::ProjectUpload + failure [ + { code: 404, message: 'Not found' } + ] + tags %w[projects] + end + get ":id/uploads", feature_category: :not_owned do # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned + upload = user_project.uploads + + present upload, with: Entities::ProjectUpload + end + desc 'Get the users list of a project' do success code: 200, model: Entities::UserBasic failure [ -- GitLab From dd9f60b8ecee62ba41a7f7fcec23d78398307f23 Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 16:26:21 +0000 Subject: [PATCH 4/7] Create public project, remove pry --- spec/requests/api/projects_spec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index dd4e1d6b2927a0..ab1119f4b226d6 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -2240,11 +2240,9 @@ context 'for public projects' do it 'successful upload list response' do - public_project = create(:project) + public_project = create(:project, :public) get api("/projects/#{public_project.id}/uploads") - binding.pry - expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array -- GitLab From 102d8742b5b042050f7b91256a83516ebeed981e Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 16:52:19 +0000 Subject: [PATCH 5/7] Attempt to create file uploads This currently fails with NoMethodError inside the get request to "uploads" due to ProjectUpload missing the markdown_name attribute. This probably means we need a new entity model (lib/api/entities) --- spec/requests/api/projects_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index ab1119f4b226d6..1c33df788db2c4 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -2228,7 +2228,6 @@ end describe "GET /projects/:id/uploads" do - # let!(:file) { fixture_file_upload("spec/fixtures/dk.png", "image/png") } context 'when unauthenticated' do it 'does not return uploads for private projects' do @@ -2241,6 +2240,7 @@ context 'for public projects' do it 'successful upload list response' do public_project = create(:project, :public) + create(:upload, :attachment_upload, :with_file, model: public_project) get api("/projects/#{public_project.id}/uploads") expect(response).to have_gitlab_http_status(:ok) -- GitLab From 3be8197fba68ccc4a2327027414c632c6294e14d Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 17:18:30 +0000 Subject: [PATCH 6/7] Add upload entity with minimal content --- lib/api/entities/upload.rb | 10 ++++++++++ lib/api/projects.rb | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 lib/api/entities/upload.rb diff --git a/lib/api/entities/upload.rb b/lib/api/entities/upload.rb new file mode 100644 index 00000000000000..1513aa6488853e --- /dev/null +++ b/lib/api/entities/upload.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module API + module Entities + class Upload < Grape::Entity + expose :path + end + end +end + diff --git a/lib/api/projects.rb b/lib/api/projects.rb index a0ad746f78fe4e..e1ffa63637423e 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -818,7 +818,7 @@ def add_import_params(params) get ":id/uploads", feature_category: :not_owned do # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned upload = user_project.uploads - present upload, with: Entities::ProjectUpload + present paginate(upload), with: Entities::Upload end desc 'Get the users list of a project' do -- GitLab From aa5b1030f0bf5f82ae70db2f0633ea3f79aa210f Mon Sep 17 00:00:00 2001 From: Jon Dybeck Date: Wed, 8 Feb 2023 17:19:16 +0000 Subject: [PATCH 7/7] Add pagination back into test --- spec/requests/api/projects_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 1c33df788db2c4..6b0c826ce1fd91 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -2243,6 +2243,8 @@ create(:upload, :attachment_upload, :with_file, model: public_project) get api("/projects/#{public_project.id}/uploads") + binding.pry + expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array -- GitLab