limit creation of file_links to 20 at once

pull/10331/head
Christophe Bliard 3 years ago
parent 4722323d12
commit 0e99279bd5
No known key found for this signature in database
GPG Key ID: 2BC07603210C3FA4
  1. 14
      docs/api/apiv3/paths/work_package_file_links.yml
  2. 2
      lib/api/utilities/endpoints/bodied.rb
  3. 4
      modules/storages/config/locales/en.yml
  4. 50
      modules/storages/lib/api/v3/file_links/parse_create_params_service.rb
  5. 36
      modules/storages/spec/requests/api/v3/file_links/file_links_spec.rb

@ -11,10 +11,10 @@ post:
The request body must contain the generated storage token, and not the storage id. In addition, the request must
send the origin file id and the stored meta data.
If there is already a link on the given work package with the same file id from the same storage, the previous
data is not overwritten.
Up to 20 file links can be submitted at once. If there is already a link on the given work package with the same
file id from the same storage, the previous data is not overwritten.
As it is possible to link folders from a storage to a work package, the _mimeType_ of this entity can be empty.
parameters:
- name: id
@ -44,7 +44,7 @@ post:
_links:
storageUrl:
href: https://nextcloud.deathstar.rocks/
responses:
'201':
description: Created
@ -137,9 +137,9 @@ get:
message: You are not authorized to access this resource.
description: |-
Returned if the client does not have sufficient permissions.
**Required permission:** view file links
*Note that you will only receive this error, if you are at least allowed to see the corresponding work package.*
'404':
content:

@ -84,7 +84,7 @@ module API
endpoint = self
-> do
request = self # proc is executed in the context of the request
request = self # proc is executed in the context of the grape request
endpoint.before_hook&.(request: request)
params = endpoint.parse(request)
call = endpoint.process(request, params)

@ -25,6 +25,10 @@ en:
minimal_nextcloud_version_unmet: "does not meet minimal version requirements (must be Nextcloud 23 or higher)"
not_nextcloud_server: "is not a Nextcloud server"
api_v3:
errors:
too_many_elements_created_at_once: "Too many elements created at once. Expected %{max} at most, got %{actual}."
storages:
page_titles:
project_settings:

@ -28,28 +28,58 @@
module API::V3::FileLinks
class ParseCreateParamsService < ::API::ParseResourceParamsService
MAX_ELEMENTS = 20
attr_reader :request_body
def call(request_body)
@request_body = request_body
ServiceResult.new(
success: true,
result: parse_elements(request_body)
result: parse_elements
)
end
def parse_elements(request_body)
request_body.dig("_embedded", "elements")
.tap { ensure_valid_elements(_1) }
.map do |params|
private
def parse_elements
assert_valid_elements
elements.map do |element|
API::V3::FileLinks::FileLinkRepresenter
.new(Hashie::Mash.new, current_user: current_user)
.from_hash(params)
.from_hash(element)
end
end
private
def elements
@elements ||= request_body.dig("_embedded", "elements")
end
def assert_valid_elements
assert_elements_is_present
assert_elements_is_an_array
assert_elements_does_not_exceed_maximum
end
def assert_elements_is_present
return if elements.present?
raise API::Errors::PropertyMissingError.new('_embedded/elements')
end
def assert_elements_is_an_array
return if elements.is_a?(Array)
raise API::Errors::PropertyFormatError.new('_embedded/elements', 'Array', elements.class.name)
end
def assert_elements_does_not_exceed_maximum
return if elements.size <= MAX_ELEMENTS
def ensure_valid_elements(elements)
raise API::Errors::PropertyMissingError.new('_embedded/elements') if elements.blank?
raise API::Errors::PropertyFormatError.new('_embedded/elements', 'Array', elements.class.name) unless elements.is_a?(Array)
raise API::Errors::Validation.new('_embedded/elements',
I18n.t('api_v3.errors.too_many_elements_created_at_once',
max: MAX_ELEMENTS, actual: elements.size))
end
end
end

@ -183,6 +183,42 @@ describe 'API v3 file links resource', type: :request do
expected_format: 'Array',
actual: 'Integer')
end
# rubocop:disable RSpec/MultipleMemoizedHelpers
context "when more than #{API::V3::FileLinks::ParseCreateParamsService::MAX_ELEMENTS} embedded elements" do
let(:max) { API::V3::FileLinks::ParseCreateParamsService::MAX_ELEMENTS }
let(:too_many) { max + 1 }
let(:params) do
{
_type: "Collection",
_embedded: {
elements: 1.upto(too_many).map do |id|
{
originData: {
id: id,
name: "logo#{id}.png",
mimeType: "image/png",
createdAt: "2021-12-19T09:42:10.170Z",
lastModifiedAt: "2021-12-20T14:00:13.987Z",
createdByName: "Luke Skywalker",
lastModifiedByName: "Anakin Skywalker"
},
_links: {
storageUrl: {
href: storage_url1
}
}
}
end
}
}
end
it_behaves_like 'constraint violation' do
let(:message) { "Too many elements created at once. Expected #{max} at most, got #{too_many}." }
end
end
# rubocop:enable RSpec/MultipleMemoizedHelpers
end
describe 'GET /api/v3/file_links/:file_link_id' do

Loading…
Cancel
Save