diff --git a/modules/storages/lib/api/v3/storages/storage_open_api.rb b/modules/storages/lib/api/v3/storages/storage_open_api.rb index be0d7d2c34c7..4159cc34af03 100644 --- a/modules/storages/lib/api/v3/storages/storage_open_api.rb +++ b/modules/storages/lib/api/v3/storages/storage_open_api.rb @@ -35,7 +35,7 @@ class API::V3::Storages::StorageOpenAPI < API::OpenProjectAPI get do Storages::Peripherals::Registry .resolve("queries.#{@storage.short_provider_type}.open_storage") - .call(storage: @storage, user: current_user, file_id: nil) + .call(storage: @storage, user: current_user) .match( on_success: ->(url) do redirect url, body: "The requested resource can be viewed at #{url}" diff --git a/modules/storages/spec/requests/api/v3/project_storages/project_storages_spec.rb b/modules/storages/spec/requests/api/v3/project_storages/project_storages_spec.rb index a72f3cb680e0..5f05963f82c9 100644 --- a/modules/storages/spec/requests/api/v3/project_storages/project_storages_spec.rb +++ b/modules/storages/spec/requests/api/v3/project_storages/project_storages_spec.rb @@ -237,4 +237,61 @@ it_behaves_like 'not found' end end + + describe 'GET /api/v3/project_storages/:id/open' do + let(:path) { api_v3_paths.project_storage_open(project_storage11.id) } + let(:location) { 'https://deathstar.storage.org/files' } + let(:location_project_folder) { 'https://deathstar.storage.org/files/data/project_destroy_alderan' } + let(:current_user) do + create(:user, member_with_permissions: { project1 => view_permissions }) + end + + before do + Storages::Peripherals::Registry.stub( + 'queries.nextcloud.open_storage', + ->(_) { ServiceResult.success(result: location) } + ) + Storages::Peripherals::Registry.stub( + 'queries.nextcloud.open_file_link', + ->(_) { ServiceResult.success(result: location_project_folder) } + ) + end + + context 'as admin' do + let(:current_user) { create(:admin) } + + it_behaves_like 'redirect response' + end + + context 'if user belongs to a project related to project storage' do + it_behaves_like 'redirect response' + + context 'if project storage has a configured project folder' do + let!(:project_storage12) do + create(:project_storage, + project: project1, + storage: storage2, + project_folder_id: '1337', + project_folder_mode: 'manual') + end + let(:path) { api_v3_paths.project_storage_open(project_storage12.id) } + + it_behaves_like 'redirect response' do + let(:location) { location_project_folder } + end + end + + context 'if user is missing permission view_file_links' do + let(:view_permissions) { [] } + + it_behaves_like 'not found' + end + end + + context 'if user is not member of the project' do + let(:path) { api_v3_paths.project_storage_open(project_storage21.id) } + + it_behaves_like 'not found' + end + end end diff --git a/modules/storages/spec/requests/api/v3/storages/storages_api_spec.rb b/modules/storages/spec/requests/api/v3/storages/storages_api_spec.rb index 72713642ae0e..649840dcfb4e 100644 --- a/modules/storages/spec/requests/api/v3/storages/storages_api_spec.rb +++ b/modules/storages/spec/requests/api/v3/storages/storages_api_spec.rb @@ -407,6 +407,40 @@ end end + describe 'GET /api/v3/storages/:storage_id/open' do + let(:path) { api_v3_paths.storage_open(storage.id) } + let(:location) { 'https://deathstar.storage.org/files' } + + before do + Storages::Peripherals::Registry.stub( + 'queries.nextcloud.open_storage', + ->(_) { ServiceResult.success(result: location) } + ) + end + + context 'as admin' do + let(:current_user) { create(:admin) } + + it_behaves_like 'redirect response' + end + + context 'if user belongs to a project using the given storage' do + it_behaves_like 'redirect response' + + context 'if user is missing permission view_file_links' do + let(:permissions) { [] } + + it_behaves_like 'not found' + end + + context 'if no storage with that id exists' do + let(:path) { api_v3_paths.storage_open('1337') } + + it_behaves_like 'not found' + end + end + end + describe 'POST /api/v3/storages/:storage_id/oauth_client_credentials' do let(:path) { api_v3_paths.storage_oauth_client_credentials(storage.id) } let(:client_id) { 'myl1ttlecl13ntidii' } diff --git a/spec/requests/api/v3/support/response_examples.rb b/spec/requests/api/v3/support/response_examples.rb index b318d5bad36f..807215133e7d 100644 --- a/spec/requests/api/v3/support/response_examples.rb +++ b/spec/requests/api/v3/support/response_examples.rb @@ -46,6 +46,18 @@ end end +RSpec.shared_examples_for 'redirect response' do |code = 303| + let(:location) { '' } + + it "has the status code #{code}" do + expect(last_response.status).to eq(code) + end + + it 'redirects to expected location' do + expect(last_response.headers['Location']).to eq(location) + end +end + RSpec.shared_examples_for 'error response' do |code, id, provided_message = nil| let(:expected_message) do provided_message || message @@ -113,7 +125,7 @@ it 'shows the given details' do if details expect(last_response.body).to be_json_eql(details.to_json) - .at_path('_embedded/details/parseError') + .at_path('_embedded/details/parseError') end end end